
/** @file  moal_eth_ioctl.c
  *
  * @brief This file contains private ioctl functions

  *
  * Copyright 2014-2021 NXP
  *
  * This software file (the File) is distributed by NXP
  * under the terms of the GNU General Public License Version 2, June 1991
  * (the License).  You may use, redistribute and/or modify the File in
  * accordance with the terms and conditions of the License, a copy of which
  * is available by writing to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
  * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
  *
  * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
  * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
  * this warranty disclaimer.
  *
  */

/************************************************************************
Change log:
    01/05/2012: initial version
************************************************************************/

#include "moal_main.h"
#include "moal_eth_ioctl.h"
#include "mlan_ioctl.h"
#if defined(STA_WEXT) || defined(UAP_WEXT)
#include "moal_priv.h"
#endif

#if defined(STA_CFG80211) || defined(UAP_CFG80211)
#include "moal_cfg80211.h"
#endif
#ifdef UAP_SUPPORT
#include "moal_uap.h"
#endif
#ifdef USB
#include "moal_usb.h"
#endif
#ifdef SDIO
#include "moal_sdio.h"
#endif
#ifdef PCIE
#include "moal_pcie.h"
#endif
#ifdef STA_CFG80211
#include "moal_sta_cfg80211.h"
#endif
#ifdef STA_CFG80211
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
#include "moal_cfg80211_util.h"
#endif
#endif

/********************************************************
			Local Variables
********************************************************/

/** Bands supported in Infra mode */
static t_u16 SupportedInfraBand[] = {
	BAND_B,
	BAND_B | BAND_G,
	BAND_G,
	BAND_GN,
	BAND_B | BAND_G | BAND_GN,
	BAND_G | BAND_GN,
	BAND_A,
	BAND_B | BAND_A,
	BAND_B | BAND_G | BAND_A,
	BAND_G | BAND_A,
	BAND_A | BAND_B | BAND_G | BAND_AN | BAND_GN,
	BAND_A | BAND_G | BAND_AN | BAND_GN,
	BAND_A | BAND_AN,
	BAND_GN | BAND_GAC,
	BAND_B | BAND_G | BAND_GN | BAND_GAC,
	BAND_G | BAND_GN | BAND_GAC,
	BAND_GN | BAND_GAC | BAND_GAX,
	BAND_B | BAND_G | BAND_GN | BAND_GAC | BAND_GAX,
	BAND_G | BAND_GN | BAND_GAC | BAND_GAX,
	BAND_A | BAND_B | BAND_G | BAND_AN | BAND_GN | BAND_AAC,
	BAND_A | BAND_B | BAND_G | BAND_AN | BAND_GN | BAND_AAC | BAND_GAC,
	BAND_A | BAND_G | BAND_AN | BAND_GN | BAND_AAC,
	BAND_A | BAND_AN | BAND_AAC,
	BAND_A | BAND_B | BAND_G | BAND_AN | BAND_GN | BAND_AAC | BAND_AAX,
	BAND_A | BAND_B | BAND_G | BAND_AN | BAND_GN | BAND_AAC | BAND_GAC |
		BAND_AAX,
	BAND_A | BAND_G | BAND_AN | BAND_GN | BAND_AAC | BAND_AAX,
	BAND_A | BAND_AN | BAND_AAC | BAND_AAX,
};

/** Bands supported in Ad-Hoc mode */
static t_u8 SupportedAdhocBand[] = {
	BAND_B,
	BAND_B | BAND_G,
	BAND_G,
	BAND_A,
};

/********************************************************
			Global Variables
********************************************************/
#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 29)
#ifdef UAP_SUPPORT
/** Network device handlers for uAP */
extern const struct net_device_ops woal_uap_netdev_ops;
#endif
#ifdef STA_SUPPORT
/** Network device handlers for STA */
extern const struct net_device_ops woal_netdev_ops;
#endif
#endif

/********************************************************
			Local Functions
********************************************************/
/**
 * @brief Parse a string to extract numerical arguments
 *
 * @param pos           Pointer to the arguments string
 * @param data          Pointer to the arguments buffer
 * @param datalen       Length of the arguments buffer
 * @param user_data_len Pointer to the number of arguments extracted
 *
 * @return              MLAN_STATUS_SUCCESS
 */
static mlan_status
parse_arguments(t_u8 *pos, int *data, int datalen, int *user_data_len)
{
	int i, j, k;
	char cdata[10];
	int is_hex = 0;

	if (strlen(pos) == 0) {
		*user_data_len = 0;
		return MLAN_STATUS_SUCCESS;
	}

	memset(cdata, 0, sizeof(cdata));
	for (i = 0, j = 0, k = 0; i <= (int)strlen(pos); i++) {
		if ((k == 0) && (i <= (int)(strlen(pos) - 2))) {
			if ((pos[i] == '0') && (pos[i + 1] == 'x')) {
				is_hex = 1;
				i = i + 2;
			}
		}
		if (pos[i] == '\0' || pos[i] == ' ') {
			if (j >= datalen) {
				j++;
				break;
			}
			if (is_hex) {
				data[j] = woal_atox(cdata);
				is_hex = 0;
			} else {
				woal_atoi(&data[j], cdata);
			}
			j++;
			k = 0;
			memset(cdata, 0, sizeof(cdata));
			if (pos[i] == '\0')
				break;
		} else {
			if (k >= (int)sizeof(cdata)) {
				PRINTM(MERROR, "Invalid numerical arguments\n");
				break;
			}
			cdata[k] = pos[i];
			k++;
		}
	}

	*user_data_len = j;
	return MLAN_STATUS_SUCCESS;
}

#if defined(STA_CFG80211) && defined(UAP_CFG80211)
/**
 *  @brief Set wps & p2p ie in AP mode
 *
 *  @param priv         Pointer to priv stucture
 *  @param ie           Pointer to ies data
 *  @param len          Length of data
 *
 *  @return             MLAN_STATUS_SUCCESS -- success, otherwise fail
 */
mlan_status
woal_set_ap_wps_p2p_ie(moal_private *priv, t_u8 *ie, size_t len)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	t_u8 *pos = ie;
	int ie_len;

	ENTER();

	ie_len = len - 2;
	if (ie_len <= 0) {
		PRINTM(MERROR, "IE len error: %d\n", ie_len);
		ret = -EFAULT;
		goto done;
	}

	/* Android cmd format:
	 * "SET_AP_WPS_P2P_IE 1"  -- beacon IE
	 * "SET_AP_WPS_P2P_IE 2"  -- proberesp IE
	 * "SET_AP_WPS_P2P_IE 4"  -- assocresp IE
	 */
	if (*pos == '1') {
		/* set the beacon wps/p2p ies */
		pos += 2;
		if (MLAN_STATUS_SUCCESS !=
		    woal_cfg80211_mgmt_frame_ie(priv, pos, ie_len, NULL, 0,
						NULL, 0, NULL, 0,
						MGMT_MASK_BEACON_WPS_P2P,
						MOAL_IOCTL_WAIT)) {
			PRINTM(MERROR, "Failed to set beacon wps/p2p ie\n");
			ret = -EFAULT;
			goto done;
		}
	} else if (*pos == '2') {
		/* set the probe resp ies */
		pos += 2;
		if (MLAN_STATUS_SUCCESS !=
		    woal_cfg80211_mgmt_frame_ie(priv, NULL, 0, pos, ie_len,
						NULL, 0, NULL, 0,
						MGMT_MASK_PROBE_RESP,
						MOAL_IOCTL_WAIT)) {
			PRINTM(MERROR, "Failed to set probe resp ie\n");
			ret = -EFAULT;
			goto done;
		}
	} else if (*pos == '4') {
		/* set the assoc resp ies */
		pos += 2;
		if (MLAN_STATUS_SUCCESS !=
		    woal_cfg80211_mgmt_frame_ie(priv, NULL, 0, NULL, 0, pos,
						ie_len, NULL, 0,
						MGMT_MASK_ASSOC_RESP,
						MOAL_IOCTL_WAIT)) {
			PRINTM(MERROR, "Failed to set assoc resp ie\n");
			ret = -EFAULT;
			goto done;
		}
	}

done:
	LEAVE();
	return ret;
}
#endif

#ifdef WIFI_DIRECT_SUPPORT
#if defined(STA_CFG80211) || defined(UAP_CFG80211)
/**
 *  @brief Set miracast mode
 *
 *  @param priv         Pointer to priv stucture
 *  @param pdata        Pointer to cmd buffer
 *  @param len          Length of data
 *
 *  @return             MLAN_STATUS_SUCCESS -- success, otherwise fail
 */
static mlan_status
woal_set_miracast_mode(moal_private *priv, t_u8 *pdata, size_t len)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	t_u8 *pos = pdata;

	ENTER();
	if (!pos || (len == 0)) {
		PRINTM(MERROR, "%s: Null buf!\n", __func__);
		ret = MLAN_STATUS_FAILURE;
		goto done;
	}
	while (!isdigit(*pos) && --len > 0)
		pos++;
	switch (*pos) {
	case '0':
		/* disable miracast mode */
		priv->phandle->miracast_mode = 0;
		break;
	case '1':
		/* Source */
		priv->phandle->miracast_mode = 1;
		break;
	case '2':
		/* Sink */
		priv->phandle->miracast_mode = 2;
		break;
	default:
		PRINTM(MERROR, "%s: Unknown miracast mode (%c)\n",
		       priv->netdev->name, *pos);
		ret = MLAN_STATUS_FAILURE;
		break;
	}
done:
	LEAVE();
	return ret;
}
#endif
#endif

/**
 *  @brief Get Driver Version
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_get_priv_driver_version(moal_private *priv, t_u8 *respbuf,
			     t_u32 respbuflen)
{
	int len = 0, ret = -1;
	char buf[MLAN_MAX_VER_STR_LEN];

	ENTER();

	if (!respbuf) {
		LEAVE();
		return 0;
	}

	memset(buf, 0, sizeof(buf));

	/* Get version string to local buffer */
	woal_get_version(priv->phandle, buf, sizeof(buf) - 1);
	len = strlen(buf);

	if (len) {
		/* Copy back the retrieved version string */
		PRINTM(MINFO, "MOAL VERSION: %s\n", buf);
		ret = MIN(len, (int)(respbuflen - 1));
		moal_memcpy_ext(priv->phandle, respbuf, buf, ret,
				respbuflen - 1);
	} else {
		ret = -1;
		PRINTM(MERROR, "Get version failed!\n");
	}

	LEAVE();
	return ret;
}

/**
 *  @brief Hostcmd interface from application
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *  @param wait_option  Wait option
 *
 *  @return             Number of bytes written, negative for failure.
 */
int
woal_priv_hostcmd(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen,
		  t_u8 wait_option)
{
	int ret = 0;
	t_u8 *data_ptr;
	t_u32 buf_len = 0;
	HostCmd_Header cmd_header;
	mlan_ioctl_req *req = NULL;
	mlan_ds_misc_cfg *misc_cfg = NULL;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	data_ptr = respbuf + (strlen(CMD_NXP) + strlen(PRIV_CMD_HOSTCMD));
	buf_len = *((t_u32 *)data_ptr);
	moal_memcpy_ext(priv->phandle, &cmd_header, data_ptr + sizeof(buf_len),
			sizeof(HostCmd_Header), sizeof(HostCmd_Header));

	PRINTM(MINFO, "Host command len = %d\n",
	       woal_le16_to_cpu(cmd_header.size));
	if (woal_le16_to_cpu(cmd_header.size) > MRVDRV_SIZE_OF_CMD_BUFFER) {
		LEAVE();
		return -EINVAL;
	}

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto error;
	}
	misc_cfg = (mlan_ds_misc_cfg *)req->pbuf;
	misc_cfg->sub_command = MLAN_OID_MISC_HOST_CMD;
	req->req_id = MLAN_IOCTL_MISC_CFG;
	req->action = MLAN_ACT_SET;
	misc_cfg->param.hostcmd.len = woal_le16_to_cpu(cmd_header.size);
	/* get the whole command */
	moal_memcpy_ext(priv->phandle, misc_cfg->param.hostcmd.cmd,
			data_ptr + sizeof(buf_len), misc_cfg->param.hostcmd.len,
			MRVDRV_SIZE_OF_CMD_BUFFER);

	status = woal_request_ioctl(priv, req, wait_option);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto error;
	}
	ret = misc_cfg->param.hostcmd.len + sizeof(buf_len) + strlen(CMD_NXP) +
		strlen(PRIV_CMD_HOSTCMD);
	if (ret > (int)respbuflen) {
		ret = -EFAULT;
		goto error;
	}
	moal_memcpy_ext(priv->phandle, data_ptr + sizeof(buf_len),
			misc_cfg->param.hostcmd.cmd,
			misc_cfg->param.hostcmd.len,
			respbuflen - (strlen(CMD_NXP) +
				      strlen(PRIV_CMD_HOSTCMD) +
				      sizeof(buf_len)));
	moal_memcpy_ext(priv->phandle, data_ptr,
			(t_u8 *)&misc_cfg->param.hostcmd.len, sizeof(t_u32),
			sizeof(t_u32));

error:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);

	LEAVE();
	return ret;
}

/**
 * @brief               configure 11ax HE capability or HE operation
 *
 *
 *  @param priv    Pointer to the mlan_private driver data struct
 *  @param respbuf      A pointer to response buffer
 *  @param len          length used
 *  @param respbuflen   Available length of response buffer
 *
 *  @return         Number of bytes written if successful else negative value
 */
static int
woal_setget_priv_11axcmdcfg(moal_private *priv, t_u8 *respbuf,
			    t_u32 respbuflen, t_u8 wait_option)
{
	mlan_ioctl_req *req = NULL;
	mlan_ds_11ax_cmd_cfg *cfg = NULL;
	int ret = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;
	int header_len = 0, user_data_len = 0;
	int data[3] = { 0 };
	ENTER();

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11ax_cmd_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	req->req_id = MLAN_IOCTL_11AX_CFG;
	req->action = MLAN_ACT_SET;

	cfg = (mlan_ds_11ax_cmd_cfg *) req->pbuf;
	cfg->sub_command = MLAN_OID_11AX_CMD_CFG;

	parse_arguments(respbuf + header_len, data, ARRAY_SIZE(data),
			&user_data_len);
	PRINTM(MINFO, "data_len=%d,data=%d,%d,%d\n", user_data_len, data[0],
	       data[1], data[2]);

	if (user_data_len > 3 || user_data_len == 0) {
		PRINTM(MERROR, "Invalid parameters\n");
		ret = -EFAULT;
		goto done;
	} else if (user_data_len == 1) {
		req->action = MLAN_ACT_GET;
	}

	switch (data[0]) {
	case MLAN_11AXCMD_CFG_ID_SR_OBSS_PD_OFFSET:
		cfg->sub_id = MLAN_11AXCMD_SR_SUBID;
		cfg->param.sr_cfg.type = MRVL_DOT11AX_OBSS_PD_OFFSET_TLV_ID;
		cfg->param.sr_cfg.len = sizeof(mlan_11axcmdcfg_obss_pd_offset);
		cfg->param.sr_cfg.param.obss_pd_offset.offset[0] = data[1];
		cfg->param.sr_cfg.param.obss_pd_offset.offset[1] = data[2];
		break;
	case MLAN_11AXCMD_CFG_ID_SR_ENABLE:
		cfg->sub_id = MLAN_11AXCMD_SR_SUBID;
		cfg->param.sr_cfg.type = MRVL_DOT11AX_ENABLE_SR_TLV_ID;
		cfg->param.sr_cfg.len = sizeof(mlan_11axcmdcfg_sr_control);
		cfg->param.sr_cfg.param.sr_control.control = data[1];
		break;
	case MLAN_11AXCMD_CFG_ID_BEAM_CHANGE:
		cfg->sub_id = MLAN_11AXCMD_BEAM_SUBID;
		cfg->param.beam_cfg.value = data[1];
		break;
	case MLAN_11AXCMD_CFG_ID_HTC_ENABLE:
		cfg->sub_id = MLAN_11AXCMD_HTC_SUBID;
		cfg->param.htc_cfg.value = data[1];
		break;
	case MLAN_11AXCMD_CFG_ID_TXOP_RTS:
		cfg->sub_id = MLAN_11AXCMD_TXOPRTS_SUBID;
		cfg->param.txop_cfg.rts_thres = data[1];
		break;
	case MLAN_11AXCMD_CFG_ID_TX_OMI:
		cfg->sub_id = MLAN_11AXCMD_TXOMI_SUBID;
		cfg->param.txomi_cfg.omi = data[1];
		break;
	case MLAN_11AXCMD_CFG_ID_OBSSNBRU_TOLTIME:
		cfg->sub_id = MLAN_11AXCMD_OBSS_TOLTIME_SUBID;
		cfg->param.toltime_cfg.tol_time = data[1];
		break;
	default:
		PRINTM(MERROR, "unknown 11axcmd\n");
		ret = -EFAULT;
		goto done;
	}

	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}
	moal_memcpy_ext(priv->phandle, respbuf, &req->action,
			sizeof(req->action), sizeof(req->action));
	respbuf += sizeof(req->action);

	cfg = (mlan_ds_11ax_cmd_cfg *) respbuf;
	moal_memcpy_ext(priv->phandle, cfg, req->pbuf,
			sizeof(mlan_ds_11ax_cmd_cfg), respbuflen);

	ret = sizeof(req->action) + sizeof(mlan_ds_11ax_cmd_cfg);

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 *  @brief             Set/get range ext mode
 *
 *
 *  @param priv    Pointer to the mlan_private driver data struct
 *  @param respbuf      A pointer to response buffer
 *  @param len          length used
 *  @param respbuflen   Available length of response buffer
 *
 *  @return         Number of bytes written if successful else negative value
 */
static int
woal_setget_priv_range_ext(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	mlan_ioctl_req *req = NULL;
	mlan_ds_misc_cfg *misc = NULL;
	int ret = 0;
	int data[1];
	int header_len = 0, user_data_len = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	if (!respbuf) {
		PRINTM(MERROR, "response buffer is not available!\n");
		ret = -EINVAL;
		goto done;
	}
	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_RANGE_EXT);
	user_data_len = strlen(respbuf) - header_len;

	/* Allocate an IOCTL request buffer */
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}
	/* Fill request buffer */
	misc = (mlan_ds_misc_cfg *)req->pbuf;
	misc->sub_command = MLAN_OID_MISC_RANGE_EXT;
	req->req_id = MLAN_IOCTL_MISC_CFG;
	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		user_data_len = 0;
		req->action = MLAN_ACT_GET;
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len, data, ARRAY_SIZE(data),
				&user_data_len);
		if (user_data_len != 1) {
			PRINTM(MERROR, "Invalid Parameter\n");
			ret = -EFAULT;
			goto done;
		}
		if (data[0] < 0 || data[0] > 2) {
			PRINTM(MERROR,
			       "Invalid Parameter: range_ext mode 0-2\n");
			ret = -EFAULT;
			goto done;
		}
		misc->param.range_ext_mode = (t_u8)data[0];
		req->action = MLAN_ACT_SET;
	}
	/* Send IOCTL request to MLAN */
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	data[0] = misc->param.range_ext_mode;
	moal_memcpy_ext(priv->phandle, respbuf, (t_u32 *)data, sizeof(data),
			respbuflen);
	ret = sizeof(data);
done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);

	LEAVE();
	return ret;
}

/**
 *  @brief Custom IE setting
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_customie(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int ret = 0;
	t_u8 *data_ptr;
	mlan_ioctl_req *ioctl_req = NULL;
	mlan_ds_misc_cfg *misc = NULL;
	mlan_ds_misc_custom_ie *pcustom_ie = NULL;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();
	data_ptr = respbuf + (strlen(CMD_NXP) + strlen(PRIV_CMD_CUSTOMIE));

	pcustom_ie = (mlan_ds_misc_custom_ie *)data_ptr;
	ioctl_req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (ioctl_req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	misc = (mlan_ds_misc_cfg *)ioctl_req->pbuf;
	misc->sub_command = MLAN_OID_MISC_CUSTOM_IE;
	ioctl_req->req_id = MLAN_IOCTL_MISC_CFG;
	if ((pcustom_ie->len == 0) ||
	    (pcustom_ie->len == sizeof(pcustom_ie->ie_data_list[0].ie_index)))
		ioctl_req->action = MLAN_ACT_GET;
	else
		ioctl_req->action = MLAN_ACT_SET;

	moal_memcpy_ext(priv->phandle, &misc->param.cust_ie, pcustom_ie,
			sizeof(mlan_ds_misc_custom_ie),
			sizeof(mlan_ds_misc_custom_ie));

	status = woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}
	pcustom_ie = (mlan_ds_misc_custom_ie *)data_ptr;
	moal_memcpy_ext(priv->phandle, pcustom_ie, &misc->param.cust_ie,
			sizeof(mlan_ds_misc_custom_ie),
			respbuflen -
			(strlen(CMD_NXP) + strlen(PRIV_CMD_CUSTOMIE)));
	ret = sizeof(mlan_ds_misc_custom_ie);
	if (ioctl_req->status_code == MLAN_ERROR_IOCTL_FAIL) {
		/* send a separate error code to indicate error from driver */
		ret = EFAULT;
	}
done:
	if (status != MLAN_STATUS_PENDING)
		kfree(ioctl_req);
	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get Band and Adhoc-band setting
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_setget_priv_bandcfg(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int ret = 0;
	unsigned int i;
	int data[3];
	int user_data_len = 0;
	t_u32 infra_band = 0;
	t_u32 adhoc_band = 0;
	t_u32 adhoc_channel = 0;
	mlan_ioctl_req *req = NULL;
	mlan_ds_radio_cfg *radio_cfg = NULL;
	mlan_ds_band_cfg *band_cfg = NULL;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	if (strlen(respbuf) == (strlen(CMD_NXP) + strlen(PRIV_CMD_BANDCFG))) {
		/* GET operation */
		user_data_len = 0;
	} else {
		/* SET operation */
		memset((char *)data, 0, sizeof(data));
		parse_arguments(respbuf + strlen(CMD_NXP) +
				strlen(PRIV_CMD_BANDCFG),
				data, ARRAY_SIZE(data), &user_data_len);
	}

	if (sizeof(int) * user_data_len > sizeof(data)) {
		PRINTM(MERROR, "Too many arguments\n");
		LEAVE();
		return -EINVAL;
	}

	if (user_data_len > 0) {
		if (priv->media_connected == MTRUE) {
			LEAVE();
			return -EOPNOTSUPP;
		}
	}

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_radio_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto error;
	}
	radio_cfg = (mlan_ds_radio_cfg *)req->pbuf;
	radio_cfg->sub_command = MLAN_OID_BAND_CFG;
	req->req_id = MLAN_IOCTL_RADIO_CFG;

	if (user_data_len == 0) {
		/* Get config_bands, adhoc_start_band and adhoc_channel values
		 * from MLAN
		 */
		req->action = MLAN_ACT_GET;
	} else {
		/* To support only <b/bg/bgn/n/aac/gac> */
		infra_band = data[0];
		for (i = 0; i < (sizeof(SupportedInfraBand) /
				 sizeof(SupportedInfraBand[0])); i++)
			if (infra_band == SupportedInfraBand[i])
				break;
		if (i == sizeof(SupportedInfraBand)) {
			ret = -EINVAL;
			goto error;
		}

		/* Set Adhoc band */
		if (user_data_len >= 2) {
			adhoc_band = data[1];
			for (i = 0; i < sizeof(SupportedAdhocBand); i++)
				if (adhoc_band == SupportedAdhocBand[i])
					break;
			if (i == sizeof(SupportedAdhocBand)) {
				ret = -EINVAL;
				goto error;
			}
		}

		/* Set Adhoc channel */
		if (user_data_len >= 3) {
			adhoc_channel = data[2];
			if (adhoc_channel == 0) {
				/* Check if specified adhoc channel is non-zero
				 */
				ret = -EINVAL;
				goto error;
			}
		}
		/* Set config_bands and adhoc_start_band values to MLAN */
		req->action = MLAN_ACT_SET;
		radio_cfg->param.band_cfg.config_bands = infra_band;
		radio_cfg->param.band_cfg.adhoc_start_band = adhoc_band;
		radio_cfg->param.band_cfg.adhoc_channel = adhoc_channel;
	}

	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto error;
	}

	band_cfg = (mlan_ds_band_cfg *)respbuf;

	moal_memcpy_ext(priv->phandle, band_cfg, &radio_cfg->param.band_cfg,
			sizeof(mlan_ds_band_cfg), respbuflen);

	ret = sizeof(mlan_ds_band_cfg);

error:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);

	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get 11n configurations
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_setget_priv_httxcfg(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	t_u32 data[2];
	mlan_ioctl_req *req = NULL;
	mlan_ds_11n_cfg *cfg_11n = NULL;
	int ret = 0;
	int user_data_len = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	if (strlen(respbuf) == (strlen(CMD_NXP) + strlen(PRIV_CMD_HTTXCFG))) {
		/* GET operation */
		user_data_len = 0;
	} else {
		/* SET operation */
		memset((char *)data, 0, sizeof(data));
		parse_arguments(respbuf + strlen(CMD_NXP) +
				strlen(PRIV_CMD_HTTXCFG),
				data, ARRAY_SIZE(data), &user_data_len);
	}

	if (user_data_len > 2) {
		PRINTM(MERROR, "Too many arguments\n");
		ret = -EINVAL;
		goto done;
	}
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11n_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	cfg_11n = (mlan_ds_11n_cfg *)req->pbuf;
	cfg_11n->sub_command = MLAN_OID_11N_CFG_TX;
	req->req_id = MLAN_IOCTL_11N_CFG;

	if (user_data_len == 0) {
		/* Get 11n tx parameters from MLAN */
		req->action = MLAN_ACT_GET;
		cfg_11n->param.tx_cfg.misc_cfg = BAND_SELECT_BG;
	} else {
		cfg_11n->param.tx_cfg.httxcap = data[0];
		PRINTM(MINFO, "SET: httxcap:0x%x\n", data[0]);
		cfg_11n->param.tx_cfg.misc_cfg = BAND_SELECT_BOTH;
		if (user_data_len == 2) {
			if (data[1] != BAND_SELECT_BG &&
			    data[1] != BAND_SELECT_A &&
			    data[1] != BAND_SELECT_BOTH) {
				PRINTM(MERROR, "Invalid band selection\n");
				ret = -EINVAL;
				goto done;
			}
			cfg_11n->param.tx_cfg.misc_cfg = data[1];
			PRINTM(MINFO, "SET: httxcap band:0x%x\n", data[1]);
		}
		/* Update 11n tx parameters in MLAN */
		req->action = MLAN_ACT_SET;
	}
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}
	data[0] = cfg_11n->param.tx_cfg.httxcap;
	PRINTM(MINFO, "GET: httxcap:0x%x\n", data[0]);

	if (req->action == MLAN_ACT_GET) {
		cfg_11n->param.tx_cfg.httxcap = 0;
		cfg_11n->param.tx_cfg.misc_cfg = BAND_SELECT_A;
		status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
		if (status != MLAN_STATUS_SUCCESS) {
			ret = -EFAULT;
			goto done;
		}
		data[1] = cfg_11n->param.tx_cfg.httxcap;
		PRINTM(MINFO, "GET: httxcap for 5GHz:0x%x\n", data[1]);
	}

	moal_memcpy_ext(priv->phandle, respbuf, data, sizeof(data), respbuflen);
	ret = sizeof(data);

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get 11n capability information
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_setget_priv_htcapinfo(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int data[2];
	mlan_ioctl_req *req = NULL;
	mlan_ds_11n_cfg *cfg_11n = NULL;
	woal_ht_cap_info *ht_cap = NULL;
	int ret = 0;
	int user_data_len = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	if (strlen(respbuf) == (strlen(CMD_NXP) + strlen(PRIV_CMD_HTCAPINFO))) {
		/* GET operation */
		user_data_len = 0;
	} else {
		/* SET operation */
		memset((char *)data, 0, sizeof(data));
		parse_arguments(respbuf + strlen(CMD_NXP) +
				strlen(PRIV_CMD_HTCAPINFO),
				data, ARRAY_SIZE(data), &user_data_len);
	}

	if (user_data_len > 2) {
		PRINTM(MERROR, "Too many arguments\n");
		ret = -EINVAL;
		goto done;
	}
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11n_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	cfg_11n = (mlan_ds_11n_cfg *)req->pbuf;
	cfg_11n->sub_command = MLAN_OID_11N_HTCAP_CFG;
	req->req_id = MLAN_IOCTL_11N_CFG;

	if (user_data_len == 0) {
		/* Get 11n tx parameters from MLAN */
		req->action = MLAN_ACT_GET;
		cfg_11n->param.htcap_cfg.misc_cfg = BAND_SELECT_BG;
	} else {
		cfg_11n->param.htcap_cfg.htcap = data[0];
		PRINTM(MINFO, "SET: htcapinfo:0x%x\n", data[0]);
		cfg_11n->param.htcap_cfg.misc_cfg = BAND_SELECT_BOTH;
		if (user_data_len == 2) {
			if (data[1] != BAND_SELECT_BG &&
			    data[1] != BAND_SELECT_A &&
			    data[1] != BAND_SELECT_BOTH) {
				PRINTM(MERROR, "Invalid band selection\n");
				ret = -EINVAL;
				goto done;
			}
			cfg_11n->param.htcap_cfg.misc_cfg = data[1];
			PRINTM(MINFO, "SET: htcapinfo band:0x%x\n", data[1]);
		}
		/* Update 11n tx parameters in MLAN */
		req->action = MLAN_ACT_SET;
	}
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}
	data[0] = cfg_11n->param.htcap_cfg.htcap;
	PRINTM(MINFO, "GET: htcapinfo for 2.4GHz:0x%x\n", data[0]);

	if (req->action == MLAN_ACT_GET) {
		cfg_11n->param.htcap_cfg.htcap = 0;
		cfg_11n->param.htcap_cfg.misc_cfg = BAND_SELECT_A;
		status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
		if (status != MLAN_STATUS_SUCCESS) {
			ret = -EFAULT;
			goto done;
		}
		data[1] = cfg_11n->param.htcap_cfg.htcap;
		PRINTM(MINFO, "GET: htcapinfo for 5GHz:0x%x\n", data[1]);
	}

	ht_cap = (woal_ht_cap_info *)respbuf;
	ht_cap->ht_cap_info_bg = data[0];
	ht_cap->ht_cap_info_a = data[1];
	ret = sizeof(woal_ht_cap_info);

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get add BA parameters
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_setget_priv_addbapara(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int data[5];
	mlan_ioctl_req *req = NULL;
	mlan_ds_11n_cfg *cfg_11n = NULL;
	woal_addba *addba = NULL;
	int ret = 0;
	int user_data_len = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	if (strlen(respbuf) == (strlen(CMD_NXP) + strlen(PRIV_CMD_ADDBAPARA))) {
		/* GET operation */
		user_data_len = 0;
	} else {
		/* SET operation */
		memset((char *)data, 0, sizeof(data));
		parse_arguments(respbuf + strlen(CMD_NXP) +
				strlen(PRIV_CMD_ADDBAPARA),
				data, ARRAY_SIZE(data), &user_data_len);

		if (user_data_len != ARRAY_SIZE(data)) {
			PRINTM(MERROR, "Invalid number of arguments\n");
			ret = -EINVAL;
			goto done;
		}
		if (data[0] < 0 || data[0] > MLAN_DEFAULT_BLOCK_ACK_TIMEOUT) {
			PRINTM(MERROR, "Incorrect addba timeout value.\n");
			ret = -EFAULT;
			goto done;
		}
		if (data[1] <= 0 || data[1] > MLAN_AMPDU_MAX_TXWINSIZE ||
		    data[2] <= 0 || data[2] > MLAN_AMPDU_MAX_RXWINSIZE) {
			PRINTM(MERROR, "Incorrect Tx/Rx window size.\n");
			ret = -EFAULT;
			goto done;
		}
		if (data[3] < 0 || data[3] > 1 || data[4] < 0 || data[4] > 1) {
			PRINTM(MERROR, "Incorrect Tx/Rx amsdu.\n");
			ret = -EFAULT;
			goto done;
		}
	}
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11n_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	cfg_11n = (mlan_ds_11n_cfg *)req->pbuf;
	cfg_11n->sub_command = MLAN_OID_11N_CFG_ADDBA_PARAM;
	req->req_id = MLAN_IOCTL_11N_CFG;

	if (user_data_len == 0) {
		/* Get add BA parameters from MLAN */
		req->action = MLAN_ACT_GET;
	} else {
		cfg_11n->param.addba_param.timeout = data[0];
		cfg_11n->param.addba_param.txwinsize = data[1];
		cfg_11n->param.addba_param.rxwinsize = data[2];
		cfg_11n->param.addba_param.txamsdu = data[3];
		cfg_11n->param.addba_param.rxamsdu = data[4];
		PRINTM(MINFO,
		       "SET: timeout:%d txwinsize:%d rxwinsize:%d txamsdu=%d rxamsdu=%d\n",
		       data[0], data[1], data[2], data[3], data[4]);
		/* Update add BA parameters in MLAN */
		req->action = MLAN_ACT_SET;
	}
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	addba = (woal_addba *)respbuf;

	addba->time_out = cfg_11n->param.addba_param.timeout;
	addba->tx_win_size = cfg_11n->param.addba_param.txwinsize;
	addba->rx_win_size = cfg_11n->param.addba_param.rxwinsize;
	addba->tx_amsdu = cfg_11n->param.addba_param.txamsdu;
	addba->rx_amsdu = cfg_11n->param.addba_param.rxamsdu;
	PRINTM(MINFO,
	       "GET: timeout:%d txwinsize:%d rxwinsize:%d txamsdu=%d, rxamsdu=%d\n",
	       addba->time_out, addba->tx_win_size, addba->rx_win_size,
	       addba->tx_amsdu, addba->rx_amsdu);

	ret = sizeof(woal_addba);

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 *  @brief Delete selective BA based on parameters
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_delba(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	t_u32 data[2] = { 0xFF, 0xFF };
	mlan_ioctl_req *req = NULL;
	mlan_ds_11n_cfg *cfg_11n = NULL;
	mlan_ds_11n_delba *del_ba = NULL;
	int ret = 0;
	int user_data_len = 0;
	int header_len = 0;
	t_u8 *mac_pos = NULL;
	t_u8 peer_mac[ETH_ALEN] = { 0 };
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_DELBA);

	if ((int)strlen(respbuf) == header_len) {
		/* Incorrect number of arguments */
		PRINTM(MERROR, "%d: Invalid arguments\n", __LINE__);
		ret = -EINVAL;
		goto done;
	}

	mac_pos = strstr(respbuf + header_len, " ");
	if (mac_pos)
		mac_pos = strstr(mac_pos + 1, " ");
	if (mac_pos) {
#define MAC_STRING_LENGTH 17
		if (strlen(mac_pos + 1) != MAC_STRING_LENGTH) {
			PRINTM(MERROR, "%d: Invalid arguments\n", __LINE__);
			ret = -EINVAL;
			goto done;
		}
		woal_mac2u8(peer_mac, mac_pos + 1);
		*mac_pos = '\0';
	}

	parse_arguments(respbuf + header_len, data, ARRAY_SIZE(data),
			&user_data_len);

	if (mac_pos)
		user_data_len++;

	if (user_data_len > 3 || (!(data[0] & (DELBA_TX | DELBA_RX))) ||
	    (data[1] != DELBA_ALL_TIDS && !(data[1] <= 7))) {
		/* Incorrect number of arguments */
		PRINTM(MERROR, "%d: Invalid arguments\n", __LINE__);
		ret = -EINVAL;
		goto done;
	}

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11n_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}
	cfg_11n = (mlan_ds_11n_cfg *)req->pbuf;
	req->req_id = MLAN_IOCTL_11N_CFG;
	cfg_11n->sub_command = MLAN_OID_11N_CFG_DELBA;

	del_ba = &cfg_11n->param.del_ba;
	memset(del_ba, 0, sizeof(mlan_ds_11n_delba));
	del_ba->direction = (t_u8)data[0];
	del_ba->tid = DELBA_ALL_TIDS;
	if (user_data_len > 1)
		del_ba->tid = (t_u8)data[1];
	if (user_data_len > 2)
		moal_memcpy_ext(priv->phandle, del_ba->peer_mac_addr, peer_mac,
				ETH_ALEN, MLAN_MAC_ADDR_LENGTH);

	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);

	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	ret = sprintf(respbuf, "OK. BA deleted successfully.\n") + 1;

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get the reject addba requst conditions
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_rejectaddbareq(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	t_u32 data[1];
	mlan_ioctl_req *req = NULL;
	mlan_ds_11n_cfg *cfg_11n = NULL;
	int ret = 0;
	int user_data_len = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	if (strlen(respbuf) ==
	    (strlen(CMD_NXP) + strlen(PRIV_CMD_REJECTADDBAREQ))) {
		/* GET operation */
		user_data_len = 0;
	} else {
		/* SET operation */
		memset((char *)data, 0, sizeof(data));
		parse_arguments(respbuf + strlen(CMD_NXP) +
				strlen(PRIV_CMD_REJECTADDBAREQ),
				data, ARRAY_SIZE(data), &user_data_len);
	}

	if (user_data_len > 1) {
		PRINTM(MERROR, "Too many arguments\n");
		ret = -EINVAL;
		goto done;
	}

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11n_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	cfg_11n = (mlan_ds_11n_cfg *)req->pbuf;
	cfg_11n->sub_command = MLAN_OID_11N_CFG_REJECT_ADDBA_REQ;
	req->req_id = MLAN_IOCTL_11N_CFG;

	if (user_data_len == 0) {
		/* Get the reject addba req conditions */
		req->action = MLAN_ACT_GET;
	} else {
		/* Set the reject addba req conditions */
		cfg_11n->param.reject_addba_req.conditions = data[0];
		req->action = MLAN_ACT_SET;
	}

	/* Send IOCTL request to MLAN */
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}
	if (req->action == MLAN_ACT_GET) {
		sprintf(respbuf, "0x%x",
			cfg_11n->param.reject_addba_req.conditions);
		ret = strlen(respbuf) + 1;
	} else {
		ret = sprintf(respbuf, "OK\n") + 1;
	}

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get the addba reject setting
 *
 *  @param priv         A pointer to moal_private structure
 *  @param action       Action set or get
 *  @param addba_reject A pointer to addba_reject array.
 *
 *  @return             MLAN_STATUS_SUCCESS/MLAN_STATUS_PENDING -- success,
 * otherwise fail
 */
static mlan_status
woal_ioctl_addba_reject(moal_private *priv, t_u32 action, t_u8 *addba_reject)
{
	mlan_ioctl_req *req = NULL;
	mlan_ds_11n_cfg *cfg_11n = NULL;
	mlan_status ret = MLAN_STATUS_SUCCESS;

	ENTER();
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11n_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	cfg_11n = (mlan_ds_11n_cfg *)req->pbuf;
	cfg_11n->sub_command = MLAN_OID_11N_CFG_ADDBA_REJECT;
	req->req_id = MLAN_IOCTL_11N_CFG;

	req->action = action;
	if (action == MLAN_ACT_SET)
		moal_memcpy_ext(priv->phandle, cfg_11n->param.addba_reject,
				addba_reject,
				sizeof(cfg_11n->param.addba_reject),
				sizeof(cfg_11n->param.addba_reject));
	/* Send IOCTL request to MLAN */
	ret = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (ret != MLAN_STATUS_SUCCESS)
		goto done;
	if (action == MLAN_ACT_GET)
		moal_memcpy_ext(priv->phandle, addba_reject,
				cfg_11n->param.addba_reject,
				sizeof(cfg_11n->param.addba_reject),
				MAX_NUM_TID);
done:
	if (ret != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get addba prio_tbl
 *
 *  @param priv         A pointer to moal_private structure
 *  @param action       Action set or get
 *  @param aggr_prio_tbl  A pointer to mlan_ds_11n_aggr_prio_tbl.
 *
 *  @return             MLAN_STATUS_SUCCESS/MLAN_STATUS_PENDING -- success,
 * otherwise fail
 */
static mlan_status
woal_ioctl_aggr_prio_tbl(moal_private *priv, t_u32 action,
			 mlan_ds_11n_aggr_prio_tbl *aggr_prio_tbl)
{
	mlan_ioctl_req *req = NULL;
	mlan_ds_11n_cfg *cfg_11n = NULL;
	mlan_status ret = MLAN_STATUS_SUCCESS;

	ENTER();

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11n_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	cfg_11n = (mlan_ds_11n_cfg *)req->pbuf;
	cfg_11n->sub_command = MLAN_OID_11N_CFG_AGGR_PRIO_TBL;
	req->req_id = MLAN_IOCTL_11N_CFG;

	req->action = action;
	if (action == MLAN_ACT_SET)
		moal_memcpy_ext(priv->phandle, &cfg_11n->param.aggr_prio_tbl,
				aggr_prio_tbl,
				sizeof(mlan_ds_11n_aggr_prio_tbl),
				sizeof(mlan_ds_11n_aggr_prio_tbl));
	/* Send IOCTL request to MLAN */
	ret = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (ret != MLAN_STATUS_SUCCESS)
		goto done;
	if (action == MLAN_ACT_GET)
		moal_memcpy_ext(priv->phandle, aggr_prio_tbl,
				&cfg_11n->param.aggr_prio_tbl,
				sizeof(mlan_ds_11n_aggr_prio_tbl),
				sizeof(mlan_ds_11n_aggr_prio_tbl));
done:
	if (ret != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get addba_param
 *
 *  @param priv         A pointer to moal_private structure
 *  @param action       Action set or get
 *  @param addba_param  A pointer to mlan_ds_11n_addba_param.
 *
 *  @return             MLAN_STATUS_SUCCESS/MLAN_STATUS_PENDING -- success,
 * otherwise fail
 */
static mlan_status
woal_ioctl_addba_param(moal_private *priv, t_u32 action,
		       mlan_ds_11n_addba_param *addba_param)
{
	mlan_ioctl_req *req = NULL;
	mlan_ds_11n_cfg *cfg_11n = NULL;
	mlan_status ret = MLAN_STATUS_SUCCESS;

	ENTER();

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11n_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	cfg_11n = (mlan_ds_11n_cfg *)req->pbuf;
	cfg_11n->sub_command = MLAN_OID_11N_CFG_ADDBA_PARAM;
	req->req_id = MLAN_IOCTL_11N_CFG;

	req->action = action;
	if (action == MLAN_ACT_SET)
		moal_memcpy_ext(priv->phandle, &cfg_11n->param.addba_param,
				addba_param, sizeof(mlan_ds_11n_addba_param),
				sizeof(mlan_ds_11n_addba_param));
	/* Send IOCTL request to MLAN */
	ret = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (ret != MLAN_STATUS_SUCCESS)
		goto done;
	if (action == MLAN_ACT_GET)
		moal_memcpy_ext(priv->phandle, addba_param,
				&cfg_11n->param.addba_param,
				sizeof(mlan_ds_11n_addba_param),
				sizeof(mlan_ds_11n_addba_param));
done:
	if (ret != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 *   @brief Configuring rx block-ack window size
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             0 --success, otherwise failure
 */
static int
woal_set_rx_ba_winsize(moal_private *priv, t_u8 *respbuf, int respbuflen)
{
	int data[2];
	t_u8 addba_reject[MAX_NUM_TID];
	mlan_ds_11n_addba_param addba_param;
	int ret = 0;
	int user_data_len = 0;

	ENTER();

	memset((char *)data, 0, sizeof(data));
	if (respbuf && strlen(respbuf) > 0)
		parse_arguments(respbuf, data, ARRAY_SIZE(data),
				&user_data_len);

	if (user_data_len != 2) {
		PRINTM(MERROR, "Invalid arguments for ba_winsize command\n");
		ret = -EINVAL;
		goto done;
	}
	if (data[0] > 7 || data[0] < 0) {
		PRINTM(MERROR, "Invalid tid %d\n", data[0]);
		ret = -EINVAL;
		goto done;
	}
	if (data[1] < 0) {
		PRINTM(MERROR, "Invalid winsize %d\n", data[1]);
		ret = -EINVAL;
		goto done;
	}
	memset(addba_reject, 0, sizeof(addba_reject));
	if (MLAN_STATUS_SUCCESS !=
	    woal_ioctl_addba_reject(priv, MLAN_ACT_GET, addba_reject)) {
		ret = -EFAULT;
		goto done;
	}
	/* disable tx ba */
	if (data[1] == 0) {
		addba_reject[data[0]] = MTRUE;
		if (MLAN_STATUS_SUCCESS !=
		    woal_ioctl_addba_reject(priv, MLAN_ACT_SET, addba_reject))
			ret = -EFAULT;
	} else {
		if (addba_reject[data[0]] == MTRUE) {
			addba_reject[data[0]] = MFALSE;
			if (MLAN_STATUS_SUCCESS !=
			    woal_ioctl_addba_reject(priv, MLAN_ACT_SET,
						    addba_reject)) {
				ret = -EFAULT;
				goto done;
			}
		}
		memset(&addba_param, 0, sizeof(addba_param));
		if (MLAN_STATUS_SUCCESS !=
		    woal_ioctl_addba_param(priv, MLAN_ACT_GET, &addba_param)) {
			ret = -EFAULT;
			goto done;
		}
		if (data[1] != (int)addba_param.rxwinsize) {
			addba_param.rxwinsize = data[1];
			if (MLAN_STATUS_SUCCESS !=
			    woal_ioctl_addba_param(priv, MLAN_ACT_SET,
						   &addba_param))
				 ret = -EFAULT;
		}
	}
done:
	LEAVE();
	return ret;
}

/**
 *   @brief Configuring trx block-ack window size
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             0 --success, otherwise failure
 */
static int
woal_set_tx_ba_winsize(moal_private *priv, t_u8 *respbuf, int respbuflen)
{
	int data[2];
	mlan_ds_11n_aggr_prio_tbl aggr_prio_tbl;
	mlan_ds_11n_addba_param addba_param;
	t_u8 tos_to_tid_inv[] = { 0x02, 0x00, 0x01, 0x03,
		0x04, 0x05, 0x06, 0x07
	};
	int ret = 0;
	int user_data_len = 0;

	ENTER();

	memset((char *)data, 0, sizeof(data));
	if (respbuf && strlen(respbuf) > 0)
		parse_arguments(respbuf, data, ARRAY_SIZE(data),
				&user_data_len);

	if (user_data_len != 2) {
		PRINTM(MERROR, "Invalid arguments for ba_winsize command\n");
		ret = -EINVAL;
		goto done;
	}
	if (data[0] > 7 || data[0] < 0) {
		PRINTM(MERROR, "Invalid tid %d\n", data[0]);
		ret = -EINVAL;
		goto done;
	}
	if (data[1] < 0) {
		PRINTM(MERROR, "Invalid winsize %d\n", data[1]);
		ret = -EINVAL;
		goto done;
	}
	memset(&aggr_prio_tbl, 0, sizeof(aggr_prio_tbl));
	if (MLAN_STATUS_SUCCESS !=
	    woal_ioctl_aggr_prio_tbl(priv, MLAN_ACT_GET, &aggr_prio_tbl)) {
		ret = -EFAULT;
		goto done;
	}
	/* disable tx ba */
	if (data[1] == 0) {
		if (aggr_prio_tbl.ampdu[data[0]] != 0xff) {
			aggr_prio_tbl.ampdu[data[0]] = 0xff;
			if (MLAN_STATUS_SUCCESS !=
			    woal_ioctl_aggr_prio_tbl(priv, MLAN_ACT_SET,
						     &aggr_prio_tbl))
				 ret = -EFAULT;
		}
	} else {
		if (aggr_prio_tbl.ampdu[data[0]] == 0xff) {
			aggr_prio_tbl.ampdu[data[0]] = tos_to_tid_inv[data[0]];
			if (MLAN_STATUS_SUCCESS !=
			    woal_ioctl_aggr_prio_tbl(priv, MLAN_ACT_SET,
						     &aggr_prio_tbl)) {
				ret = -EFAULT;
				goto done;
			}
		}
		memset(&addba_param, 0, sizeof(addba_param));
		if (MLAN_STATUS_SUCCESS !=
		    woal_ioctl_addba_param(priv, MLAN_ACT_GET, &addba_param)) {
			ret = -EFAULT;
			goto done;
		}
		if (data[1] != (int)addba_param.txwinsize) {
			addba_param.txwinsize = data[1];
			if (MLAN_STATUS_SUCCESS !=
			    woal_ioctl_addba_param(priv, MLAN_ACT_SET,
						   &addba_param))
				 ret = -EFAULT;
		}
	}
done:
	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get aggregation priority table configurations
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_setget_priv_aggrpriotbl(moal_private *priv, t_u8 *respbuf,
			     t_u32 respbuflen)
{
	int data[MAX_NUM_TID * 2], i, j;
	mlan_ioctl_req *req = NULL;
	mlan_ds_11n_cfg *cfg_11n = NULL;
	int ret = 0;
	int user_data_len = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	if (strlen(respbuf) == (strlen(CMD_NXP) + strlen(PRIV_CMD_AGGRPRIOTBL))) {
		/* GET operation */
		user_data_len = 0;
	} else {
		/* SET operation */
		memset((char *)data, 0, sizeof(data));
		parse_arguments(respbuf + strlen(CMD_NXP) +
				strlen(PRIV_CMD_AGGRPRIOTBL),
				data, ARRAY_SIZE(data), &user_data_len);

		if (user_data_len != ARRAY_SIZE(data)) {
			PRINTM(MERROR, "Invalid number of arguments\n");
			ret = -EINVAL;
			goto done;
		}
		for (i = 0, j = 0; i < user_data_len; i = i + 2, ++j) {
			if ((data[i] > 7 && data[i] != 0xff) ||
			    (data[i + 1] > 7 && data[i + 1] != 0xff)) {
				PRINTM(MERROR,
				       "Invalid priority, valid value 0-7 or 0xff.\n");
				ret = -EFAULT;
				goto done;
			}
		}
	}
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11n_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	cfg_11n = (mlan_ds_11n_cfg *)req->pbuf;
	cfg_11n->sub_command = MLAN_OID_11N_CFG_AGGR_PRIO_TBL;
	req->req_id = MLAN_IOCTL_11N_CFG;

	if (user_data_len == 0) {
		/* Get aggr priority table from MLAN */
		req->action = MLAN_ACT_GET;
	} else {
		for (i = 0, j = 0; i < user_data_len; i = i + 2, ++j) {
			cfg_11n->param.aggr_prio_tbl.ampdu[j] = data[i];
			cfg_11n->param.aggr_prio_tbl.amsdu[j] = data[i + 1];
		}
		/* Update aggr priority table in MLAN */
		req->action = MLAN_ACT_SET;
	}
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	for (i = 0, j = 0; i < (MAX_NUM_TID * 2); i = i + 2, ++j) {
		respbuf[i] = cfg_11n->param.aggr_prio_tbl.ampdu[j];
		respbuf[i + 1] = cfg_11n->param.aggr_prio_tbl.amsdu[j];
	}

	ret = sizeof(data);

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get Add BA reject configurations
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_setget_priv_addbareject(moal_private *priv, t_u8 *respbuf,
			     t_u32 respbuflen)
{
	int data[MAX_NUM_TID], i;
	mlan_ioctl_req *req = NULL;
	mlan_ds_11n_cfg *cfg_11n = NULL;
	int ret = 0;
	int user_data_len = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	if (strlen(respbuf) == (strlen(CMD_NXP) + strlen(PRIV_CMD_ADDBAREJECT))) {
		/* GET operation */
		user_data_len = 0;
	} else {
		/* SET operation */
		memset((char *)data, 0, sizeof(data));
		parse_arguments(respbuf + strlen(CMD_NXP) +
				strlen(PRIV_CMD_ADDBAREJECT),
				data, ARRAY_SIZE(data), &user_data_len);

		if (user_data_len != ARRAY_SIZE(data)) {
			PRINTM(MERROR, "Invalid number of arguments\n");
			ret = -EINVAL;
			goto done;
		}
		for (i = 0; i < user_data_len; i++) {
			if (data[i] != 0 && data[i] != 1) {
				PRINTM(MERROR,
				       "addba reject only takes argument as 0 or 1\n");
				ret = -EFAULT;
				goto done;
			}
		}
	}
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11n_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	cfg_11n = (mlan_ds_11n_cfg *)req->pbuf;
	cfg_11n->sub_command = MLAN_OID_11N_CFG_ADDBA_REJECT;
	req->req_id = MLAN_IOCTL_11N_CFG;

	if (user_data_len == 0) {
		/* Get add BA reject configuration from MLAN */
		req->action = MLAN_ACT_GET;
	} else {
		for (i = 0; i < user_data_len; i++)
			cfg_11n->param.addba_reject[i] = data[i];
		/* Update add BA reject configuration in MLAN */
		req->action = MLAN_ACT_SET;
	}
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	for (i = 0; i < MAX_NUM_TID; i++)
		respbuf[i] = cfg_11n->param.addba_reject[i];

	ret = sizeof(data);

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get 11AC configurations
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_setget_priv_vhtcfg(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int data[6];
	mlan_ioctl_req *req = NULL;
	mlan_ds_11ac_cfg *cfg_11ac = NULL;
	mlan_ds_11ac_vht_cfg *vhtcfg = NULL;
	int ret = 0;
	int user_data_len = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	if (strlen(respbuf) == (strlen(CMD_NXP) + strlen(PRIV_CMD_VHTCFG))) {
		PRINTM(MERROR, "Invalid number of arguments\n");
		ret = -EINVAL;
		goto done;
	}
	memset((char *)data, 0, sizeof(data));
	parse_arguments(respbuf + strlen(CMD_NXP) + strlen(PRIV_CMD_VHTCFG),
			data, ARRAY_SIZE(data), &user_data_len);

	if ((user_data_len > 6) || (user_data_len < 2)) {
		PRINTM(MERROR, "Invalid number of arguments\n");
		ret = -EINVAL;
		goto done;
	}
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11ac_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	cfg_11ac = (mlan_ds_11ac_cfg *)req->pbuf;
	cfg_11ac->sub_command = MLAN_OID_11AC_VHT_CFG;
	req->req_id = MLAN_IOCTL_11AC_CFG;

	/* Band */
	if ((data[0] < 0) || (data[0] > 2)) {
		PRINTM(MERROR, "Invalid band selection\n");
		ret = -EINVAL;
		goto done;
	} else {
		if (data[0] == BAND_SELECT_BOTH) {
			cfg_11ac->param.vht_cfg.band =
				(BAND_SELECT_BG | BAND_SELECT_A);
		} else {
			cfg_11ac->param.vht_cfg.band = data[0];
		}
		PRINTM(MINFO, "GET/SET: vhtcfg band: 0x%x\n", data[0]);
	}

	/* Tx/Rx */
	if ((data[1] <= 0) || (data[1] > 3)) {
		PRINTM(MERROR, "Invalid Tx/Rx selection\n");
		ret = -EINVAL;
		goto done;
	} else {
		cfg_11ac->param.vht_cfg.txrx = data[1];
		PRINTM(MINFO, "GET/SET: vhtcfg txrx: 0x%x\n", data[1]);
	}

	if (user_data_len == 2) {
		/* GET operation */
		if (data[0] == BAND_SELECT_BOTH) {
			/* if get both bands, get BG first */
			cfg_11ac->param.vht_cfg.band = BAND_SELECT_BG;
		}
		if (priv->bss_role == MLAN_BSS_ROLE_UAP)
			cfg_11ac->param.vht_cfg.txrx = MLAN_RADIO_RX;

		req->action = MLAN_ACT_GET;
	} else {
		if (user_data_len == 3) {
			PRINTM(MERROR, "Invalid number of arguments\n");
			ret = -EINVAL;
			goto done;
		}
		if (user_data_len >= 4) {
			/* BW cfg */
			if ((data[2] < 0) || (data[2] > 1) ||
			    ((data[2] == 1) && (data[0] & BAND_SELECT_BG))) {
				PRINTM(MERROR, "Invalid BW cfg selection\n");
				ret = -EINVAL;
				goto done;
			} else {
				cfg_11ac->param.vht_cfg.bwcfg = data[2];
				PRINTM(MINFO, "SET: vhtcfg bw cfg:0x%x\n",
				       data[2]);
			}

			cfg_11ac->param.vht_cfg.vht_cap_info = data[3];
			PRINTM(MINFO, "SET: vhtcfg vht_cap_info:0x%x\n",
			       data[3]);
		}
		if (user_data_len == 4) {
			data[4] = 0xffffffff;
			data[5] = 0xffffffff;
		}
		if (user_data_len == 5) {
			PRINTM(MERROR, "Invalid number of arguments\n");
			ret = -EINVAL;
			goto done;
		}
		if (user_data_len >= 4) {
			cfg_11ac->param.vht_cfg.vht_tx_mcs = data[4];
			cfg_11ac->param.vht_cfg.vht_rx_mcs = data[5];
		}
		/* Update 11AC parameters in MLAN */
		req->action = MLAN_ACT_SET;
	}
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	/* number of vhtcfg entries */
	*respbuf = 1;
	vhtcfg = (mlan_ds_11ac_vht_cfg *)(respbuf + 1);
	moal_memcpy_ext(priv->phandle, vhtcfg, &cfg_11ac->param.vht_cfg,
			sizeof(mlan_ds_11ac_vht_cfg), respbuflen - 1);
	ret = 1 + sizeof(mlan_ds_11ac_vht_cfg);

	if ((req->action == MLAN_ACT_GET) && (data[0] == BAND_SELECT_BOTH)) {
		cfg_11ac->param.vht_cfg.band = BAND_SELECT_A;
		status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
		if (status != MLAN_STATUS_SUCCESS) {
			ret = -EFAULT;
			goto done;
		}
		/* number of vhtcfg entries */
		*respbuf = 2;
		vhtcfg++;
		moal_memcpy_ext(priv->phandle, vhtcfg, &cfg_11ac->param.vht_cfg,
				sizeof(mlan_ds_11ac_vht_cfg),
				respbuflen - 1 - sizeof(mlan_ds_11ac_vht_cfg));
		ret += sizeof(mlan_ds_11ac_vht_cfg);
	}

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get 11AC Operating Mode Notification configurations
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_setget_priv_opermodecfg(moal_private *priv, t_u8 *respbuf,
			     t_u32 respbuflen)
{
	int data[2];
	mlan_ioctl_req *req = NULL;
	mlan_ds_11ac_cfg *cfg_11ac = NULL;
	mlan_ds_11ac_opermode_cfg *opermodecfg = NULL;
	int ret = 0;
	int user_data_len = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	memset((char *)data, 0, sizeof(data));
	parse_arguments(respbuf + strlen(CMD_NXP) +
			strlen(PRIV_CMD_OPERMODECFG),
			data, ARRAY_SIZE(data), &user_data_len);

	if ((user_data_len != 0) && (user_data_len != 2)) {
		PRINTM(MERROR, "Invalid number of arguments\n");
		ret = -EINVAL;
		goto done;
	}
	if (user_data_len == 2) {
		/* Channel width */
		if ((data[0] < 1) || (data[0] > 4)) {
			PRINTM(MERROR, "Invalid channel width: 0x%x\n",
			       data[0]);
			ret = -EINVAL;
			goto done;
		}
		/* nss */
		if ((data[1] < 1) || (data[1] > 8)) {
			PRINTM(MERROR, "Invalid nss: 0x%x\n", data[1]);
			ret = -EINVAL;
			goto done;
		}
	}

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11ac_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	cfg_11ac = (mlan_ds_11ac_cfg *)req->pbuf;
	cfg_11ac->sub_command = MLAN_OID_11AC_OPERMODE_CFG;
	req->req_id = MLAN_IOCTL_11AC_CFG;

	if (user_data_len == 0) {
		req->action = MLAN_ACT_GET;
	} else {
		req->action = MLAN_ACT_SET;
		cfg_11ac->param.opermode_cfg.bw = data[0];
		cfg_11ac->param.opermode_cfg.nss = data[1];
	}
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}
	opermodecfg = (mlan_ds_11ac_opermode_cfg *) respbuf;
	moal_memcpy_ext(priv->phandle, opermodecfg,
			&(cfg_11ac->param.opermode_cfg), sizeof(*opermodecfg),
			respbuflen);
	ret = sizeof(*opermodecfg);

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get 11AC configurations
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_get_priv_datarate(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	mlan_ioctl_req *req = NULL;
	mlan_ds_rate *rate = NULL;
	mlan_data_rate *data_rate = NULL;
	int ret = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_rate));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	rate = (mlan_ds_rate *)req->pbuf;
	rate->sub_command = MLAN_OID_GET_DATA_RATE;
	req->req_id = MLAN_IOCTL_RATE;
	req->action = MLAN_ACT_GET;

	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	data_rate = (mlan_data_rate *)respbuf;

	moal_memcpy_ext(priv->phandle, data_rate, &rate->param.data_rate,
			sizeof(mlan_data_rate), respbuflen);

	ret = sizeof(mlan_data_rate);

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get tx rate configurations
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_setget_priv_txratecfg(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	t_u32 data[4];
	mlan_ioctl_req *req = NULL;
	mlan_ds_rate *rate = NULL;
	woal_tx_rate_cfg *ratecfg = NULL;
	int ret = 0;
	int user_data_len = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;
	txrate_setting *rate_setting = NULL;

	ENTER();

	if (strlen(respbuf) == (strlen(CMD_NXP) + strlen(PRIV_CMD_TXRATECFG))) {
		/* GET operation */
		user_data_len = 0;
	} else {
		/* SET operation */
		memset((char *)data, 0, sizeof(data));
		parse_arguments(respbuf + strlen(CMD_NXP) +
				strlen(PRIV_CMD_TXRATECFG),
				data, ARRAY_SIZE(data), &user_data_len);
	}

	if (user_data_len > 4) {
		PRINTM(MERROR, "Too many arguments\n");
		ret = -EINVAL;
		goto done;
	}

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_rate));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	req->req_id = MLAN_IOCTL_RATE;
	rate = (mlan_ds_rate *)req->pbuf;
	rate->sub_command = MLAN_OID_RATE_CFG;
	rate->param.rate_cfg.rate_type = MLAN_RATE_INDEX;

	if (user_data_len == 0) {
		/* Get operation */
		req->action = MLAN_ACT_GET;
	} else {
		/* Set operation */
		req->action = MLAN_ACT_SET;
		/* format */
		if ((data[0] != AUTO_RATE) && (data[0] >= 4)) {
			PRINTM(MERROR, "Invalid format selection\n");
			ret = -EINVAL;
			goto done;
		}
		if (data[0] == AUTO_RATE) {
			/* auto */
			rate->param.rate_cfg.is_rate_auto = 1;
		} else {
			/* fixed rate */
			PRINTM(MINFO, "SET: txratefg format: 0x%x\n", data[0]);
			if ((data[0] != AUTO_RATE) &&
			    (data[0] > MLAN_RATE_FORMAT_HE)
				) {
				PRINTM(MERROR, "Invalid format selection\n");
				ret = -EINVAL;
				goto done;
			}
			rate->param.rate_cfg.rate_format = data[0];

			if (user_data_len >= 2) {
				PRINTM(MINFO, "SET: txratefg index: 0x%x\n",
				       data[1]);
				/* sanity check */
				if (((data[0] == MLAN_RATE_FORMAT_LG) &&
				     (data[1] > MLAN_RATE_INDEX_OFDM7)) ||
				    ((data[0] == MLAN_RATE_FORMAT_HT) &&
				     (data[1] != 32) && (data[1] > 15)
				    )
				    || ((data[0] == MLAN_RATE_FORMAT_VHT) &&
					(data[1] > MLAN_RATE_INDEX_MCS9))
				    || ((data[0] == MLAN_RATE_FORMAT_HE) &&
					(data[1] > MLAN_RATE_INDEX_MCS11))
					) {
					PRINTM(MERROR,
					       "Invalid index selection\n");
					ret = -EINVAL;
					goto done;
				}

				PRINTM(MINFO, "SET: txratefg index: 0x%x\n",
				       data[1]);
				rate->param.rate_cfg.rate = data[1];
			}

			if (data[0] == 2 || data[0] == 3) {
				PRINTM(MINFO, "SET: txratefg nss: 0x%x\n",
				       data[2]);
				/* NSS is supported up to 2 */
				if ((data[2] <= 0) || (data[2] >= 3)) {
					PRINTM(MERROR,
					       "Invalid nss selection\n");
					ret = -EINVAL;
					goto done;
				}
				rate->param.rate_cfg.nss = data[2];
			}
			if (user_data_len == 4) {
				rate->param.rate_cfg.rate_setting =
					data[3] & ~0x0C00;
				PRINTM(MIOCTL,
				       "SET: txratefg HE Rate Setting: 0x%x\n",
				       data[3]);

/* HE Preamble type */
//#define HE_SU_PREAMBLE 0
#define HE_ER_PREAMBLE 1

/* HE ER SU Type */
#define HE_ER_SU_BANDWIDTH_TONE242 0
#define HE_ER_SU_BANDWIDTH_TONE106 1

				rate_setting = (txrate_setting *) & data[3];

				if (data[0] == MLAN_RATE_FORMAT_HE) {
					if (rate_setting->preamble ==
					    HE_ER_PREAMBLE) {
						if (rate_setting->bandwidth ==
						    HE_ER_SU_BANDWIDTH_TONE242)
						{
							if ((data[1] >
							     MLAN_RATE_INDEX_MCS2)
							    || data[2] >
							    MLAN_RATE_NSS1) {
								PRINTM(MERROR,
								       "Invalid rate and MCS or NSS configuration for 242 tone\n");
								ret = -EINVAL;
								goto done;
							}
						} else if (rate_setting->
							   bandwidth ==
							   HE_ER_SU_BANDWIDTH_TONE106)
						{
							if ((data[1] !=
							     MLAN_RATE_INDEX_MCS0)
							    || data[2] !=
							    MLAN_RATE_NSS1) {
								PRINTM(MERROR,
								       "Invalid rate and MCS or NSS configuration\n for 106 tone");
								ret = -EINVAL;
								goto done;
							}
						} else {
							PRINTM(MERROR,
							       "Invalid Bandwidth for HE ER Preamble\n");
							ret = -EINVAL;
							goto done;
						}
					}
					if ((rate_setting->dcm) &&
					    (rate_setting->stbc == 0)) {
						if ((data[1] ==
						     MLAN_RATE_INDEX_MCS2) ||
						    (data[1] >
						     MLAN_RATE_INDEX_MCS4)) {
							PRINTM(MERROR,
							       "Invalid MCS configuration if DCM is supported\n");
							ret = -EINVAL;
							goto done;
						}
					}
				}
			} else {
				rate->param.rate_cfg.rate_setting = 0xffff;
			}
		}
	}

	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	ratecfg = (woal_tx_rate_cfg *)respbuf;
	if (rate->param.rate_cfg.is_rate_auto == MTRUE) {
		ratecfg->rate_format = 0xFF;
	} else {
		/* fixed rate */
		ratecfg->rate_format = rate->param.rate_cfg.rate_format;
		ratecfg->rate_index = rate->param.rate_cfg.rate;
		if (rate->param.rate_cfg.rate_format == MLAN_RATE_FORMAT_VHT
		    || rate->param.rate_cfg.rate_format == MLAN_RATE_FORMAT_HE)
			ratecfg->nss = rate->param.rate_cfg.nss;
		ratecfg->rate_setting = rate->param.rate_cfg.rate_setting;
	}

	ret = sizeof(woal_tx_rate_cfg);

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

#if defined(STA_SUPPORT) || defined(UAP_SUPPORT)
/**
 *  @brief Get statistics information
 *
 *  @param priv         A pointer to moal_private structure
 *  @param wait_option  Wait option
 *  @param stats        A pointer to mlan_ds_get_stats structure
 *
 *  @return             MLAN_STATUS_SUCCESS/MLAN_STATUS_PENDING -- success,
 * otherwise fail
 */
mlan_status
woal_get_stats_info(moal_private *priv, t_u8 wait_option,
		    mlan_ds_get_stats *stats)
{
	mlan_ds_get_info *info = NULL;
	mlan_ioctl_req *req = NULL;
	mlan_status status = MLAN_STATUS_SUCCESS;
	ENTER();

	/* Allocate an IOCTL request buffer */
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_get_info));
	if (req == NULL) {
		status = MLAN_STATUS_FAILURE;
		goto done;
	}

	/* Fill request buffer */
	info = (mlan_ds_get_info *)req->pbuf;
	if (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_STA)
		info->sub_command = MLAN_OID_GET_STATS;
	else if (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_UAP)
		info->sub_command = MLAN_OID_GET_UAP_STATS_LOG;
	req->req_id = MLAN_IOCTL_GET_INFO;
	req->action = MLAN_ACT_GET;

	/* Send IOCTL request to MLAN */
	status = woal_request_ioctl(priv, req, wait_option);
	if (status == MLAN_STATUS_SUCCESS) {
		if (stats)
			moal_memcpy_ext(priv->phandle, stats,
					&info->param.stats,
					sizeof(mlan_ds_get_stats),
					sizeof(mlan_ds_get_stats));
#if defined(STA_WEXT) || defined(UAP_WEXT)
		priv->w_stats.discard.fragment = info->param.stats.fcs_error;
		priv->w_stats.discard.retries = info->param.stats.retry;
		priv->w_stats.discard.misc = info->param.stats.ack_failure;
#endif
	}
done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return status;
}

/**
 *  @brief Get wireless stats information
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_get_priv_getlog(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int ret = 0;
	mlan_ds_get_stats *stats;
	ENTER();

	if (respbuflen < sizeof(*stats)) {
		PRINTM(MERROR, "Get log: respbuflen (%d) too small!",
		       (int)respbuflen);
		ret = -EFAULT;
		goto done;
	}
	stats = (mlan_ds_get_stats *)respbuf;
	if (MLAN_STATUS_SUCCESS !=
	    woal_get_stats_info(priv, MOAL_IOCTL_WAIT, stats)) {
		PRINTM(MERROR, "Get log: Failed to get stats info!");
		ret = -EFAULT;
		goto done;
	}

	if (priv->phandle->fw_getlog_enable)
		ret = sizeof(mlan_ds_get_stats);
	else
		ret = sizeof(mlan_ds_get_stats_org);

done:
	LEAVE();
	return ret;
}
#endif

/**
 *  @brief Set/Get esupplicant mode configurations
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_setget_priv_esuppmode(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	t_u32 data[3];
	mlan_ioctl_req *req = NULL;
	mlan_ds_sec_cfg *sec = NULL;
	woal_esuppmode_cfg *esupp_mode = NULL;
	int ret = 0;
	int user_data_len = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	if (!priv->phandle->card_info->embedded_supp) {
		PRINTM(MERROR, "Not supported cmd on this card\n");
		ret = -EOPNOTSUPP;
		goto done;
	}
	if (strlen(respbuf) == (strlen(CMD_NXP) + strlen(PRIV_CMD_ESUPPMODE))) {
		/* GET operation */
		user_data_len = 0;
	} else {
		/* SET operation */
		memset((char *)data, 0, sizeof(data));
		parse_arguments(respbuf + strlen(CMD_NXP) +
				strlen(PRIV_CMD_ESUPPMODE),
				data, ARRAY_SIZE(data), &user_data_len);
	}

	if (user_data_len >= 4 || user_data_len == 1 || user_data_len == 2) {
		PRINTM(MERROR, "Invalid number of arguments\n");
		ret = -EINVAL;
		goto done;
	}

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_sec_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	req->req_id = MLAN_IOCTL_SEC_CFG;
	sec = (mlan_ds_sec_cfg *)req->pbuf;
	sec->sub_command = MLAN_OID_SEC_CFG_ESUPP_MODE;

	if (user_data_len == 0) {
		/* Get operation */
		req->action = MLAN_ACT_GET;
	} else {
		/* Set operation */
		req->action = MLAN_ACT_SET;
		/* RSN mode */
		sec->param.esupp_mode.rsn_mode = data[0];
		/* Pairwise cipher */
		sec->param.esupp_mode.act_paircipher = (data[1] & 0xFF);
		/* Group cipher */
		sec->param.esupp_mode.act_groupcipher = (data[2] & 0xFF);
	}

	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	esupp_mode = (woal_esuppmode_cfg *)respbuf;
	esupp_mode->rsn_mode =
		(t_u16)((sec->param.esupp_mode.rsn_mode) & 0xFFFF);
	esupp_mode->pairwise_cipher =
		(t_u8)((sec->param.esupp_mode.act_paircipher) & 0xFF);
	esupp_mode->group_cipher =
		(t_u8)((sec->param.esupp_mode.act_groupcipher) & 0xFF);

	ret = sizeof(woal_esuppmode_cfg);
done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get esupplicant passphrase configurations
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_setget_priv_passphrase(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	mlan_ioctl_req *req = NULL;
	mlan_ds_sec_cfg *sec = NULL;
	int ret = 0, action = -1, i = 0;
	char *begin, *end, *opt;
	t_u16 len = 0;
	t_u8 zero_mac[] = { 0, 0, 0, 0, 0, 0 };
	t_u8 *mac = NULL;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	if (!priv->phandle->card_info->embedded_supp) {
		PRINTM(MERROR, "Not supported cmd on this card\n");
		ret = -EOPNOTSUPP;
		goto done;
	}

	if (strlen(respbuf) == (strlen(CMD_NXP) + strlen(PRIV_CMD_PASSPHRASE))) {
		PRINTM(MERROR, "No arguments provided\n");
		ret = -EINVAL;
		goto done;
	}

	/* Parse the buf to get the cmd_action */
	begin = respbuf + strlen(CMD_NXP) + strlen(PRIV_CMD_PASSPHRASE);
	end = woal_strsep(&begin, ';', '/');
	if (end)
		action = woal_atox(end);
	if (action < 0 || action > 2 || end[1] != '\0') {
		PRINTM(MERROR, "Invalid action argument %s\n", end);
		ret = -EINVAL;
		goto done;
	}

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_sec_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	req->req_id = MLAN_IOCTL_SEC_CFG;
	sec = (mlan_ds_sec_cfg *)req->pbuf;
	sec->sub_command = MLAN_OID_SEC_CFG_PASSPHRASE;
	if (action == 0)
		req->action = MLAN_ACT_GET;
	else
		req->action = MLAN_ACT_SET;

	while (begin) {
		end = woal_strsep(&begin, ';', '/');
		opt = woal_strsep(&end, '=', '/');
		if (!opt || !end || !end[0]) {
			PRINTM(MERROR, "Invalid option\n");
			ret = -EINVAL;
			break;
		} else if (!strnicmp(opt, "ssid", strlen(opt))) {
			if (strlen(end) > MLAN_MAX_SSID_LENGTH) {
				PRINTM(MERROR,
				       "SSID length exceeds max length\n");
				ret = -EFAULT;
				break;
			}
			sec->param.passphrase.ssid.ssid_len = strlen(end);
			moal_memcpy_ext(priv->phandle,
					sec->param.passphrase.ssid.ssid, end,
					strlen(end), MLAN_MAX_SSID_LENGTH);
			PRINTM(MINFO, "ssid=%s, len=%d\n",
			       sec->param.passphrase.ssid.ssid,
			       (int)sec->param.passphrase.ssid.ssid_len);
		} else if (!strnicmp(opt, "bssid", strlen(opt))) {
			woal_mac2u8((t_u8 *)&sec->param.passphrase.bssid, end);
		} else if (!strnicmp(opt, "psk", strlen(opt)) &&
			   req->action == MLAN_ACT_SET) {
			if (strlen(end) != MLAN_PMK_HEXSTR_LENGTH) {
				PRINTM(MERROR, "Invalid PMK length\n");
				ret = -EINVAL;
				break;
			}
			woal_ascii2hex((t_u8 *)(sec->param.passphrase.psk.pmk.
						pmk), end,
				       MLAN_PMK_HEXSTR_LENGTH / 2);
			sec->param.passphrase.psk_type = MLAN_PSK_PMK;
		} else if (!strnicmp(opt, "passphrase", strlen(opt)) &&
			   req->action == MLAN_ACT_SET) {
			if (strlen(end) < MLAN_MIN_PASSPHRASE_LENGTH ||
			    strlen(end) > MLAN_MAX_PASSPHRASE_LENGTH) {
				PRINTM(MERROR,
				       "Invalid length for passphrase\n");
				ret = -EINVAL;
				break;
			}
			sec->param.passphrase.psk_type = MLAN_PSK_PASSPHRASE;
			moal_memcpy_ext(priv->phandle,
					sec->param.passphrase.psk.passphrase.
					passphrase, end,
					sizeof(sec->param.passphrase.psk.
					       passphrase.passphrase),
					sizeof(sec->param.passphrase.psk.
					       passphrase.passphrase));
			sec->param.passphrase.psk.passphrase.passphrase_len =
				strlen(end);
			PRINTM(MINFO, "passphrase=%s, len=%d\n",
			       sec->param.passphrase.psk.passphrase.passphrase,
			       (int)sec->param.passphrase.psk.passphrase.
			       passphrase_len);
		} else if (!strnicmp(opt, "sae_password", strlen(opt)) &&
			   req->action == MLAN_ACT_SET) {
			if (strlen(end) < MLAN_MIN_SAE_PASSWORD_LENGTH ||
			    strlen(end) > MLAN_MAX_SAE_PASSWORD_LENGTH) {
				PRINTM(MERROR,
				       "Invalid length for sae password\n");
				ret = -EINVAL;
				break;
			}
			sec->param.passphrase.psk_type = MLAN_PSK_SAE_PASSWORD;
			moal_memcpy_ext(priv->phandle,
					sec->param.passphrase.psk.sae_password.
					sae_password, end,
					sizeof(sec->param.passphrase.psk.
					       sae_password.sae_password),
					sizeof(sec->param.passphrase.psk.
					       sae_password.sae_password));
			sec->param.passphrase.psk.sae_password.
				sae_password_len = strlen(end);
			PRINTM(MINFO, "sae_password=%s, len=%d\n",
			       sec->param.passphrase.psk.sae_password.
			       sae_password,
			       (int)sec->param.passphrase.psk.sae_password.
			       sae_password_len);
		} else {
			PRINTM(MERROR, "Invalid option %s\n", opt);
			ret = -EINVAL;
			break;
		}
	}
	if (ret)
		goto done;

	if (action == 2)
		sec->param.passphrase.psk_type = MLAN_PSK_CLEAR;
	else if (action == 0)
		sec->param.passphrase.psk_type = MLAN_PSK_QUERY;

	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	memset(respbuf, 0, respbuflen);
	if (sec->param.passphrase.ssid.ssid_len) {
		len += sprintf(respbuf + len, "ssid:");
		moal_memcpy_ext(priv->phandle, respbuf + len,
				sec->param.passphrase.ssid.ssid,
				sec->param.passphrase.ssid.ssid_len,
				respbuflen - len);
		len += sec->param.passphrase.ssid.ssid_len;
		len += sprintf(respbuf + len, " ");
	}
	if (memcmp(&sec->param.passphrase.bssid, zero_mac, sizeof(zero_mac))) {
		mac = (t_u8 *)&sec->param.passphrase.bssid;
		len += sprintf(respbuf + len, "bssid:");
		for (i = 0; i < ETH_ALEN - 1; ++i)
			len += sprintf(respbuf + len, "%02x:", mac[i]);
		len += sprintf(respbuf + len, "%02x ", mac[i]);
	}
	if (sec->param.passphrase.psk_type == MLAN_PSK_PMK) {
		len += sprintf(respbuf + len, "psk:");
		for (i = 0; i < MLAN_MAX_KEY_LENGTH; ++i)
			len += sprintf(respbuf + len, "%02x",
				       sec->param.passphrase.psk.pmk.pmk[i]);
		len += sprintf(respbuf + len, "\n");
	}
	if (sec->param.passphrase.psk_type == MLAN_PSK_PASSPHRASE)
		len += sprintf(respbuf + len, "passphrase:%s\n",
			       sec->param.passphrase.psk.passphrase.passphrase);
	if (sec->param.passphrase.psk_type == MLAN_PSK_SAE_PASSWORD)
		len += sprintf(respbuf + len, "sae_password:%s\n",
			       sec->param.passphrase.psk.sae_password.
			       sae_password);

	ret = len;
done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 *  @brief Deauthenticate
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_deauth(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int ret = 0;
	t_u8 mac[ETH_ALEN];

	ENTER();

	if (strlen(respbuf) > (strlen(CMD_NXP) + strlen(PRIV_CMD_DEAUTH))) {
		/* Deauth mentioned BSSID */
		woal_mac2u8(mac, respbuf + strlen(CMD_NXP) +
			    strlen(PRIV_CMD_DEAUTH));
		if (MLAN_STATUS_SUCCESS !=
		    woal_disconnect(priv, MOAL_IOCTL_WAIT, mac,
				    DEF_DEAUTH_REASON_CODE)) {
			ret = -EFAULT;
			goto done;
		}
	} else {
		if (MLAN_STATUS_SUCCESS !=
		    woal_disconnect(priv, MOAL_IOCTL_WAIT, NULL,
				    DEF_DEAUTH_REASON_CODE))
			ret = -EFAULT;
	}

done:
	LEAVE();
	return ret;
}

#ifdef UAP_SUPPORT
/**
 *  @brief uap station deauth ioctl handler
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_ap_deauth(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	t_u8 *data_ptr;
	mlan_ioctl_req *ioctl_req = NULL;
	mlan_ds_bss *bss = NULL;
	mlan_deauth_param deauth_param;
	int ret = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	data_ptr = respbuf + (strlen(CMD_NXP) + strlen(PRIV_CMD_AP_DEAUTH));
	memset(&deauth_param, 0, sizeof(mlan_deauth_param));
	moal_memcpy_ext(priv->phandle, &deauth_param, data_ptr,
			sizeof(mlan_deauth_param), sizeof(mlan_deauth_param));

	PRINTM(MIOCTL, "ioctl deauth station: " MACSTR ", reason=%d\n",
	       MAC2STR(deauth_param.mac_addr), deauth_param.reason_code);

	ioctl_req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss));
	if (ioctl_req == NULL) {
		ret = -ENOMEM;
		goto done;
	}
	bss = (mlan_ds_bss *)ioctl_req->pbuf;

	bss->sub_command = MLAN_OID_UAP_DEAUTH_STA;
	ioctl_req->req_id = MLAN_IOCTL_BSS;
	ioctl_req->action = MLAN_ACT_SET;

	moal_memcpy_ext(priv->phandle, &bss->param.deauth_param, &deauth_param,
			sizeof(mlan_deauth_param), sizeof(mlan_deauth_param));
	status = woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	moal_memcpy_ext(priv->phandle, data_ptr, &ioctl_req->status_code,
			sizeof(t_u32),
			respbuflen - (strlen(CMD_NXP) +
				      strlen(PRIV_CMD_AP_DEAUTH)));
	ret = sizeof(t_u32);
done:
	if (status != MLAN_STATUS_PENDING)
		kfree(ioctl_req);
	LEAVE();
	return ret;
}

/**
 *  @brief uap get station list handler
 *
 *  @param dev      A pointer to net_device structure
 *  @param req      A pointer to ifreq structure
 *  @return         0 --success, otherwise fail
 */
static int
woal_priv_get_sta_list(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int ret = 0;
	mlan_ds_get_info *info = NULL;
	mlan_ds_sta_list *sta_list = NULL;
	mlan_ioctl_req *ioctl_req = NULL;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	/* Allocate an IOCTL request buffer */
	ioctl_req =
		(mlan_ioctl_req *)
		woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_get_info));
	if (ioctl_req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	info = (mlan_ds_get_info *)ioctl_req->pbuf;
	info->sub_command = MLAN_OID_UAP_STA_LIST;
	ioctl_req->req_id = MLAN_IOCTL_GET_INFO;
	ioctl_req->action = MLAN_ACT_GET;

	status = woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	sta_list = (mlan_ds_sta_list *)(respbuf + strlen(CMD_NXP) +
					strlen(PRIV_CMD_GET_STA_LIST));
	moal_memcpy_ext(priv->phandle, sta_list, &info->param.sta_list,
			ioctl_req->data_read_written,
			respbuflen - (strlen(CMD_NXP) +
				      strlen(PRIV_CMD_GET_STA_LIST)));
	ret = ioctl_req->data_read_written + strlen(CMD_NXP) +
		strlen(PRIV_CMD_GET_STA_LIST);
done:
	if (status != MLAN_STATUS_PENDING)
		kfree(ioctl_req);
	LEAVE();
	return ret;
}

/**
 *  @brief uap bss_config handler
 *
 *  @param dev      A pointer to net_device structure
 *  @param req      A pointer to ifreq structure
 *  @return         0 --success, otherwise fail
 */
static int
woal_priv_bss_config(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int ret = 0;
	mlan_ds_bss *bss = NULL;
	mlan_ioctl_req *ioctl_req = NULL;
	t_u32 action = 0;
	int offset = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	offset = strlen(CMD_NXP) + strlen(PRIV_CMD_BSS_CONFIG);
	moal_memcpy_ext(priv->phandle, (u8 *)&action, respbuf + offset,
			sizeof(action), sizeof(action));
	offset += sizeof(action);

	/* Allocate an IOCTL request buffer */
	ioctl_req =
		(mlan_ioctl_req *)
		woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss));
	if (ioctl_req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	bss = (mlan_ds_bss *)ioctl_req->pbuf;
	bss->sub_command = MLAN_OID_UAP_BSS_CONFIG;
	ioctl_req->req_id = MLAN_IOCTL_BSS;
	if (action == 1) {
		ioctl_req->action = MLAN_ACT_SET;
		/* Get the BSS config from user */
		moal_memcpy_ext(priv->phandle, &bss->param.bss_config,
				respbuf + offset, sizeof(mlan_uap_bss_param),
				sizeof(mlan_uap_bss_param));
	} else {
		ioctl_req->action = MLAN_ACT_GET;
	}

	status = woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	if (ioctl_req->action == MLAN_ACT_GET) {
		moal_memcpy_ext(priv->phandle, respbuf + offset,
				&bss->param.bss_config,
				sizeof(mlan_uap_bss_param),
				respbuflen - (t_u32)offset);
	}
	ret = sizeof(mlan_uap_bss_param);
done:
	if (status != MLAN_STATUS_PENDING)
		kfree(ioctl_req);
	LEAVE();
	return ret;
}
#endif

#ifdef WIFI_DIRECT_SUPPORT
#if defined(STA_SUPPORT) && defined(UAP_SUPPORT)
/**
 *  @brief Set/Get BSS role
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_bssrole(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	t_u32 data[1];
	int ret = 0;
	int user_data_len = 0;
	t_u8 action = MLAN_ACT_GET;

	ENTER();

	memset((char *)data, 0, sizeof(data));
	if (strlen(respbuf) == (strlen(CMD_NXP) + strlen(PRIV_CMD_BSSROLE))) {
		/* GET operation */
		user_data_len = 0;
	} else {
		/* SET operation */
		parse_arguments(respbuf + strlen(CMD_NXP) +
				strlen(PRIV_CMD_BSSROLE),
				data, ARRAY_SIZE(data), &user_data_len);
	}

	if (user_data_len >= 2) {
		PRINTM(MERROR, "Too many arguments\n");
		ret = -EINVAL;
		goto error;
	}

	if (user_data_len == 0) {
		action = MLAN_ACT_GET;
	} else {
		if ((data[0] != MLAN_BSS_ROLE_STA &&
		     data[0] != MLAN_BSS_ROLE_UAP) ||
		    priv->bss_type != MLAN_BSS_TYPE_WIFIDIRECT) {
			PRINTM(MWARN, "Invalid BSS role\n");
			ret = -EINVAL;
			goto error;
		}
		if (data[0] == GET_BSS_ROLE(priv)) {
			PRINTM(MWARN, "Already BSS is in desired role\n");
			goto done;
		}
		action = MLAN_ACT_SET;
		/* Reset interface */
		woal_reset_intf(priv, MOAL_IOCTL_WAIT, MFALSE);
	}

	if (MLAN_STATUS_SUCCESS !=
	    woal_bss_role_cfg(priv, action, MOAL_IOCTL_WAIT, (t_u8 *)data)) {
		ret = -EFAULT;
		goto error;
	}

	if (user_data_len) {
		/* Initialize private structures */
		woal_init_priv(priv, MOAL_IOCTL_WAIT);
		/* Enable interfaces */
		netif_device_attach(priv->netdev);
		woal_start_queue(priv->netdev);
	}

done:
	memset(respbuf, 0, respbuflen);
	respbuf[0] = (t_u8)data[0];
	ret = 1;

error:
	LEAVE();
	return ret;
}
#endif /* STA_SUPPORT && UAP_SUPPORT */
#endif /* WIFI_DIRECT_SUPPORT */

#ifdef STA_SUPPORT
/**
 *  @brief Set user scan
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_setuserscan(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	wlan_user_scan_cfg scan_cfg;
	int ret = 0;

	ENTER();

	/* Create the scan_cfg structure */
	memset(&scan_cfg, 0, sizeof(scan_cfg));

	/* We expect the scan_cfg structure to be passed in respbuf */
	moal_memcpy_ext(priv->phandle, (char *)&scan_cfg,
			respbuf + strlen(CMD_NXP) +
			strlen(PRIV_CMD_SETUSERSCAN),
			sizeof(wlan_user_scan_cfg), sizeof(wlan_user_scan_cfg));
	moal_memcpy_ext(priv->phandle, scan_cfg.random_mac, priv->random_mac,
			ETH_ALEN, MLAN_MAC_ADDR_LENGTH);
	/* Call for scan */
	if (MLAN_STATUS_FAILURE == woal_do_scan(priv, &scan_cfg))
		ret = -EFAULT;

	LEAVE();
	return ret;
}

/**
 *  @brief Get channel statistics
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_get_chanstats(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	mlan_scan_resp scan_resp;
	chan_stats *stats = NULL;
	int ret = 0;
	ENTER();

	if (!respbuf) {
		PRINTM(MERROR, "response buffer is not available!\n");
		ret = -EINVAL;
		goto done;
	}
	memset(&scan_resp, 0, sizeof(scan_resp));
	if (MLAN_STATUS_SUCCESS !=
	    woal_get_scan_table(priv, MOAL_IOCTL_WAIT, &scan_resp)) {
		ret = -EFAULT;
		goto done;
	}
	memset(respbuf, 0, respbuflen);
	stats = (chan_stats *) respbuf;
	stats->num_in_chan_stats = scan_resp.num_in_chan_stats;
	ret = sizeof(ChanStatistics_t) * stats->num_in_chan_stats;
	moal_memcpy_ext(priv->phandle, (t_u8 *)stats->stats,
			(t_u8 *)scan_resp.pchan_stats, ret, respbuflen);
	ret += sizeof(stats->num_in_chan_stats);
done:
	LEAVE();
	return ret;
}

/**
 *  @brief Retrieve the scan response/beacon table
 *
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *  @param scan_resp    A pointer to mlan_scan_resp structure
 *  @param scan_start   Argument
 *
 *  @return             MLAN_STATUS_SUCCESS --success, otherwise fail
 */
static int
moal_ret_get_scan_table_ioctl(t_u8 *respbuf, t_u32 respbuflen,
			      mlan_scan_resp *scan_resp, t_u32 scan_start)
{
	pBSSDescriptor_t pbss_desc, scan_table;
	wlan_ioctl_get_scan_table_info *prsp_info;
	int ret_code;
	int ret_len;
	int space_left;
	t_u8 *pcurrent;
	t_u8 *pbuffer_end;
	t_u32 num_scans_done;

	ENTER();

	num_scans_done = 0;
	ret_code = MLAN_STATUS_SUCCESS;

	prsp_info = (wlan_ioctl_get_scan_table_info *)respbuf;
	pcurrent = (t_u8 *)prsp_info->scan_table_entry_buf;

	pbuffer_end = respbuf + respbuflen - 1;
	space_left = pbuffer_end - pcurrent;
	scan_table = (BSSDescriptor_t *)(scan_resp->pscan_table);

	PRINTM(MINFO, "GetScanTable: scan_start req = %d\n", scan_start);
	PRINTM(MINFO, "GetScanTable: length avail = %d\n", respbuflen);

	if (!scan_start) {
		PRINTM(MINFO, "GetScanTable: get current BSS Descriptor\n");

		/* Use to get current association saved descriptor */
		pbss_desc = scan_table;

		ret_code = wlan_get_scan_table_ret_entry(pbss_desc, &pcurrent,
							 &space_left);

		if (ret_code == MLAN_STATUS_SUCCESS)
			num_scans_done = 1;

	} else {
		scan_start--;

		while (space_left &&
		       (scan_start + num_scans_done <
			scan_resp->num_in_scan_table) &&
		       (ret_code == MLAN_STATUS_SUCCESS)) {
			pbss_desc =
				(scan_table + (scan_start + num_scans_done));

			PRINTM(MINFO,
			       "GetScanTable: get current BSS Descriptor [%d]\n",
			       scan_start + num_scans_done);

			ret_code =
				wlan_get_scan_table_ret_entry(pbss_desc,
							      &pcurrent,
							      &space_left);

			if (ret_code == MLAN_STATUS_SUCCESS)
				num_scans_done++;
		}
	}

	prsp_info->scan_number = num_scans_done;
	ret_len = pcurrent - respbuf;

	LEAVE();
	return ret_len;
}

/**
 *  @brief Get scan table
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_getscantable(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int ret = 0;
	mlan_ioctl_req *req = NULL;
	mlan_ds_scan *scan = NULL;
	t_u32 scan_start;
	mlan_status status = MLAN_STATUS_SUCCESS;
	moal_handle *handle = priv->phandle;

	ENTER();

	/* First make sure scanning is not in progress */
	if (handle->scan_pending_on_block == MTRUE) {
		ret = -EAGAIN;
		goto done;
	}

	/* Allocate an IOCTL request buffer */
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_scan));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	/* Fill request buffer */
	scan = (mlan_ds_scan *)req->pbuf;
	req->req_id = MLAN_IOCTL_SCAN;
	req->action = MLAN_ACT_GET;

	/* Get the whole command from user */
	moal_memcpy_ext(handle, &scan_start,
			respbuf + strlen(CMD_NXP) +
			strlen(PRIV_CMD_GETSCANTABLE),
			sizeof(scan_start), sizeof(scan_start));
	if (scan_start)
		scan->sub_command = MLAN_OID_SCAN_NORMAL;
	else
		scan->sub_command = MLAN_OID_SCAN_GET_CURRENT_BSS;

	/* Send IOCTL request to MLAN */
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status == MLAN_STATUS_SUCCESS) {
		ret = moal_ret_get_scan_table_ioctl(respbuf, respbuflen,
						    &scan->param.scan_resp,
						    scan_start);
	}
done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 *  @brief Extended capabilities configuration
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_extcapcfg(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int ret, header;
	mlan_ioctl_req *req = NULL;
	mlan_ds_misc_cfg *cfg = NULL;
	IEEEtypes_Header_t *ie;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	if (!respbuf) {
		LEAVE();
		return 0;
	}

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	cfg = (mlan_ds_misc_cfg *)req->pbuf;
	cfg->sub_command = MLAN_OID_MISC_EXT_CAP_CFG;
	req->req_id = MLAN_IOCTL_MISC_CFG;
	header = strlen(CMD_NXP) + strlen(PRIV_CMD_EXTCAPCFG);
	if ((int)strlen(respbuf) == header)
		/* GET operation */
		req->action = MLAN_ACT_GET;
	else {
		/* SET operation */
		ie = (IEEEtypes_Header_t *)(respbuf + header);
		if (ie->len > sizeof(ExtCap_t)) {
			PRINTM(MERROR,
			       "Extended Capability lenth is invalid\n");
			ret = -EFAULT;
			goto done;
		}
		req->action = MLAN_ACT_SET;
		memset(&cfg->param.ext_cap, 0, sizeof(ExtCap_t));
		moal_memcpy_ext(priv->phandle, &cfg->param.ext_cap, ie + 1,
				ie->len, sizeof(ExtCap_t));
	}

	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	memset(respbuf, 0, respbuflen);
	ie = (IEEEtypes_Header_t *)respbuf;
	ie->element_id = EXT_CAPABILITY;
	ie->len = sizeof(ExtCap_t);
	moal_memcpy_ext(priv->phandle, ie + 1, &cfg->param.ext_cap,
			sizeof(ExtCap_t),
			respbuflen - sizeof(IEEEtypes_Header_t));

	ret = sizeof(IEEEtypes_Header_t) + ie->len;

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}
#endif

/**
 *  @brief Set/Get deep sleep mode configurations
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_setgetdeepsleep(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	t_u32 data[2];
	int ret = 0;
	int user_data_len = 0;

	ENTER();

	if (strlen(respbuf) == (strlen(CMD_NXP) + strlen(PRIV_CMD_DEEPSLEEP))) {
		/* GET operation */
		user_data_len = 0;
	} else {
		/* SET operation */
		memset((char *)data, 0, sizeof(data));
		parse_arguments(respbuf + strlen(CMD_NXP) +
				strlen(PRIV_CMD_DEEPSLEEP),
				data, ARRAY_SIZE(data), &user_data_len);
	}

	if (user_data_len >= 3) {
		PRINTM(MERROR, "Too many arguments\n");
		ret = -EINVAL;
		goto done;
	}

	if (user_data_len == 0) {
		if (MLAN_STATUS_SUCCESS != woal_get_deep_sleep(priv, data)) {
			ret = -EFAULT;
			goto done;
		}
		sprintf(respbuf, "%d %d", data[0], data[1]);
		ret = strlen(respbuf) + 1;
	} else {
		if (data[0] == DEEP_SLEEP_OFF) {
			PRINTM(MINFO, "Exit Deep Sleep Mode\n");
			ret = woal_set_deep_sleep(priv, MOAL_IOCTL_WAIT, MFALSE,
						  0);
			if (ret != MLAN_STATUS_SUCCESS) {
				ret = -EINVAL;
				goto done;
			}
		} else if (data[0] == DEEP_SLEEP_ON) {
			PRINTM(MINFO, "Enter Deep Sleep Mode\n");
			if (user_data_len != 2)
				data[1] = 0;
			ret = woal_set_deep_sleep(priv, MOAL_IOCTL_WAIT, MTRUE,
						  data[1]);
			if (ret != MLAN_STATUS_SUCCESS) {
				ret = -EINVAL;
				goto done;
			}
		} else {
			PRINTM(MERROR, "Unknown option = %u\n", data[0]);
			ret = -EINVAL;
			goto done;
		}
		ret = sprintf(respbuf, "OK\n") + 1;
	}

done:
	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get IP address configurations
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_setgetipaddr(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	mlan_ioctl_req *req = NULL;
	mlan_ds_misc_cfg *misc = NULL;
	int ret = 0, op_code = 0, data_length = 0, header = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	if (priv->bss_type != MLAN_BSS_TYPE_STA) {
		PRINTM(MIOCTL, "Bss type[%d]: Not STA, ignore it\n",
		       priv->bss_type);
		ret = sprintf(respbuf, "OK\n") + 1;
		goto done;
	}

	header = strlen(CMD_NXP) + strlen(PRIV_CMD_IPADDR);
	data_length = strlen(respbuf) - header;

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}
	misc = (mlan_ds_misc_cfg *)req->pbuf;

	if (data_length < 1) {	/* GET */
		req->action = MLAN_ACT_GET;
	} else {
		/* Make sure we have the operation argument */
		if (data_length > 2 && respbuf[header + 1] != ';') {
			PRINTM(MERROR,
			       "No operation argument. Separate with ';'\n");
			ret = -EINVAL;
			goto done;
		} else {
			respbuf[header + 1] = '\0';
		}
		req->action = MLAN_ACT_SET;

		/* Only one IP is supported in current firmware */
		memset(misc->param.ipaddr_cfg.ip_addr[0], 0, IPADDR_LEN);
		if (data_length > 2)
			in4_pton(&respbuf[header + 2],
				 MIN((IPADDR_MAX_BUF - 3), (data_length - 2)),
				 misc->param.ipaddr_cfg.ip_addr[0], ' ', NULL);
		misc->param.ipaddr_cfg.ip_addr_num = 1;
		misc->param.ipaddr_cfg.ip_addr_type = IPADDR_TYPE_IPV4;

		if (woal_atoi(&op_code, &respbuf[header]) !=
		    MLAN_STATUS_SUCCESS) {
			ret = -EINVAL;
			goto done;
		}
		misc->param.ipaddr_cfg.op_code = (t_u32)op_code;
	}

	req->req_id = MLAN_IOCTL_MISC_CFG;
	misc->sub_command = MLAN_OID_MISC_IP_ADDR;

	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	if (req->action == MLAN_ACT_GET) {
		snprintf(respbuf, IPADDR_MAX_BUF, "%d;%d.%d.%d.%d",
			 misc->param.ipaddr_cfg.op_code,
			 misc->param.ipaddr_cfg.ip_addr[0][0],
			 misc->param.ipaddr_cfg.ip_addr[0][1],
			 misc->param.ipaddr_cfg.ip_addr[0][2],
			 misc->param.ipaddr_cfg.ip_addr[0][3]);
		ret = IPADDR_MAX_BUF + 1;
	} else {
		ret = sprintf(respbuf, "OK\n") + 1;
	}

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get WPS session configurations
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_setwpssession(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	mlan_ioctl_req *req = NULL;
	mlan_ds_wps_cfg *pwps = NULL;
	t_u32 data[1];
	int ret = 0;
	int user_data_len = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	memset((char *)data, 0, sizeof(data));
	if (strlen(respbuf) == (strlen(CMD_NXP) + strlen(PRIV_CMD_WPSSESSION))) {
		/* GET operation */
		user_data_len = 0;
	} else {
		/* SET operation */
		parse_arguments(respbuf + strlen(CMD_NXP) +
				strlen(PRIV_CMD_WPSSESSION),
				data, ARRAY_SIZE(data), &user_data_len);
	}

	if (user_data_len > 1) {
		PRINTM(MERROR, "Too many arguments\n");
		ret = -EINVAL;
		goto done;
	}

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_wps_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}
	pwps = (mlan_ds_wps_cfg *)req->pbuf;

	req->req_id = MLAN_IOCTL_WPS_CFG;
	req->action = MLAN_ACT_SET;
	pwps->sub_command = MLAN_OID_WPS_CFG_SESSION;

	if (data[0] == 1)
		pwps->param.wps_session = MLAN_WPS_CFG_SESSION_START;
	else
		pwps->param.wps_session = MLAN_WPS_CFG_SESSION_END;

	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	ret = sprintf(respbuf, "OK\n") + 1;
done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 *  @brief Get OTP user data
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_otpuserdata(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int data[1];
	int user_data_len = 0;
	mlan_ioctl_req *req = NULL;
	mlan_ds_misc_cfg *misc = NULL;
	mlan_ds_misc_otp_user_data *otp = NULL;
	int ret = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	if (strlen(respbuf) == (strlen(CMD_NXP) + strlen(PRIV_CMD_OTPUSERDATA))) {
		PRINTM(MERROR, "Invalid number of arguments\n");
		ret = -EINVAL;
		goto done;
	}
	memset((char *)data, 0, sizeof(data));
	parse_arguments(respbuf + strlen(CMD_NXP) +
			strlen(PRIV_CMD_OTPUSERDATA),
			data, ARRAY_SIZE(data), &user_data_len);

	if (user_data_len != 1) {
		PRINTM(MERROR, "Invalid number of arguments\n");
		ret = -EINVAL;
		goto done;
	}

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}
	req->action = MLAN_ACT_GET;
	req->req_id = MLAN_IOCTL_MISC_CFG;

	misc = (mlan_ds_misc_cfg *)req->pbuf;
	misc->sub_command = MLAN_OID_MISC_OTP_USER_DATA;
	misc->param.otp_user_data.user_data_length = data[0];

	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}
	otp = (mlan_ds_misc_otp_user_data *)req->pbuf;

	if (req->action == MLAN_ACT_GET) {
		ret = MIN(otp->user_data_length, data[0]);
		moal_memcpy_ext(priv->phandle, respbuf, otp->user_data, ret,
				respbuflen);
	}

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 *  @brief Set / Get country code
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_set_get_countrycode(moal_private *priv, t_u8 *respbuf,
			      t_u32 respbuflen)
{
	int ret = 0;
	/* char data[COUNTRY_CODE_LEN] = {0, 0, 0}; */
	int header = 0, data_length = 0;	/* wrq->u.data.length; */
	mlan_ioctl_req *req = NULL;
	mlan_ds_misc_cfg *pcfg_misc = NULL;
	mlan_ds_misc_country_code *country_code = NULL;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	header = strlen(CMD_NXP) + strlen(PRIV_CMD_COUNTRYCODE);
	data_length = strlen(respbuf) - header;

	if (data_length > COUNTRY_CODE_LEN) {
		PRINTM(MERROR, "Invalid argument!\n");
		ret = -EINVAL;
		goto done;
	}

	/* Allocate an IOCTL request buffer */
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	/* Fill request buffer */
	pcfg_misc = (mlan_ds_misc_cfg *)req->pbuf;
	country_code = &pcfg_misc->param.country_code;
	pcfg_misc->sub_command = MLAN_OID_MISC_COUNTRY_CODE;
	req->req_id = MLAN_IOCTL_MISC_CFG;

	if (data_length <= 1) {
		req->action = MLAN_ACT_GET;
	} else {
		memset(country_code->country_code, 0, COUNTRY_CODE_LEN);
		moal_memcpy_ext(priv->phandle, country_code->country_code,
				respbuf + header, COUNTRY_CODE_LEN,
				COUNTRY_CODE_LEN);
		req->action = MLAN_ACT_SET;
	}

	/* Send IOCTL request to MLAN */
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	if (req->action == MLAN_ACT_GET) {
		ret = data_length = COUNTRY_CODE_LEN;
		memset(respbuf + header, 0, COUNTRY_CODE_LEN);
		moal_memcpy_ext(priv->phandle, respbuf,
				country_code->country_code, COUNTRY_CODE_LEN,
				respbuflen);
	}

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);

	LEAVE();
	return ret;
}

/**
 *  @brief Get cfp information
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_get_cfpinfo(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int ret = 0;
	mlan_ioctl_req *req = NULL;
	mlan_ds_misc_cfg *cfp_misc = NULL;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	if (!respbuf) {
		PRINTM(MERROR, "response buffer is not available!\n");
		ret = -EINVAL;
		goto done;
	}

	/* Allocate an IOCTL request buffer */
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	/* Fill request buffer */
	cfp_misc = (mlan_ds_misc_cfg *)req->pbuf;
	cfp_misc->sub_command = MLAN_OID_MISC_CFP_INFO;
	req->req_id = MLAN_IOCTL_MISC_CFG;
	req->action = MLAN_ACT_GET;

	/* Send IOCTL request to MLAN */
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}
	if (respbuflen < req->data_read_written) {
		PRINTM(MERROR, "response buffer length is too short!\n");
		ret = -EINVAL;
		goto done;
	}
	moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)req->pbuf,
			req->data_read_written, respbuflen);
	ret = req->data_read_written;
done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);

	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get TCP Ack enhancement configurations
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_setgettcpackenh(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	t_u32 data[2] = { 0, 0 };
	int ret = 0;
	int user_data_len = 0;

	ENTER();
	if (!priv || !priv->phandle) {
		PRINTM(MERROR, "priv or handle is null\n");
		ret = -EFAULT;
		goto done;
	}

	if (strlen(respbuf) == (strlen(CMD_NXP) + strlen(PRIV_CMD_TCPACKENH))) {
		/* GET operation */
		user_data_len = 0;
	} else {
		/* SET operation */
		memset((char *)data, 0, sizeof(data));
		parse_arguments(respbuf + strlen(CMD_NXP) +
				strlen(PRIV_CMD_TCPACKENH),
				data, ARRAY_SIZE(data), &user_data_len);
	}

	if (user_data_len == 0) {
		/* get operation */
		data[0] = priv->enable_tcp_ack_enh;
		data[1] = priv->tcp_ack_max_hold;
		moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)data,
				sizeof(data), respbuflen);
		ret = sizeof(data);
	} else {
		/* set operation */
		if (user_data_len >= 3) {
			PRINTM(MERROR, "Too many arguments\n");
			ret = -EINVAL;
			goto done;
		}
		if (data[0] > 1 || data[1] > TCP_ACK_MAX_HOLD) {
			PRINTM(MERROR, "Invalid argument\n");
			ret = -EINVAL;
			goto done;
		}
		if (data[0] == MTRUE) {
			PRINTM(MINFO, "Enabling TCP Ack enhancement\n");
			priv->enable_tcp_ack_enh = MTRUE;
		} else if (data[0] == MFALSE) {
			PRINTM(MINFO, "Disabling TCP Ack enhancement\n");
			priv->enable_tcp_ack_enh = MFALSE;
			/* release the tcp sessions if any */
			woal_flush_tcp_sess_queue(priv);
		}
		if (user_data_len >= 2) {
			PRINTM(MINFO, "TCP drop Ack configure: %d\n", data[1]);
			priv->tcp_ack_max_hold = data[1];
		}
		data[0] = priv->enable_tcp_ack_enh;
		data[1] = priv->tcp_ack_max_hold;
		moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)data,
				sizeof(data), respbuflen);
		ret = sizeof(data);
	}

done:
	LEAVE();
	return ret;
}

#ifdef REASSOCIATION
/**
 *  @brief Set Asynced ESSID
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *  @param bBSSID       A variable that bssid is set or not
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_assocessid(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen,
		     t_u8 bBSSID)
{
	mlan_ssid_bssid ssid_bssid;
	moal_handle *handle = priv->phandle;
	int ret = 0;
	int header_len = 0;
	int copy_len = 0;
	char buf[64];
	t_u8 buflen = 0;
	t_u8 i = 0;
	t_u8 mac_idx = 0;

	ENTER();

	if (bBSSID)
		header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_ASSOCBSSID);
	else
		header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_ASSOCESSID);

	if ((int)strlen(respbuf) == header_len) {
		PRINTM(MERROR, "No argument, invalid operation!\n");
		ret = -EINVAL;
		LEAVE();
		return ret;
	}
	copy_len = strlen(respbuf) - header_len;
	buflen = MIN(copy_len, (int)(sizeof(buf) - 1));
	memset(buf, 0, sizeof(buf));
	memset(&ssid_bssid, 0, sizeof(mlan_ssid_bssid));
	moal_memcpy_ext(handle, buf, respbuf + header_len, buflen, sizeof(buf));
	priv->assoc_with_mac = MFALSE;

	/* check if has parameter BSSID */
	if (bBSSID) {
		if (buflen < (3 * ETH_ALEN) + 2) {
			PRINTM(MERROR,
			       "Associate: Insufficient length in IOCTL input\n");
			/* buffer should be at least 3 characters per BSSID
			 *octet "00:"
			 **   plus a space separater and at least 1 char in the
			 *SSID
			 */
			ret = -EINVAL;
			goto setessid_ret;
		}
		for (; (i < buflen) && (mac_idx < ETH_ALEN) && (buf[i] != ' ');
		     i++) {
			if (buf[i] == ':') {
				mac_idx++;
			} else {
				ssid_bssid.bssid[mac_idx] =
					(t_u8)woal_atox(buf + i);
				while ((i < buflen) && isxdigit(buf[i + 1]))
					/* Skip entire hex value */
					i++;
			}
		}
		/* Skip one space between the BSSID and start of the SSID */
		i++;
		PRINTM(MMSG, "Trying to associate AP BSSID = [" MACSTR "]\n",
		       MAC2STR(ssid_bssid.bssid));
		priv->assoc_with_mac = MTRUE;
	}

	ssid_bssid.ssid.ssid_len = buflen - i;
	/* Check the size of the ssid_len */
	if (ssid_bssid.ssid.ssid_len > MLAN_MAX_SSID_LENGTH + 1) {
		PRINTM(MERROR, "ssid_bssid.ssid.ssid_len = %d\n",
		       ssid_bssid.ssid.ssid_len);
		ret = -E2BIG;
		goto setessid_ret;
	}

	/* Copy the SSID */
	moal_memcpy_ext(handle, ssid_bssid.ssid.ssid, buf + i,
			ssid_bssid.ssid.ssid_len, MLAN_MAX_SSID_LENGTH);

	if (!ssid_bssid.ssid.ssid_len ||
	    (MFALSE == woal_ssid_valid(&ssid_bssid.ssid))) {
		PRINTM(MERROR, "Invalid SSID - aborting set_essid\n");
		ret = -EINVAL;
		goto setessid_ret;
	}

	PRINTM(MMSG, "Trying to associate AP SSID = %s\n",
	       (char *)ssid_bssid.ssid.ssid);

	/* Cancel re-association */
	priv->reassoc_required = MFALSE;

	if (MOAL_ACQ_SEMAPHORE_BLOCK(&handle->reassoc_sem)) {
		PRINTM(MERROR, "Acquire semaphore error, woal_set_essid\n");
		ret = -EBUSY;
		LEAVE();
		return ret;
	}

	if (priv->scan_type == MLAN_SCAN_TYPE_PASSIVE)
		woal_set_scan_type(priv, MLAN_SCAN_TYPE_ACTIVE);

	if (MTRUE == woal_is_connected(priv, &ssid_bssid)) {
		PRINTM(MIOCTL, "Already connect to the network\n");
		ret = sprintf(respbuf,
			      "Has already connected to this ESSID!\n") + 1;
		goto setessid_ret;
	}
	moal_memcpy_ext(handle, &priv->prev_ssid_bssid, &ssid_bssid,
			sizeof(mlan_ssid_bssid), sizeof(mlan_ssid_bssid));
	/* disconnect before driver assoc */
	woal_disconnect(priv, MOAL_IOCTL_WAIT, NULL, DEF_DEAUTH_REASON_CODE);
	priv->set_asynced_essid_flag = MTRUE;
	priv->reassoc_required = MTRUE;
	priv->phandle->is_reassoc_timer_set = MTRUE;
	woal_mod_timer(&priv->phandle->reassoc_timer, 0);
	ret = sprintf(respbuf, "%s\n", buf) + 1;

setessid_ret:
	if (priv->scan_type == MLAN_SCAN_TYPE_PASSIVE)
		woal_set_scan_type(priv, MLAN_SCAN_TYPE_PASSIVE);
	MOAL_REL_SEMAPHORE(&handle->reassoc_sem);
	LEAVE();
	return ret;
}
#endif

/**
 *  @brief Get wakeup reason
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_getwakeupreason(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	mlan_ioctl_req *req = NULL;
	mlan_ds_pm_cfg *pm_cfg = NULL;
	t_u32 data;
	int ret = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	if (strlen(respbuf) ==
	    (strlen(CMD_NXP) + strlen(PRIV_CMD_WAKEUPREASON))) {
		/* GET operation */
		req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_pm_cfg));
		if (req == NULL) {
			LEAVE();
			return -ENOMEM;
		}

		pm_cfg = (mlan_ds_pm_cfg *)req->pbuf;
		pm_cfg->sub_command = MLAN_OID_PM_HS_WAKEUP_REASON;
		req->req_id = MLAN_IOCTL_PM_CFG;
		req->action = MLAN_ACT_GET;

		status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
		if (status != MLAN_STATUS_SUCCESS) {
			ret = -EFAULT;
			if (status != MLAN_STATUS_PENDING)
				kfree(req);
			goto done;
		} else {
			data = pm_cfg->param.wakeup_reason.hs_wakeup_reason;
			sprintf(respbuf, " %d", data);
			ret = strlen(respbuf) + 1;
			kfree(req);
		}
	} else {
		PRINTM(MERROR, "Not need argument, invalid operation!\n");
		ret = -EINVAL;
		goto done;
	}

done:
	LEAVE();
	return ret;
}

#ifdef STA_SUPPORT
/**
 *  @brief Set / Get listen interval
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_set_get_listeninterval(moal_private *priv, t_u8 *respbuf,
				 t_u32 respbuflen)
{
	int data[1];
	int user_data_len = 0;
	int ret = 0;
	mlan_ioctl_req *req = NULL;
	mlan_ds_bss *pcfg_bss = NULL;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	if (strlen(respbuf) ==
	    (strlen(CMD_NXP) + strlen(PRIV_CMD_LISTENINTERVAL))) {
		/* GET operation */
		user_data_len = 0;
	} else {
		/* SET operation */
		memset((char *)data, 0, sizeof(data));
		parse_arguments(respbuf + strlen(CMD_NXP) +
				strlen(PRIV_CMD_LISTENINTERVAL),
				data, ARRAY_SIZE(data), &user_data_len);
	}

	if (user_data_len > 1) {
		PRINTM(MERROR, "Too many arguments\n");
		ret = -EINVAL;
		goto done;
	}

	/* Allocate an IOCTL request buffer */
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	/* Fill request buffer */
	pcfg_bss = (mlan_ds_bss *)req->pbuf;
	pcfg_bss->sub_command = MLAN_OID_BSS_LISTEN_INTERVAL;
	req->req_id = MLAN_IOCTL_BSS;

	if (user_data_len) {
		pcfg_bss->param.listen_interval = (t_u16)data[0];
		req->action = MLAN_ACT_SET;
	} else {
		req->action = MLAN_ACT_GET;
	}

	/* Send IOCTL request to MLAN */
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}
	if (req->action == MLAN_ACT_GET) {
		sprintf(respbuf, "%d", pcfg_bss->param.listen_interval);
		ret = strlen(respbuf) + 1;
	} else {
		ret = sprintf(respbuf, "OK\n") + 1;
	}

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);

	LEAVE();
	return ret;
}
#endif

#ifdef DEBUG_LEVEL1
/**
 *  @brief Set / Get driver debug level
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_set_get_drvdbg(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int data[4];
	int user_data_len = 0;
	int ret = 0;

	ENTER();

	if (strlen(respbuf) == (strlen(CMD_NXP) + strlen(PRIV_CMD_DRVDBG))) {
		/* GET operation */
		user_data_len = 0;
	} else {
		/* SET operation */
		memset((char *)data, 0, sizeof(data));
		parse_arguments(respbuf + strlen(CMD_NXP) +
				strlen(PRIV_CMD_DRVDBG),
				data, ARRAY_SIZE(data), &user_data_len);
	}

	if (user_data_len > 1) {
		PRINTM(MERROR, "Too many arguments\n");
		ret = -EINVAL;
		goto done;
	}

	if (user_data_len) {
		/* Get the driver debug bit masks from user */
		drvdbg = data[0];
		/* Set the driver debug bit masks into mlan */
		if (woal_set_drvdbg(priv, drvdbg)) {
			PRINTM(MERROR, "Set drvdbg failed!\n");
			ret = MLAN_STATUS_FAILURE;
			goto done;
		}
	}

	ret = sizeof(drvdbg);

	moal_memcpy_ext(priv->phandle, respbuf, &drvdbg, sizeof(drvdbg),
			respbuflen);

	printk(KERN_ALERT "drvdbg = 0x%08x\n", drvdbg);
#ifdef DEBUG_LEVEL2
	printk(KERN_ALERT "MINFO  (%08x) %s\n", MINFO,
	       (drvdbg & MINFO) ? "X" : "");
	printk(KERN_ALERT "MWARN  (%08x) %s\n", MWARN,
	       (drvdbg & MWARN) ? "X" : "");
	printk(KERN_ALERT "MENTRY (%08x) %s\n", MENTRY,
	       (drvdbg & MENTRY) ? "X" : "");
#endif
	printk(KERN_ALERT "MMPA_D (%08x) %s\n", MMPA_D,
	       (drvdbg & MMPA_D) ? "X" : "");
	printk(KERN_ALERT "MIF_D  (%08x) %s\n", MIF_D,
	       (drvdbg & MIF_D) ? "X" : "");
	printk(KERN_ALERT "MFW_D  (%08x) %s\n", MFW_D,
	       (drvdbg & MFW_D) ? "X" : "");
	printk(KERN_ALERT "MEVT_D (%08x) %s\n", MEVT_D,
	       (drvdbg & MEVT_D) ? "X" : "");
	printk(KERN_ALERT "MCMD_D (%08x) %s\n", MCMD_D,
	       (drvdbg & MCMD_D) ? "X" : "");
	printk(KERN_ALERT "MDAT_D (%08x) %s\n", MDAT_D,
	       (drvdbg & MDAT_D) ? "X" : "");
	printk(KERN_ALERT "MREG_D (%08x) %s\n", MREG_D,
	       (drvdbg & MREG_D) ? "X" : "");
	printk(KERN_ALERT "MIOCTL (%08x) %s\n", MIOCTL,
	       (drvdbg & MIOCTL) ? "X" : "");
	printk(KERN_ALERT "MINTR  (%08x) %s\n", MINTR,
	       (drvdbg & MINTR) ? "X" : "");
	printk(KERN_ALERT "MEVENT (%08x) %s\n", MEVENT,
	       (drvdbg & MEVENT) ? "X" : "");
	printk(KERN_ALERT "MCMND  (%08x) %s\n", MCMND,
	       (drvdbg & MCMND) ? "X" : "");
	printk(KERN_ALERT "MDATA  (%08x) %s\n", MDATA,
	       (drvdbg & MDATA) ? "X" : "");
	printk(KERN_ALERT "MERROR (%08x) %s\n", MERROR,
	       (drvdbg & MERROR) ? "X" : "");
	printk(KERN_ALERT "MFATAL (%08x) %s\n", MFATAL,
	       (drvdbg & MFATAL) ? "X" : "");
	printk(KERN_ALERT "MMSG   (%08x) %s\n", MMSG,
	       (drvdbg & MMSG) ? "X" : "");

done:
	LEAVE();
	return ret;
}

#endif

/**
 *  @brief management frame filter wakeup config
 *
 *  @param priv             A pointer to moal_private structure
 *  @param respbuf          A pointer to response buffer
 *  @param respbuflen       Available length of response buffer
 *
 *  @return             0 --success, otherwise fail
 */
static int
woal_priv_mgmt_filter(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	mlan_ioctl_req *ioctl_req = NULL;
	mlan_ds_pm_cfg *pm_cfg = NULL;
	mlan_status status = MLAN_STATUS_SUCCESS;
	int header_len = 0, data_len = 0;
	int ret = 0;
	t_u16 action;
	t_u8 *argument;

	ENTER();

	if (!priv || !priv->phandle) {
		PRINTM(MERROR, "priv or handle is null\n");
		ret = -EFAULT;
		goto done;
	}

	ioctl_req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (ioctl_req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	pm_cfg = (mlan_ds_pm_cfg *)ioctl_req->pbuf;
	pm_cfg->sub_command = MLAN_OID_PM_MGMT_FILTER;
	ioctl_req->req_id = MLAN_IOCTL_PM_CFG;

	header_len = strlen(PRIV_CMD_MGMT_FILTER) + strlen(CMD_NXP);

	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		action = MLAN_ACT_GET;
	} else {
		/* SET operation */
		argument = (t_u8 *)(respbuf + header_len);
		data_len = respbuflen - header_len;
		if (data_len >
		    (int)(MAX_MGMT_FRAME_FILTER *
			  sizeof(mlan_mgmt_frame_wakeup))) {
			PRINTM(MERROR, "%d: Invalid arguments\n", __LINE__);
			ret = -EINVAL;
			goto done;
		}
		moal_memcpy_ext(priv->phandle,
				(t_u8 *)pm_cfg->param.mgmt_filter, argument,
				data_len, sizeof(pm_cfg->param.mgmt_filter));
		action = MLAN_ACT_SET;
	}

	ioctl_req->action = action;
	status = woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(ioctl_req);

	LEAVE();
	return ret;
}

#define PARAMETER_GPIO_INDICATION 1
#define PARAMETER_EXTEND_HSCFG 2
#define PARAMETER_HS_WAKEUP_INTERVAL 3
/**
 *  @brief Set/Get Host Sleep configuration
 *
 *  @param priv             A pointer to moal_private structure
 *  @param respbuf          A pointer to response buffer
 *  @param respbuflen       Available length of response buffer
 *  @param invoke_hostcmd   MTRUE --invoke HostCmd, otherwise MFALSE
 *
 *  @return             0 --success, otherwise fail
 */
static int
woal_priv_hscfg(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen,
		BOOLEAN invoke_hostcmd)
{
	int data[13] = { 0 };
	int *temp_data, type;
	int user_data_len = 0;
	int ret = 0;
	mlan_ds_hs_cfg hscfg, hscfg_temp;
	t_u16 action;
	mlan_bss_info bss_info;
	int is_negative = MFALSE;
	t_u8 *arguments = NULL;

	ENTER();

	memset(data, 0, sizeof(data));
	memset(&hscfg, 0, sizeof(mlan_ds_hs_cfg));
	memset(&hscfg_temp, 0, sizeof(mlan_ds_hs_cfg));

	if (strlen(respbuf) == (strlen(CMD_NXP) + strlen(PRIV_CMD_HSCFG))) {
		/* GET operation */
		user_data_len = 0;
	} else {
		/* SET operation */
		memset((char *)data, 0, sizeof(data));
		arguments = respbuf + strlen(CMD_NXP) + strlen(PRIV_CMD_HSCFG);
		if (*arguments == '-') {
			is_negative = MTRUE;
			arguments += 1;
		}
		parse_arguments(arguments, data, ARRAY_SIZE(data),
				&user_data_len);

		if (is_negative == MTRUE) {
			if (data[0] == 1) {
				data[0] = -1;
			} else {
				PRINTM(MERROR, "Invalid arguments\n");
				ret = -EINVAL;
				goto done;
			}
		}
	}

	if (sizeof(int) * user_data_len > sizeof(data)) {
		PRINTM(MERROR, "Too many arguments\n");
		LEAVE();
		return -EINVAL;
	}

	if (user_data_len == 0) {
		action = MLAN_ACT_GET;
	} else {
		if (user_data_len >= 1 && user_data_len <= 13) {
			action = MLAN_ACT_SET;
		} else {
			PRINTM(MERROR, "Invalid arguments\n");
			ret = -EINVAL;
			goto done;
		}
	}

	/* HS config is blocked if HS is already activated */
	if (user_data_len &&
	    (data[0] != (int)HOST_SLEEP_CFG_CANCEL ||
	     invoke_hostcmd == MFALSE)) {
		memset(&bss_info, 0, sizeof(bss_info));
		woal_get_bss_info(priv, MOAL_IOCTL_WAIT, &bss_info);
		if (bss_info.is_hs_configured) {
			PRINTM(MERROR, "HS already configured\n");
			ret = -EFAULT;
			goto done;
		}
	}

	/* Do a GET first if some arguments are not provided */
	if (user_data_len >= 1 && user_data_len < 11) {
		woal_set_get_hs_params(priv, MLAN_ACT_GET, MOAL_IOCTL_WAIT,
				       &hscfg_temp);
	}
	hscfg.conditions = hscfg_temp.conditions;
	hscfg.gpio = hscfg_temp.gpio;
	hscfg.gap = hscfg_temp.gap;

	if (user_data_len)
		hscfg.conditions = data[0];
	if (user_data_len >= 2)
		hscfg.gpio = data[1];
	if (user_data_len >= 3)
		hscfg.gap = data[2];
	user_data_len = user_data_len - 3;
	if (user_data_len > 0) {
		temp_data = data + 3;
		while ((user_data_len > 0) && temp_data) {
			type = *temp_data;
			switch (type) {
			case PARAMETER_GPIO_INDICATION:
				if (user_data_len >= 2)
					hscfg.ind_gpio = *(++temp_data);
				else {
					PRINTM(MERROR,
					       "Invaild number of parameters\n");
					ret = -EINVAL;
					goto done;
				}
				if (user_data_len >= 3) {
					hscfg.level = *(++temp_data);
					if (hscfg.level != 0 &&
					    hscfg.level != 1) {
						PRINTM(MERROR,
						       "Invalid indication gpio arguments\n");
						ret = -EINVAL;
						goto done;
					}
				}
				hscfg.param_type_ind = type;
				user_data_len = user_data_len - 3;
				temp_data++;
				break;
			case PARAMETER_EXTEND_HSCFG:
				if (user_data_len >= 4) {
					hscfg.event_force_ignore =
						*(++temp_data);
					hscfg.event_use_ext_gap =
						*(++temp_data);
					hscfg.ext_gap = *(++temp_data);
					hscfg.gpio_wave = *(++temp_data);
				} else {
					PRINTM(MERROR,
					       "Invaild number of parameters\n");
					ret = -EINVAL;
					goto done;
				}
				/* Force_ignore_gpio and ext_gap_gpio should not
				 * set the same bit(s)*/
				if ((hscfg.event_force_ignore &
				     hscfg.event_use_ext_gap) ||
				    (hscfg.gpio_wave != 1 &&
				     hscfg.gpio_wave != 0)) {
					PRINTM(MERROR,
					       "Invalid arguments for extend hscfg\n");
					ret = -EINVAL;
					goto done;
				}
				hscfg.param_type_ext = type;
				user_data_len = user_data_len - 5;
				temp_data++;
				break;
			case PARAMETER_HS_WAKEUP_INTERVAL:
				if (user_data_len >= 2)
					hscfg.hs_wake_interval = *(++temp_data);
				else {
					PRINTM(MERROR,
					       "Invaild number of parameters\n");
					ret = -EINVAL;
					goto done;
				}
				user_data_len = user_data_len - 2;
				temp_data++;
				break;
			default:
				PRINTM(MERROR, "Unsupported type\n");
				ret = -EINVAL;
				goto done;
			}
		}
	}

	if ((invoke_hostcmd == MTRUE) && (action == MLAN_ACT_SET)) {
		/* Need to issue an extra IOCTL first to set up parameters */
		hscfg.is_invoke_hostcmd = MFALSE;
		if (MLAN_STATUS_SUCCESS !=
		    woal_set_get_hs_params(priv, MLAN_ACT_SET, MOAL_IOCTL_WAIT,
					   &hscfg)) {
			ret = -EFAULT;
			goto done;
		}
	}
	hscfg.is_invoke_hostcmd = invoke_hostcmd;
	if (MLAN_STATUS_SUCCESS !=
	    woal_set_get_hs_params(priv, action, MOAL_IOCTL_WAIT, &hscfg)) {
		ret = -EFAULT;
		goto done;
	}

	if (action == MLAN_ACT_GET) {
		/* Return the current driver host sleep configurations */
		moal_memcpy_ext(priv->phandle, respbuf, &hscfg,
				sizeof(mlan_ds_hs_cfg), respbuflen);
		ret = sizeof(mlan_ds_hs_cfg);
	}
done:
	LEAVE();
	return ret;
}

/**
 *  @brief Set Host Sleep parameters
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             0 --success, otherwise fail
 */
static int
woal_priv_hssetpara(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int data[13] = { 0 };
	int user_data_len = 0;
	int ret = 0;

	ENTER();

	if (strlen(respbuf) == (strlen(CMD_NXP) + strlen(PRIV_CMD_HSSETPARA))) {
		PRINTM(MERROR, "Invalid arguments\n");
		ret = -EINVAL;
		goto done;
	} else {
		/* SET operation */
		memset((char *)data, 0, sizeof(data));
		parse_arguments(respbuf + strlen(CMD_NXP) +
				strlen(PRIV_CMD_HSSETPARA),
				data, ARRAY_SIZE(data), &user_data_len);
	}

	if (sizeof(int) * user_data_len > sizeof(data)) {
		PRINTM(MERROR, "Too many arguments\n");
		LEAVE();
		return -EINVAL;
	}

	if (user_data_len >= 1 && user_data_len <= 13) {
		sprintf(respbuf, "%s%s%s", CMD_NXP, PRIV_CMD_HSCFG,
			respbuf +
			(strlen(CMD_NXP) + strlen(PRIV_CMD_HSSETPARA)));
		respbuflen = strlen(respbuf);
		ret = woal_priv_hscfg(priv, respbuf, respbuflen, MFALSE);
		goto done;
	}
done:
	LEAVE();
	return ret;
}

/**
 * @brief Set/Get scan configuration parameters
 *
 * @param priv         A pointer to moal_private structure
 * @param respbuf      A pointer to response buffer
 * @param respbuflen   Available length of response buffer
 *
 * @return         0 --success, otherwise fail
 */
static int
woal_priv_set_get_scancfg(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int ret = 0;
	int user_data_len = 0;
	int data[9];
	mlan_ds_scan *scan = NULL;
	mlan_ioctl_req *req = NULL;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	memset(data, 0, sizeof(data));
	if (strlen(respbuf) == (strlen(CMD_NXP) + strlen(PRIV_CMD_SCANCFG))) {
		/* GET operation */
		user_data_len = 0;
	} else {
		/* SET operation */
		memset((char *)data, 0, sizeof(data));
		parse_arguments(respbuf + strlen(CMD_NXP) +
				strlen(PRIV_CMD_SCANCFG),
				data, ARRAY_SIZE(data), &user_data_len);
	}

	if (sizeof(int) * user_data_len > sizeof(data)) {
		PRINTM(MERROR, "Too many arguments\n");
		LEAVE();
		return -EINVAL;
	}

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_scan));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}
	scan = (mlan_ds_scan *)req->pbuf;
	scan->sub_command = MLAN_OID_SCAN_CONFIG;
	req->req_id = MLAN_IOCTL_SCAN;

	if (user_data_len) {
		if ((data[0] < 0) || (data[0] > MLAN_SCAN_TYPE_PASSIVE)) {
			PRINTM(MERROR, "Invalid argument for scan type\n");
			ret = -EINVAL;
			goto done;
		}
		if ((data[1] < 0) || (data[1] > MLAN_SCAN_MODE_ANY)) {
			PRINTM(MERROR, "Invalid argument for scan mode\n");
			ret = -EINVAL;
			goto done;
		}
		if ((data[2] < 0) || (data[2] > MAX_PROBES)) {
			PRINTM(MERROR, "Invalid argument for scan probes\n");
			ret = -EINVAL;
			goto done;
		}
		if (((data[3] < 0) ||
		     (data[3] > MRVDRV_MAX_ACTIVE_SCAN_CHAN_TIME)) ||
		    ((data[4] < 0) ||
		     (data[4] > MRVDRV_MAX_ACTIVE_SCAN_CHAN_TIME)) ||
		    ((data[5] < 0) ||
		     (data[5] > MRVDRV_MAX_PASSIVE_SCAN_CHAN_TIME))) {
			PRINTM(MERROR, "Invalid argument for scan time\n");
			ret = -EINVAL;
			goto done;
		}
		if ((data[6] < 0) || (data[6] > MLAN_PASS_TO_ACT_SCAN_DIS)) {
			PRINTM(MERROR,
			       "Invalid argument for Passive to Active Scan\n");
			ret = -EINVAL;
			goto done;
		}
		if ((data[7] < 0) || (data[7] > 3)) {
			PRINTM(MERROR, "Invalid argument for extended scan\n");
			ret = -EINVAL;
			goto done;
		}
		if ((data[8] < 0) || (data[8] > MRVDRV_MAX_SCAN_CHAN_GAP_TIME)) {
			PRINTM(MERROR,
			       "Invalid argument for scan channel gap\n");
			ret = -EINVAL;
			goto done;
		}
		req->action = MLAN_ACT_SET;
		moal_memcpy_ext(priv->phandle, &scan->param.scan_cfg, data,
				sizeof(data), sizeof(scan->param.scan_cfg));
	} else
		req->action = MLAN_ACT_GET;

	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}
	moal_memcpy_ext(priv->phandle, respbuf, &scan->param.scan_cfg,
			sizeof(mlan_scan_cfg), respbuflen);
	ret = sizeof(mlan_scan_cfg);
done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 * @brief Get Netlink Number
 *
 * @param priv         A pointer to moal_private structure
 * @param respbuf      A pointer to response buffer
 * @param respbuflen   Available length of response buffer
 *
 * @return         Number of bytes written, negative for failure.
 */
static int
woal_priv_getnlnum(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int ret = 0;
	int data = 0;

	ENTER();

	if (!priv || !priv->phandle) {
		PRINTM(MERROR, "priv or handle is null in %s\n", __FUNCTION__);
		ret = -EFAULT;
		goto done;
	}

	data = priv->phandle->netlink_num;
	moal_memcpy_ext(priv->phandle, respbuf, &data, sizeof(data),
			respbuflen);
	ret = sizeof(data);

done:
	LEAVE();
	return ret;
}

/**
 *  @brief Set / Get packet aggregation control
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_set_get_aggrctrl(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int data[1];
	int user_data_len = 0;
	int ret = 0;
	mlan_ioctl_req *req = NULL;
	mlan_ds_misc_cfg *pcfg_misc = NULL;
	moal_handle *handle = priv->phandle;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	if (!handle || !handle->card) {
		PRINTM(MERROR, "Handle or card is null\n");
		ret = -EFAULT;
		goto done;
	}

	memset((char *)data, 0, sizeof(data));
	if (strlen(respbuf) == (strlen(CMD_NXP) + strlen(PRIV_CMD_AGGRCTRL))) {
		/* GET operation */
		user_data_len = 0;
	} else {
		if (woal_is_any_interface_active(priv->phandle)) {
			PRINTM(MERROR,
			       "aggrctrl are not allowed to change after BSS active!\n");
			ret = -EFAULT;
			goto done;
		}
		/* SET operation */
		parse_arguments(respbuf + strlen(CMD_NXP) +
				strlen(PRIV_CMD_AGGRCTRL),
				data, ARRAY_SIZE(data), &user_data_len);

		if (sizeof(int) * user_data_len > sizeof(data)) {
			PRINTM(MERROR, "Too many arguments\n");
			ret = -EINVAL;
			goto done;
		}
	}

	/* Allocate an IOCTL request buffer */
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	/* Fill request buffer */
	pcfg_misc = (mlan_ds_misc_cfg *)req->pbuf;
	pcfg_misc->sub_command = MLAN_OID_MISC_AGGR_CTRL;
	req->req_id = MLAN_IOCTL_MISC_CFG;

	/* Get the values first, then modify these values if user had modified
	 * them */
	if (user_data_len == 0)
		req->action = MLAN_ACT_GET;
	else {
		req->action = MLAN_ACT_SET;
		pcfg_misc->param.aggr_params.tx.enable = (t_u16)data[0];
	}

	/* Send IOCTL request to MLAN */
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		/* MLAN will return CMD_INVALID if FW does not support this
		 * feature */
		if (MLAN_ERROR_CMD_INVALID == req->status_code)
			ret = -EOPNOTSUPP;
		else
			ret = -EFAULT;
		goto done;
	}

	moal_memcpy_ext(handle, respbuf, (t_u8 *)&pcfg_misc->param.aggr_params,
			sizeof(mlan_ds_misc_aggr_ctrl), respbuflen);
	ret = sizeof(mlan_ds_misc_aggr_ctrl);
done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);

	LEAVE();
	return ret;
}

#ifdef USB
/**
 *  @brief Set / Get USB packet aggregation control
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_set_get_usbaggrctrl(moal_private *priv, t_u8 *respbuf,
			      t_u32 respbuflen)
{
	int data[8];
	int user_data_len = 0;
	int ret = 0;
	mlan_ioctl_req *req = NULL;
	mlan_ds_misc_cfg *pcfg_misc = NULL;
	moal_handle *handle = priv->phandle;
	struct usb_card_rec *cardp = NULL;
	int i = 0, usb_resubmit_urbs = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	if (!handle || !handle->card) {
		PRINTM(MERROR, "Handle or card is null\n");
		ret = -EFAULT;
		goto done;
	}
	cardp = (struct usb_card_rec *)handle->card;

	memset((char *)data, 0, sizeof(data));
	if (strlen(respbuf) == (strlen(CMD_NXP) + strlen(PRIV_CMD_USBAGGRCTRL))) {
		/* GET operation */
		user_data_len = 0;
	} else {
		/* SET operation */
		parse_arguments(respbuf + strlen(CMD_NXP) +
				strlen(PRIV_CMD_USBAGGRCTRL),
				data, ARRAY_SIZE(data), &user_data_len);

		if (sizeof(int) * user_data_len > sizeof(data)) {
			PRINTM(MERROR, "Too many arguments\n");
			ret = -EINVAL;
			goto done;
		}
	}

	/* Allocate an IOCTL request buffer */
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	/* Fill request buffer */
	pcfg_misc = (mlan_ds_misc_cfg *)req->pbuf;
	pcfg_misc->sub_command = MLAN_OID_MISC_USB_AGGR_CTRL;
	req->req_id = MLAN_IOCTL_MISC_CFG;

	/* Get the values first, then modify these values if user had modified
	 * them */
	req->action = MLAN_ACT_GET;
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		/* MLAN will return CMD_INVALID if FW does not support this
		 * feature */
		if (MLAN_ERROR_CMD_INVALID == req->status_code)
			ret = -EOPNOTSUPP;
		else
			ret = -EFAULT;
		goto done;
	}

	if (user_data_len == 0) {
		moal_memcpy_ext(handle, respbuf,
				(t_u8 *)&pcfg_misc->param.usb_aggr_params,
				sizeof(mlan_ds_misc_usb_aggr_ctrl), respbuflen);
		ret = sizeof(mlan_ds_misc_usb_aggr_ctrl);
		goto done;
	}

	switch (user_data_len) {
	case 8:
		if (data[7] < 0) {
			PRINTM(MERROR, "Invalid Rx timeout value (%d)\n",
			       data[7]);
			ret = -EINVAL;
			goto done;
		}
		pcfg_misc->param.usb_aggr_params.rx_deaggr_ctrl.aggr_tmo =
			(t_u16)data[7];
		/* fall through */
	case 7:
		if (data[6] < 0 || (data[6] > 10000 &&
				    data[6] != MLAN_USB_TX_AGGR_TIMEOUT_DYN)) {
			PRINTM(MERROR, "Invalid Tx timeout value (%d)\n",
			       data[6]);
			ret = -EINVAL;
			goto done;
		}
		pcfg_misc->param.usb_aggr_params.tx_aggr_ctrl.aggr_tmo =
			(t_u16)data[6];
		/* fall through */
	case 6:
		if ((data[5] < 512) || ((data[5] % 512) != 0)) {
			PRINTM(MERROR, "Invalid Rx alignment value (%d)\n",
			       data[5]);
			ret = -EINVAL;
			goto done;
		}
		if (cardp->rx_deaggr_ctrl.enable &&
		    pcfg_misc->param.usb_aggr_params.rx_deaggr_ctrl.
		    aggr_align != (t_u16)data[5])
			usb_resubmit_urbs = 1;
		pcfg_misc->param.usb_aggr_params.rx_deaggr_ctrl.aggr_align =
			(t_u16)data[5];
		/* fall through */
	case 5:
		if ((data[4] < 2048) || ((data[4] % 2048) != 0)) {
			PRINTM(MERROR, "Invalid Tx alignment value (%d)\n",
			       data[4]);
			ret = -EINVAL;
			goto done;
		}
		pcfg_misc->param.usb_aggr_params.tx_aggr_ctrl.aggr_align =
			(t_u16)data[4];
		/* fall through */
	case 4:
		if ((data[3] == 2) || (data[3] == 4) || (data[3] == 8) ||
		    (data[3] == 16)) {
			pcfg_misc->param.usb_aggr_params.rx_deaggr_ctrl.
				aggr_mode = MLAN_USB_AGGR_MODE_NUM;
		} else if ((data[3] == 4096) || (data[3] == 8192) ||
			   (data[3] == 16384) || (data[3] == 32768)) {
			pcfg_misc->param.usb_aggr_params.rx_deaggr_ctrl.
				aggr_mode = MLAN_USB_AGGR_MODE_LEN;
		} else {
			PRINTM(MERROR, "Invalid Rx max size/num value (%d)\n",
			       data[3]);
			ret = -EINVAL;
			goto done;
		}
		if (cardp->rx_deaggr_ctrl.enable &&
		    pcfg_misc->param.usb_aggr_params.rx_deaggr_ctrl.aggr_max !=
		    (t_u16)data[3])
			usb_resubmit_urbs = 1;
		pcfg_misc->param.usb_aggr_params.rx_deaggr_ctrl.aggr_max =
			(t_u16)data[3];
		/* fall through */
	case 3:
		if ((data[2] == 2) || (data[2] == 4) || (data[2] == 8) ||
		    (data[2] == 16)) {
			pcfg_misc->param.usb_aggr_params.tx_aggr_ctrl.
				aggr_mode = MLAN_USB_AGGR_MODE_NUM;
		} else if ((data[2] == 4096) || (data[2] == 8192) ||
			   (data[2] == 16384) || (data[2] == 32768)) {
			pcfg_misc->param.usb_aggr_params.tx_aggr_ctrl.
				aggr_mode = MLAN_USB_AGGR_MODE_LEN;
		} else {
			PRINTM(MERROR, "Invalid Tx max size/num value (%d)\n",
			       data[2]);
			ret = -EINVAL;
			goto done;
		}
		pcfg_misc->param.usb_aggr_params.tx_aggr_ctrl.aggr_max =
			(t_u16)data[2];
		/* fall through */
	case 2:
		if ((data[1] != 0) && (data[1] != 1)) {
			PRINTM(MERROR, "Invalid Rx enable value (%d)\n",
			       data[1]);
			ret = -EINVAL;
			goto done;
		}
		if (pcfg_misc->param.usb_aggr_params.rx_deaggr_ctrl.enable !=
		    (t_u16)data[1])
			usb_resubmit_urbs = 1;
		pcfg_misc->param.usb_aggr_params.rx_deaggr_ctrl.enable =
			(t_u16)data[1];
		/* fall through */
	case 1:
		if ((data[0] != 0) && (data[0] != 1)) {
			PRINTM(MERROR, "Invalid Tx enable value (%d)\n",
			       data[0]);
			ret = -EINVAL;
			goto done;
		}
		pcfg_misc->param.usb_aggr_params.tx_aggr_ctrl.enable =
			(t_u16)data[0];
	default:
		break;
	}

	pcfg_misc->sub_command = MLAN_OID_MISC_USB_AGGR_CTRL;
	req->req_id = MLAN_IOCTL_MISC_CFG;
	req->action = MLAN_ACT_SET;

	/* Send IOCTL request to MLAN */
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	moal_memcpy_ext(handle, respbuf,
			(t_u8 *)&pcfg_misc->param.usb_aggr_params,
			sizeof(mlan_ds_misc_usb_aggr_ctrl), respbuflen);
	ret = sizeof(mlan_ds_misc_usb_aggr_ctrl);

	/* Keep a copy of the latest Tx aggregation parameters in MOAL */
	moal_memcpy_ext(handle, &cardp->tx_aggr_ctrl,
			&pcfg_misc->param.usb_aggr_params.tx_aggr_ctrl,
			sizeof(usb_aggr_ctrl_cfg), sizeof(usb_aggr_ctrl_cfg));

	if (usb_resubmit_urbs) {
		/* Indicate resubmition from here */
		cardp->resubmit_urbs = 1;
		/* Rx SG parameters has changed or disabled, kill the URBs, they
		   will be resubmitted after saving the parameters to USB card
		 */
		if (atomic_read(&cardp->rx_data_urb_pending)) {
			for (i = 0; i < MVUSB_RX_DATA_URB; i++) {
				if (cardp->rx_data_list[i].urb) {
					usb_kill_urb(cardp->rx_data_list[i].
						     urb);
					usb_init_urb(cardp->rx_data_list[i].
						     urb);
				}
			}
		}
	}

	/* Keep a copy of the latest Rx deaggregation parameters in MOAL */
	moal_memcpy_ext(handle, &cardp->rx_deaggr_ctrl,
			&pcfg_misc->param.usb_aggr_params.rx_deaggr_ctrl,
			sizeof(usb_aggr_ctrl_cfg), sizeof(usb_aggr_ctrl_cfg));

	if (usb_resubmit_urbs) {
		/* Ensure the next data URBs will use the modified parameters */
		if (!atomic_read(&cardp->rx_data_urb_pending)) {
			/* Submit multiple Rx data URBs */
			woal_usb_submit_rx_data_urbs(handle);
		}
		cardp->resubmit_urbs = 0;
	}

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);

	LEAVE();
	return ret;
}
#endif

#ifdef STA_SUPPORT
/**
 * @brief Set AP settings
 *
 * @param priv         A pointer to moal_private structure
 * @param respbuf      A pointer to response buffer
 * @param respbuflen   Available length of response buffer
 *
 * @return         Number of bytes written if successful, otherwise fail
 */
static int
woal_priv_set_ap(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int ret = 0;
	t_u8 *data_ptr;
	const t_u8 bcast[MLAN_MAC_ADDR_LENGTH] =
		{ 255, 255, 255, 255, 255, 255 };
	const t_u8 zero_mac[MLAN_MAC_ADDR_LENGTH] = { 0, 0, 0, 0, 0, 0 };
	mlan_ssid_bssid ssid_bssid;
	mlan_bss_info bss_info;
	struct mwreq *mwr;
	struct sockaddr *awrq;

	ENTER();
	data_ptr = respbuf + (strlen(CMD_NXP) + strlen(PRIV_CMD_SET_AP));

	mwr = (struct mwreq *)data_ptr;

	if (mwr->u.ap_addr.sa_family != ARPHRD_ETHER) {
		ret = -EINVAL;
		goto done;
	}

	awrq = (struct sockaddr *)&(mwr->u.ap_addr);

	PRINTM(MINFO, "ASSOC: WAP: sa_data: " MACSTR "\n",
	       MAC2STR((t_u8 *)awrq->sa_data));

	if (MLAN_STATUS_SUCCESS !=
	    woal_get_bss_info(priv, MOAL_IOCTL_WAIT, &bss_info)) {
		ret = -EFAULT;
		goto done;
	}
#ifdef REASSOCIATION
	/* Cancel re-association */
	priv->reassoc_required = MFALSE;
#endif

	/* zero_mac means disconnect */
	if (!memcmp(zero_mac, awrq->sa_data, MLAN_MAC_ADDR_LENGTH)) {
		woal_disconnect(priv, MOAL_IOCTL_WAIT, NULL,
				DEF_DEAUTH_REASON_CODE);
		goto done;
	}

	/* Broadcast MAC means search for best network */
	memset(&ssid_bssid, 0, sizeof(mlan_ssid_bssid));

	if (memcmp(bcast, awrq->sa_data, MLAN_MAC_ADDR_LENGTH)) {
		/* Check if we are already assoicated to the AP */
		if (bss_info.media_connected == MTRUE) {
			if (!memcmp(awrq->sa_data, &bss_info.bssid, ETH_ALEN))
				goto done;
		}
		moal_memcpy_ext(priv->phandle, &ssid_bssid.bssid, awrq->sa_data,
				ETH_ALEN, sizeof(mlan_802_11_mac_addr));
	}

	if (MLAN_STATUS_SUCCESS !=
	    woal_find_best_network(priv, MOAL_IOCTL_WAIT, &ssid_bssid)) {
		PRINTM(MERROR,
		       "ASSOC: WAP: MAC address not found in BSSID List\n");
		ret = -ENETUNREACH;
		goto done;
	}
	/* Zero SSID implies use BSSID to connect */
	memset(&ssid_bssid.ssid, 0, sizeof(mlan_802_11_ssid));
	if (MLAN_STATUS_SUCCESS !=
	    woal_bss_start(priv, MOAL_IOCTL_WAIT, &ssid_bssid)) {
		ret = -EFAULT;
		goto done;
	}
#ifdef REASSOCIATION
	memset(&bss_info, 0, sizeof(bss_info));
	if (MLAN_STATUS_SUCCESS !=
	    woal_get_bss_info(priv, MOAL_IOCTL_WAIT, &bss_info)) {
		ret = -EFAULT;
		goto done;
	}
	moal_memcpy_ext(priv->phandle, &priv->prev_ssid_bssid.ssid,
			&bss_info.ssid, sizeof(mlan_802_11_ssid),
			sizeof(mlan_802_11_ssid));
	moal_memcpy_ext(priv->phandle, &priv->prev_ssid_bssid.bssid,
			&bss_info.bssid, MLAN_MAC_ADDR_LENGTH,
			sizeof(mlan_802_11_mac_addr));
#endif /* REASSOCIATION */

done:
	LEAVE();
	return ret;
}
#endif

/**
 * @brief Set BSS mode
 *
 * @param priv         A pointer to moal_private structure
 * @param respbuf      A pointer to response buffer
 * @param respbuflen   Available length of response buffer
 *
 * @return         Number of bytes written if successful, otherwise fail
 */
static int
woal_priv_set_bss_mode(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int ret = 0;
	mlan_ds_bss *bss = NULL;
	mlan_ioctl_req *req = NULL;
	struct mwreq *mwr;
	t_u8 *data_ptr;
	t_u32 mode;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	data_ptr = respbuf + (strlen(CMD_NXP) + strlen(PRIV_CMD_SET_BSS_MODE));

	mwr = (struct mwreq *)data_ptr;
	mode = mwr->u.mode;
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}
	bss = (mlan_ds_bss *)req->pbuf;
	bss->sub_command = MLAN_OID_BSS_MODE;
	req->req_id = MLAN_IOCTL_BSS;
	req->action = MLAN_ACT_SET;

	switch (mode) {
	case MW_MODE_INFRA:
		bss->param.bss_mode = MLAN_BSS_MODE_INFRA;
		break;
	case MW_MODE_ADHOC:
		bss->param.bss_mode = MLAN_BSS_MODE_IBSS;
		break;
	case MW_MODE_AUTO:
		bss->param.bss_mode = MLAN_BSS_MODE_AUTO;
		break;
	default:
		ret = -EINVAL;
		break;
	}
	if (ret)
		goto done;
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}
done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

#ifdef STA_SUPPORT
/**
 * @brief Set power management
 *
 * @param priv         A pointer to moal_private structure
 * @param respbuf      A pointer to response buffer
 * @param respbuflen   Available length of response buffer
 *
 * @return         Number of bytes written if successful, otherwise fail
 */
static int
woal_priv_set_power(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	struct mwreq *mwr;
	t_u8 *data_ptr;
	int ret = 0, disabled;

	ENTER();

	if (moal_extflg_isset(priv->phandle, EXT_HW_TEST)) {
		PRINTM(MIOCTL, "block set power in hw_test mode\n");
		LEAVE();
		return ret;
	}

	data_ptr = respbuf + (strlen(CMD_NXP) + strlen(PRIV_CMD_SET_POWER));

	mwr = (struct mwreq *)data_ptr;
	disabled = mwr->u.power.disabled;

	if (MLAN_STATUS_SUCCESS !=
	    woal_set_get_power_mgmt(priv, MLAN_ACT_SET, &disabled,
				    mwr->u.power.flags, MOAL_IOCTL_WAIT)) {
		return -EFAULT;
	}
	LEAVE();
	return ret;
}

/**
 *  @brief Set essid
 *
 * @param priv         A pointer to moal_private structure
 * @param respbuf      A pointer to response buffer
 * @param respbuflen   Available length of response buffer
 *
 * @return         Number of bytes written if successful, otherwise fail
 */
static int
woal_priv_set_essid(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	mlan_802_11_ssid req_ssid;
	mlan_ssid_bssid ssid_bssid;
#ifdef REASSOCIATION
	moal_handle *handle = priv->phandle;
	mlan_bss_info bss_info;
#endif
	int ret = 0;
	t_u32 mode = 0;
	struct mwreq *mwr;
	t_u8 *data_ptr;

	ENTER();

	data_ptr = respbuf + (strlen(CMD_NXP) + strlen(PRIV_CMD_SET_ESSID));

	mwr = (struct mwreq *)data_ptr;

#ifdef REASSOCIATION
	/* Cancel re-association */
	priv->reassoc_required = MFALSE;

	if (MOAL_ACQ_SEMAPHORE_BLOCK(&handle->reassoc_sem)) {
		PRINTM(MERROR, "Acquire semaphore error, woal_set_essid\n");
		LEAVE();
		return -EBUSY;
	}
#endif /* REASSOCIATION */

	/* Check the size of the string */
	if (mwr->u.essid.length > MW_ESSID_MAX_SIZE - 1) {
		ret = -E2BIG;
		goto setessid_ret;
	}
	if (priv->scan_type == MLAN_SCAN_TYPE_PASSIVE)
		woal_set_scan_type(priv, MLAN_SCAN_TYPE_ACTIVE);
	memset(&req_ssid, 0, sizeof(mlan_802_11_ssid));
	memset(&ssid_bssid, 0, sizeof(mlan_ssid_bssid));

	req_ssid.ssid_len = mwr->u.essid.length;

	/* Check if we asked for 'any' or 'particular' */
	if (!mwr->u.essid.flags) {
#ifdef REASSOCIATION
		if (!req_ssid.ssid_len) {
			memset(&priv->prev_ssid_bssid.ssid, 0x00,
			       sizeof(mlan_802_11_ssid));
			memset(&priv->prev_ssid_bssid.bssid, 0x00,
			       MLAN_MAC_ADDR_LENGTH);
			goto setessid_ret;
		}
#endif
		/* Do normal SSID scanning */
		if (MLAN_STATUS_SUCCESS !=
		    woal_request_scan(priv, MOAL_IOCTL_WAIT, NULL)) {
			ret = -EFAULT;
			goto setessid_ret;
		}
	} else {
		/* Set the SSID */
		moal_memcpy_ext(handle, req_ssid.ssid, mwr->u.essid.pointer,
				req_ssid.ssid_len, MLAN_MAX_SSID_LENGTH);
		if (!req_ssid.ssid_len ||
		    (MFALSE == woal_ssid_valid(&req_ssid))) {
			PRINTM(MERROR, "Invalid SSID - aborting set_essid\n");
			ret = -EINVAL;
			goto setessid_ret;
		}

		PRINTM(MINFO, "Requested new SSID = %s\n",
		       (char *)req_ssid.ssid);
		moal_memcpy_ext(handle, &ssid_bssid.ssid, &req_ssid,
				sizeof(mlan_802_11_ssid),
				sizeof(mlan_802_11_ssid));
		if (MTRUE == woal_is_connected(priv, &ssid_bssid)) {
			PRINTM(MIOCTL, "Already connect to the network\n");
			goto setessid_ret;
		}

		if (mwr->u.essid.flags != 0xFFFF) {
			if (MLAN_STATUS_SUCCESS !=
			    woal_find_essid(priv, &ssid_bssid,
					    MOAL_IOCTL_WAIT)) {
				/* Do specific SSID scanning */
				if (MLAN_STATUS_SUCCESS !=
				    woal_request_scan(priv, MOAL_IOCTL_WAIT,
						      &req_ssid)) {
					ret = -EFAULT;
					goto setessid_ret;
				}
			}
		}
	}

	mode = woal_get_mode(priv, MOAL_IOCTL_WAIT);

	if (mode != MW_MODE_ADHOC) {
		if (MLAN_STATUS_SUCCESS !=
		    woal_find_best_network(priv, MOAL_IOCTL_WAIT,
					   &ssid_bssid)) {
			ret = -EFAULT;
			goto setessid_ret;
		}
	}
#ifdef UAP_SUPPORT
	else if (MLAN_STATUS_SUCCESS !=
		 woal_find_best_network(priv, MOAL_IOCTL_WAIT, &ssid_bssid))
		/* Adhoc start, Check the channel command */
		woal_11h_channel_check_ioctl(priv, MOAL_IOCTL_WAIT);
#endif

	/* Connect to BSS by ESSID */
	memset(&ssid_bssid.bssid, 0, MLAN_MAC_ADDR_LENGTH);

	if (MLAN_STATUS_SUCCESS !=
	    woal_bss_start(priv, MOAL_IOCTL_WAIT, &ssid_bssid)) {
		ret = -EFAULT;
		goto setessid_ret;
	}
#ifdef REASSOCIATION
	memset(&bss_info, 0, sizeof(bss_info));
	if (MLAN_STATUS_SUCCESS !=
	    woal_get_bss_info(priv, MOAL_IOCTL_WAIT, &bss_info)) {
		ret = -EFAULT;
		goto setessid_ret;
	}
	moal_memcpy_ext(handle, &priv->prev_ssid_bssid.ssid, &bss_info.ssid,
			sizeof(mlan_802_11_ssid), sizeof(mlan_802_11_ssid));
	moal_memcpy_ext(handle, &priv->prev_ssid_bssid.bssid, &bss_info.bssid,
			MLAN_MAC_ADDR_LENGTH, sizeof(mlan_802_11_mac_addr));
#endif /* REASSOCIATION */

setessid_ret:
	if (priv->scan_type == MLAN_SCAN_TYPE_PASSIVE)
		woal_set_scan_type(priv, MLAN_SCAN_TYPE_PASSIVE);
#ifdef REASSOCIATION
	MOAL_REL_SEMAPHORE(&handle->reassoc_sem);
#endif
	LEAVE();
	return ret;
}

/**
 *  @brief Set authentication mode parameters
 *
 * @param priv         A pointer to moal_private structure
 * @param respbuf      A pointer to response buffer
 * @param respbuflen   Available length of response buffer
 *
 * @return         Number of bytes written if successful, otherwise fail
 */
static int
woal_priv_set_auth(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	struct mwreq *mwr;
	t_u8 *data_ptr;
	int ret = 0;
	t_u32 auth_mode = 0;
	t_u32 encrypt_mode = 0;

	ENTER();

	data_ptr = respbuf + (strlen(CMD_NXP) + strlen(PRIV_CMD_SET_AUTH));

	mwr = (struct mwreq *)data_ptr;

	switch (mwr->u.param.flags & MW_AUTH_INDEX) {
	case MW_AUTH_CIPHER_PAIRWISE:
	case MW_AUTH_CIPHER_GROUP:
		if (mwr->u.param.value & MW_AUTH_CIPHER_NONE)
			encrypt_mode = MLAN_ENCRYPTION_MODE_NONE;
		else if (mwr->u.param.value & MW_AUTH_CIPHER_WEP40)
			encrypt_mode = MLAN_ENCRYPTION_MODE_WEP40;
		else if (mwr->u.param.value & MW_AUTH_CIPHER_WEP104)
			encrypt_mode = MLAN_ENCRYPTION_MODE_WEP104;
		else if (mwr->u.param.value & MW_AUTH_CIPHER_TKIP)
			encrypt_mode = MLAN_ENCRYPTION_MODE_TKIP;
		else if (mwr->u.param.value & MW_AUTH_CIPHER_CCMP)
			encrypt_mode = MLAN_ENCRYPTION_MODE_CCMP;
		if (MLAN_STATUS_SUCCESS !=
		    woal_set_encrypt_mode(priv, MOAL_IOCTL_WAIT, encrypt_mode))
			ret = -EFAULT;
		break;
	case MW_AUTH_80211_AUTH_ALG:
		switch (mwr->u.param.value) {
		case MW_AUTH_ALG_SHARED_KEY:
			PRINTM(MINFO, "Auth mode shared key!\n");
			auth_mode = MLAN_AUTH_MODE_SHARED;
			break;
		case MW_AUTH_ALG_LEAP:
			PRINTM(MINFO, "Auth mode LEAP!\n");
			auth_mode = MLAN_AUTH_MODE_NETWORKEAP;
			break;
		case MW_AUTH_ALG_OPEN_SYSTEM:
			PRINTM(MINFO, "Auth mode open!\n");
			auth_mode = MLAN_AUTH_MODE_OPEN;
			break;
		case MW_AUTH_ALG_SHARED_KEY | MW_AUTH_ALG_OPEN_SYSTEM:
		default:
			PRINTM(MINFO, "Auth mode auto!\n");
			auth_mode = MLAN_AUTH_MODE_AUTO;
			break;
		}
		if (MLAN_STATUS_SUCCESS !=
		    woal_set_auth_mode(priv, MOAL_IOCTL_WAIT, auth_mode))
			ret = -EFAULT;
		break;
	case MW_AUTH_WPA_ENABLED:
		if (MLAN_STATUS_SUCCESS !=
		    woal_set_wpa_enable(priv, MOAL_IOCTL_WAIT,
					mwr->u.param.value))
			ret = -EFAULT;
		break;
#define MW_AUTH_WAPI_ENABLED 0x20
	case MW_AUTH_WAPI_ENABLED:
		if (MLAN_STATUS_SUCCESS !=
		    woal_set_wapi_enable(priv, MOAL_IOCTL_WAIT,
					 mwr->u.param.value))
			ret = -EFAULT;
		break;
	case MW_AUTH_WPA_VERSION:
		/* set WPA_VERSION_DISABLED/VERSION_WPA/VERSION_WP2 */
		priv->wpa_version = mwr->u.param.value;
		break;
	case MW_AUTH_KEY_MGMT:
		/* set KEY_MGMT_802_1X/KEY_MGMT_PSK */
		priv->key_mgmt = mwr->u.param.value;
		break;
	case MW_AUTH_TKIP_COUNTERMEASURES:
	case MW_AUTH_DROP_UNENCRYPTED:
	case MW_AUTH_RX_UNENCRYPTED_EAPOL:
	case MW_AUTH_ROAMING_CONTROL:
	case MW_AUTH_PRIVACY_INVOKED:
		break;
	default:
		ret = -EOPNOTSUPP;
		break;
	}
	LEAVE();
	return ret;
}

/**
 *  @brief Get current BSSID
 *
 * @param priv         A pointer to moal_private structure
 * @param respbuf      A pointer to response buffer
 * @param respbuflen   Available length of response buffer
 *
 * @return         Number of bytes written if successful else negative value
 */
static int
woal_priv_get_ap(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	struct mwreq *mwr;
	t_u8 *data_ptr;
	int ret = 0;
	mlan_bss_info bss_info;

	ENTER();

	data_ptr = respbuf + (strlen(CMD_NXP) + strlen(PRIV_CMD_GET_AP));

	mwr = (struct mwreq *)data_ptr;

	memset(&bss_info, 0, sizeof(bss_info));

	ret = woal_get_bss_info(priv, MOAL_IOCTL_WAIT, &bss_info);
	if (ret != MLAN_STATUS_SUCCESS)
		return -EFAULT;

	if (bss_info.media_connected == MTRUE) {
		moal_memcpy_ext(priv->phandle, mwr->u.ap_addr.sa_data,
				&bss_info.bssid, MLAN_MAC_ADDR_LENGTH,
				sizeof(mwr->u.ap_addr.sa_data));
	} else {
		memset(mwr->u.ap_addr.sa_data, 0, MLAN_MAC_ADDR_LENGTH);
	}
	mwr->u.ap_addr.sa_family = ARPHRD_ETHER;
	ret = strlen(CMD_NXP) + strlen(PRIV_CMD_GET_AP) + sizeof(struct mwreq);

	LEAVE();
	return ret;
}

/**
 *  @brief  Get power management
 *
 * @param priv         A pointer to moal_private structure
 * @param respbuf      A pointer to response buffer
 * @param respbuflen   Available length of response buffer
 *
 * @return         Number of bytes written if successful else negative value
 */
static int
woal_priv_get_power(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	struct mwreq *mwr;
	t_u8 *data_ptr;
	int ret = 0, ps_mode;

	ENTER();

	data_ptr = respbuf + (strlen(CMD_NXP) + strlen(PRIV_CMD_GET_POWER));

	mwr = (struct mwreq *)data_ptr;

	if (MLAN_STATUS_SUCCESS != woal_set_get_power_mgmt(priv, MLAN_ACT_GET,
							   &ps_mode, 0,
							   MOAL_IOCTL_WAIT)) {
		return -EFAULT;
	}

	if (ps_mode)
		mwr->u.power.disabled = 0;
	else
		mwr->u.power.disabled = 1;

	mwr->u.power.value = 0;
	ret = strlen(CMD_NXP) + strlen(PRIV_CMD_GET_POWER) +
		sizeof(struct mwreq);
	LEAVE();
	return ret;
}

/**
 * @brief Set/Get power save mode
 *
 * @param priv         A pointer to moal_private structure
 * @param respbuf      A pointer to response buffer
 * @param respbuflen   Available length of response buffer
 *
 * @return         0 --success, otherwise fail
 */
static int
woal_priv_set_get_psmode(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int ret = 0;
	int data = 0;
	int user_data_len = 0, header_len = 0;
	t_u32 action = MLAN_ACT_GET;

	ENTER();

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_PSMODE);

	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		user_data_len = 0;
		action = MLAN_ACT_GET;
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len, &data,
				sizeof(data) / sizeof(int), &user_data_len);
		action = MLAN_ACT_SET;
	}

	if (sizeof(int) * user_data_len > sizeof(data)) {
		PRINTM(MERROR, "Too many arguments\n");
		ret = -EINVAL;
		goto done;
	}

	if (data != 0 && data != 1) {
		PRINTM(MERROR, "Invalid psmode=%d\n", data);
		ret = -EINVAL;
		goto done;
	}

	/* Flip the value */
	data = !data;

	if (MLAN_STATUS_SUCCESS !=
	    woal_set_get_power_mgmt(priv, action, &data, 0, MOAL_IOCTL_WAIT)) {
		ret = -EFAULT;
		goto done;
	}

	if (action == MLAN_ACT_SET)
		data = !data;

	moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)&data, sizeof(data),
			respbuflen);
	ret = sizeof(data);

done:
	LEAVE();
	return ret;
}
#endif /* STA_SUPPORT */

/**
 * @brief Performs warm reset
 *
 * @param priv         A pointer to moal_private structure
 * @param respbuf      A pointer to response buffer
 * @param respbuflen   Available length of response buffer
 *
 * @return         Number of bytes written if successful else negative value
 */
static int
woal_priv_warmreset(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int ret = 0;
	moal_handle *handle = priv->phandle;
	moal_handle *ref_handle;
	moal_private *ref_priv;
	ENTER();
	ret = woal_pre_warmreset(priv);
	if (ret)
		goto done;
	ref_handle = (moal_handle *)handle->pref_mac;
	if (ref_handle) {
		ref_priv = woal_get_priv(ref_handle, MLAN_BSS_ROLE_ANY);
		if (ref_priv) {
			ret = woal_pre_warmreset(ref_priv);
			if (ret)
				goto done;
			ret = woal_warmreset(ref_priv);
			if (ret)
				goto done;
		}
	}
	ret = woal_warmreset(priv);
done:
	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get TX power configurations
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return         0 --success, otherwise fail
 */
static int
woal_priv_txpowercfg(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int data[5];
	int user_data_len;
	int ret = 0;
	mlan_bss_info bss_info;
	mlan_ds_power_cfg *pcfg = NULL;
	mlan_ioctl_req *req = NULL;
	t_u8 *arguments = NULL;
	mlan_status status = MLAN_STATUS_SUCCESS;
	ENTER();

	memset(data, 0, sizeof(data));
	memset(&bss_info, 0, sizeof(bss_info));
	woal_get_bss_info(priv, MOAL_IOCTL_WAIT, &bss_info);

	if (strlen(respbuf) == (strlen(CMD_NXP) + strlen(PRIV_CMD_TXPOWERCFG))) {
		/* GET operation */
		user_data_len = 0;
	} else {
		/* SET operation */
		arguments =
			respbuf + strlen(CMD_NXP) + strlen(PRIV_CMD_TXPOWERCFG);
		parse_arguments(arguments, data, ARRAY_SIZE(data),
				&user_data_len);
	}

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_power_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}
	pcfg = (mlan_ds_power_cfg *)req->pbuf;
	pcfg->sub_command = MLAN_OID_POWER_CFG_EXT;
	req->req_id = MLAN_IOCTL_POWER_CFG;

	if (!user_data_len)
		req->action = MLAN_ACT_GET;
	else {
		/* SET operation */
		req->action = MLAN_ACT_SET;
		if (sizeof(int) * user_data_len > sizeof(data)) {
			PRINTM(MERROR, "Too many arguments\n");
			ret = -EINVAL;
			goto done;
		}
		switch (user_data_len) {
		case 1:
			if (data[0] == 0xFF)
				pcfg->param.power_ext.power_group[0]
					.rate_format = TX_PWR_CFG_AUTO_CTRL_OFF;
			else
				ret = -EINVAL;
			break;
		case 3:
		case 5:
			switch (data[0]) {
			case 0:	/* LG */
				pcfg->param.power_ext.power_group[0]
					.rate_format = MLAN_RATE_FORMAT_LG;
				pcfg->param.power_ext.power_group[0].bandwidth =
					MLAN_HT_BW20;
				break;
			case 1:	/* 20 MHz HT */
				pcfg->param.power_ext.power_group[0]
					.rate_format = MLAN_RATE_FORMAT_HT;
				pcfg->param.power_ext.power_group[0].bandwidth =
					MLAN_HT_BW20;
				break;
			case 2:	/* 40 MHz HT */
				pcfg->param.power_ext.power_group[0]
					.rate_format = MLAN_RATE_FORMAT_HT;
				pcfg->param.power_ext.power_group[0].bandwidth =
					MLAN_HT_BW40;
				break;
			case 3:	/* 1 NSS 20 MHZ VHT */
				pcfg->param.power_ext.power_group[0]
					.rate_format = MLAN_RATE_FORMAT_VHT;
				pcfg->param.power_ext.power_group[0].bandwidth =
					MLAN_HT_BW20;
				pcfg->param.power_ext.power_group[0].nss = 1;
				break;
			case 4:	/* 2 NSS 20 MHZ VHT */
				pcfg->param.power_ext.power_group[0]
					.rate_format = MLAN_RATE_FORMAT_VHT;
				pcfg->param.power_ext.power_group[0].bandwidth =
					MLAN_HT_BW20;
				pcfg->param.power_ext.power_group[0].nss = 2;
				break;
			case 5:	/* 1 NSS 40 MHZ VHT */
				pcfg->param.power_ext.power_group[0]
					.rate_format = MLAN_RATE_FORMAT_VHT;
				pcfg->param.power_ext.power_group[0].bandwidth =
					MLAN_HT_BW40;
				pcfg->param.power_ext.power_group[0].nss = 1;
				break;
			case 6:	/* 2 NSS 40 MHZ VHT */
				pcfg->param.power_ext.power_group[0]
					.rate_format = MLAN_RATE_FORMAT_VHT;
				pcfg->param.power_ext.power_group[0].bandwidth =
					MLAN_HT_BW40;
				pcfg->param.power_ext.power_group[0].nss = 2;
				break;
			case 7:	/* 1 NSS 80 MHZ VHT */
				pcfg->param.power_ext.power_group[0]
					.rate_format = MLAN_RATE_FORMAT_VHT;
				pcfg->param.power_ext.power_group[0].bandwidth =
					MLAN_VHT_BW80;
				pcfg->param.power_ext.power_group[0].nss = 1;
				break;
			case 8:	/* 2 NSS 80 MHZ VHT */
				pcfg->param.power_ext.power_group[0]
					.rate_format = MLAN_RATE_FORMAT_VHT;
				pcfg->param.power_ext.power_group[0].bandwidth =
					MLAN_VHT_BW80;
				pcfg->param.power_ext.power_group[0].nss = 2;
				break;
			default:
				ret = -EINVAL;
				break;
			}
			pcfg->param.power_ext.power_group[0].first_rate_ind =
				data[1];
			pcfg->param.power_ext.power_group[0].last_rate_ind =
				data[1];
			if (data[2] < bss_info.min_power_level) {
				PRINTM(MERROR,
				       "The set powercfg rate value %d dBm is out of range (%d dBm-%d dBm)!\n",
				       data[2], (int)bss_info.min_power_level,
				       (int)bss_info.max_power_level);
				ret = -EINVAL;
				break;
			}
			if (data[2] > bss_info.max_power_level) {
				PRINTM(MERROR,
				       "The set powercfg rate value %d dBm is out of range (%d dBm-%d dBm)!\n",
				       data[2], (int)bss_info.min_power_level,
				       (int)bss_info.max_power_level);
				ret = -EINVAL;
				break;
			}
			pcfg->param.power_ext.power_group[0].power_min =
				data[2];
			pcfg->param.power_ext.power_group[0].power_max =
				data[2];
			pcfg->param.power_ext.power_group[0].power_step = 0;
			pcfg->param.power_ext.num_pwr_grp = 1;

			break;
		default:
			ret = -EINVAL;
			break;
		}
		if (ret)
			goto done;
	}
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}
	if (!user_data_len) {
		/* GET operation */
		moal_memcpy_ext(priv->phandle, respbuf,
				(t_u8 *)&pcfg->param.power_ext,
				sizeof(pcfg->param.power_ext.num_pwr_grp) +
				(MIN(pcfg->param.power_ext.num_pwr_grp,
				     MAX_POWER_GROUP) *
				 sizeof(mlan_power_group)), respbuflen);
		ret = sizeof(pcfg->param.power_ext.num_pwr_grp) +
			(MIN(pcfg->param.power_ext.num_pwr_grp, MAX_POWER_GROUP)
			 * sizeof(mlan_power_group));
	}
done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 * @brief Set/Get PS configuration parameters
 *
 * @param priv         A pointer to moal_private structure
 * @param respbuf      A pointer to response buffer
 * @param respbuflen   Available length of response buffer
 *
 * @return         0 --success, otherwise fail
 */
static int
woal_priv_pscfg(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int data[7] = { 0 }, ret = 0;
	mlan_ds_pm_cfg *pm_cfg = NULL;
	mlan_ioctl_req *req = NULL;
	int allowed = 3;
	int i = 3;
	int user_data_len = 0, header_len = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	allowed++;		/* For beacon missing timeout parameter */
	allowed += 2;		/* For delay to PS and PS mode parameters */
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_pm_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_PSCFG);

	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		user_data_len = 0;
	} else {
		/* SET operation */
		memset((char *)data, 0, sizeof(data));
		parse_arguments(respbuf + header_len, data, ARRAY_SIZE(data),
				&user_data_len);
	}

	if (user_data_len && user_data_len > allowed) {
		PRINTM(MERROR, "Too many arguments\n");
		ret = -EINVAL;
		goto done;
	}
	pm_cfg = (mlan_ds_pm_cfg *)req->pbuf;
	pm_cfg->sub_command = MLAN_OID_PM_CFG_PS_CFG;
	req->req_id = MLAN_IOCTL_PM_CFG;
	if (user_data_len) {
		if ((data[0] < PS_NULL_DISABLE)) {
			PRINTM(MERROR,
			       "Invalid argument for PS null interval\n");
			ret = -EINVAL;
			goto done;
		}
		if ((data[1] != MRVDRV_IGNORE_MULTIPLE_DTIM) &&
		    (data[1] != MRVDRV_MATCH_CLOSEST_DTIM) &&
		    ((data[1] < MRVDRV_MIN_MULTIPLE_DTIM) ||
		     (data[1] > MRVDRV_MAX_MULTIPLE_DTIM))) {
			PRINTM(MERROR, "Invalid argument for multiple DTIM\n");
			ret = -EINVAL;
			goto done;
		}

		if ((data[2] < MRVDRV_MIN_LISTEN_INTERVAL) &&
		    (data[2] != MRVDRV_LISTEN_INTERVAL_DISABLE)) {
			PRINTM(MERROR,
			       "Invalid argument for listen interval\n");
			ret = -EINVAL;
			goto done;
		}

		if ((data[i] != DISABLE_BCN_MISS_TO) &&
		    ((data[i] < MIN_BCN_MISS_TO) ||
		     (data[i] > MAX_BCN_MISS_TO))) {
			PRINTM(MERROR,
			       "Invalid argument for beacon miss timeout\n");
			ret = -EINVAL;
			goto done;
		}
		i++;
		if (user_data_len < allowed - 1)
			data[i] = DELAY_TO_PS_UNCHANGED;
		else if ((data[i] < MIN_DELAY_TO_PS) ||
			 (data[i] > MAX_DELAY_TO_PS)) {
			PRINTM(MERROR, "Invalid argument for delay to PS\n");
			ret = -EINVAL;
			goto done;
		}
		i++;
		if ((data[i] != PS_MODE_UNCHANGED) &&
		    (data[i] != PS_MODE_AUTO) && (data[i] != PS_MODE_POLL) &&
		    (data[i] != PS_MODE_NULL)) {
			PRINTM(MERROR, "Invalid argument for PS mode\n");
			ret = -EINVAL;
			goto done;
		}
		i++;
		req->action = MLAN_ACT_SET;
		moal_memcpy_ext(priv->phandle, &pm_cfg->param.ps_cfg, data,
				sizeof(data), sizeof(pm_cfg->param.ps_cfg));
	} else
		req->action = MLAN_ACT_GET;

	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}
	moal_memcpy_ext(priv->phandle, data, &pm_cfg->param.ps_cfg,
			MIN((sizeof(int) * allowed),
			    sizeof(pm_cfg->param.ps_cfg)), sizeof(data));
	moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)data,
			sizeof(int) * allowed, respbuflen);
	ret = sizeof(int) * allowed;
	if (req->action == MLAN_ACT_SET) {
		pm_cfg = (mlan_ds_pm_cfg *)req->pbuf;
		pm_cfg->sub_command = MLAN_OID_PM_CFG_IEEE_PS;
		pm_cfg->param.ps_mode = 1;
		req->req_id = MLAN_IOCTL_PM_CFG;
		req->action = MLAN_ACT_SET;
		status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	}

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 * @brief Set/Get PS configuration parameters
 *
 * @param priv         A pointer to moal_private structure
 * @param respbuf      A pointer to response buffer
 * @param respbuflen   Available length of response buffer
 *
 * @return         0 --success, otherwise fail
 */
static int
woal_priv_bcntimeoutcfg(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int data[4] = { 0 }, ret = 0;
	mlan_ds_pm_cfg *pm_cfg = NULL;
	mlan_ioctl_req *req = NULL;
	int allowed = 4;
	int i = 0;
	int user_data_len = 0, header_len = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_BCNTIMEOUTCFG);

	memset((char *)data, 0, sizeof(data));
	parse_arguments(respbuf + header_len, data, ARRAY_SIZE(data),
			&user_data_len);
	if (user_data_len != allowed) {
		PRINTM(MERROR, "Invalid args num: input=%d allowed=%d\n",
		       user_data_len, allowed);
		ret = -EINVAL;
		goto done;
	}
	for (i = 0; i < allowed; i++) {
		if (data[i] <= 0) {
			PRINTM(MERROR, "Invalid data[%d]=%d\n", i, data[i]);
			ret = -EINVAL;
			goto done;
		}
	}

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_pm_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}
	pm_cfg = (mlan_ds_pm_cfg *)req->pbuf;
	pm_cfg->sub_command = MLAN_OID_PM_CFG_BCN_TIMEOUT;
	req->req_id = MLAN_IOCTL_PM_CFG;
	req->action = MLAN_ACT_SET;
	pm_cfg->param.bcn_timeout.bcn_miss_tmo_window = (t_u16)data[0];
	pm_cfg->param.bcn_timeout.bcn_miss_tmo_period = (t_u16)data[1];
	pm_cfg->param.bcn_timeout.bcn_rq_tmo_window = (t_u16)data[2];
	pm_cfg->param.bcn_timeout.bcn_rq_tmo_period = (t_u16)data[3];

	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 * @brief Set/Get sleep period
 *
 * @param priv         A pointer to moal_private structure
 * @param respbuf      A pointer to response buffer
 * @param respbuflen   Available length of response buffer
 *
 * @return         0 --success, otherwise fail
 */
static int
woal_priv_sleeppd(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int ret = 0;
	mlan_ds_pm_cfg *pm_cfg = NULL;
	mlan_ioctl_req *req = NULL;
	int data = 0;
	int user_data_len = 0, header_len = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_pm_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}
	pm_cfg = (mlan_ds_pm_cfg *)req->pbuf;
	pm_cfg->sub_command = MLAN_OID_PM_CFG_SLEEP_PD;
	req->req_id = MLAN_IOCTL_PM_CFG;

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_SLEEPPD);

	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		user_data_len = 0;
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len, &data,
				sizeof(data) / sizeof(int), &user_data_len);
	}

	if (sizeof(int) * user_data_len > sizeof(data)) {
		PRINTM(MERROR, "Too many arguments\n");
		ret = -EINVAL;
		goto done;
	}

	if (user_data_len) {
		if ((data <= MAX_SLEEP_PERIOD && data >= MIN_SLEEP_PERIOD) ||
		    (data == 0)
		    || (data == SLEEP_PERIOD_RESERVED_FF)
			) {
			req->action = MLAN_ACT_SET;
			pm_cfg->param.sleep_period = data;
		} else {
			ret = -EINVAL;
			goto done;
		}
	} else
		req->action = MLAN_ACT_GET;

	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}
	if (!user_data_len) {
		data = pm_cfg->param.sleep_period;
		moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)&data,
				sizeof(data), respbuflen);
		ret = sizeof(data);
	}

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 * @brief Set/Get Tx control flag
 *
 * @param priv         A pointer to moal_private structure
 * @param respbuf      A pointer to response buffer
 * @param respbuflen   Available length of response buffer
 *
 * @return         0 --success, otherwise fail
 */
static int
woal_priv_txcontrol(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int ret = 0;
	mlan_ds_misc_cfg *misc_cfg = NULL;
	mlan_ioctl_req *req = NULL;
	int data = 0;
	int user_data_len = 0, header_len = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}
	misc_cfg = (mlan_ds_misc_cfg *)req->pbuf;
	misc_cfg->sub_command = MLAN_OID_MISC_TXCONTROL;
	req->req_id = MLAN_IOCTL_MISC_CFG;

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_TXCONTROL);

	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		user_data_len = 0;
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len, &data,
				sizeof(data) / sizeof(int), &user_data_len);
	}

	if (sizeof(int) * user_data_len > sizeof(data)) {
		PRINTM(MERROR, "Too many arguments\n");
		ret = -EINVAL;
		goto done;
	}

	if (user_data_len) {
		req->action = MLAN_ACT_SET;
		misc_cfg->param.tx_control = (t_u32)data;
	} else {
		req->action = MLAN_ACT_GET;
	}

	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}
	if (!user_data_len) {
		data = misc_cfg->param.tx_control;
		moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)&data,
				sizeof(data), respbuflen);
		ret = sizeof(data);
	}

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 * @brief Read/Write adapter registers value
 *
 * @param priv         A pointer to moal_private structure
 * @param respbuf      A pointer to response buffer
 * @param respbuflen   Available length of response buffer
 *
 * @return         0 --success, otherwise fail
 */
static int
woal_priv_regrdwr(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int data[3];
	int ret = 0;
	mlan_ioctl_req *req = NULL;
	mlan_ds_reg_mem *reg_mem = NULL;
	int user_data_len = 0, header_len = 0;
	t_u8 *arguments = NULL, *space_ind = NULL;
	t_u32 is_negative_val = MFALSE;
	mlan_status status = MLAN_STATUS_SUCCESS;
	gfp_t flag;

	ENTER();

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_reg_mem));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	reg_mem = (mlan_ds_reg_mem *)req->pbuf;
	reg_mem->sub_command = MLAN_OID_REG_RW;
	req->req_id = MLAN_IOCTL_REG_MEM;

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_REGRDWR);

	if ((int)strlen(respbuf) == header_len) {
		ret = -EINVAL;
		goto done;
	}
	/* SET operation */
	memset((char *)data, 0, sizeof(data));
	flag = (in_atomic() || irqs_disabled())? GFP_ATOMIC : GFP_KERNEL;
	arguments = kzalloc(strlen(respbuf) * sizeof(char), flag);
	if (arguments == NULL) {
		ret = -ENOMEM;
		goto done;
	}
	strcpy(arguments, respbuf + header_len);
	space_ind = strstr((char *)arguments, " ");
	if (space_ind)
		space_ind = strstr(space_ind + 1, " ");
	if (space_ind) {
		if (*(char *)(space_ind + 1) == '-') {
			is_negative_val = MTRUE;
			arguments[space_ind + 1 - arguments] = '\0';
			strcat(arguments, space_ind + 2);
		}
	}
	parse_arguments(arguments, data, ARRAY_SIZE(data), &user_data_len);
	if (is_negative_val == MTRUE)
		data[2] *= -1;

	if (user_data_len == 2) {
		req->action = MLAN_ACT_GET;
	} else if (user_data_len == 3) {
		req->action = MLAN_ACT_SET;
	} else {
		ret = -EINVAL;
		goto done;
	}

	reg_mem->param.reg_rw.type = (t_u32)data[0];
	reg_mem->param.reg_rw.offset = (t_u32)data[1];
	if (user_data_len == 3)
		reg_mem->param.reg_rw.value = (t_u32)data[2];

	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	if (req->action == MLAN_ACT_GET) {
		moal_memcpy_ext(priv->phandle, respbuf, &reg_mem->param.reg_rw,
				sizeof(reg_mem->param.reg_rw), respbuflen);
		ret = sizeof(reg_mem->param.reg_rw);
	}

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	kfree(arguments);
	LEAVE();
	return ret;
}

/**
 * @brief Read the EEPROM contents of the card
 *
 * @param priv         A pointer to moal_private structure
 * @param respbuf      A pointer to response buffer
 * @param respbuflen   Available length of response buffer
 *
 * @return         0 --success, otherwise fail
 */
static int
woal_priv_rdeeprom(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int data[2];
	int ret = 0;
	mlan_ioctl_req *req = NULL;
	mlan_ds_reg_mem *reg_mem = NULL;
	int user_data_len = 0, header_len = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_reg_mem));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	reg_mem = (mlan_ds_reg_mem *)req->pbuf;
	reg_mem->sub_command = MLAN_OID_EEPROM_RD;
	req->req_id = MLAN_IOCTL_REG_MEM;

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_RDEEPROM);

	if ((int)strlen(respbuf) == header_len) {
		ret = -EINVAL;
		goto done;
	}
	/* SET operation */
	memset((char *)data, 0, sizeof(data));
	parse_arguments(respbuf + header_len, data, ARRAY_SIZE(data),
			&user_data_len);

	if (user_data_len == 2) {
		req->action = MLAN_ACT_GET;
	} else {
		ret = -EINVAL;
		goto done;
	}

	reg_mem->param.rd_eeprom.offset = (t_u16)data[0];
	reg_mem->param.rd_eeprom.byte_count = (t_u16)data[1];

	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	if (req->action == MLAN_ACT_GET) {
		moal_memcpy_ext(priv->phandle, respbuf,
				&reg_mem->param.rd_eeprom,
				sizeof(reg_mem->param.rd_eeprom), respbuflen);
		ret = sizeof(reg_mem->param.rd_eeprom);
	}

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 * @brief Read/Write device memory value
 *
 * @param priv         A pointer to moal_private structure
 * @param respbuf      A pointer to response buffer
 * @param respbuflen   Available length of response buffer
 *
 * @return         0 --success, otherwise fail
 */
static int
woal_priv_memrdwr(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int data[2];
	int ret = 0;
	mlan_ioctl_req *req = NULL;
	mlan_ds_reg_mem *reg_mem = NULL;
	int user_data_len = 0, header_len = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_reg_mem));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	reg_mem = (mlan_ds_reg_mem *)req->pbuf;
	reg_mem->sub_command = MLAN_OID_MEM_RW;
	req->req_id = MLAN_IOCTL_REG_MEM;

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_MEMRDWR);

	if ((int)strlen(respbuf) == header_len) {
		ret = -EINVAL;
		goto done;
	}
	/* SET operation */
	memset((char *)data, 0, sizeof(data));
	parse_arguments(respbuf + header_len, data, ARRAY_SIZE(data),
			&user_data_len);

	if (user_data_len == 1) {
		PRINTM(MINFO, "MEM_RW: GET\n");
		req->action = MLAN_ACT_GET;
	} else if (user_data_len == 2) {
		PRINTM(MINFO, "MEM_RW: SET\n");
		req->action = MLAN_ACT_SET;
	} else {
		ret = -EINVAL;
		goto done;
	}

	reg_mem->param.mem_rw.addr = (t_u32)data[0];
	if (user_data_len == 2)
		reg_mem->param.mem_rw.value = (t_u32)data[1];

	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	if (req->action == MLAN_ACT_GET) {
		moal_memcpy_ext(priv->phandle, respbuf, &reg_mem->param.mem_rw,
				sizeof(reg_mem->param.mem_rw), respbuflen);
		ret = sizeof(reg_mem->param.mem_rw);
	}

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

#ifdef SDIO
/**
 *  @brief Cmd52 read/write register
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             MLAN_STATUS_SUCCESS --success, otherwise fail
 */
static int
woal_priv_sdcmd52rw(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	t_u8 rw = 0, func, data = 0;
	int buf[3], reg, ret = MLAN_STATUS_SUCCESS;
	int user_data_len = 0, header_len = 0;

	ENTER();

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_SDCMD52RW);
	memset((t_u8 *)buf, 0, sizeof(buf));

	if ((int)strlen(respbuf) == header_len) {
		PRINTM(MERROR, "Invalid number of arguments\n");
		ret = -EINVAL;
		goto done;
	}
	parse_arguments(respbuf + header_len, buf, ARRAY_SIZE(buf),
			&user_data_len);

	if (user_data_len < 2 || user_data_len > 3) {
		PRINTM(MERROR, "Invalid number of arguments\n");
		ret = -EINVAL;
		goto done;
	}

	func = (t_u8)buf[0];
	if (func > 7) {
		PRINTM(MERROR, "Invalid function number!\n");
		ret = -EINVAL;
		goto done;
	}
	reg = (t_u32)buf[1];
	if (user_data_len == 2) {
		rw = 0;		/* CMD52 read */
		PRINTM(MINFO, "Cmd52 read, func=%d, reg=0x%08X\n", func, reg);
	}
	if (user_data_len == 3) {
		rw = 1;		/* CMD52 write */
		data = (t_u8)buf[2];
		PRINTM(MINFO, "Cmd52 write, func=%d, reg=0x%08X, data=0x%02X\n",
		       func, reg, data);
	}

	if (!rw) {
#ifdef SDIO_MMC
		sdio_claim_host(((struct sdio_mmc_card *)priv->phandle->card)->
				func);
		if (func)
			data = sdio_readb(((struct sdio_mmc_card *)priv->
					   phandle->card)
					  ->func, reg, &ret);
		else
			data = sdio_f0_readb(((struct sdio_mmc_card *)priv->
					      phandle->card)
					     ->func, reg, &ret);
		sdio_release_host(((struct sdio_mmc_card *)priv->phandle->
				   card)->func);
		if (ret) {
			PRINTM(MERROR,
			       "sdio_readb: reading register 0x%X failed\n",
			       reg);
			goto done;
		}
#else
		if (sdio_read_ioreg(priv->phandle->card, func, reg, &data) < 0) {
			PRINTM(MERROR,
			       "sdio_read_ioreg: reading register 0x%X failed\n",
			       reg);
			ret = MLAN_STATUS_FAILURE;
			goto done;
		}
#endif /* SDIO_MMC */
	} else {
#ifdef SDIO_MMC
		sdio_claim_host(((struct sdio_mmc_card *)priv->phandle->card)->
				func);
		if (func)
			sdio_writeb(((struct sdio_mmc_card *)priv->phandle->
				     card)
				    ->func, data, reg, &ret);
		else
			sdio_f0_writeb(((struct sdio_mmc_card *)priv->phandle->
					card)
				       ->func, data, reg, &ret);
		sdio_release_host(((struct sdio_mmc_card *)priv->phandle->
				   card)->func);
		if (ret) {
			PRINTM(MERROR,
			       "sdio_writeb: writing register 0x%X failed\n",
			       reg);
			goto done;
		}
#else
		if (sdio_write_ioreg(priv->phandle->card, func, reg, data) < 0) {
			PRINTM(MERROR,
			       "sdio_write_ioreg: writing register 0x%X failed\n",
			       reg);
			ret = MLAN_STATUS_FAILURE;
			goto done;
		}
#endif /* SDIO_MMC */
	}

	/* Action = GET */
	buf[0] = data;

	moal_memcpy_ext(priv->phandle, respbuf, &buf, sizeof(int), respbuflen);
	ret = sizeof(int);

done:
	LEAVE();
	return ret;
}
#endif /* SDIO */

#ifdef STA_SUPPORT
/**
 *  @brief arpfilter ioctl function
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return		0 --success, otherwise fail
 */
static int
woal_priv_arpfilter(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int ret = 0;
	mlan_ds_misc_cfg *misc = NULL;
	mlan_ioctl_req *req = NULL;
	t_u8 *data_ptr = NULL;
	t_u32 buf_len = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}
	misc = (mlan_ds_misc_cfg *)req->pbuf;
	misc->sub_command = MLAN_OID_MISC_GEN_IE;
	req->req_id = MLAN_IOCTL_MISC_CFG;
	req->action = MLAN_ACT_SET;
	misc->param.gen_ie.type = MLAN_IE_TYPE_ARP_FILTER;

	data_ptr = respbuf + (strlen(CMD_NXP) + strlen(PRIV_CMD_ARPFILTER));
	buf_len = *((t_u16 *)data_ptr);
	misc->param.gen_ie.len = buf_len;
	moal_memcpy_ext(priv->phandle, (void *)(misc->param.gen_ie.ie_data),
			data_ptr + sizeof(buf_len), buf_len, MAX_IE_SIZE);

	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}
done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}
#endif /* STA_SUPPORT */

/**
 *  @brief Set / Get Auto ARP Response configuration
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_set_get_auto_arp(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int data[4];
	int user_data_len = 0;
	int ret = 0;
	moal_handle *handle = NULL;

	ENTER();

	if (priv == NULL) {
		PRINTM(MERROR, "Invalid priv\n");
		goto done;
	}
	handle = priv->phandle;

	if (strlen(respbuf) == (strlen(CMD_NXP) + strlen(PRIV_CMD_AUTO_ARP))) {
		/* GET operation */
		user_data_len = 0;
	} else {
		/* SET operation */
		memset((char *)data, 0, sizeof(data));
		parse_arguments(respbuf + strlen(CMD_NXP) +
				strlen(PRIV_CMD_AUTO_ARP),
				data, ARRAY_SIZE(data), &user_data_len);
	}

	if (user_data_len > 1) {
		PRINTM(MERROR, "Too many arguments\n");
		ret = -EINVAL;
		goto done;
	}

	if (user_data_len) {
		/* Get the enable/disable value from user */
		handle->hs_auto_arp = data[0];
		PRINTM(MIOCTL, "Auto ARP : %s\n",
		       handle->hs_auto_arp ? "enable" : "disable");
	}

	moal_memcpy_ext(handle, respbuf, &handle->hs_auto_arp,
			sizeof(handle->hs_auto_arp), respbuflen);
	ret = sizeof(handle->hs_auto_arp);

done:
	LEAVE();
	return ret;
}

/**
 *  @brief Get/Set deauth control
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_deauth_ctrl(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	mlan_ds_snmp_mib *cfg = NULL;
	mlan_ioctl_req *req = NULL;
	int ret = 0, header_len = 0, data = 0, user_data_len = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_snmp_mib));
	if (req == NULL) {
		ret = ENOMEM;
		goto done;
	}

	cfg = (mlan_ds_snmp_mib *)req->pbuf;
	cfg->sub_command = MLAN_OID_SNMP_MIB_CTRL_DEAUTH;
	req->req_id = MLAN_IOCTL_SNMP_MIB;

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_DEAUTH_CTRL);

	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		req->action = MLAN_ACT_GET;
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len, &data,
				sizeof(data) / sizeof(int), &user_data_len);
		if (user_data_len != 1) {
			PRINTM(MERROR, "Invalid number of args! %d\n",
			       user_data_len);
			ret = -EINVAL;
			goto done;
		}
		req->action = MLAN_ACT_SET;
		cfg->param.deauthctrl = (t_u8)data;
	}

	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	data = (int)cfg->param.deauthctrl;
	moal_memcpy_ext(priv->phandle, respbuf, &data, sizeof(data),
			respbuflen);
	ret = sizeof(data);

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

#define MRVL_TLV_HEADER_SIZE 4
/**
 *  @brief              Get/Set per packet Txctl and Rxinfo configuration
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_per_pkt_cfg(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	mlan_ds_misc_cfg *misc = NULL;
	mlan_ioctl_req *req = NULL;
	int ret = 0;
	t_u8 *pos = NULL;
	int left_len, header_len = 0;
	mlan_per_pkt_cfg *perpkt = NULL;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_PER_PKT_CFG);
	pos = respbuf + header_len;
	left_len = respbuflen - header_len;

	if (priv->phandle->card_info->per_pkt_cfg_support == 0) {
		PRINTM(MERROR, "Device not support per packet configuration\n");
		ret = -EFAULT;
		goto done;
	}

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (req == NULL) {
		ret = ENOMEM;
		goto done;
	}

	misc = (mlan_ds_misc_cfg *)req->pbuf;
	misc->sub_command = MLAN_OID_MISC_PER_PKT_CFG;
	req->req_id = MLAN_IOCTL_MISC_CFG;

	if (*pos == 0) {
		/* GET operation */
		pos++;
		if (priv->tx_protocols.protocol_num) {
			perpkt = (mlan_per_pkt_cfg *) pos;
			perpkt->type = TLV_TYPE_PER_PKT_CFG;
			perpkt->tx_rx_control = TX_PKT_CTRL;
			perpkt->proto_type_num =
				priv->tx_protocols.protocol_num;
			moal_memcpy_ext(priv->phandle, perpkt->ether_type,
					priv->tx_protocols.protocols,
					perpkt->proto_type_num * sizeof(t_u16),
					MAX_NUM_ETHER_TYPE * sizeof(t_u16));
			perpkt->len =
				(perpkt->proto_type_num + 1) * sizeof(t_u16);
			pos += perpkt->len + MRVL_TLV_HEADER_SIZE;
		}
		if (priv->rx_protocols.protocol_num) {
			perpkt = (mlan_per_pkt_cfg *) pos;
			perpkt->type = TLV_TYPE_PER_PKT_CFG;
			perpkt->tx_rx_control = RX_PKT_INFO;
			perpkt->proto_type_num =
				priv->rx_protocols.protocol_num;
			moal_memcpy_ext(priv->phandle, perpkt->ether_type,
					priv->rx_protocols.protocols,
					perpkt->proto_type_num * sizeof(t_u16),
					MAX_NUM_ETHER_TYPE * sizeof(t_u16));
			perpkt->len =
				(perpkt->proto_type_num + 1) * sizeof(t_u16);
			pos += perpkt->len + MRVL_TLV_HEADER_SIZE;
		}
		ret = pos - respbuf;
		goto done;
	} else if (*pos == 1) {
		/* SET operation */
		req->action = MLAN_ACT_SET;
		pos++;
		left_len--;
		while (*pos == TLV_TYPE_PER_PKT_CFG && (left_len > 2)) {
			perpkt = (mlan_per_pkt_cfg *) pos;
			if (perpkt->tx_rx_control & TX_PKT_CTRL) {
				priv->tx_protocols.protocol_num =
					perpkt->proto_type_num;
				if (perpkt->proto_type_num <=
				    MAX_NUM_ETHER_TYPE)
					moal_memcpy_ext(priv->phandle,
							priv->tx_protocols.
							protocols,
							perpkt->ether_type,
							perpkt->proto_type_num *
							sizeof(t_u16),
							MAX_NUM_ETHER_TYPE *
							sizeof(t_u16));
			}
			if (perpkt->tx_rx_control & RX_PKT_INFO) {
				priv->rx_protocols.protocol_num =
					perpkt->proto_type_num;
				if (perpkt->proto_type_num <=
				    MAX_NUM_ETHER_TYPE)
					moal_memcpy_ext(priv->phandle,
							priv->rx_protocols.
							protocols,
							perpkt->ether_type,
							perpkt->proto_type_num *
							sizeof(t_u16),
							MAX_NUM_ETHER_TYPE *
							sizeof(t_u16));
			}
			if (!perpkt->tx_rx_control) {
				memset(&priv->tx_protocols, 0,
				       sizeof(dot11_protocol));
				memset(&priv->rx_protocols, 0,
				       sizeof(dot11_protocol));
			}
			pos += perpkt->len + MRVL_TLV_HEADER_SIZE;
			left_len -= (perpkt->len + MRVL_TLV_HEADER_SIZE);
		}
	} else
		goto done;

	if (perpkt != NULL)
		misc->param.txrx_pkt_ctrl = perpkt->tx_rx_control;
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 *  @brief              Get Region Channel Power
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_get_chnrgpwr(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int ret = 0;
	mlan_ioctl_req *req = NULL;
	mlan_ds_misc_cfg *misc = NULL;
	int header_len = 0;
	t_u8 *pos = NULL;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();
	header_len = strlen(PRIV_CMD_GET_CHNRGPWR);
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}
	misc = (mlan_ds_misc_cfg *)req->pbuf;
	misc->sub_command = MLAN_OID_MISC_GET_REGIONPWR_CFG;
	req->req_id = MLAN_IOCTL_MISC_CFG;
	req->action = MLAN_ACT_GET;
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}
	ret = header_len + sizeof(t_u16) + misc->param.rgchnpwr_cfg.length;
	pos = respbuf + header_len;
	moal_memcpy_ext(priv->phandle, pos, &misc->param.rgchnpwr_cfg,
			sizeof(t_u16) + misc->param.rgchnpwr_cfg.length,
			respbuflen - header_len);
done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 *  @brief              Get TX/RX histogram statistic
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_get_txpwrlimit(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int ret = 0;
	mlan_ioctl_req *req = NULL;
	mlan_ds_misc_cfg *misc = NULL;
	mlan_ds_misc_chan_trpc_cfg *trpc_cfg = NULL;
	int header_len = 0;
	t_u8 *pos = NULL;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();
	header_len = strlen(PRIV_CMD_GET_TXPWR_LIMIT);
	trpc_cfg = (mlan_ds_misc_chan_trpc_cfg *) (respbuf + header_len);
	if ((trpc_cfg->sub_band != 0) && (trpc_cfg->sub_band != 0x10) &&
	    (trpc_cfg->sub_band != 0x11) && (trpc_cfg->sub_band != 0x12) &&
	    (trpc_cfg->sub_band != 0x13)) {
		PRINTM(MERROR, "Invalid subband=0x%x\n", trpc_cfg->sub_band);
		ret = -EINVAL;
		goto done;
	}
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}
	misc = (mlan_ds_misc_cfg *)req->pbuf;
	misc->sub_command = MLAN_OID_MISC_GET_CHAN_TRPC_CFG;
	req->req_id = MLAN_IOCTL_MISC_CFG;
	req->action = MLAN_ACT_GET;
	misc->param.trpc_cfg.sub_band = trpc_cfg->sub_band;
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}
	ret = header_len + sizeof(t_u16) + sizeof(t_u16) +
		misc->param.trpc_cfg.length;
	pos = respbuf + header_len;
	moal_memcpy_ext(priv->phandle, pos, &misc->param.trpc_cfg,
			sizeof(t_u16) + sizeof(t_u16) +
			misc->param.trpc_cfg.length, respbuflen - header_len);
done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

#if defined(STA_CFG80211) || defined(UAP_CFG80211)
/**
 *  @brief              Get TX/RX histogram statistic
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_getcfgchanlist(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int ret = 0;
	int num_chan = 0;
	wlan_ieee80211_chan_list *plist = NULL;
	struct ieee80211_supported_band *sband;
	struct wiphy *wiphy = NULL;
	int i;

	ENTER();
	if (priv && priv->wdev)
		wiphy = priv->wdev->wiphy;
	if (!wiphy) {
		PRINTM(MERROR, "wiphy is NULL\n");
		ret = -EFAULT;
		goto done;
	}
	plist = (wlan_ieee80211_chan_list *) respbuf;
	sband = wiphy->bands[NL80211_BAND_2GHZ];
	if (sband) {
		num_chan += sband->n_channels;
		for (i = 0; i < sband->n_channels; i++) {
			plist->chan_list[i].center_freq =
				sband->channels[i].center_freq;
			plist->chan_list[i].hw_value =
				sband->channels[i].hw_value;
			plist->chan_list[i].flags = sband->channels[i].flags;
			plist->chan_list[i].max_power =
				sband->channels[i].max_power;
		}
	}
	sband = wiphy->bands[NL80211_BAND_5GHZ];
	if (sband) {
		for (i = 0; i < sband->n_channels; i++) {
			plist->chan_list[i + num_chan].center_freq =
				sband->channels[i].center_freq;
			plist->chan_list[i + num_chan].hw_value =
				sband->channels[i].hw_value;
			plist->chan_list[i + num_chan].flags =
				sband->channels[i].flags;
			plist->chan_list[i + num_chan].max_power =
				sband->channels[i].max_power;
#if LINUX_VERSION_CODE > KERNEL_VERSION(3, 8, 13)
			plist->chan_list[i + num_chan].dfs_state =
				sband->channels[i].dfs_state;
#endif
		}
		num_chan += sband->n_channels;
	}
	plist->num_chan = num_chan;
	ret = sizeof(wlan_ieee80211_chan_list) +
		sizeof(wlan_ieee80211_chan) * num_chan;
done:
	LEAVE();
	return ret;
}
#endif

/**
 *  @brief              Get TX/RX histogram statistic
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_get_rx_tx_histogram(moal_private *priv, t_u8 *respbuf,
			      t_u32 respbuflen)
{
	int ret = 0;
	mlan_ioctl_req *req = NULL;
	mlan_ds_misc_cfg *misc = NULL;
	tx_rx_histogram *tx_rx_info = NULL;
	int header_len = 0;
	t_u8 *pos = NULL;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();
	header_len = strlen(PRIV_CMD_TX_RX_HISTOGRAM);
	tx_rx_info = (tx_rx_histogram *) (respbuf + header_len);
	if (tx_rx_info->enable > 2 ||
	    (tx_rx_info->enable == GET_TX_RX_HISTOGRAM &&
	     (tx_rx_info->action > 3 || tx_rx_info->action <= 0))) {
		PRINTM(MERROR, "Invalid parameters\n");
		ret = -EINVAL;
		goto done;
	}
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}
	misc = (mlan_ds_misc_cfg *)req->pbuf;
	misc->sub_command = MLAN_OID_MISC_GET_TX_RX_HISTOGRAM;
	req->req_id = MLAN_IOCTL_MISC_CFG;
	if (tx_rx_info->enable == GET_TX_RX_HISTOGRAM) {
		misc->param.tx_rx_histogram.enable = ENABLE_TX_RX_HISTOGRAM;
		misc->param.tx_rx_histogram.action = (t_u16)tx_rx_info->action;
	} else {
		misc->param.tx_rx_histogram.enable = tx_rx_info->enable;
		misc->param.tx_rx_histogram.action |=
			FLAG_TX_HISTOGRAM | FLAG_RX_HISTOGRAM;
	}

	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	ret = header_len + 2 * sizeof(t_u8);
	if (tx_rx_info->enable & GET_TX_RX_HISTOGRAM) {
		pos = respbuf + header_len + 2 * sizeof(t_u8);
		/* Save tx/rx histogram size */
		moal_memcpy_ext(priv->phandle, pos,
				&misc->param.tx_rx_histogram.size,
				sizeof(misc->param.tx_rx_histogram.size),
				respbuflen - (header_len + 2 * sizeof(t_u8)));
		ret += sizeof(misc->param.tx_rx_histogram.size);
		pos += sizeof(misc->param.tx_rx_histogram.size);
		moal_memcpy_ext(priv->phandle, pos,
				&misc->param.tx_rx_histogram.value,
				misc->param.tx_rx_histogram.size,
				respbuflen - (header_len + 2 * sizeof(t_u8)) -
				sizeof(misc->param.tx_rx_histogram.size));
		ret += misc->param.tx_rx_histogram.size;
	}

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get hotspot mode configurations
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return         0 --success, otherwise fail
 */
static int
woal_priv_hotspotcfg(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int ret = 0;
	mlan_ioctl_req *req = NULL;
	mlan_ds_misc_cfg *cfg = NULL;
	int data = 0;
	int user_data_len = 0, header_len = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_HOTSPOTCFG);
	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		user_data_len = 0;
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len, &data, 1, &user_data_len);
	}
	if (user_data_len >= 2) {
		PRINTM(MERROR, "Too many arguments\n");
		ret = -EINVAL;
		goto done;
	} else {
		req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
		if (req == NULL) {
			ret = -ENOMEM;
			goto done;
		}

		cfg = (mlan_ds_misc_cfg *)req->pbuf;
		if (user_data_len == 0) {
			req->action = MLAN_ACT_GET;
		} else {
			cfg->param.hotspot_cfg = data;
			req->action = MLAN_ACT_SET;
		}
	}
	cfg->sub_command = MLAN_OID_MISC_HOTSPOT_CFG;
	req->req_id = MLAN_IOCTL_MISC_CFG;

	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}
	data = cfg->param.hotspot_cfg;
	moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)&data, sizeof(data),
			respbuflen);
	ret = sizeof(data);

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get Mgmt Frame passthru mask
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return         0 --success, otherwise fail
 */
static int
woal_priv_mgmt_frame_passthru_ctrl(moal_private *priv, t_u8 *respbuf,
				   t_u32 respbuflen)
{
	int ret = 0;
	int data = 0;
	int user_data_len = 0, header_len = 0;
	mlan_ioctl_req *req = NULL;
	mlan_ds_misc_cfg *mgmt_cfg = NULL;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();
	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_MGMT_FRAME_CTRL);
	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		user_data_len = 0;
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len, &data, 1, &user_data_len);
	}

	if (user_data_len >= 2) {
		PRINTM(MERROR, "Too many arguments\n");
		ret = -EINVAL;
		goto done;
	} else {
		req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
		if (req == NULL) {
			ret = -ENOMEM;
			goto done;
		}
		mgmt_cfg = (mlan_ds_misc_cfg *)req->pbuf;
		req->req_id = MLAN_IOCTL_MISC_CFG;
		mgmt_cfg->sub_command = MLAN_OID_MISC_RX_MGMT_IND;

		if (user_data_len == 0) {	/* Get */
			req->action = MLAN_ACT_GET;
		} else {	/* Set */
			mgmt_cfg->param.mgmt_subtype_mask = data;
			req->action = MLAN_ACT_SET;
		}
	}

	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	data = mgmt_cfg->param.mgmt_subtype_mask;
	moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)&data, sizeof(data),
			respbuflen);
	ret = sizeof(data);

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 *  @brief Private IOCTL entry to send an ADDTS TSPEC
 *
 *  Receive a ADDTS command from the application.  The command structure
 *    contains a TSPEC and timeout in milliseconds.  The timeout is performed
 *    in the firmware after the ADDTS command frame is sent.
 *
 *  The TSPEC is received in the API as an opaque block. The firmware will
 *    send the entire data block, including the bytes after the TSPEC.  This
 *    is done to allow extra IEs to be packaged with the TSPEC in the ADDTS
 *    action frame.
 *
 *  The IOCTL structure contains two return fields:
 *    - The firmware command result, which indicates failure and timeouts
 *    - The IEEE Status code which contains the corresponding value from
 *      any ADDTS response frame received.
 *
 *  In addition, the opaque TSPEC data block passed in is replaced with the
 *    TSPEC received in the ADDTS response frame.  In case of failure, the
 *    AP may modify the TSPEC on return and in the case of success, the
 *    medium time is returned as calculated by the AP.  Along with the TSPEC,
 *    any IEs that are sent in the ADDTS response are also returned and can be
 *    parsed using the IOCTL length as an indicator of extra elements.
 *
 *  The return value to the application layer indicates a driver execution
 *    success or failure.  A successful return could still indicate a firmware
 *    failure or AP negotiation failure via the commandResult field copied
 *    back to the application.
 *
 *  @param priv    Pointer to the mlan_private driver data struct
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return         Number of bytes written if successful else negative value
 */
static int
woal_priv_wmm_addts_req_ioctl(moal_private *priv, t_u8 *respbuf,
			      t_u32 respbuflen)
{
	mlan_ioctl_req *req = NULL;
	mlan_ds_wmm_cfg *cfg = NULL;
	wlan_ioctl_wmm_addts_req_t addts_ioctl;
	int ret = 0, header_len = 0, copy_len = sizeof(addts_ioctl);
	t_u8 *data_ptr;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_ADDTS);
	data_ptr = respbuf + header_len;
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_wmm_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	req->req_id = MLAN_IOCTL_WMM_CFG;
	cfg = (mlan_ds_wmm_cfg *)req->pbuf;
	cfg->sub_command = MLAN_OID_WMM_CFG_ADDTS;

	memset(&addts_ioctl, 0x00, sizeof(addts_ioctl));

	moal_memcpy_ext(priv->phandle, (t_u8 *)&addts_ioctl, data_ptr,
			sizeof(addts_ioctl), sizeof(addts_ioctl));

	cfg->param.addts.timeout = addts_ioctl.timeout_ms;
	cfg->param.addts.ie_data_len = addts_ioctl.ie_data_len;

	moal_memcpy_ext(priv->phandle, cfg->param.addts.ie_data,
			addts_ioctl.ie_data, cfg->param.addts.ie_data_len,
			MLAN_WMM_TSPEC_SIZE + MLAN_WMM_ADDTS_EXTRA_IE_BYTES);

	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}
	addts_ioctl.cmd_result = cfg->param.addts.result;
	addts_ioctl.ieee_status_code = (t_u8)cfg->param.addts.status_code;
	addts_ioctl.ie_data_len = cfg->param.addts.ie_data_len;

	moal_memcpy_ext(priv->phandle, addts_ioctl.ie_data,
			cfg->param.addts.ie_data, cfg->param.addts.ie_data_len,
			MLAN_WMM_TSPEC_SIZE + MLAN_WMM_ADDTS_EXTRA_IE_BYTES);

	copy_len = (sizeof(addts_ioctl) - sizeof(addts_ioctl.ie_data) +
		    cfg->param.addts.ie_data_len);

	moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)&addts_ioctl, copy_len,
			respbuflen);
	ret = copy_len;

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 *  @brief Private IOCTL entry to send a DELTS TSPEC
 *
 *  Receive a DELTS command from the application.  The command structure
 *    contains a TSPEC and reason code along with space for a command result
 *    to be returned.  The information is packaged is sent to the wlan_cmd.c
 *    firmware command prep and send routines for execution in the firmware.
 *
 *  The reason code is not used for WMM implementations but is indicated in
 *    the 802.11e specification.
 *
 *  The return value to the application layer indicates a driver execution
 *    success or failure.  A successful return could still indicate a firmware
 *    failure via the cmd_result field copied back to the application.
 *
 *  @param priv    Pointer to the mlan_private driver data struct
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return         Number of bytes written if successful else negative value
 */
static int
woal_priv_wmm_delts_req_ioctl(moal_private *priv, t_u8 *respbuf,
			      t_u32 respbuflen)
{
	mlan_ioctl_req *req = NULL;
	mlan_ds_wmm_cfg *cfg = NULL;
	wlan_ioctl_wmm_delts_req_t delts_ioctl;
	int ret = 0, header_len = 0, copy_len = 0;
	t_u8 *data_ptr;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_DELTS);
	data_ptr = respbuf + header_len;
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_wmm_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	req->req_id = MLAN_IOCTL_WMM_CFG;
	cfg = (mlan_ds_wmm_cfg *)req->pbuf;
	cfg->sub_command = MLAN_OID_WMM_CFG_DELTS;

	memset(&delts_ioctl, 0x00, sizeof(delts_ioctl));

	if ((int)strlen(respbuf) > header_len) {
		copy_len = MIN(strlen(data_ptr), sizeof(delts_ioctl));
		moal_memcpy_ext(priv->phandle, (t_u8 *)&delts_ioctl, data_ptr,
				copy_len, sizeof(delts_ioctl));

		cfg->param.delts.status_code =
			(t_u32)delts_ioctl.ieee_reason_code;
		cfg->param.delts.ie_data_len = (t_u8)delts_ioctl.ie_data_len;

		moal_memcpy_ext(priv->phandle, cfg->param.delts.ie_data,
				delts_ioctl.ie_data,
				cfg->param.delts.ie_data_len,
				MLAN_WMM_TSPEC_SIZE);

		status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
		if (status != MLAN_STATUS_SUCCESS) {
			ret = -EFAULT;
			goto done;
		}

		/* Return the firmware command result back to the application
		 * layer */
		delts_ioctl.cmd_result = cfg->param.delts.result;
		copy_len = sizeof(delts_ioctl);
		moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)&delts_ioctl,
				copy_len, respbuflen);
		ret = copy_len;
	}

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 *  @brief Private IOCTL entry to get/set a specified AC Queue's parameters
 *
 *  Receive a AC Queue configuration command which is used to get, set, or
 *    default the parameters associated with a specific WMM AC Queue.
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return         0 --success, otherwise fail
 */
static int
woal_priv_qconfig(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	mlan_ioctl_req *req = NULL;
	mlan_ds_wmm_cfg *pwmm = NULL;
	mlan_ds_wmm_queue_config *pqcfg = NULL;
	wlan_ioctl_wmm_queue_config_t qcfg_ioctl;
	t_u8 *data_ptr;
	int ret = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_wmm_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	req->req_id = MLAN_IOCTL_WMM_CFG;
	pwmm = (mlan_ds_wmm_cfg *)req->pbuf;
	pwmm->sub_command = MLAN_OID_WMM_CFG_QUEUE_CONFIG;

	memset(&qcfg_ioctl, 0x00, sizeof(qcfg_ioctl));
	pqcfg = (mlan_ds_wmm_queue_config *)&pwmm->param.q_cfg;
	data_ptr = respbuf + (strlen(CMD_NXP) + strlen(PRIV_CMD_QCONFIG));

	moal_memcpy_ext(priv->phandle, (t_u8 *)&qcfg_ioctl, data_ptr,
			sizeof(qcfg_ioctl), sizeof(qcfg_ioctl));
	pqcfg->action = qcfg_ioctl.action;
	pqcfg->access_category = qcfg_ioctl.access_category;
	pqcfg->msdu_lifetime_expiry = qcfg_ioctl.msdu_lifetime_expiry;

	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}
	memset(&qcfg_ioctl, 0x00, sizeof(qcfg_ioctl));
	qcfg_ioctl.action = pqcfg->action;
	qcfg_ioctl.access_category = pqcfg->access_category;
	qcfg_ioctl.msdu_lifetime_expiry = pqcfg->msdu_lifetime_expiry;
	moal_memcpy_ext(priv->phandle, data_ptr, (t_u8 *)&qcfg_ioctl,
			sizeof(qcfg_ioctl),
			respbuflen -
			(strlen(CMD_NXP) + strlen(PRIV_CMD_QCONFIG)));
	ret = strlen(CMD_NXP) + strlen(PRIV_CMD_QCONFIG) + sizeof(qcfg_ioctl);
done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 *  @brief Private IOCTL entry to get the status of the WMM queues
 *
 *  Return the following information for each WMM AC:
 *        - WMM IE Acm Required
 *        - Firmware Flow Required
 *        - Firmware Flow Established
 *        - Firmware Queue Enabled
 *        - Firmware Delivery Enabled
 *        - Firmware Trigger Enabled
 *
 *  @param priv    Pointer to the moal_private driver data struct
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return         Number of bytes written if successful else negative value
 */
static int
woal_priv_wmm_queue_status_ioctl(moal_private *priv, t_u8 *respbuf,
				 t_u32 respbuflen)
{
	mlan_ioctl_req *req = NULL;
	mlan_ds_wmm_cfg *pwmm = NULL;
	wlan_ioctl_wmm_queue_status_t qstatus_ioctl;
	int ret = 0, header_len = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_QSTATUS);
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_wmm_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	req->req_id = MLAN_IOCTL_WMM_CFG;
	pwmm = (mlan_ds_wmm_cfg *)req->pbuf;
	pwmm->sub_command = MLAN_OID_WMM_CFG_QUEUE_STATUS;

	if ((int)strlen(respbuf) == header_len) {
		status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
		if (status != MLAN_STATUS_SUCCESS) {
			ret = -EFAULT;
			goto done;
		}

		memset(&qstatus_ioctl, 0x00, sizeof(qstatus_ioctl));
		moal_memcpy_ext(priv->phandle, (void *)&qstatus_ioctl,
				(void *)&pwmm->param.q_status,
				sizeof(qstatus_ioctl), sizeof(qstatus_ioctl));
		moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)&qstatus_ioctl,
				sizeof(qstatus_ioctl), respbuflen);
		ret = sizeof(qstatus_ioctl);
	}

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 *  @brief Private IOCTL entry to get the status of the WMM Traffic Streams
 *
 *  @param priv    Pointer to the moal_private driver data struct
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return         Number of bytes written if successful else negative value
 */
static int
woal_priv_wmm_ts_status_ioctl(moal_private *priv, t_u8 *respbuf,
			      t_u32 respbuflen)
{
	mlan_ioctl_req *req = NULL;
	mlan_ds_wmm_cfg *pwmm = NULL;
	wlan_ioctl_wmm_ts_status_t ts_status_ioctl;
	int ret = 0, header_len = 0;
	t_u8 *data_ptr;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_TS_STATUS);
	data_ptr = respbuf + header_len;
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_wmm_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	req->req_id = MLAN_IOCTL_WMM_CFG;
	pwmm = (mlan_ds_wmm_cfg *)req->pbuf;
	pwmm->sub_command = MLAN_OID_WMM_CFG_TS_STATUS;

	memset(&ts_status_ioctl, 0x00, sizeof(ts_status_ioctl));

	moal_memcpy_ext(priv->phandle, (t_u8 *)&ts_status_ioctl, data_ptr,
			sizeof(ts_status_ioctl), sizeof(ts_status_ioctl));

	memset(&pwmm->param.ts_status, 0x00, sizeof(ts_status_ioctl));
	pwmm->param.ts_status.tid = ts_status_ioctl.tid;

	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	memset(&ts_status_ioctl, 0x00, sizeof(ts_status_ioctl));
	moal_memcpy_ext(priv->phandle, (void *)&ts_status_ioctl,
			(void *)&pwmm->param.ts_status, sizeof(ts_status_ioctl),
			sizeof(ts_status_ioctl));
	moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)&ts_status_ioctl,
			sizeof(ts_status_ioctl), respbuflen);
	ret = sizeof(ts_status_ioctl);

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get MAC control
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_macctrl(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int data = 0;
	mlan_ioctl_req *req = NULL;
	mlan_ds_misc_cfg *cfg = NULL;
	int ret = 0;
	int user_data_len = 0, header_len = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_MAC_CTRL);
	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		user_data_len = 0;
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len, &data, 1, &user_data_len);
	}

	if (user_data_len > 1) {
		PRINTM(MERROR, "Invalid number of arguments\n");
		ret = -EINVAL;
		goto done;
	}
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	cfg = (mlan_ds_misc_cfg *)req->pbuf;
	cfg->sub_command = MLAN_OID_MISC_MAC_CONTROL;
	req->req_id = MLAN_IOCTL_MISC_CFG;

	if (user_data_len == 0)
		req->action = MLAN_ACT_GET;
	else {
		cfg->param.mac_ctrl = (t_u32)data;
		req->action = MLAN_ACT_SET;
	}

	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)&cfg->param.mac_ctrl,
			sizeof(data), respbuflen);
	ret = sizeof(data);

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 *  @brief Get connection status
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             0 --success, otherwise fail
 */
static int
woal_priv_getwap(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int ret = 0;
#ifdef STA_SUPPORT
	mlan_bss_info bss_info;
#endif

	ENTER();

#ifdef STA_SUPPORT
	if (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_STA) {
		memset(&bss_info, 0, sizeof(bss_info));

		woal_get_bss_info(priv, MOAL_IOCTL_WAIT, &bss_info);

		if (bss_info.media_connected == MTRUE) {
			moal_memcpy_ext(priv->phandle, respbuf,
					(t_u8 *)&bss_info.bssid,
					MLAN_MAC_ADDR_LENGTH, respbuflen);
		} else {
			memset(respbuf, 0, MLAN_MAC_ADDR_LENGTH);
		}
	}
#endif
#ifdef UAP_SUPPORT
	if (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_UAP) {
		if (priv->bss_started) {
			moal_memcpy_ext(priv->phandle, respbuf,
					priv->current_addr,
					MLAN_MAC_ADDR_LENGTH, respbuflen);
		} else {
			memset(respbuf, 0, MLAN_MAC_ADDR_LENGTH);
		}
	}
#endif
	ret = MLAN_MAC_ADDR_LENGTH;
	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get Region Code
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_region_code(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int data = 0;
	mlan_ioctl_req *req = NULL;
	mlan_ds_misc_cfg *cfg = NULL;
	int ret = 0;
	int user_data_len = 0, header_len = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_REGION_CODE);
	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		user_data_len = 0;
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len, &data, 1, &user_data_len);
	}

	if (user_data_len > 1) {
		PRINTM(MERROR, "Invalid number of arguments\n");
		ret = -EINVAL;
		goto done;
	}
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	cfg = (mlan_ds_misc_cfg *)req->pbuf;
	cfg->sub_command = MLAN_OID_MISC_REGION;
	req->req_id = MLAN_IOCTL_MISC_CFG;

	if (user_data_len == 0)
		req->action = MLAN_ACT_GET;
	else {
		cfg->param.region_code = (t_u32)data;
		req->action = MLAN_ACT_SET;
	}

	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)&cfg->param.region_code,
			sizeof(data), respbuflen);
	ret = sizeof(data);

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

#ifdef RX_PACKET_COALESCE
/**
 *  @brief Set/Get RX packet coalesceing setting
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_rx_pkt_coalesce_cfg(moal_private *priv, t_u8 *respbuf,
			      t_u32 respbuflen)
{
	int ret = 0;
	t_u32 data[2];
	int user_data_len = 0, header_len = 0;
	mlan_ds_misc_cfg *cfg = NULL;
	t_u8 *data_ptr;
	mlan_ioctl_req *req = NULL;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	data_ptr = respbuf + strlen(CMD_NXP) + strlen(PRIV_CMD_RX_COAL_CFG);
	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_RX_COAL_CFG);
	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		user_data_len = 0;
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len, data, ARRAY_SIZE(data),
				&user_data_len);
	}

	if (sizeof(int) * user_data_len > sizeof(data)) {
		PRINTM(MERROR, "Too many arguments\n");
		ret = -EINVAL;
		goto done;
	}

	if ((user_data_len != 0) && (user_data_len != 2)) {
		PRINTM(MERROR, "Invalid arguments\n");
		ret = -EINVAL;
		goto done;
	}

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	cfg = (mlan_ds_misc_cfg *)req->pbuf;
	cfg->sub_command = MLAN_OID_MISC_RX_PACKET_COALESCE;
	req->req_id = MLAN_IOCTL_MISC_CFG;

	if (user_data_len == 0) {
		req->action = MLAN_ACT_GET;
	} else {
		req->action = MLAN_ACT_SET;
		cfg->param.rx_coalesce.packet_threshold = data[0];
		cfg->param.rx_coalesce.delay = data[1];
	}

	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	moal_memcpy_ext(priv->phandle, respbuf,
			(mlan_ds_misc_rx_packet_coalesce *)&cfg->param.
			rx_coalesce, req->buf_len, respbuflen);
	ret = req->buf_len;

done:
	LEAVE();
	return ret;
}
#endif
/**
 *  @brief Set/Get FW side mac address
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             0 --success, otherwise fail
 */
static int
woal_priv_fwmacaddr(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	t_u8 data[ETH_ALEN];
	int ret = 0;
	int header_len = 0;
	mlan_ioctl_req *req = NULL;
	mlan_ds_bss *bss = NULL;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_FWMACADDR);

	/* Allocate an IOCTL request buffer */
	req = (mlan_ioctl_req *)woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}
	/* Fill request buffer */
	bss = (mlan_ds_bss *)req->pbuf;
	bss->sub_command = MLAN_OID_BSS_MAC_ADDR;
	req->req_id = MLAN_IOCTL_BSS;

	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		req->action = MLAN_ACT_GET;
	} else {
		/* SET operation */
		req->action = MLAN_ACT_SET;
		memset(data, 0, sizeof(data));
		woal_mac2u8(data, respbuf + header_len);
		moal_memcpy_ext(priv->phandle, bss->param.mac_addr, data,
				ETH_ALEN, sizeof(mlan_802_11_mac_addr));
	}

	/* Send IOCTL request to MLAN */
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	moal_memcpy_ext(priv->phandle, respbuf, bss->param.mac_addr,
			sizeof(data), respbuflen);
	ret = sizeof(data);
	HEXDUMP("FW MAC Addr:", respbuf, ETH_ALEN);

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

#if defined(STA_CFG80211) || defined(UAP_CFG80211)
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)
/**
 *  @brief Set offchannel
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             0 --success, otherwise fail
 */
static int
woal_priv_offchannel(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int data[4];
	int ret = 0;
	t_u8 status = 1;
	t_u8 chan_type = CHAN_NO_HT;
	int user_data_len = 0, header_len = 0;

	ENTER();

	memset(data, 0, sizeof(data));

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_OFFCHANNEL);

	if (header_len == (int)strlen(respbuf)) {
		/* Query current remain on channel status */
		if (priv->phandle->remain_on_channel)
			ret = sprintf(respbuf,
				      "There is pending remain on channel from bss %d\n",
				      priv->phandle->remain_bss_index) + 1;
		else
			ret = sprintf(respbuf,
				      "There is no pending remain on channel\n")
				+ 1;
		goto done;
	} else
		parse_arguments(respbuf + header_len, data, ARRAY_SIZE(data),
				&user_data_len);

	if (sizeof(int) * user_data_len > sizeof(data)) {
		PRINTM(MERROR, "Too many arguments\n");
		ret = -EINVAL;
		goto done;
	}

	if (user_data_len >= 1) {
		if ((data[0] != 0) && (data[0] != 1)) {
			PRINTM(MERROR, "action (%d) must be either 0 or 1\n",
			       data[0]);
			ret = -EINVAL;
			goto done;
		}
	}
	if (user_data_len == 2) {
		if (data[0] == 1) {
			PRINTM(MERROR,
			       "channel and duration must both the mentioned\n");
			ret = -EINVAL;
			goto done;
		} else {
			PRINTM(MWARN,
			       "extra arguments are ignored since action is 'cancel'\n");
		}
	}
	if (user_data_len >= 3) {
		if (data[0] == 1) {
			if (data[1] < 0) {
				PRINTM(MERROR, "channel cannot be negative\n");
				ret = -EINVAL;
				goto done;
			}
			if (data[2] < 0) {
				PRINTM(MERROR, "duration cannot be negative\n");
				ret = -EINVAL;
				goto done;
			}
			if (user_data_len == 4) {
				if (data[3] &&
				    (data[3] != CHANNEL_BW_40MHZ_ABOVE) &&
				    (data[3] != CHANNEL_BW_40MHZ_BELOW)
				    && (data[3] != CHANNEL_BW_80MHZ)
					) {
					PRINTM(MERROR, "invalid bandwidth");
					ret = -EINVAL;
					goto done;
				}
				switch (data[3]) {
				case CHANNEL_BW_40MHZ_ABOVE:
					chan_type = CHAN_HT40PLUS;
					break;
				case CHANNEL_BW_40MHZ_BELOW:
					chan_type = CHAN_HT40MINUS;
					break;
				case CHANNEL_BW_80MHZ:
					chan_type = CHAN_VHT80;
					break;
				default:
					break;
				}
			}
		}
	}

	if (data[0] == 0) {
		if (!priv->phandle->remain_on_channel) {
			ret = sprintf(respbuf,
				      "There is no pending remain on channel to be canceled\n")
				+ 1;
			goto done;
		}
		if (woal_cfg80211_remain_on_channel_cfg(priv, MOAL_IOCTL_WAIT,
							MTRUE, &status, NULL, 0,
							0)) {
			PRINTM(MERROR, "remain_on_channel: Failed to cancel\n");
			ret = -EFAULT;
			goto done;
		}
		if (status == MLAN_STATUS_SUCCESS)
			priv->phandle->remain_on_channel = MFALSE;
	} else if (data[0] == 1) {
		if (woal_cfg80211_remain_on_channel_cfg
		    (priv, MOAL_IOCTL_WAIT, MFALSE, &status,
		     ieee80211_get_channel(priv->wdev->wiphy,
					   ieee80211_channel_to_frequency(data
									  [1]
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)
									  ,
									  (data
									   [1]
									   <=
									   14 ?
									   IEEE80211_BAND_2GHZ
									   :
									   IEEE80211_BAND_5GHZ)
#endif
					   )), chan_type, (t_u32)data[2])) {
			PRINTM(MERROR, "remain_on_channel: Failed to start\n");
			ret = -EFAULT;
			goto done;
		}
		if (status == MLAN_STATUS_SUCCESS) {
			priv->phandle->remain_on_channel = MTRUE;
			priv->phandle->remain_bss_index = priv->bss_index;
		}
	}

	if (status != MLAN_STATUS_SUCCESS)
		ret = -EFAULT;
	else
		ret = sprintf(respbuf, "OK\n") + 1;

done:
	LEAVE();
	return ret;
}
#endif
#endif

/**
 *  @brief Set/Get dscp map
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             0 --success, otherwise fail
 */
static int
woal_priv_set_get_dscp_map(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int ret = MLAN_STATUS_SUCCESS;
	t_u8 *pos = NULL;
	int copy_size = 0, header_len = 0;

	ENTER();

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_DSCP_MAP);
	if ((int)strlen(respbuf) != header_len) {
		/* SET operation */
		pos = respbuf + header_len;
		moal_memcpy_ext(priv->phandle, priv->dscp_map, pos,
				sizeof(priv->dscp_map), sizeof(priv->dscp_map));
	}

	copy_size = MIN(sizeof(priv->dscp_map), respbuflen);
	moal_memcpy_ext(priv->phandle, respbuf, priv->dscp_map, copy_size,
			respbuflen);
	ret = copy_size;

	LEAVE();
	return ret;
}

/**
 *  @brief Get extended driver version
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_get_driver_verext(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int data = 0;
	mlan_ds_get_info *info = NULL;
	mlan_ioctl_req *req = NULL;
	int ret = 0;
	int copy_size = 0;
	int user_data_len = 0, header_len = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_get_info));
	if (req == NULL) {
		ret = ENOMEM;
		goto done;
	}

	info = (mlan_ds_get_info *)req->pbuf;
	info->sub_command = MLAN_OID_GET_VER_EXT;
	req->req_id = MLAN_IOCTL_GET_INFO;
	req->action = MLAN_ACT_GET;

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_VEREXT);

	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		user_data_len = 0;
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len, &data, 1, &user_data_len);
	}

	if (user_data_len > 1) {
		PRINTM(MERROR, "Too many arguments\n");
		ret = -EINVAL;
		goto done;
	}
	info->param.ver_ext.version_str_sel = data;
	if (((t_s32)(info->param.ver_ext.version_str_sel)) < 0) {
		PRINTM(MERROR, "Invalid arguments!\n");
		ret = -EINVAL;
		goto done;
	}

	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	/*
	 * Set the amount to copy back to the application as the minimum of the
	 *   available assoc resp data or the buffer provided by the application
	 */
	copy_size = MIN(strlen(info->param.ver_ext.version_str), respbuflen);
	moal_memcpy_ext(priv->phandle, respbuf, info->param.ver_ext.version_str,
			copy_size, respbuflen);
	ret = copy_size;
	PRINTM(MINFO, "MOAL EXTENDED VERSION: %s\n",
	       info->param.ver_ext.version_str);

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

#ifdef USB
#ifdef CONFIG_USB_SUSPEND
/**
 *  @brief This function makes USB device to suspend.
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_enter_usb_suspend(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int ret = 0;

	ENTER();
	ret = woal_enter_usb_suspend(priv->phandle);
	moal_memcpy_ext(priv->phandle, respbuf, &ret, sizeof(int), respbuflen);
	ret = sizeof(int);

	LEAVE();
	return ret;
}

/**
 *  @brief This function makes USB device to resume.
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_exit_usb_suspend(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int ret = 0;

	ENTER();
	ret = woal_exit_usb_suspend(priv->phandle);
	moal_memcpy_ext(priv->phandle, respbuf, &ret, sizeof(int), respbuflen);
	ret = sizeof(int);

	LEAVE();
	return ret;
}
#endif /* CONFIG_USB_SUSPEND */
#endif

#if defined(STA_SUPPORT) && defined(STA_WEXT)
/**
 *  @brief SET/Get radio
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_radio_ctrl(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int ret = 0, option = 0;
	int user_data_len = 0, header_len = 0;
	mlan_bss_info bss_info;

	ENTER();

	memset(&bss_info, 0, sizeof(bss_info));

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_RADIO_CTRL);

	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		user_data_len = 0;
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len, &option, 1,
				&user_data_len);
	}

	if (user_data_len > 1) {
		PRINTM(MERROR, "Too many arguments\n");
		ret = -EINVAL;
		goto done;
	}
	if (user_data_len == 1) {
		/* Set radio */
		if (option < 0 || option > 1) {
			PRINTM(MERROR, "Invalid arguments!\n");
			ret = -EINVAL;
			goto done;
		}
		if (MLAN_STATUS_SUCCESS != woal_set_radio(priv, (t_u8)option))
			ret = -EFAULT;
		goto done;
	} else {
		/* Get radio status */
		woal_get_bss_info(priv, MOAL_IOCTL_WAIT, &bss_info);
		moal_memcpy_ext(priv->phandle, respbuf, &bss_info.radio_on,
				sizeof(bss_info.radio_on), respbuflen);
		ret = sizeof(bss_info.radio_on);
	}
done:
	LEAVE();
	return ret;
}
#endif

/**
 *  @brief Implement WMM enable command
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_wmm_cfg(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int data = 0;
	mlan_ds_wmm_cfg *wmm = NULL;
	mlan_ioctl_req *req = NULL;
	int ret = 0;
	int user_data_len = 0, header_len = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_wmm_cfg));
	if (req == NULL) {
		ret = ENOMEM;
		goto done;
	}

	wmm = (mlan_ds_wmm_cfg *)req->pbuf;
	wmm->sub_command = MLAN_OID_WMM_CFG_ENABLE;
	req->req_id = MLAN_IOCTL_WMM_CFG;

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_WMM_CFG);

	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		req->action = MLAN_ACT_GET;
		user_data_len = 0;
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len, &data, 1, &user_data_len);
		if (user_data_len == 1) {
			/* Set wmm */
			if ((data < CMD_DISABLED) || (data > CMD_ENABLED)) {
				PRINTM(MERROR, "Invalid arguments!\n");
				ret = -EINVAL;
				goto done;
			}
			req->action = MLAN_ACT_SET;
			if (data == CMD_DISABLED)
				wmm->param.wmm_enable = MFALSE;
			else
				wmm->param.wmm_enable = MTRUE;
		} else {
			PRINTM(MERROR, "Too many arguments\n");
			ret = -EINVAL;
			goto done;
		}
	}
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	moal_memcpy_ext(priv->phandle, respbuf, &wmm->param.wmm_enable,
			sizeof(wmm->param.wmm_enable), respbuflen);
	ret = sizeof(wmm->param.wmm_enable);

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 *  @brief Implement Mininum BA Threshold cfg command
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_min_ba_threshold_cfg(moal_private *priv, t_u8 *respbuf,
			       t_u32 respbuflen)
{
	int data = 0;
	mlan_ds_11n_cfg *cfg_11n = NULL;
	mlan_ioctl_req *req = NULL;
	int ret = 0;
	int user_data_len = 0, header_len = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11n_cfg));
	if (req == NULL) {
		ret = ENOMEM;
		goto done;
	}
	cfg_11n = (mlan_ds_11n_cfg *)req->pbuf;
	cfg_11n->sub_command = MLAN_OID_11N_CFG_MIN_BA_THRESHOLD;
	req->req_id = MLAN_IOCTL_11N_CFG;

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_MIN_BA_THRESH_CFG);

	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		req->action = MLAN_ACT_GET;
		user_data_len = 0;
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len, &data, 1, &user_data_len);
		if (user_data_len == 1) {
			/* Set minimum BA Threshold */
			if ((data < 0) || (data > 16)) {
				PRINTM(MERROR,
				       "Error: Valid minimum BA threshold range (0-16)!\n");
				ret = -EINVAL;
				goto done;
			}
			req->action = MLAN_ACT_SET;
			cfg_11n->param.min_ba_threshold = data;
		} else {
			PRINTM(MERROR, "Too many arguments\n");
			ret = -EINVAL;
			goto done;
		}
	}
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	moal_memcpy_ext(priv->phandle, respbuf,
			&cfg_11n->param.min_ba_threshold,
			sizeof(cfg_11n->param.min_ba_threshold), respbuflen);
	ret = sizeof(cfg_11n->param.min_ba_threshold);

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

#if defined(STA_SUPPORT)
/**
 *  @brief Implement 802.11D enable command
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_11d_cfg(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int data = 0;
	mlan_ds_11d_cfg *pcfg_11d = NULL;
	mlan_ioctl_req *req = NULL;
	int ret = 0;
	int user_data_len = 0, header_len = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11d_cfg));
	if (req == NULL) {
		ret = ENOMEM;
		goto done;
	}

	pcfg_11d = (mlan_ds_11d_cfg *)req->pbuf;
	pcfg_11d->sub_command = MLAN_OID_11D_CFG_ENABLE;
	req->req_id = MLAN_IOCTL_11D_CFG;

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_11D_CFG);

	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		req->action = MLAN_ACT_GET;
		user_data_len = 0;
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len, &data, 1, &user_data_len);
		if (user_data_len == 1) {
			if ((data < CMD_DISABLED) || (data > CMD_ENABLED)) {
				PRINTM(MERROR, "Invalid arguments!\n");
				ret = -EINVAL;
				goto done;
			}
			req->action = MLAN_ACT_SET;
			if (data == CMD_DISABLED)
				pcfg_11d->param.enable_11d = MFALSE;
			else
				pcfg_11d->param.enable_11d = MTRUE;
		} else {
			PRINTM(MERROR, "Too many arguments\n");
			ret = -EINVAL;
			goto done;
		}
	}
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	moal_memcpy_ext(priv->phandle, respbuf, &pcfg_11d->param.enable_11d,
			sizeof(pcfg_11d->param.enable_11d), respbuflen);
	ret = sizeof(pcfg_11d->param.enable_11d);

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 *  @brief Implement 802.11D clear chan table command
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             0 --success, otherwise fail
 */
static int
woal_priv_11d_clr_chan_tbl(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	mlan_ds_11d_cfg *pcfg_11d = NULL;
	mlan_ioctl_req *req = NULL;
	int ret = 0;
	int header_len = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11d_cfg));
	if (req == NULL) {
		ret = ENOMEM;
		goto done;
	}

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_11D_CLR_TBL);

	if ((int)strlen(respbuf) != header_len) {
		PRINTM(MERROR, "Too many arguments\n");
		ret = -EINVAL;
		goto done;
	}
	pcfg_11d = (mlan_ds_11d_cfg *)req->pbuf;
	pcfg_11d->sub_command = MLAN_OID_11D_CLR_CHAN_TABLE;
	req->req_id = MLAN_IOCTL_11D_CFG;
	req->action = MLAN_ACT_SET;

	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}
#endif

#ifndef OPCHAN
/**
 *  @brief Set/Get WWS mode
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_wws_cfg(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int data = 0;
	mlan_ds_misc_cfg *wws = NULL;
	mlan_ioctl_req *req = NULL;
	int ret = 0;
	int user_data_len = 0, header_len = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (req == NULL) {
		ret = ENOMEM;
		goto done;
	}

	wws = (mlan_ds_misc_cfg *)req->pbuf;
	wws->sub_command = MLAN_OID_MISC_WWS;
	req->req_id = MLAN_IOCTL_MISC_CFG;

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_WWS_CFG);

	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		req->action = MLAN_ACT_GET;
		user_data_len = 0;
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len, &data, 1, &user_data_len);
		if (user_data_len == 1) {
			if ((data < CMD_DISABLED) || (data > CMD_ENABLED)) {
				PRINTM(MERROR,
				       "Invalid arguments, WWS config not changed!\n");
				ret = -EINVAL;
				goto done;
			}
			req->action = MLAN_ACT_SET;
			wws->param.wws_cfg = (t_u16)data;
		} else {
			PRINTM(MERROR, "Too many arguments\n");
			ret = -EINVAL;
			goto done;
		}
	}
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	moal_memcpy_ext(priv->phandle, respbuf, &wws->param.wws_cfg,
			sizeof(wws->param.wws_cfg), respbuflen);
	ret = sizeof(wws->param.wws_cfg);

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}
#endif

#if defined(REASSOCIATION)
/**
 *  @brief Set/Get reassociation settings
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_set_get_reassoc(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	moal_handle *handle = priv->phandle;
	int data = 0;
	int ret = 0;
	int user_data_len = 0, header_len = 0;

	ENTER();

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_REASSOCTRL);

	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		user_data_len = 0;
		data = (int)(priv->reassoc_on);
		moal_memcpy_ext(handle, respbuf, &data, sizeof(data),
				respbuflen);
		ret = sizeof(data);
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len, &data, 1, &user_data_len);
		if (user_data_len == 1) {
			if (data == 0) {
				handle->reassoc_on &= ~MBIT(priv->bss_index);
				priv->reassoc_on = MFALSE;
				priv->reassoc_required = MFALSE;
				if (!handle->reassoc_on &&
				    handle->is_reassoc_timer_set == MTRUE) {
					woal_cancel_timer(&handle->
							  reassoc_timer);
					handle->is_reassoc_timer_set = MFALSE;
				}
			} else if (data == 1) {
				handle->reassoc_on |= MBIT(priv->bss_index);
				priv->reassoc_on = MTRUE;
			} else {
				PRINTM(MERROR, "Invalid arguments!\n");
				ret = -EINVAL;
			}
		} else {
			PRINTM(MERROR, "Too many arguments\n");
			ret = -EINVAL;
		}
	}

	LEAVE();
	return ret;
}
#endif /* REASSOCIATION */

/**
 *  @brief Get Transmit buffer size
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_txbuf_cfg(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	mlan_ds_11n_cfg *cfg_11n = NULL;
	mlan_ioctl_req *req = NULL;
	int ret = 0;
	int buf_size = 0, header_len = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11n_cfg));
	if (req == NULL) {
		ret = ENOMEM;
		goto done;
	}

	cfg_11n = (mlan_ds_11n_cfg *)req->pbuf;
	cfg_11n->sub_command = MLAN_OID_11N_CFG_MAX_TX_BUF_SIZE;
	req->req_id = MLAN_IOCTL_11N_CFG;

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_TXBUF_CFG);

	if ((int)strlen(respbuf) != header_len) {
		PRINTM(MERROR,
		       "Don't support set Tx buffer size after driver loaded!\n");
		ret = -EINVAL;
		goto done;
	} else {
		/* Get Tx buffer size from MLAN */
		req->action = MLAN_ACT_GET;
	}
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	buf_size = cfg_11n->param.tx_buf_size;
	moal_memcpy_ext(priv->phandle, respbuf, &buf_size, sizeof(buf_size),
			respbuflen);
	ret = sizeof(buf_size);

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

#ifdef STA_SUPPORT
/**
 *  @brief Set/Get auth type
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_auth_type(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int auth_type = 0;
	t_u32 auth_mode;
	int ret = 0;
	int user_data_len = 0, header_len = 0;

	ENTER();

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_AUTH_TYPE);

	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		if (MLAN_STATUS_SUCCESS !=
		    woal_get_auth_mode(priv, MOAL_IOCTL_WAIT, &auth_mode)) {
			ret = -EFAULT;
			goto done;
		}
		user_data_len = 0;
		auth_type = auth_mode;
		moal_memcpy_ext(priv->phandle, respbuf, &auth_type,
				sizeof(auth_type), respbuflen);
		ret = sizeof(auth_type);
		goto done;
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len, &auth_type, 1,
				&user_data_len);
		if (user_data_len == 1) {
			PRINTM(MINFO, "SET: auth_type %d\n", auth_type);
			if (((auth_type < MLAN_AUTH_MODE_OPEN) ||
			     (auth_type > MLAN_AUTH_MODE_SAE))
			    && (auth_type != MLAN_AUTH_MODE_AUTO)
				) {
				ret = -EINVAL;
				goto done;
			}
			auth_mode = auth_type;
			if (MLAN_STATUS_SUCCESS !=
			    woal_set_auth_mode(priv, MOAL_IOCTL_WAIT,
					       auth_mode)) {
				ret = -EFAULT;
				goto done;
			}
		} else {
			PRINTM(MERROR, "Too many arguments\n");
			ret = -EINVAL;
		}
	}

done:
	LEAVE();
	return ret;
}
#endif

/**
 *  @brief Set/get user provisioned local power constraint
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_11h_local_pwr_constraint(moal_private *priv, t_u8 *respbuf,
				   t_u32 respbuflen)
{
	int data = 0;
	mlan_ds_11h_cfg *ds_11hcfg = NULL;
	mlan_ioctl_req *req = NULL;
	int ret = 0;
	int user_data_len = 0, header_len = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11h_cfg));
	if (req == NULL) {
		ret = ENOMEM;
		goto done;
	}

	ds_11hcfg = (mlan_ds_11h_cfg *)req->pbuf;
	ds_11hcfg->sub_command = MLAN_OID_11H_LOCAL_POWER_CONSTRAINT;
	req->req_id = MLAN_IOCTL_11H_CFG;

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_POWER_CONS);

	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		req->action = MLAN_ACT_GET;
		user_data_len = 0;
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len, &data, 1, &user_data_len);
		if (user_data_len == 1) {
			req->action = MLAN_ACT_SET;
			ds_11hcfg->param.usr_local_power_constraint =
				(t_s8)data;
		} else {
			PRINTM(MERROR, "Too many arguments\n");
			ret = -EINVAL;
			goto done;
		}
	}
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	if (req->action == MLAN_ACT_GET) {
		data = (int)ds_11hcfg->param.usr_local_power_constraint;
		moal_memcpy_ext(priv->phandle, respbuf, &data, sizeof(data),
				respbuflen);
		ret = sizeof(data);
	}

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 *  @brief Set/get HT stream configurations
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_ht_stream_cfg(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int data = 0;
	mlan_ds_11n_cfg *cfg = NULL;
	mlan_ioctl_req *req = NULL;
	int ret = 0;
	int user_data_len = 0, header_len = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11n_cfg));
	if (req == NULL) {
		ret = ENOMEM;
		goto done;
	}

	cfg = (mlan_ds_11n_cfg *)req->pbuf;
	cfg->sub_command = MLAN_OID_11N_CFG_STREAM_CFG;
	req->req_id = MLAN_IOCTL_11N_CFG;

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_HT_STREAM_CFG);

	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		req->action = MLAN_ACT_GET;
		user_data_len = 0;
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len, &data, 1, &user_data_len);
		if (user_data_len == 1) {
			if (data != HT_STREAM_MODE_1X1 &&
			    data != HT_STREAM_MODE_2X2) {
				PRINTM(MERROR, "Invalid arguments!\n");
				ret = -EINVAL;
				goto done;
			}
			req->action = MLAN_ACT_SET;
			cfg->param.stream_cfg = data;
		} else {
			PRINTM(MERROR, "Too many arguments\n");
			ret = -EINVAL;
			goto done;
		}
	}
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	data = ((mlan_ds_11n_cfg *)req->pbuf)->param.stream_cfg;
	moal_memcpy_ext(priv->phandle, respbuf, &data, sizeof(data),
			respbuflen);
	ret = sizeof(data);

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 *  @brief Set mimo switch configurations
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_mimo_switch(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int data[2] = { 0 };
	mlan_ds_radio_cfg *radio = NULL;
	mlan_ioctl_req *req = NULL;
	int ret = 0;
	int user_data_len = 0, header_len = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_radio_cfg));
	if (req == NULL) {
		ret = ENOMEM;
		goto done;
	}

	radio = (mlan_ds_radio_cfg *)req->pbuf;
	radio->sub_command = MLAN_OID_MIMO_SWITCH;
	req->req_id = MLAN_IOCTL_RADIO_CFG;

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_MIMO_SWITCH);

	if ((int)strlen(respbuf) > header_len) {
		/* SET operation */
		req->action = MLAN_ACT_SET;
		parse_arguments(respbuf + header_len, data, 2, &user_data_len);
		if (user_data_len == 2) {
			radio->param.mimo_switch_cfg.txpath_antmode = data[0];
			radio->param.mimo_switch_cfg.rxpath_antmode = data[1];
		} else {
			PRINTM(MERROR, "Invalid arguments!\n");
			ret = -EINVAL;
			goto done;
		}
		status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
		if (status != MLAN_STATUS_SUCCESS) {
			ret = -EFAULT;
			goto done;
		}
	} else {
		PRINTM(MERROR, "Invalid arguments!\n");
		ret = -EINVAL;
		goto done;
	}

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 *  @brief Get thermal reading
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_thermal(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	mlan_ds_misc_cfg *cfg = NULL;
	mlan_ioctl_req *req = NULL;
	int ret = 0, header_len = 0, data = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (req == NULL) {
		ret = ENOMEM;
		goto done;
	}

	cfg = (mlan_ds_misc_cfg *)req->pbuf;
	cfg->sub_command = MLAN_OID_MISC_THERMAL;
	req->req_id = MLAN_IOCTL_MISC_CFG;

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_THERMAL);

	if ((int)strlen(respbuf) != header_len) {
		PRINTM(MERROR, "Set is not supported for this command\n");
		ret = -EINVAL;
		goto done;
	}
	req->action = MLAN_ACT_GET;

	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	data = (int)cfg->param.thermal;
	moal_memcpy_ext(priv->phandle, respbuf, &data, sizeof(data),
			respbuflen);
	ret = sizeof(data);

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get beacon interval
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_beacon_interval(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int data = 0;
	mlan_ds_bss *bss = NULL;
	mlan_ioctl_req *req = NULL;
	int ret = 0;
	int user_data_len = 0, header_len = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss));
	if (req == NULL) {
		ret = ENOMEM;
		goto done;
	}

	bss = (mlan_ds_bss *)req->pbuf;
	bss->sub_command = MLAN_OID_IBSS_BCN_INTERVAL;
	req->req_id = MLAN_IOCTL_BSS;

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_BCN_INTERVAL);

	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		req->action = MLAN_ACT_GET;
		user_data_len = 0;
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len, &data, 1, &user_data_len);
		if (user_data_len == 1) {
			if ((data < MLAN_MIN_BEACON_INTERVAL) ||
			    (data > MLAN_MAX_BEACON_INTERVAL)) {
				PRINTM(MERROR, "Invalid arguments!\n");
				ret = -EINVAL;
				goto done;
			}
			req->action = MLAN_ACT_SET;
			bss->param.bcn_interval = data;
		} else {
			PRINTM(MERROR, "Too many arguments\n");
			ret = -EINVAL;
			goto done;
		}
	}
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	data = ((mlan_ds_bss *)req->pbuf)->param.bcn_interval;
	moal_memcpy_ext(priv->phandle, respbuf, &data, sizeof(data),
			respbuflen);
	ret = sizeof(data);

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

#ifdef STA_SUPPORT
/**
 *  @brief Get signal
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_get_signal(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
/** Input data size */
#define IN_DATA_SIZE 2
/** Output data size */
#define OUT_DATA_SIZE 12
	int ret = 0;
	int in_data[IN_DATA_SIZE];
	int out_data[OUT_DATA_SIZE];
	mlan_ds_get_signal signal;
	int data_length = 0;
	int user_data_len = 0, header_len = 0;

	ENTER();

	memset(in_data, 0, sizeof(in_data));
	memset(out_data, 0, sizeof(out_data));

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_GET_SIGNAL);

	if ((int)strlen(respbuf) != header_len)
		parse_arguments(respbuf + header_len, in_data, IN_DATA_SIZE,
				&user_data_len);

	if (priv->media_connected == MFALSE) {
		PRINTM(MERROR, "Can not get RSSI in disconnected state\n");
		ret = -ENOTSUPP;
		goto done;
	}

	if (user_data_len) {
		if (user_data_len > IN_DATA_SIZE) {
			PRINTM(MERROR, "Too many arguments\n");
			ret = -EINVAL;
			goto done;
		}
	}

	switch (user_data_len) {
	case 0:		/* No checking, get everything */
		break;
	case 2:		/* Check subtype range */
		if (in_data[1] < 1 || in_data[1] > 4) {
			ret = -EINVAL;
			goto done;
		}
		/* Fall through */
	case 1:		/* Check type range */
		if (in_data[0] < 1 || in_data[0] > 3) {
			ret = -EINVAL;
			goto done;
		}
		break;
	default:
		ret = -EINVAL;
		goto done;
	}

	memset(&signal, 0, sizeof(mlan_ds_get_signal));
	if (MLAN_STATUS_SUCCESS !=
	    woal_get_signal_info(priv, MOAL_IOCTL_WAIT, &signal)) {
		ret = -EFAULT;
		goto done;
	}
	PRINTM(MINFO, "RSSI Beacon Last   : %d\n", (int)signal.bcn_rssi_last);
	PRINTM(MINFO, "RSSI Beacon Average: %d\n", (int)signal.bcn_rssi_avg);
	PRINTM(MINFO, "RSSI Data Last     : %d\n", (int)signal.data_rssi_last);
	PRINTM(MINFO, "RSSI Data Average  : %d\n", (int)signal.data_rssi_avg);
	PRINTM(MINFO, "SNR Beacon Last    : %d\n", (int)signal.bcn_snr_last);
	PRINTM(MINFO, "SNR Beacon Average : %d\n", (int)signal.bcn_snr_avg);
	PRINTM(MINFO, "SNR Data Last      : %d\n", (int)signal.data_snr_last);
	PRINTM(MINFO, "SNR Data Average   : %d\n", (int)signal.data_snr_avg);
	PRINTM(MINFO, "NF Beacon Last     : %d\n", (int)signal.bcn_nf_last);
	PRINTM(MINFO, "NF Beacon Average  : %d\n", (int)signal.bcn_nf_avg);
	PRINTM(MINFO, "NF Data Last       : %d\n", (int)signal.data_nf_last);
	PRINTM(MINFO, "NF Data Average    : %d\n", (int)signal.data_nf_avg);

	/* Check type */
	switch (in_data[0]) {
	case 0:		/* Send everything */
		out_data[data_length++] = signal.bcn_rssi_last;
		out_data[data_length++] = signal.bcn_rssi_avg;
		out_data[data_length++] = signal.data_rssi_last;
		out_data[data_length++] = signal.data_rssi_avg;
		out_data[data_length++] = signal.bcn_snr_last;
		out_data[data_length++] = signal.bcn_snr_avg;
		out_data[data_length++] = signal.data_snr_last;
		out_data[data_length++] = signal.data_snr_avg;
		out_data[data_length++] = signal.bcn_nf_last;
		out_data[data_length++] = signal.bcn_nf_avg;
		out_data[data_length++] = signal.data_nf_last;
		out_data[data_length++] = signal.data_nf_avg;
		break;
	case 1:		/* RSSI */
		/* Check subtype */
		switch (in_data[1]) {
		case 0:	/* Everything */
			out_data[data_length++] = signal.bcn_rssi_last;
			out_data[data_length++] = signal.bcn_rssi_avg;
			out_data[data_length++] = signal.data_rssi_last;
			out_data[data_length++] = signal.data_rssi_avg;
			break;
		case 1:	/* bcn last */
			out_data[data_length++] = signal.bcn_rssi_last;
			break;
		case 2:	/* bcn avg */
			out_data[data_length++] = signal.bcn_rssi_avg;
			break;
		case 3:	/* data last */
			out_data[data_length++] = signal.data_rssi_last;
			break;
		case 4:	/* data avg */
			out_data[data_length++] = signal.data_rssi_avg;
			break;
		default:
			break;
		}
		break;
	case 2:		/* SNR */
		/* Check subtype */
		switch (in_data[1]) {
		case 0:	/* Everything */
			out_data[data_length++] = signal.bcn_snr_last;
			out_data[data_length++] = signal.bcn_snr_avg;
			out_data[data_length++] = signal.data_snr_last;
			out_data[data_length++] = signal.data_snr_avg;
			break;
		case 1:	/* bcn last */
			out_data[data_length++] = signal.bcn_snr_last;
			break;
		case 2:	/* bcn avg */
			out_data[data_length++] = signal.bcn_snr_avg;
			break;
		case 3:	/* data last */
			out_data[data_length++] = signal.data_snr_last;
			break;
		case 4:	/* data avg */
			out_data[data_length++] = signal.data_snr_avg;
			break;
		default:
			break;
		}
		break;
	case 3:		/* NF */
		/* Check subtype */
		switch (in_data[1]) {
		case 0:	/* Everything */
			out_data[data_length++] = signal.bcn_nf_last;
			out_data[data_length++] = signal.bcn_nf_avg;
			out_data[data_length++] = signal.data_nf_last;
			out_data[data_length++] = signal.data_nf_avg;
			break;
		case 1:	/* bcn last */
			out_data[data_length++] = signal.bcn_nf_last;
			break;
		case 2:	/* bcn avg */
			out_data[data_length++] = signal.bcn_nf_avg;
			break;
		case 3:	/* data last */
			out_data[data_length++] = signal.data_nf_last;
			break;
		case 4:	/* data avg */
			out_data[data_length++] = signal.data_nf_avg;
			break;
		default:
			break;
		}
		break;
	default:
		break;
	}

	moal_memcpy_ext(priv->phandle, respbuf, out_data,
			(data_length * sizeof(int)), respbuflen);
	ret = data_length * sizeof(int);

done:
	LEAVE();
	return ret;
}

static int
woal_signal_ext_enable(moal_private *priv, t_u8 enable)
{
	int ret = 0;
	mlan_ioctl_req *req = NULL;
	mlan_ds_snmp_mib *snmp = NULL;
	mlan_status status = MLAN_STATUS_SUCCESS;

	/* Allocate an IOCTL request buffer */
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_get_info));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	snmp = (mlan_ds_snmp_mib *)req->pbuf;
	snmp->sub_command = MLAN_OID_SNMP_MIB_SIGNALEXT_ENABLE;
	req->req_id = MLAN_IOCTL_SNMP_MIB;
	req->action = MLAN_ACT_SET;
	snmp->param.signalext_enable = enable;

	/* Send IOCTL request to MLAN */
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 *  @brief Get signal
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_get_signal_ext(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
#define PATH_SIZE 13
	int ret = 0;
	int data = 0, path = 0, data_len = 0;
	int user_data_len = 0, header_len = 0;
	int out_data[PATH_SIZE * MAX_PATH_NUM] = { 0 };
	mlan_ioctl_req *req = NULL;
	mlan_ds_get_info *info = NULL;
	mlan_ds_get_signal signal_get[MAX_PATH_NUM];
	mlan_status status = MLAN_STATUS_SUCCESS;
	int path_num;
	t_u8 enable = 1;

	ENTER();

	if (priv->media_connected == MFALSE) {
		PRINTM(MERROR, "Can not get RSSI in disconnected state\n");
		ret = -ENOTSUPP;
		goto done;
	}

	/* Allocate an IOCTL request buffer */
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_get_info));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_GET_SIGNAL_EXT);

	if ((int)strlen(respbuf) != header_len) {
		parse_arguments(respbuf + header_len, &data,
				sizeof(data) / sizeof(int), &user_data_len);
	}

	if (user_data_len > 1) {
		PRINTM(MERROR, "Too many arguments\n");
		ret = -EINVAL;
		goto done;
	}
	if (data < PATH_ALL || data > PATH_AB) {
		PRINTM(MERROR, "Wrong arguments\n");
		ret = -EINVAL;
		goto done;
	}

	/** Enable signalext feature in firmware */
	if (MLAN_STATUS_SUCCESS != woal_signal_ext_enable(priv, enable)) {
		ret = -EFAULT;
		goto done;
	}
	woal_sched_timeout(1000);
	enable = 0;

	/* Fill request buffer */
	info = (mlan_ds_get_info *)req->pbuf;
	info->sub_command = MLAN_OID_GET_SIGNAL_EXT;
	req->req_id = MLAN_IOCTL_GET_INFO;
	req->action = MLAN_ACT_GET;
	info->param.path_id = (t_u16)data;

	/* Send IOCTL request to MLAN */
	if (MLAN_STATUS_SUCCESS !=
	    woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
		woal_signal_ext_enable(priv, enable);
		ret = -EFAULT;
		goto done;
	}
	if (MLAN_STATUS_SUCCESS != woal_signal_ext_enable(priv, enable)) {
		ret = -EFAULT;
		goto done;
	}
	path_num = 1;
	if (data == PATH_ALL) {
		moal_memcpy_ext(priv->phandle, signal_get,
				info->param.signal_ext, sizeof(signal_get),
				sizeof(signal_get));
		path_num = MAX_PATH_NUM;
	} else
		moal_memcpy_ext(priv->phandle, signal_get,
				info->param.signal_ext,
				sizeof(mlan_ds_get_signal), sizeof(signal_get));

	for (path = 0; path < path_num; path++) {
		if (signal_get[path].selector == PATH_AB)
			PRINTM(MINFO, "PATH A+B:\n");
		else if (signal_get[path].selector == PATH_A)
			PRINTM(MINFO, "PATH A:\n");
		else if (signal_get[path].selector == PATH_B)
			PRINTM(MINFO, "PATH B:\n");
		PRINTM(MINFO, "RSSI Beacon Last   : %d\n",
		       (int)signal_get[path].bcn_rssi_last);
		PRINTM(MINFO, "RSSI Beacon Average: %d\n",
		       (int)signal_get[path].bcn_rssi_avg);
		PRINTM(MINFO, "RSSI Data Last     : %d\n",
		       (int)signal_get[path].data_rssi_last);
		PRINTM(MINFO, "RSSI Data Average  : %d\n",
		       (int)signal_get[path].data_rssi_avg);
		PRINTM(MINFO, "SNR Beacon Last    : %d\n",
		       (int)signal_get[path].bcn_snr_last);
		PRINTM(MINFO, "SNR Beacon Average : %d\n",
		       (int)signal_get[path].bcn_snr_avg);
		PRINTM(MINFO, "SNR Data Last      : %d\n",
		       (int)signal_get[path].data_snr_last);
		PRINTM(MINFO, "SNR Data Average   : %d\n",
		       (int)signal_get[path].data_snr_avg);
		PRINTM(MINFO, "NF Beacon Last     : %d\n",
		       (int)signal_get[path].bcn_nf_last);
		PRINTM(MINFO, "NF Beacon Average  : %d\n",
		       (int)signal_get[path].bcn_nf_avg);
		PRINTM(MINFO, "NF Data Last       : %d\n",
		       (int)signal_get[path].data_nf_last);
		PRINTM(MINFO, "NF Data Average    : %d\n",
		       (int)signal_get[path].data_nf_avg);
		out_data[data_len++] = (int)signal_get[path].selector;
		out_data[data_len++] = (int)signal_get[path].bcn_rssi_last;
		out_data[data_len++] = (int)signal_get[path].bcn_rssi_avg;
		out_data[data_len++] = (int)signal_get[path].data_rssi_last;
		out_data[data_len++] = (int)signal_get[path].data_rssi_avg;
		out_data[data_len++] = (int)signal_get[path].bcn_snr_last;
		out_data[data_len++] = (int)signal_get[path].bcn_snr_avg;
		out_data[data_len++] = (int)signal_get[path].data_snr_last;
		out_data[data_len++] = (int)signal_get[path].data_snr_avg;
		out_data[data_len++] = (int)signal_get[path].bcn_nf_last;
		out_data[data_len++] = (int)signal_get[path].bcn_nf_avg;
		out_data[data_len++] = (int)signal_get[path].data_nf_last;
		out_data[data_len++] = (int)signal_get[path].data_nf_avg;
	}
	moal_memcpy_ext(priv->phandle, respbuf, out_data,
			(MIN((PATH_SIZE * MAX_PATH_NUM), data_len) *
			 sizeof(int)), respbuflen);
	ret = data_len * sizeof(int);
done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 *  @brief Get signalext v2
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_get_signal_ext_v2(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
#define PATH_SIZE 13
	int ret = 0;
	int data = 0, path = 0, data_len = 0;
	int user_data_len = 0, header_len = 0;
	int out_data[PATH_SIZE * MAX_PATH_NUM] = { 0 };
	mlan_ioctl_req *req = NULL;
	mlan_ds_get_info *info = NULL;
	mlan_ds_get_signal signal_get[MAX_PATH_NUM];
	mlan_status status = MLAN_STATUS_SUCCESS;
	int path_num;

	ENTER();

	if (priv->media_connected == MFALSE) {
		PRINTM(MERROR, "Can not get RSSI in disconnected state\n");
		ret = -ENOTSUPP;
		goto done;
	}

	/* Allocate an IOCTL request buffer */
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_get_info));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_GET_SIGNAL_EXT_V2);
	if ((int)strlen(respbuf) != header_len) {
		parse_arguments(respbuf + header_len, &data,
				sizeof(data) / sizeof(int), &user_data_len);
	}

	if (user_data_len > 1) {
		PRINTM(MERROR, "Too many arguments\n");
		ret = -EINVAL;
		goto done;
	}
	if (data < PATH_ALL || data > PATH_AB) {
		PRINTM(MERROR, "Wrong arguments\n");
		ret = -EINVAL;
		goto done;
	}

	/* Fill request buffer */
	info = (mlan_ds_get_info *)req->pbuf;
	info->sub_command = MLAN_OID_GET_SIGNAL_EXT;
	req->req_id = MLAN_IOCTL_GET_INFO;
	req->action = MLAN_ACT_GET;
	info->param.path_id = (t_u16)data;

	/* Send IOCTL request to MLAN */
	if (MLAN_STATUS_SUCCESS !=
	    woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
		PRINTM(MERROR,
		       "Enable signalextcfg: mlanutl mlanX signalextcfg 1"
		       " before issuing this command\n");
		ret = -EFAULT;
		goto done;
	}
	path_num = 1;

	if (data == PATH_ALL) {
		moal_memcpy_ext(priv->phandle, signal_get,
				info->param.signal_ext, sizeof(signal_get),
				sizeof(signal_get));
		path_num = MAX_PATH_NUM;
	} else
		moal_memcpy_ext(priv->phandle, signal_get,
				info->param.signal_ext,
				sizeof(mlan_ds_get_signal), sizeof(signal_get));

	PRINTM(MMSG, "data=%d path_num=%d\n", data, path_num);

	for (path = 0; path < path_num; path++) {
		if (signal_get[path].selector == PATH_AB)
			PRINTM(MINFO, "PATH A+B:\n");
		else if (signal_get[path].selector == PATH_A)
			PRINTM(MINFO, "PATH A:\n");
		else if (signal_get[path].selector == PATH_B)
			PRINTM(MINFO, "PATH B:\n");
		PRINTM(MINFO, "RSSI Beacon Last   : %d\n",
		       (int)signal_get[path].bcn_rssi_last);
		PRINTM(MINFO, "RSSI Beacon Average: %d\n",
		       (int)signal_get[path].bcn_rssi_avg);
		PRINTM(MINFO, "RSSI Data Last     : %d\n",
		       (int)signal_get[path].data_rssi_last);
		PRINTM(MINFO, "RSSI Data Average  : %d\n",
		       (int)signal_get[path].data_rssi_avg);
		PRINTM(MINFO, "SNR Beacon Last    : %d\n",
		       (int)signal_get[path].bcn_snr_last);
		PRINTM(MINFO, "SNR Beacon Average : %d\n",
		       (int)signal_get[path].bcn_snr_avg);
		PRINTM(MINFO, "SNR Data Last      : %d\n",
		       (int)signal_get[path].data_snr_last);
		PRINTM(MINFO, "SNR Data Average   : %d\n",
		       (int)signal_get[path].data_snr_avg);
		PRINTM(MINFO, "NF Beacon Last     : %d\n",
		       (int)signal_get[path].bcn_nf_last);
		PRINTM(MINFO, "NF Beacon Average  : %d\n",
		       (int)signal_get[path].bcn_nf_avg);
		PRINTM(MINFO, "NF Data Last       : %d\n",
		       (int)signal_get[path].data_nf_last);
		PRINTM(MINFO, "NF Data Average    : %d\n",
		       (int)signal_get[path].data_nf_avg);
		out_data[data_len++] = (int)signal_get[path].selector;
		out_data[data_len++] = (int)signal_get[path].bcn_rssi_last;
		out_data[data_len++] = (int)signal_get[path].bcn_rssi_avg;
		out_data[data_len++] = (int)signal_get[path].data_rssi_last;
		out_data[data_len++] = (int)signal_get[path].data_rssi_avg;
		out_data[data_len++] = (int)signal_get[path].bcn_snr_last;
		out_data[data_len++] = (int)signal_get[path].bcn_snr_avg;
		out_data[data_len++] = (int)signal_get[path].data_snr_last;
		out_data[data_len++] = (int)signal_get[path].data_snr_avg;
		out_data[data_len++] = (int)signal_get[path].bcn_nf_last;
		out_data[data_len++] = (int)signal_get[path].bcn_nf_avg;
		out_data[data_len++] = (int)signal_get[path].data_nf_last;
		out_data[data_len++] = (int)signal_get[path].data_nf_avg;
	}
	moal_memcpy_ext(priv->phandle, respbuf, out_data,
			(MIN((PATH_SIZE * MAX_PATH_NUM), data_len) *
			 sizeof(int)), respbuflen);
	ret = data_len * sizeof(int);
done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 *  @brief Set signalext cfg
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             The result of this processing.
 */
static int
woal_priv_signalext_cfg(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int enable = 0;
	int ret = 0;
	int user_data_len = 0, header_len = 0;
	ENTER();
	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_SIGNALEXT_CFG);
	if ((int)strlen(respbuf) == header_len) {
		PRINTM(MERROR, "Invalid arguments!\n");
		ret = -EINVAL;
		goto done;
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len, &enable, 1,
				&user_data_len);
		if (user_data_len == 1) {
			if (enable != 0x0 && enable != 0x1) {
				PRINTM(MERROR, "Invalid arguments!\n");
				ret = -EINVAL;
				goto done;
			}
			ret = woal_signal_ext_enable(priv, enable);
		} else {
			PRINTM(MERROR, "Too many arguments\n");
			ret = -EINVAL;
			goto done;
		}
	}
done:
	LEAVE();
	return ret;
}
#endif /* #ifdef STA_SUPPORT */

#if defined(STA_SUPPORT)
/**
 * @brief               Make PMF bit required/optional
 * @param priv          Pointer to moal_private structure
 * @param respbuf       Pointer to response buffer
 * @param resplen       Response buffer length
 *
 * @return              0 -- success, otherwise fail
 */
static int
woal_priv_set_get_pmfcfg(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int data[2] = { 0, 0 };
	mlan_ioctl_req *req = NULL;
	mlan_ds_misc_cfg *cfg = NULL;
	mlan_ds_misc_pmfcfg *pmfcfg;
	int ret = 0;
	int user_data_len = 0, header_len = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	if (!priv->phandle->card_info->embedded_supp) {
		PRINTM(MERROR, "Not supported cmd on this card\n");
		ret = -EOPNOTSUPP;
		goto done;
	}

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_PMFCFG);
	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		user_data_len = 0;
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len, data, ARRAY_SIZE(data),
				&user_data_len);
	}

	if (user_data_len > 2) {
		PRINTM(MERROR, "Invalid number of arguments\n");
		ret = -EINVAL;
		goto done;
	}
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	cfg = (mlan_ds_misc_cfg *)req->pbuf;
	pmfcfg = (mlan_ds_misc_pmfcfg *)&cfg->param.pmfcfg;
	cfg->sub_command = MLAN_OID_MISC_PMFCFG;
	req->req_id = MLAN_IOCTL_MISC_CFG;

	if (user_data_len == 0)
		req->action = MLAN_ACT_GET;
	else {
		pmfcfg->mfpc = (t_u8)data[0];
		pmfcfg->mfpr = (t_u8)data[1];
		req->action = MLAN_ACT_SET;
	}

	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)&cfg->param.pmfcfg,
			sizeof(mlan_ds_misc_pmfcfg), respbuflen);
	ret = sizeof(mlan_ds_misc_pmfcfg);

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}
#endif

/**
 * @brief               Get/Set inactivity timeout extend
 * @param priv          Pointer to moal_private structure
 * @param respbuf       Pointer to response buffer
 * @param resplen       Response buffer length
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_inactivity_timeout_ext(moal_private *priv, t_u8 *respbuf,
				 t_u32 respbuflen)
{
	int data[4];
	mlan_ioctl_req *req = NULL;
	mlan_ds_pm_cfg *pmcfg = NULL;
	pmlan_ds_inactivity_to inac_to = NULL;
	int ret = 0;
	int user_data_len = 0, header_len = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_INACTIVITYTO);
	memset(data, 0, sizeof(data));
	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		user_data_len = 0;
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len, data, ARRAY_SIZE(data),
				&user_data_len);
	}

	if (user_data_len != 0 && user_data_len != 3 && user_data_len != 4) {
		PRINTM(MERROR, "Invalid number of parameters\n");
		ret = -EINVAL;
		goto done;
	}
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_pm_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	pmcfg = (mlan_ds_pm_cfg *)req->pbuf;
	inac_to = &pmcfg->param.inactivity_to;
	pmcfg->sub_command = MLAN_OID_PM_CFG_INACTIVITY_TO;
	req->req_id = MLAN_IOCTL_PM_CFG;
	req->action = MLAN_ACT_GET;

	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	if (user_data_len) {
		inac_to->timeout_unit = data[0];
		inac_to->unicast_timeout = data[1];
		inac_to->mcast_timeout = data[2];
		if (user_data_len == 4)
			inac_to->ps_entry_timeout = data[3];
		req->action = MLAN_ACT_SET;

		status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
		if (status != MLAN_STATUS_SUCCESS) {
			ret = -EFAULT;
			goto done;
		}
	} else {
		data[0] = inac_to->timeout_unit;
		data[1] = inac_to->unicast_timeout;
		data[2] = inac_to->mcast_timeout;
		data[3] = inac_to->ps_entry_timeout;

		moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)data,
				sizeof(data), respbuflen);
		ret = sizeof(data);
	}

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 * @brief               Enable/Disable amsdu_aggr_ctrl
 *
 * @param priv          Pointer to moal_private structure
 * @param respbuf       Pointer to response buffer
 * @param resplen       Response buffer length
 *
 * @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_11n_amsdu_aggr_ctrl(moal_private *priv, t_u8 *respbuf,
			      t_u32 respbuflen)
{
	mlan_ioctl_req *req = NULL;
	mlan_ds_11n_cfg *cfg_11n = NULL;
	int ret = 0, data[2] = { 0 };
	int user_data_len = 0, header_len = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_AMSDU_AGGR_CTRL);
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11n_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	cfg_11n = (mlan_ds_11n_cfg *)req->pbuf;
	cfg_11n->sub_command = MLAN_OID_11N_CFG_AMSDU_AGGR_CTRL;
	req->req_id = MLAN_IOCTL_11N_CFG;

	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		user_data_len = 0;
		req->action = MLAN_ACT_GET;
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len, data, 1, &user_data_len);

		if (user_data_len != 1) {
			PRINTM(MERROR, "Invalid number of parameters\n");
			ret = -EINVAL;
			goto done;
		}
		req->action = MLAN_ACT_SET;
		cfg_11n->param.amsdu_aggr_ctrl.enable = data[0];
	}

	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	data[0] = cfg_11n->param.amsdu_aggr_ctrl.enable;
	data[1] = cfg_11n->param.amsdu_aggr_ctrl.curr_buf_size;

	moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)data, sizeof(data),
			respbuflen);
	ret = sizeof(data);

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 * @brief               Set/Get Transmit beamforming capabilities
 *
 * @param priv          Pointer to moal_private structure
 * @param respbuf       Pointer to response buffer
 * @param resplen       Response buffer length
 *
 * @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_tx_bf_cap_ioctl(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	mlan_ioctl_req *req = NULL;
	mlan_ds_11n_cfg *bf_cfg = NULL;
	int ret = 0, bf_cap = 0;
	int user_data_len = 0, header_len = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_TX_BF_CAP);
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11n_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	bf_cfg = (mlan_ds_11n_cfg *)req->pbuf;
	bf_cfg->sub_command = MLAN_OID_11N_CFG_TX_BF_CAP;
	req->req_id = MLAN_IOCTL_11N_CFG;

	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		user_data_len = 0;
		req->action = MLAN_ACT_GET;
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len, &bf_cap, 1,
				&user_data_len);

		if (user_data_len != 1) {
			PRINTM(MERROR, "Invalid number of parameters\n");
			ret = -EINVAL;
			goto done;
		}
		req->action = MLAN_ACT_SET;
		bf_cfg->param.tx_bf_cap = bf_cap;
	}

	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	bf_cap = bf_cfg->param.tx_bf_cap;

	moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)&bf_cap, sizeof(bf_cap),
			respbuflen);
	ret = sizeof(bf_cap);

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

#ifdef SDIO
/**
 * @brief               Turn on/off the sdio clock
 *
 * @param priv          Pointer to moal_private structure
 * @param respbuf       Pointer to response buffer
 * @param resplen       Response buffer length
 *
 * @return              Number of bytes written, negative for failure.
 */
static int
woal_priv_sdio_clock_ioctl(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int ret = 0;
	int data = 2;
	int user_data_len = 0, header_len = 0;
	/* Initialize the clock state as on */
	static int clock_state = 1;

	ENTER();

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_SDIO_CLOCK);
	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)&clock_state,
				sizeof(clock_state), respbuflen);
		ret = sizeof(clock_state);
		goto done;
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len, &data, 1, &user_data_len);

		if (user_data_len != 1) {
			PRINTM(MERROR, "Invalid number of parameters\n");
			ret = -EINVAL;
			goto done;
		}
	}
	switch (data) {
	case CMD_DISABLED:
		PRINTM(MINFO, "SDIO clock is turned off\n");
		ret = woal_sdio_set_bus_clock(priv->phandle, MFALSE);
		clock_state = data;
		break;
	case CMD_ENABLED:
		PRINTM(MINFO, "SDIO clock is turned on\n");
		ret = woal_sdio_set_bus_clock(priv->phandle, MTRUE);
		clock_state = data;
		break;
	default:
		ret = -EINVAL;
		PRINTM(MINFO, "sdioclock: wrong parameter\n");
		break;
	}
done:
	LEAVE();
	return ret;
}
#endif

#ifdef SDIO
/**
 * @brief               Set SDIO Multi-point aggregation control parameters
 *
 * @param priv          Pointer to moal_private structure
 * @param respbuf       Pointer to response buffer
 * @param resplen       Response buffer length
 *
 * @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_sdio_mpa_ctrl(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	mlan_ioctl_req *req = NULL;
	mlan_ds_misc_cfg *misc = NULL;
	int ret = 0, data[6];
	int user_data_len = 0, header_len = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	memset(data, 0, sizeof(data));
	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_MPA_CTRL);
	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		user_data_len = 0;
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len, data, ARRAY_SIZE(data),
				&user_data_len);

		if (user_data_len > 6) {
			PRINTM(MERROR, "Invalid number of parameters\n");
			ret = -EINVAL;
			goto done;
		}
	}
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	misc = (mlan_ds_misc_cfg *)req->pbuf;
	misc->sub_command = MLAN_OID_MISC_SDIO_MPA_CTRL;
	req->req_id = MLAN_IOCTL_MISC_CFG;
	req->action = MLAN_ACT_GET;
	/* Get the values first, then modify these values if
	 * user had modified them */

	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		PRINTM(MERROR, "woal_request_ioctl returned %d\n", ret);
		ret = -EFAULT;
		goto done;
	}

	if (user_data_len == 0) {
		data[0] = misc->param.mpa_ctrl.tx_enable;
		data[1] = misc->param.mpa_ctrl.rx_enable;
		data[2] = misc->param.mpa_ctrl.tx_buf_size;
		data[3] = misc->param.mpa_ctrl.rx_buf_size;
		data[4] = misc->param.mpa_ctrl.tx_max_ports;
		data[5] = misc->param.mpa_ctrl.rx_max_ports;

		PRINTM(MINFO, "Get Param: %d %d %d %d %d %d\n", data[0],
		       data[1], data[2], data[3], data[4], data[5]);

		moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)data,
				sizeof(data), respbuflen);
		ret = sizeof(data);
		goto done;
	}

	switch (user_data_len) {
	case 6:
		misc->param.mpa_ctrl.rx_max_ports = data[5];
		/* fall through */
	case 5:
		misc->param.mpa_ctrl.tx_max_ports = data[4];
		/* fall through */
	case 4:
		misc->param.mpa_ctrl.rx_buf_size = data[3];
		/* fall through */
	case 3:
		misc->param.mpa_ctrl.tx_buf_size = data[2];
		/* fall through */
	case 2:
		misc->param.mpa_ctrl.rx_enable = data[1];
		/* fall through */
	case 1:
		/* Set cmd */
		req->action = MLAN_ACT_SET;

		PRINTM(MINFO, "Set Param: %d %d %d %d %d %d\n", data[0],
		       data[1], data[2], data[3], data[4], data[5]);

		misc->param.mpa_ctrl.tx_enable = data[0];
		break;
	default:
		PRINTM(MERROR, "Default case error\n");
		ret = -EINVAL;
		goto done;
	}

	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}
#endif

/**
 * @brief               Configure sleep parameters
 *
 * @param priv          Pointer to moal_private structure
 * @param respbuf       Pointer to response buffer
 * @param resplen       Response buffer length
 *
 * @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_sleep_params_ioctl(moal_private *priv, t_u8 *respbuf,
			     t_u32 respbuflen)
{
	int ret = 0;
	mlan_ioctl_req *req = NULL;
	mlan_ds_pm_cfg *pm = NULL;
	mlan_ds_sleep_params *psleep_params = NULL;
	int data[6] = { 0 }, i;
	int user_data_len = 0, header_len = 0;
#ifdef DEBUG_LEVEL1
	char err_str[][36] = { {"sleep clock error in ppm"},
	{"wakeup offset in usec"},
	{"clock stabilization time in usec"},
	{"control periodic calibration(0-2)"},
	{"control of external sleepClock(0-2)"},
	{"value of reserved for debug"}
	};
#endif
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	memset(data, 0, sizeof(data));
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_pm_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}
	pm = (mlan_ds_pm_cfg *)req->pbuf;
	pm->sub_command = MLAN_OID_PM_CFG_SLEEP_PARAMS;
	req->req_id = MLAN_IOCTL_PM_CFG;
	psleep_params = (pmlan_ds_sleep_params)&pm->param.sleep_params;

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_SLEEP_PARAMS);
	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		user_data_len = 0;
		req->action = MLAN_ACT_GET;
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len, data, ARRAY_SIZE(data),
				&user_data_len);
		if (user_data_len != 6) {
			PRINTM(MERROR, "Invalid number of parameters\n");
			ret = -EINVAL;
			goto done;
		}
#define MIN_VAL 0x0000
#define MAX_VAL 0xFFFF
		for (i = 0; i < 6; i++) {
			if ((i == 3) || (i == 4)) {
				/* These two cases are handled below the loop */
				continue;
			}
			if (data[i] < MIN_VAL || data[i] > MAX_VAL) {
				PRINTM(MERROR, "Invalid %s (0-65535)!\n",
				       err_str[i]);
				ret = -EINVAL;
				goto done;
			}
		}
		if (data[3] < 0 || data[3] > 2) {
			PRINTM(MERROR,
			       "Invalid control periodic calibration (0-2)!\n");
			ret = -EINVAL;
			goto done;
		}
		if (data[4] < 0 || data[4] > 2) {
			PRINTM(MERROR,
			       "Invalid control of external sleep clock (0-2)!\n");
			ret = -EINVAL;
			goto done;
		}
		req->action = MLAN_ACT_SET;
		psleep_params->error = data[0];
		psleep_params->offset = data[1];
		psleep_params->stable_time = data[2];
		psleep_params->cal_control = data[3];
		psleep_params->ext_sleep_clk = data[4];
		psleep_params->reserved = data[5];
	}

	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	data[0] = psleep_params->error;
	data[1] = psleep_params->offset;
	data[2] = psleep_params->stable_time;
	data[3] = psleep_params->cal_control;
	data[4] = psleep_params->ext_sleep_clk;
	data[5] = psleep_params->reserved;

	moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)data, sizeof(data),
			respbuflen);
	ret = sizeof(data);

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);

	LEAVE();
	return ret;
}

/**
 * @brief               Set/Get DFS Testing settings
 *
 * @param priv          Pointer to moal_private structure
 * @param respbuf       Pointer to response buffer
 * @param resplen       Response buffer length
 *
 * @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_dfs_testing(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	mlan_ioctl_req *req = NULL;
	mlan_ds_11h_cfg *ds_11hcfg = NULL;
	int ret = 0;
	int data[5] = { 0 };
	int user_data_len = 0, header_len = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_DFS_TESTING);
	/* Allocate an IOCTL request buffer */
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11h_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	/* Fill request buffer */
	ds_11hcfg = (mlan_ds_11h_cfg *)req->pbuf;
	ds_11hcfg->sub_command = MLAN_OID_11H_DFS_TESTING;
	req->req_id = MLAN_IOCTL_11H_CFG;

	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		user_data_len = 0;
		req->action = MLAN_ACT_GET;
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len, data, ARRAY_SIZE(data),
				&user_data_len);
		if (user_data_len != 5) {
			PRINTM(MERROR, "Invalid number of args!\n");
			ret = -EINVAL;
			goto done;
		}
		if ((unsigned)data[0] > 1800) {
			PRINTM(MERROR,
			       "The maximum user CAC is 1800 seconds (30 mins).\n");
			ret = -EINVAL;
			goto done;
		}
		if ((unsigned)data[1] > 0xFFFF) {
			PRINTM(MERROR, "The maximum user NOP is 65535 sec.\n");
			ret = -EINVAL;
			goto done;
		}
		if ((unsigned)data[3] > 0xFF) {
			PRINTM(MERROR,
			       "The maximum user fixed channel is 255.\n");
			ret = -EINVAL;
			goto done;
		}
		if ((unsigned)data[4] != 0 && ((unsigned)data[4] != 1)) {
			PRINTM(MERROR, "CAC restart should be 0/1\n");
			ret = -EINVAL;
			goto done;
		}

		ds_11hcfg->param.dfs_testing.usr_cac_period_msec =
			(t_u32)data[0] * 1000;
		ds_11hcfg->param.dfs_testing.usr_nop_period_sec =
			(t_u16)data[1];
		ds_11hcfg->param.dfs_testing.usr_no_chan_change =
			data[2] ? 1 : 0;
		ds_11hcfg->param.dfs_testing.usr_fixed_new_chan = (t_u8)data[3];
		ds_11hcfg->param.dfs_testing.usr_cac_restart = (t_u8)data[4];
		priv->phandle->cac_restart = (t_u8)data[4];
		priv->phandle->cac_period_jiffies = (t_u32)data[0] * HZ;
		priv->phandle->usr_nop_period_sec = (t_u16)data[1];
		req->action = MLAN_ACT_SET;
#ifdef UAP_SUPPORT
		priv->user_cac_period_msec =
			ds_11hcfg->param.dfs_testing.usr_cac_period_msec;
#endif
	}

	/* Send IOCTL request to MLAN */
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	if (!user_data_len) {
		data[0] =
			ds_11hcfg->param.dfs_testing.usr_cac_period_msec / 1000;
		data[1] = ds_11hcfg->param.dfs_testing.usr_nop_period_sec;
		data[2] = ds_11hcfg->param.dfs_testing.usr_no_chan_change;
		data[3] = ds_11hcfg->param.dfs_testing.usr_fixed_new_chan;
		data[4] = ds_11hcfg->param.dfs_testing.usr_cac_restart;
		moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)data,
				sizeof(data), respbuflen);
		ret = sizeof(data);
	}

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);

	LEAVE();
	return ret;
}

/**
 * @brief               Set/Get DFS W53 settings
 *
 * @param priv          Pointer to moal_private structure
 * @param respbuf       Pointer to response buffer
 * @param resplen       Response buffer length
 *
 * @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_dfs53cfg(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	mlan_ioctl_req *req = NULL;
	mlan_ds_11h_cfg *ds_11hcfg = NULL;
	int ret = 0;
	int data = 0;
	int user_data_len = 0, header_len = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_DFS53_CFG);
	/* Allocate an IOCTL request buffer */
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11h_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	/* Fill request buffer */
	ds_11hcfg = (mlan_ds_11h_cfg *)req->pbuf;
	ds_11hcfg->sub_command = MLAN_OID_11H_DFS_W53_CFG;
	req->req_id = MLAN_IOCTL_11H_CFG;

	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		user_data_len = 0;
		req->action = MLAN_ACT_GET;
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len, &data,
				sizeof(data) / sizeof(int), &user_data_len);
		if (user_data_len != 1) {
			PRINTM(MERROR, "Invalid number of args !\n");
			ret = -EINVAL;
			goto done;
		}
		if (data > DFS_W53_OLD) {
			PRINTM(MERROR, "Invalid config !\n");
			ret = -EINVAL;
			goto done;
		}

		ds_11hcfg->param.dfs_w53_cfg.dfs53cfg = (t_u8)data;
		req->action = MLAN_ACT_SET;
	}

	/* Send IOCTL request to MLAN */
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	if (!user_data_len) {
		moal_memcpy_ext(priv->phandle, respbuf,
				(t_u8 *)&ds_11hcfg->param.dfs_w53_cfg.dfs53cfg,
				sizeof(ds_11hcfg->param.dfs_w53_cfg.dfs53cfg),
				respbuflen);
		ret = sizeof(t_u8);
	}

	PRINTM(MIOCTL, "dfs w53 cfg %d\n",
	       ds_11hcfg->param.dfs_w53_cfg.dfs53cfg);

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);

	LEAVE();
	return ret;
}

/**
 *  @brief determine the center frquency center index for bandwidth
 *         of 80 MHz and 160 MHz
 *
 ** @param priv          Pointer to moal_private structure
 *  @param band         band
 *  @param pri_chan     primary channel
 *  @param chan_bw      channel bandwidth
 *
 *  @return             channel center frequency center, if found; O, otherwise
 */

static t_u8
woal_get_center_freq_idx(moal_private *priv, t_u8 band,
			 t_u32 pri_chan, t_u8 chan_bw)
{
	t_u8 center_freq_idx = 0;

	if (band & BAND_AAC) {
		switch (pri_chan) {
		case 36:
		case 40:
			if (chan_bw == CHANNEL_BW_40MHZ_ABOVE ||
			    chan_bw == CHANNEL_BW_40MHZ_BELOW) {
				center_freq_idx = 38;
				break;
			}
			/* fall through */
		case 44:
		case 48:
			if (chan_bw == CHANNEL_BW_40MHZ_ABOVE ||
			    chan_bw == CHANNEL_BW_40MHZ_BELOW) {
				center_freq_idx = 46;
				break;
			} else if (chan_bw == CHANNEL_BW_80MHZ) {
				center_freq_idx = 42;
				break;
			}
			/* fall through */
		case 52:
		case 56:
			if (chan_bw == CHANNEL_BW_40MHZ_ABOVE ||
			    chan_bw == CHANNEL_BW_40MHZ_BELOW) {
				center_freq_idx = 54;
				break;
			}
			/* fall through */
		case 60:
		case 64:
			if (chan_bw == CHANNEL_BW_40MHZ_ABOVE ||
			    chan_bw == CHANNEL_BW_40MHZ_BELOW) {
				center_freq_idx = 62;
				break;
			} else if (chan_bw == CHANNEL_BW_80MHZ) {
				center_freq_idx = 58;
				break;
			} else if (chan_bw == CHANNEL_BW_160MHZ) {
				center_freq_idx = 50;
				break;
			}
			/* fall through */
		case 68:
		case 72:
			if (chan_bw == CHANNEL_BW_40MHZ_ABOVE ||
			    chan_bw == CHANNEL_BW_40MHZ_BELOW) {
				center_freq_idx = 70;
				break;
			}
			/* fall through */
		case 76:
		case 80:
			if (chan_bw == CHANNEL_BW_40MHZ_ABOVE ||
			    chan_bw == CHANNEL_BW_40MHZ_BELOW) {
				center_freq_idx = 78;
				break;
			} else if (chan_bw == CHANNEL_BW_80MHZ) {
				center_freq_idx = 74;
				break;
			}
			/* fall through */
		case 84:
		case 88:
			if (chan_bw == CHANNEL_BW_40MHZ_ABOVE ||
			    chan_bw == CHANNEL_BW_40MHZ_BELOW) {
				center_freq_idx = 86;
				break;
			}
			/* fall through */
		case 92:
		case 96:
			if (chan_bw == CHANNEL_BW_40MHZ_ABOVE ||
			    chan_bw == CHANNEL_BW_40MHZ_BELOW) {
				center_freq_idx = 94;
				break;
			} else if (chan_bw == CHANNEL_BW_80MHZ) {
				center_freq_idx = 90;
				break;
			}
			/* fall through */
		case 100:
		case 104:
			if (chan_bw == CHANNEL_BW_40MHZ_ABOVE ||
			    chan_bw == CHANNEL_BW_40MHZ_BELOW) {
				center_freq_idx = 102;
				break;
			}
			/* fall through */
		case 108:
		case 112:
			if (chan_bw == CHANNEL_BW_40MHZ_ABOVE ||
			    chan_bw == CHANNEL_BW_40MHZ_BELOW) {
				center_freq_idx = 110;
				break;
			} else if (chan_bw == CHANNEL_BW_80MHZ) {
				center_freq_idx = 106;
				break;
			}
			/* fall through */
		case 116:
		case 120:
			if (chan_bw == CHANNEL_BW_40MHZ_ABOVE ||
			    chan_bw == CHANNEL_BW_40MHZ_BELOW) {
				center_freq_idx = 118;
				break;
			}
			/* fall through */
		case 124:
		case 128:
			if (chan_bw == CHANNEL_BW_40MHZ_ABOVE ||
			    chan_bw == CHANNEL_BW_40MHZ_BELOW) {
				center_freq_idx = 126;
			} else if (chan_bw == CHANNEL_BW_80MHZ) {
				center_freq_idx = 122;
			} else if (chan_bw == CHANNEL_BW_160MHZ) {
				center_freq_idx = 114;
			}
			break;
		case 132:
		case 136:
			if (chan_bw == CHANNEL_BW_40MHZ_ABOVE ||
			    chan_bw == CHANNEL_BW_40MHZ_BELOW) {
				center_freq_idx = 134;
				break;
			}
			/* fall through */
		case 140:
		case 144:
			if (chan_bw == CHANNEL_BW_40MHZ_ABOVE ||
			    chan_bw == CHANNEL_BW_40MHZ_BELOW) {
				center_freq_idx = 126;
			} else if (chan_bw == CHANNEL_BW_80MHZ) {
				center_freq_idx = 138;
			}
			break;
		case 149:
		case 153:
			if (chan_bw == CHANNEL_BW_40MHZ_ABOVE ||
			    chan_bw == CHANNEL_BW_40MHZ_BELOW) {
				center_freq_idx = 151;
				break;
			}
			/* fall through */
		case 157:
		case 161:
			if (chan_bw == CHANNEL_BW_40MHZ_ABOVE ||
			    chan_bw == CHANNEL_BW_40MHZ_BELOW) {
				center_freq_idx = 159;
				break;
			} else if (chan_bw == CHANNEL_BW_80MHZ) {
				center_freq_idx = 155;
				break;
			}
			/* fall through */
		case 165:
		case 169:
			if (chan_bw == CHANNEL_BW_40MHZ_ABOVE ||
			    chan_bw == CHANNEL_BW_40MHZ_BELOW) {
				center_freq_idx = 167;
				break;
			}
			/* fall through */
		case 173:
		case 177:
			if (chan_bw == CHANNEL_BW_40MHZ_ABOVE ||
			    chan_bw == CHANNEL_BW_40MHZ_BELOW) {
				center_freq_idx = 175;
				break;
			} else if (chan_bw == CHANNEL_BW_80MHZ) {
				center_freq_idx = 171;
				break;
			}
			/* fall through */
		case 184:
		case 188:
			if (chan_bw == CHANNEL_BW_40MHZ_ABOVE ||
			    chan_bw == CHANNEL_BW_40MHZ_BELOW) {
				center_freq_idx = 186;
				break;
			}
			/* fall through */
		case 192:
		case 196:
			if (chan_bw == CHANNEL_BW_40MHZ_ABOVE ||
			    chan_bw == CHANNEL_BW_40MHZ_BELOW) {
				center_freq_idx = 194;
				break;
			} else if (chan_bw == CHANNEL_BW_80MHZ) {
				center_freq_idx = 190;
				break;
			}
			/* fall through */
		default:	/* error. go to the default */
			center_freq_idx = 42;
		}
	}
	return center_freq_idx;
}

#if defined(UAP_SUPPORT)
/**
 *  @brief This function handles channel switch with CSA/ECSA IE.
 *
 ** @param priv          Pointer to moal_private structure
 *  @param block_tx      0-no need block traffic 1- need block traffic
 *  @param oper_class    oper_class
 *  @param channel       channel
 *  @param switch count  how many csa/ecsa beacon will send out
 *  @param band_width    1-40Mhz above, 3-40Mhz below, 4-80Mhz, 5-160Mhz
 *  @param ecsa          MTRUE/MFALSE;
 *
 *  @return             channel center frequency center, if found; O, otherwise
 */
static int
woal_channel_switch(moal_private *priv, t_u8 block_tx, t_u8 oper_class,
		    t_u8 channel, t_u8 switch_count, t_u8 band_width, t_u8 ecsa)
{
	IEEEtypes_ExtChanSwitchAnn_t *ext_chan_switch = NULL;
	IEEEtypes_ChanSwitchAnn_t *chan_switch = NULL;
	custom_ie *pcust_chansw_ie = NULL;
	t_u8 center_freq_idx = 0;
	IEEEtypes_Header_t *pChanSwWrap_ie = NULL;
	IEEEtypes_WideBWChanSwitch_t *pbwchansw_ie = NULL;
	IEEEtypes_VhtTpcEnvelope_t *pvhttpcEnv_ie = NULL;
	mlan_ioctl_req *ioctl_req = NULL;
	mlan_ds_misc_cfg *misc = NULL;
	mlan_status status = MLAN_STATUS_SUCCESS;
	t_u8 bw;
	t_u8 new_oper_class = oper_class;
	int ret = 0;

	ENTER();

	ioctl_req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (ioctl_req == NULL) {
		ret = -ENOMEM;
		goto done;
	}
	misc = (mlan_ds_misc_cfg *)ioctl_req->pbuf;
	misc->sub_command = MLAN_OID_MISC_CUSTOM_IE;
	ioctl_req->req_id = MLAN_IOCTL_MISC_CFG;
	ioctl_req->action = MLAN_ACT_SET;
	misc->param.cust_ie.type = TLV_TYPE_MGMT_IE;
	misc->param.cust_ie.len = (sizeof(custom_ie) - MAX_IE_SIZE);

	pcust_chansw_ie = (custom_ie *)&misc->param.cust_ie.ie_data_list[0];
	pcust_chansw_ie->ie_index = 0xffff;	/*Auto index */
	pcust_chansw_ie->ie_length = sizeof(IEEEtypes_ChanSwitchAnn_t);
	pcust_chansw_ie->mgmt_subtype_mask = MGMT_MASK_BEACON | MGMT_MASK_PROBE_RESP;	/*Add IE for
											   BEACON/probe resp */
	chan_switch = (IEEEtypes_ChanSwitchAnn_t *)pcust_chansw_ie->ie_buffer;
	chan_switch->element_id = CHANNEL_SWITCH_ANN;
	chan_switch->len = 3;
	chan_switch->chan_switch_mode = block_tx;
	chan_switch->new_channel_num = channel;
	chan_switch->chan_switch_count = switch_count;
	DBG_HEXDUMP(MCMD_D, "CSA IE", (t_u8 *)pcust_chansw_ie->ie_buffer,
		    pcust_chansw_ie->ie_length);
	switch (band_width) {
	case CHANNEL_BW_40MHZ_ABOVE:
	case CHANNEL_BW_40MHZ_BELOW:
		bw = 40;
		break;
	case CHANNEL_BW_80MHZ:
		bw = 80;
		break;
	case CHANNEL_BW_160MHZ:
		bw = 160;
		break;
	default:
		bw = 20;
		break;
	}
	if (!new_oper_class && ecsa)
		woal_priv_get_nonglobal_operclass_by_bw_channel(priv, bw,
								channel,
								&new_oper_class);
	if (new_oper_class) {
		pcust_chansw_ie->ie_length +=
			sizeof(IEEEtypes_ExtChanSwitchAnn_t);
		ext_chan_switch =
			(IEEEtypes_ExtChanSwitchAnn_t *) (pcust_chansw_ie->
							  ie_buffer +
							  sizeof
							  (IEEEtypes_ChanSwitchAnn_t));
		ext_chan_switch->element_id = EXTEND_CHANNEL_SWITCH_ANN;
		ext_chan_switch->len = 4;
		ext_chan_switch->chan_switch_mode = block_tx;
		ext_chan_switch->new_oper_class = new_oper_class;
		ext_chan_switch->new_channel_num = channel;
		ext_chan_switch->chan_switch_count = switch_count;
		DBG_HEXDUMP(MCMD_D, "ECSA IE",
			    (t_u8 *)(pcust_chansw_ie->ie_buffer +
				     sizeof(IEEEtypes_ChanSwitchAnn_t)),
			    pcust_chansw_ie->ie_length -
			    sizeof(IEEEtypes_ChanSwitchAnn_t));
	}
	/* bandwidth 40/80/160 should set channel switch wrapper ie for 11ac 5G
	 * channel*/
	if (band_width && channel > 14) {
		pChanSwWrap_ie =
			(IEEEtypes_Header_t *)(pcust_chansw_ie->ie_buffer +
					       pcust_chansw_ie->ie_length);
		pChanSwWrap_ie->element_id = EXT_POWER_CONSTR;
		pChanSwWrap_ie->len = sizeof(IEEEtypes_WideBWChanSwitch_t);

		pbwchansw_ie = (IEEEtypes_WideBWChanSwitch_t
				*)((t_u8 *)pChanSwWrap_ie +
				   sizeof(IEEEtypes_Header_t));
		pbwchansw_ie->ieee_hdr.element_id = BW_CHANNEL_SWITCH;
		pbwchansw_ie->ieee_hdr.len =
			sizeof(IEEEtypes_WideBWChanSwitch_t) -
			sizeof(IEEEtypes_Header_t);

		center_freq_idx = woal_get_center_freq_idx(priv, BAND_AAC,
							   channel, band_width);
		if (band_width == CHANNEL_BW_40MHZ_ABOVE ||
		    band_width == CHANNEL_BW_40MHZ_BELOW) {
			pbwchansw_ie->new_channel_width = 0;
			pbwchansw_ie->new_channel_center_freq0 =
				center_freq_idx;
		} else if (band_width == CHANNEL_BW_80MHZ) {
			pbwchansw_ie->new_channel_width = 1;
			pbwchansw_ie->new_channel_center_freq0 =
				center_freq_idx - 4;
			pbwchansw_ie->new_channel_center_freq1 =
				center_freq_idx + 4;
		} else if (band_width == CHANNEL_BW_160MHZ) {
			pbwchansw_ie->new_channel_width = 2;
			pbwchansw_ie->new_channel_center_freq0 =
				center_freq_idx - 8;
			pbwchansw_ie->new_channel_center_freq1 =
				center_freq_idx + 8;
		} else
			PRINTM(MERROR,
			       "Invalid bandwidth.Support value 1/3/4/5 for 40+/40-/80/160MHZ\n");

		/*prepare the VHT Transmit Power Envelope IE */
		pvhttpcEnv_ie =
			(IEEEtypes_VhtTpcEnvelope_t
			 *)((t_u8 *)pChanSwWrap_ie +
			    sizeof(IEEEtypes_Header_t) +
			    sizeof(IEEEtypes_WideBWChanSwitch_t));
		pvhttpcEnv_ie->ieee_hdr.element_id = VHT_TX_POWER_ENV;
		pvhttpcEnv_ie->ieee_hdr.len =
			sizeof(IEEEtypes_VhtTpcEnvelope_t) -
			sizeof(IEEEtypes_Header_t);
		/* Local Max TX Power Count= 3,
		 * Local TX Power Unit Inter=EIP(0) */
		pvhttpcEnv_ie->tpc_info = 3;
		pvhttpcEnv_ie->local_max_tp_20mhz = 0xff;
		pvhttpcEnv_ie->local_max_tp_40mhz = 0xff;
		pvhttpcEnv_ie->local_max_tp_80mhz = 0xff;
		pvhttpcEnv_ie->local_max_tp_160mhz_80_80mhz = 0xff;
		pChanSwWrap_ie->len += sizeof(IEEEtypes_VhtTpcEnvelope_t);
		pcust_chansw_ie->ie_length +=
			pChanSwWrap_ie->len + sizeof(IEEEtypes_Header_t);
		DBG_HEXDUMP(MCMD_D, "Channel switch wrapper IE",
			    (t_u8 *)pChanSwWrap_ie,
			    pChanSwWrap_ie->len + sizeof(IEEEtypes_Header_t));
	}
	if (block_tx) {
		if (netif_carrier_ok(priv->netdev))
			netif_carrier_off(priv->netdev);
		woal_stop_queue(priv->netdev);
		priv->uap_tx_blocked = MTRUE;
	}

	status = woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		PRINTM(MERROR, "Failed to set ECSA IE\n");
		ret = -EFAULT;
		goto done;
	}

	priv->phandle->chsw_wait_q_woken = MFALSE;
	/* wait for channel switch to complete  */
	wait_event_interruptible_timeout(priv->phandle->chsw_wait_q,
					 priv->phandle->chsw_wait_q_woken,
					 (u32)HZ * (switch_count +
						    2) * 110 / 1000);

	pcust_chansw_ie->ie_index = 0xffff;	/*Auto index */
	pcust_chansw_ie->mgmt_subtype_mask = 0;
	status = woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		PRINTM(MERROR, "Failed to clear ECSA IE\n");
	}
done:
	if (status != MLAN_STATUS_PENDING)
		kfree(ioctl_req);

	LEAVE();
	return ret;

}
#endif

/**
 * @brief               Set/Get CFP table codes
 *
 * @param priv          Pointer to moal_private structure
 * @param respbuf       Pointer to response buffer
 * @param resplen       Response buffer length
 *
 * @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_cfp_code(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int ret = 0;
	int user_data_len = 0, header_len = 0;
	int data[2] = { 0 };
	mlan_ioctl_req *req = NULL;
	mlan_ds_misc_cfg *misc_cfg = NULL;
	mlan_ds_misc_cfp_code *cfp_code = NULL;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_CFP_CODE);

	/* Allocate an IOCTL request buffer */
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	/* Fill request buffer */
	misc_cfg = (mlan_ds_misc_cfg *)req->pbuf;
	cfp_code = &misc_cfg->param.cfp_code;
	misc_cfg->sub_command = MLAN_OID_MISC_CFP_CODE;
	req->req_id = MLAN_IOCTL_MISC_CFG;

	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		user_data_len = 0;
		req->action = MLAN_ACT_GET;
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len, data, ARRAY_SIZE(data),
				&user_data_len);
		if (user_data_len > 2) {
			PRINTM(MERROR, "Invalid number of args!\n");
			ret = -EINVAL;
			goto done;
		}
		cfp_code->cfp_code_bg = data[0];
		if (user_data_len == 2)
			cfp_code->cfp_code_a = data[1];
		req->action = MLAN_ACT_SET;
	}

	/* Send IOCTL request to MLAN */
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	if (!user_data_len) {
		data[0] = cfp_code->cfp_code_bg;
		data[1] = cfp_code->cfp_code_a;
		moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)data,
				sizeof(data), respbuflen);
		ret = sizeof(data);
	}

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);

	LEAVE();
	return ret;
}

/**
 * @brief               Set/Get Tx/Rx antenna
 *
 * @param priv          Pointer to moal_private structure
 * @param respbuf       Pointer to response buffer
 * @param resplen       Response buffer length
 *
 * @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_set_get_tx_rx_ant(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int ret = 0;
	int user_data_len = 0, header_len = 0;
	mlan_ds_radio_cfg *radio = NULL;
	mlan_ioctl_req *req = NULL;
	int data[3] = { 0 };
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_ANT_CFG);
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_radio_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}
	radio = (mlan_ds_radio_cfg *)req->pbuf;
	radio->sub_command = MLAN_OID_ANT_CFG;
	req->req_id = MLAN_IOCTL_RADIO_CFG;

	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		user_data_len = 0;
		req->action = MLAN_ACT_GET;
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len, data, ARRAY_SIZE(data),
				&user_data_len);
		if (user_data_len > 2) {
			PRINTM(MERROR, "Invalid number of args!\n");
			ret = -EINVAL;
			goto done;
		}
		if (priv->phandle->feature_control & FEATURE_CTRL_STREAM_2X2) {
			radio->param.ant_cfg.tx_antenna = data[0];
			radio->param.ant_cfg.rx_antenna = data[0];
			if (user_data_len == 2)
				radio->param.ant_cfg.rx_antenna = data[1];
#if defined(STA_CFG80211) || defined(UAP_CFG80211)
			if (IS_CARD9098(priv->phandle->card_type) ||
			    IS_CARD9097(priv->phandle->card_type)) {
				woal_cfg80211_notify_antcfg(priv,
							    priv->phandle->
							    wiphy, radio);
			}
#endif
		} else {
			radio->param.ant_cfg_1x1.antenna = data[0];
			if (user_data_len == 2)
				radio->param.ant_cfg_1x1.evaluate_time =
					data[1];
		}
		req->action = MLAN_ACT_SET;
	}
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}
	if (!user_data_len) {
		if (priv->phandle->feature_control & FEATURE_CTRL_STREAM_2X2) {
			data[0] = radio->param.ant_cfg.tx_antenna;
			data[1] = radio->param.ant_cfg.rx_antenna;
			if (data[0] && data[1])
				ret = sizeof(int) * 2;
			else
				ret = sizeof(int) * 1;
			moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)data,
					sizeof(data), respbuflen);
		} else {
			data[0] = (int)radio->param.ant_cfg_1x1.antenna;
			data[1] = (int)radio->param.ant_cfg_1x1.evaluate_time;
			data[2] = (int)radio->param.ant_cfg_1x1.current_antenna;
			moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)data,
					sizeof(data), respbuflen);
			ret = sizeof(data);
		}
	}
done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/*
 * @brief               Set/Get CWMode
 *
 * @param priv          Pointer to moal_private structure
 * @param respbuf       Pointer to response buffer
 * @param resplen       Response buffer length
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_set_get_cwmode(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	mlan_ioctl_req *ioctl_req = NULL;
	mlan_ds_misc_cfg *misc = NULL;
	mlan_status status = MLAN_STATUS_SUCCESS;
	mlan_ds_cw_mode_ctrl *cwmode;
	int ret = 0;
	int header_len = 0;

	ENTER();

	if (!priv || !priv->phandle) {
		PRINTM(MERROR, "priv or handle is null\n");
		ret = -EFAULT;
		goto done;
	}

	ioctl_req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (ioctl_req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	misc = (mlan_ds_misc_cfg *)ioctl_req->pbuf;
	misc->sub_command = MLAN_OID_MISC_CWMODE_CTRL;
	ioctl_req->req_id = MLAN_IOCTL_MISC_CFG;

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_CWMODE);
	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		ioctl_req->action = MLAN_ACT_GET;
	} else {
		/* SET operation */
		ioctl_req->action = MLAN_ACT_SET;

		cwmode = (mlan_ds_cw_mode_ctrl *) (respbuf + header_len +
						   sizeof(t_u8));
		misc->param.cwmode.mode = cwmode->mode;
		misc->param.cwmode.txPower = cwmode->txPower;
		misc->param.cwmode.rateInfo = cwmode->rateInfo;
		misc->param.cwmode.channel = cwmode->channel;
		misc->param.cwmode.chanInfo = cwmode->chanInfo;
		misc->param.cwmode.pktLength = cwmode->pktLength;
	}

	status = woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)&misc->param.cwmode,
			sizeof(misc->param.cwmode), respbuflen);
	ret = sizeof(misc->param.cwmode);

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(ioctl_req);

	LEAVE();
	return ret;
}

/**
 * @brief               Set/Get out band independent reset
 *
 * @param priv          Pointer to moal_private structure
 * @param respbuf       Pointer to response buffer
 * @param resplen       Response buffer length
 *
 * @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_ind_rst_cfg(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int ret = 0;
	int user_data_len = 0, header_len = 0;
	mlan_ds_misc_cfg *misc = NULL;
	mlan_ioctl_req *req = NULL;
	int data[2] = { 0 };
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_IND_RST_CFG);
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}
	misc = (mlan_ds_misc_cfg *)req->pbuf;
	memset(misc, 0, sizeof(mlan_ds_misc_cfg));
	misc->sub_command = MLAN_OID_MISC_IND_RST_CFG;
	req->req_id = MLAN_IOCTL_MISC_CFG;

	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		user_data_len = 0;
		req->action = MLAN_ACT_GET;
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len, data, ARRAY_SIZE(data),
				&user_data_len);
		if (user_data_len > 2) {
			PRINTM(MERROR, "Invalid number of args!\n");
			ret = -EINVAL;
			goto done;
		}

		if ((user_data_len == 1) || (user_data_len == 2)) {
			req->action = MLAN_ACT_SET;

			/* ir_mode */
			if (data[0] < 0 || data[0] > 2) {
				PRINTM(MERROR, "Invalid ir mode parameter!\n");
				ret = -EINVAL;
				goto done;
			}
			misc->param.ind_rst_cfg.ir_mode = data[0];

			/* gpio_pin */
			if (user_data_len == 2) {
				if ((data[1] != 0xFF) && (data[1] < 0)) {
					PRINTM(MERROR,
					       "Invalid gpio pin no!\n");
					ret = -EINVAL;
					goto done;
				}
				misc->param.ind_rst_cfg.gpio_pin = data[1];
			}
		}
	}
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	data[0] = (int)misc->param.ind_rst_cfg.ir_mode;
	data[1] = (int)misc->param.ind_rst_cfg.gpio_pin;
	moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)data, sizeof(data),
			respbuflen);
	ret = sizeof(data);

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 * @brief               Get/Set system clock
 * @param priv          Pointer to moal_private structure
 * @param respbuf       Pointer to response buffer
 * @param resplen       Response buffer length
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_sysclock(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int data[65];
	mlan_ioctl_req *req = NULL;
	mlan_ds_misc_cfg *cfg = NULL;
	int ret = 0, i = 0;
	int user_data_len = 0, header_len = 0;
	int data_length = 0, length_index = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_SYSCLOCK);
	memset(data, 0, sizeof(data));
	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		user_data_len = 0;
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len, data, ARRAY_SIZE(data),
				&user_data_len);
	}

	if (user_data_len > MLAN_MAX_CLK_NUM) {
		PRINTM(MERROR, "Invalid number of parameters\n");
		ret = -EINVAL;
		goto done;
	}
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	cfg = (mlan_ds_misc_cfg *)req->pbuf;
	cfg->sub_command = MLAN_OID_MISC_SYS_CLOCK;
	req->req_id = MLAN_IOCTL_MISC_CFG;

	if (user_data_len) {
		/* SET operation */
		req->action = MLAN_ACT_SET;

		/* Set configurable clocks */
		cfg->param.sys_clock.sys_clk_type = MLAN_CLK_CONFIGURABLE;
		cfg->param.sys_clock.sys_clk_num =
			MIN(MLAN_MAX_CLK_NUM, user_data_len);
		for (i = 0; i < cfg->param.sys_clock.sys_clk_num; i++)
			cfg->param.sys_clock.sys_clk[i] = (t_u16)data[i];

		status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
		if (status != MLAN_STATUS_SUCCESS) {
			ret = -EFAULT;
			goto done;
		}
	} else {
		/* GET operation */
		req->action = MLAN_ACT_GET;

		/* Get configurable clocks */
		cfg->param.sys_clock.sys_clk_type = MLAN_CLK_CONFIGURABLE;
		status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
		if (status != MLAN_STATUS_SUCCESS) {
			ret = -EFAULT;
			goto done;
		}

		/* Current system clock */
		data[1] = (int)cfg->param.sys_clock.cur_sys_clk;
		data_length = 1;

		length_index =
			MIN(cfg->param.sys_clock.sys_clk_num, MLAN_MAX_CLK_NUM);

		/* Configurable clocks */
		for (i = 1; i <= length_index; i++)
			data[i + data_length] =
				(int)cfg->param.sys_clock.sys_clk[i - 1];

		data_length += length_index;

		/* Get supported clocks */
		cfg->param.sys_clock.sys_clk_type = MLAN_CLK_SUPPORTED;
		status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
		if (status != MLAN_STATUS_SUCCESS) {
			ret = -EFAULT;
			goto done;
		}

		length_index =
			MIN(cfg->param.sys_clock.sys_clk_num, MLAN_MAX_CLK_NUM);

		/* Supported clocks */
		for (i = 1; i <= length_index; i++)
			data[i + data_length] =
				(int)cfg->param.sys_clock.sys_clk[i - 1];

		data_length += length_index;

		/* Send length as first element */
		data[0] = data_length;
		data_length++;

		moal_memcpy_ext(priv->phandle, respbuf, data,
				sizeof(int) * data_length, respbuflen);
		ret = data_length * sizeof(int);
	}

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 * @brief               Get GTK/PTK
 * @param priv          Pointer to moal_private structure
 * @param respbuf       Pointer to response buffer
 * @param resplen       Response buffer length
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_get_key(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int ret = 0, copy_len = 0;
	int header_len = 0;
	unsigned int i;
	t_u8 key_ascii[256];
	t_u8 *tmp;
	mlan_ds_sec_cfg *sec = NULL;
	mlan_ioctl_req *req = NULL;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_GET_KEY);
	if ((int)strlen(respbuf) != header_len) {
		PRINTM(MERROR, "Invalid number of parameters\n");
		ret = -EINVAL;
		goto done;
	}
	memset(key_ascii, 0x00, sizeof(key_ascii));
	tmp = key_ascii;

	if (priv->media_connected == MFALSE) {
		PRINTM(MERROR, "Can't get key in un-associated state\n");
		ret = -EFAULT;
		goto done;
	}

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_sec_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	/* Get Unicast Key */
	req->req_id = MLAN_IOCTL_SEC_CFG;
	req->action = MLAN_ACT_GET;
	sec = (mlan_ds_sec_cfg *)req->pbuf;
	sec->sub_command = MLAN_OID_SEC_QUERY_KEY;
	sec->param.encrypt_key.key_index = 0;
	sec->param.encrypt_key.key_flags = 0;
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}
	if (sec->param.encrypt_key.key_len) {
		sprintf((char *)tmp, "\n%s", "PTK: ");
		tmp += 5;
		for (i = 0; i < sec->param.encrypt_key.key_len; i++)
			tmp += sprintf((char *)tmp, "%02x",
				       sec->param.encrypt_key.key_material[i]);
	}

	/* Get Multicase Key */
	req->req_id = MLAN_IOCTL_SEC_CFG;
	req->action = MLAN_ACT_GET;
	sec = (mlan_ds_sec_cfg *)req->pbuf;
	sec->sub_command = MLAN_OID_SEC_QUERY_KEY;
	sec->param.encrypt_key.key_index = 0;
	sec->param.encrypt_key.key_flags = KEY_FLAG_GROUP_KEY;
	memset(sec->param.encrypt_key.mac_addr, 0x0, MLAN_MAC_ADDR_LENGTH);
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}
	if (sec->param.encrypt_key.key_len) {
		sprintf((char *)tmp, "\n%s", "GTK: ");
		tmp += 5;
		for (i = 0; i < sec->param.encrypt_key.key_len; i++)
			tmp += sprintf((char *)tmp, "%02x",
				       sec->param.encrypt_key.key_material[i]);
	}

	/* Get IGTK Key */
	req->req_id = MLAN_IOCTL_SEC_CFG;
	req->action = MLAN_ACT_GET;
	sec = (mlan_ds_sec_cfg *)req->pbuf;
	sec->sub_command = MLAN_OID_SEC_QUERY_KEY;
	sec->param.encrypt_key.key_index = 0;
	sec->param.encrypt_key.key_flags = KEY_FLAG_AES_MCAST_IGTK;
	memset(sec->param.encrypt_key.mac_addr, 0x0, MLAN_MAC_ADDR_LENGTH);
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}
	if (sec->param.encrypt_key.key_len) {
		sprintf((char *)tmp, "\n%s", "IGTK: ");
		tmp += 6;
		for (i = 0; i < sec->param.encrypt_key.key_len; i++)
			tmp += sprintf((char *)tmp, "%02x",
				       sec->param.encrypt_key.key_material[i]);
	}

	copy_len = tmp - key_ascii;
	moal_memcpy_ext(priv->phandle, respbuf, &key_ascii, copy_len,
			respbuflen);
	ret = copy_len;
done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);

	LEAVE();
	return ret;
}

/**
 * @brief               Associate to a specific indexed entry in the ScanTable
 * @param priv          Pointer to moal_private structure
 * @param respbuf       Pointer to response buffer
 * @param resplen       Response buffer length
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_associate_ssid_bssid(moal_private *priv, t_u8 *respbuf,
			       t_u32 respbuflen)
{
	int ret = 0, copy_len = 0;
	int header_len = 0;
	mlan_ssid_bssid ssid_bssid;
#ifdef REASSOCIATION
	mlan_bss_info bss_info;
#endif
	char buf[64];
	t_u8 buflen;
	t_u8 mac_idx;
	t_u8 i;

	ENTER();

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_ASSOCIATE);
	if ((int)strlen(respbuf) == header_len) {
		PRINTM(MERROR, "Invalid number of parameters\n");
		ret = -EINVAL;
		goto done;
	}
	copy_len = strlen(respbuf) - header_len;
	mac_idx = 0;
	buflen = MIN(copy_len, (int)(sizeof(buf) - 1));
	memset(buf, 0, sizeof(buf));
	memset(&ssid_bssid, 0, sizeof(ssid_bssid));

	if (buflen < (3 * ETH_ALEN) + 2) {
		PRINTM(MERROR,
		       "Associate: Insufficient length in IOCTL input\n");

		/* buffer should be at least 3 characters per BSSID octet "00:"
		 **   plus a space separater and at least 1 char in the SSID
		 */
		ret = -EINVAL;
		goto done;
	}

	moal_memcpy_ext(priv->phandle, buf, respbuf + header_len, buflen,
			sizeof(buf));

	/* Skip white space */
	for (i = 0; (i < buflen) && (buf[i] == ' '); i++) ;

	/* Copy/Convert the BSSID */
	for (; (i < buflen) && (mac_idx < ETH_ALEN) && (buf[i] != ' '); i++) {
		if (buf[i] == ':') {
			mac_idx++;
		} else {
			ssid_bssid.bssid[mac_idx] = (t_u8)woal_atox(buf + i);

			while (((i < buflen) && isxdigit(buf[i + 1])))
				/* Skip entire hex value */
				i++;
		}
	}

	/* Skip one space between the BSSID and start of the SSID */
	i++;

	/* Copy the SSID */
	ssid_bssid.ssid.ssid_len = buflen - i;
	moal_memcpy_ext(priv->phandle, ssid_bssid.ssid.ssid, buf + i,
			sizeof(ssid_bssid.ssid.ssid),
			sizeof(ssid_bssid.ssid.ssid));

	PRINTM(MCMND, "iwpriv assoc: AP=[" MACSTR "], ssid(%d)=[%s]\n",
	       MAC2STR(ssid_bssid.bssid), (int)ssid_bssid.ssid.ssid_len,
	       ssid_bssid.ssid.ssid);

	if (MLAN_STATUS_SUCCESS !=
	    woal_bss_start(priv, MOAL_IOCTL_WAIT, &ssid_bssid)) {
		ret = -EFAULT;
		goto done;
	}
#ifdef REASSOCIATION
	memset(&bss_info, 0x00, sizeof(bss_info));
	if (MLAN_STATUS_SUCCESS ==
	    woal_get_bss_info(priv, MOAL_IOCTL_WAIT, &bss_info)) {
		moal_memcpy_ext(priv->phandle, &priv->prev_ssid_bssid.ssid,
				&bss_info.ssid, sizeof(mlan_802_11_ssid),
				sizeof(mlan_802_11_ssid));
		moal_memcpy_ext(priv->phandle, &priv->prev_ssid_bssid.bssid,
				&bss_info.bssid, MLAN_MAC_ADDR_LENGTH,
				sizeof(mlan_802_11_mac_addr));
	}
#endif /* REASSOCIATION */

done:
	LEAVE();
	return ret;
}

/* Maximum input output characters in group WOAL_SET_GET_256_CHAR */
#define MAX_IN_OUT_CHAR 256
/** Tx BF Global conf argument index */
#define BF_ENABLE_PARAM 1
#define SOUND_ENABLE_PARAM 2
#define FB_TYPE_PARAM 3
#define SNR_THRESHOLD_PARAM 4
#define SOUND_INTVL_PARAM 5
#define BF_MODE_PARAM 6
#define BF_CFG_ACT_GET 0
#define BF_CFG_ACT_SET 1

/**
 * @brief               Set/Get Transmit beamforming configuration
 * @param priv          Pointer to moal_private structure
 * @param respbuf       Pointer to response buffer
 * @param resplen       Response buffer length
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_tx_bf_cfg(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int header_len = 0;
	int ret = 0, copy_len = 0;
	int bf_action = 0, interval = 0;
	int snr = 0, i, tmp_val = 0;
	t_u8 buf[MAX_IN_OUT_CHAR], char_count = 0;
	t_u8 *str, *token, *pos;
	t_u16 action = 0;

	mlan_ds_11n_tx_bf_cfg bf_cfg;
	mlan_trigger_sound_args *bf_sound = NULL;
	mlan_tx_bf_peer_args *tx_bf_peer = NULL;
	mlan_snr_thr_args *bf_snr = NULL;
	mlan_bf_periodicity_args *bf_periodicity = NULL;
	mlan_bf_global_cfg_args *bf_global = NULL;

	ENTER();

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_TX_BF_CFG);
	if ((int)strlen(respbuf) == header_len) {
		PRINTM(MERROR, "Invalid number of parameters\n");
		ret = -EINVAL;
		goto done;
	}
	memset(&bf_cfg, 0, sizeof(bf_cfg));
	/* Pointer to corresponding buffer */
	bf_sound = bf_cfg.body.bf_sound;
	tx_bf_peer = bf_cfg.body.tx_bf_peer;
	bf_snr = bf_cfg.body.bf_snr;
	bf_periodicity = bf_cfg.body.bf_periodicity;
	bf_global = &bf_cfg.body.bf_global_cfg;

	/* Total characters in buffer */
	char_count = strlen(respbuf) - header_len;
	copy_len = char_count;
	memset(buf, 0, sizeof(buf));
	if (char_count) {
		if (copy_len > (int)sizeof(buf)) {
			PRINTM(MERROR, "Too many arguments\n");
			ret = -EINVAL;
			goto done;
		}
		moal_memcpy_ext(priv->phandle, buf, respbuf + header_len,
				copy_len, sizeof(buf));

		if (char_count > 1 && buf[1] != ';') {
			PRINTM(MERROR,
			       "No action argument. Separate with ';'\n");
			ret = -EINVAL;
			goto done;
		}
		/* Replace ';' with NULL in the string to separate args */
		for (i = 0; i < char_count; i++) {
			if (buf[i] == ';')
				buf[i] = '\0';
		}
		/* The first byte represents the beamforming action */
		if (woal_atoi(&bf_action, &buf[0]) != MLAN_STATUS_SUCCESS) {
			ret = -EINVAL;
			goto done;
		}
		switch (bf_action) {
		case BF_GLOBAL_CONFIGURATION:
			if (char_count == 1) {
				action = MLAN_ACT_GET;
				bf_cfg.action = BF_CFG_ACT_GET;
			} else {
				action = MLAN_ACT_SET;
				bf_cfg.action = BF_CFG_ACT_SET;
				/* Eliminate action field */
				token = &buf[2];
				for (i = 1, str = &buf[2]; token != NULL; i++) {
					token = strstr(str, " ");
					pos = str;
					if (token != NULL) {
						*token = '\0';
						str = token + 1;
					}
					woal_atoi(&tmp_val, pos);
					switch (i) {
					case BF_ENABLE_PARAM:
						bf_global->bf_enbl =
							(t_u8)tmp_val;
						break;
					case SOUND_ENABLE_PARAM:
						bf_global->sounding_enbl =
							(t_u8)tmp_val;
						break;
					case FB_TYPE_PARAM:
						bf_global->fb_type =
							(t_u8)tmp_val;
						break;
					case SNR_THRESHOLD_PARAM:
						bf_global->snr_threshold =
							(t_u8)tmp_val;
						break;
					case SOUND_INTVL_PARAM:
						bf_global->sounding_interval =
							(t_u16)tmp_val;
						break;
					case BF_MODE_PARAM:
						bf_global->bf_mode =
							(t_u8)tmp_val;
						break;
					default:
						PRINTM(MERROR,
						       "Invalid Argument\n");
						ret = -EINVAL;
						goto done;
					}
				}
			}
			break;
		case TRIGGER_SOUNDING_FOR_PEER:
			/* First arg  = 2   BfAction
			 * Second arg = 17  MAC "00:50:43:20:BF:64" */
			if (char_count != 19) {
				PRINTM(MERROR, "Invalid argument\n");
				ret = -EINVAL;
				goto done;
			}
			woal_mac2u8(bf_sound->peer_mac, &buf[2]);
			action = MLAN_ACT_SET;
			bf_cfg.action = BF_CFG_ACT_SET;
			break;
		case SET_GET_BF_PERIODICITY:
			/* First arg  = 2   BfAction
			 * Second arg = 18  MAC "00:50:43:20:BF:64;"
			 * Third arg =  1  (min char)  TX BF interval
			 *              10 (max char)  u32 maximum value
			 * 4294967295 */
			if (char_count < 19 || char_count > 30) {
				PRINTM(MERROR, "Invalid argument\n");
				ret = -EINVAL;
				goto done;
			}

			woal_mac2u8(bf_periodicity->peer_mac, &buf[2]);
			if (char_count == 19) {
				action = MLAN_ACT_GET;
				bf_cfg.action = BF_CFG_ACT_GET;
			} else {
				action = MLAN_ACT_SET;
				bf_cfg.action = BF_CFG_ACT_SET;
				if (woal_atoi(&interval, &buf[20]) !=
				    MLAN_STATUS_SUCCESS) {
					ret = -EINVAL;
					goto done;
				}
				bf_periodicity->interval = interval;
			}
			break;
		case TX_BF_FOR_PEER_ENBL:
			/* Handle only SET operation here
			 * First arg  = 2   BfAction
			 * Second arg = 18  MAC "00:50:43:20:BF:64;"
			 * Third arg  = 2   enable/disable bf
			 * Fourth arg = 2   enable/disable sounding
			 * Fifth arg  = 1   FB Type */
			if (char_count != 25 && char_count != 1) {
				PRINTM(MERROR, "Invalid argument\n");
				ret = -EINVAL;
				goto done;
			}
			if (char_count == 1) {
				action = MLAN_ACT_GET;
				bf_cfg.action = BF_CFG_ACT_GET;
			} else {
				woal_mac2u8(tx_bf_peer->peer_mac, &buf[2]);
				woal_atoi(&tmp_val, &buf[20]);
				tx_bf_peer->bf_enbl = (t_u8)tmp_val;
				woal_atoi(&tmp_val, &buf[22]);
				tx_bf_peer->sounding_enbl = (t_u8)tmp_val;
				woal_atoi(&tmp_val, &buf[24]);
				tx_bf_peer->fb_type = (t_u8)tmp_val;
				action = MLAN_ACT_SET;
				bf_cfg.action = BF_CFG_ACT_SET;
			}
			break;
		case SET_SNR_THR_PEER:
			/* First arg  = 2   BfAction
			 * Second arg = 18  MAC "00:50:43:20:BF:64;"
			 * Third arg  = 1/2 SNR u8 - can be 1/2 charerters */
			if (char_count != 1 &&
			    !(char_count == 21 || char_count == 22)) {
				PRINTM(MERROR, "Invalid argument\n");
				ret = -EINVAL;
				goto done;
			}
			if (char_count == 1) {
				action = MLAN_ACT_GET;
				bf_cfg.action = BF_CFG_ACT_GET;
			} else {
				woal_mac2u8(bf_snr->peer_mac, &buf[2]);
				if (woal_atoi(&snr, &buf[20]) !=
				    MLAN_STATUS_SUCCESS) {
					ret = -EINVAL;
					goto done;
				}
				bf_snr->snr = snr;
				action = MLAN_ACT_SET;
				bf_cfg.action = BF_CFG_ACT_SET;
			}
			break;
		default:
			ret = -EINVAL;
			goto done;
		}

		/* Save the value */
		bf_cfg.bf_action = bf_action;
		if (MLAN_STATUS_SUCCESS !=
		    woal_set_get_tx_bf_cfg(priv, action, &bf_cfg)) {
			ret = -EFAULT;
			goto done;
		}
	} else {
		ret = -EINVAL;
		goto done;
	}

	switch (bf_action) {
	case BF_GLOBAL_CONFIGURATION:
		moal_memcpy_ext(priv->phandle, respbuf, bf_global,
				sizeof(mlan_bf_global_cfg_args), respbuflen);
		ret = sizeof(mlan_bf_global_cfg_args);
		break;
	case TRIGGER_SOUNDING_FOR_PEER:
		moal_memcpy_ext(priv->phandle, respbuf, bf_sound,
				sizeof(mlan_bf_global_cfg_args), respbuflen);
		ret = sizeof(mlan_bf_global_cfg_args);
		break;
	case SET_GET_BF_PERIODICITY:
		moal_memcpy_ext(priv->phandle, respbuf, bf_periodicity,
				sizeof(mlan_bf_periodicity_args), respbuflen);
		ret = sizeof(mlan_bf_periodicity_args);
		break;
	case TX_BF_FOR_PEER_ENBL:
		moal_memcpy_ext(priv->phandle, respbuf, tx_bf_peer,
				sizeof(mlan_tx_bf_peer_args), respbuflen);
		ret = sizeof(mlan_tx_bf_peer_args);
		break;
	case SET_SNR_THR_PEER:
		moal_memcpy_ext(priv->phandle, respbuf, bf_snr,
				sizeof(mlan_snr_thr_args), respbuflen);
		ret = sizeof(mlan_snr_thr_args);
		break;
	default:
		ret = 0;
	}

done:
	LEAVE();
	return ret;
}

#ifdef SDIO
/**
 * @brief               Cmd53 read/write register
 * @param priv          Pointer to moal_private structure
 * @param respbuf       Pointer to response buffer
 * @param resplen       Response buffer length
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_cmd53rdwr(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int header_len = 0;
	int ret = 0;
	t_u8 *buf = NULL;
	t_u8 *data = NULL;
	t_u8 rw, mode;
	t_u16 blklen = 0, blknum = 0;
	int reg = 0;
	t_u32 pattern_len = 0, total_len = 0;
	t_u16 cmd_len;
	gfp_t flag;

	ENTER();

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_SD_CMD53_RW);

	flag = (in_atomic() || irqs_disabled())? GFP_ATOMIC : GFP_KERNEL;
	data = kzalloc(WOAL_2K_BYTES, flag);
	if (!data) {
		PRINTM(MERROR, "Cannot allocate buffer for command!\n");
		ret = -EFAULT;
		goto done;
	}
	moal_memcpy_ext(priv->phandle, &cmd_len, respbuf + header_len,
			sizeof(cmd_len), sizeof(cmd_len));
	buf = respbuf + header_len + sizeof(cmd_len);

	rw = buf[0];		/* read/write (0/1) */
	reg = buf[5];		/* address */
	reg = (reg << 8) | buf[4];
	reg = (reg << 8) | buf[3];
	reg = (reg << 8) | buf[2];
	mode = buf[6];		/* byte mode/block mode (0/1) */
	blklen = buf[8];	/* block size */
	blklen = (blklen << 8) | buf[7];
	blknum = buf[10];	/* block number or byte number */
	blknum = (blknum << 8) | buf[9];

	if (mode == BYTE_MODE)
		blklen = 1;
	else
		mode = BLOCK_MODE;

	total_len = (mode == BLOCK_MODE) ? blknum * blklen : blknum;
	if (total_len > WOAL_2K_BYTES) {
		PRINTM(MERROR, "Total data length is too large!\n");
		ret = -EINVAL;
		goto done;
	}
	PRINTM(MINFO,
	       "CMD53 read/write, addr = %#x, mode = %d, "
	       "block size = %d, block(byte) number = %d\n",
	       reg, mode, blklen, blknum);

	if (!rw) {
		sdio_claim_host(((struct sdio_mmc_card *)priv->phandle->card)->
				func);
		if (sdio_readsb
		    (((struct sdio_mmc_card *)priv->phandle->card)->func,
		     respbuf, reg, total_len)) {
			PRINTM(MERROR,
			       "sdio_readsb: reading memory 0x%x failed\n",
			       reg);
			goto done;
		}
		sdio_release_host(((struct sdio_mmc_card *)priv->phandle->
				   card)->func);
		ret = total_len;
	} else {
		int pos = 0;
		pattern_len = cmd_len - 11;
		if (pattern_len > total_len)
			pattern_len = total_len;

		/* Copy/duplicate the pattern to data buffer */
		for (pos = 0; pos < (int)total_len; pos++)
			data[pos] = buf[11 + (pos % pattern_len)];
		sdio_claim_host(((struct sdio_mmc_card *)priv->phandle->card)->
				func);
		if (sdio_writesb
		    (((struct sdio_mmc_card *)priv->phandle->card)->func, reg,
		     data, total_len))
			PRINTM(MERROR,
			       "sdio_writesb: writing memory 0x%x failed\n",
			       reg);
		sdio_release_host(((struct sdio_mmc_card *)priv->phandle->
				   card)->func);
	}

done:
	kfree(data);
	LEAVE();
	return ret;
}
#endif /* SDIO */

/**
 * @brief               Set/Get Port Control mode
 * @param priv          Pointer to moal_private structure
 * @param respbuf       Pointer to response buffer
 * @param resplen       Response buffer length
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_port_ctrl(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int header_len = 0, user_data_len = 0;
	mlan_ioctl_req *req = NULL;
	mlan_ds_sec_cfg *sec = NULL;
	int ret = 0, data = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;
	ENTER();

	/* Allocate an IOCTL request buffer */
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_sec_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	/* Fill request buffer */
	sec = (mlan_ds_sec_cfg *)req->pbuf;
	sec->sub_command = MLAN_OID_SEC_CFG_PORT_CTRL_ENABLED;
	req->req_id = MLAN_IOCTL_SEC_CFG;

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_PORT_CTRL);
	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		user_data_len = 0;
		req->action = MLAN_ACT_GET;
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len, &data,
				sizeof(data) / sizeof(int), &user_data_len);
		if (user_data_len == 1) {
			sec->param.port_ctrl_enabled = data;
			req->action = MLAN_ACT_SET;
		} else {
			PRINTM(MERROR, "Invalid number of parameters\n");
			ret = -EINVAL;
			goto done;
		}
	}

	/* Send IOCTL request to MLAN */
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	if (!user_data_len) {
		moal_memcpy_ext(priv->phandle, respbuf,
				&sec->param.port_ctrl_enabled, sizeof(int),
				respbuflen);
		ret = sizeof(int);
	}

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);

	LEAVE();
	return ret;
}

/**
 * @brief               Private IOCTL entry to get the By-passed TX packet from
 * upper layer
 * @param priv          Pointer to moal_private structure
 * @param respbuf       Pointer to response buffer
 * @param resplen       Response buffer length
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_bypassed_packet(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int header_len = 0;
	int ret = 0;
	struct sk_buff *skb = NULL;
	struct ethhdr *eth;
	t_u16 moreLen = 0, copyLen = 0;
	ENTER();

#define MLAN_BYPASS_PKT_EXTRA_OFFSET (4)

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_PB_BYPASS);
	copyLen = strlen(respbuf) - header_len;
	moreLen = MLAN_MIN_DATA_HEADER_LEN + MLAN_BYPASS_PKT_EXTRA_OFFSET +
		sizeof(mlan_buffer);

	skb = alloc_skb(copyLen + moreLen, GFP_KERNEL);
	if (skb == NULL) {
		PRINTM(MERROR, "kmalloc no memory !!\n");
		LEAVE();
		return -ENOMEM;
	}

	skb_reserve(skb, moreLen);

	moal_memcpy_ext(priv->phandle, skb_put(skb, copyLen),
			respbuf + header_len, copyLen, copyLen);

	eth = (struct ethhdr *)skb->data;
	eth->h_proto = __constant_htons(eth->h_proto);
	skb->dev = priv->netdev;

	HEXDUMP("Bypass TX Data", skb->data, MIN(skb->len, 100));

	woal_hard_start_xmit(skb, priv->netdev);

	LEAVE();
	return ret;
}

/**
 * @brief               Set Robustcoex gpiocfg
 * @param priv          Pointer to moal_private structure
 * @param respbuf       Pointer to response buffer
 * @param resplen       Response buffer length
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_robustcoex(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int header_len = 0, user_data_len = 0;
	int ret = 0, data[3] = { 0 };
	mlan_ds_misc_cfg *robust_coex_cfg = NULL;
	mlan_ioctl_req *req = NULL;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}
	robust_coex_cfg = (mlan_ds_misc_cfg *)req->pbuf;
	while (respbuf[0] == ' ') {
		/** skip space */
		respbuf++;
	}

	if (strncmp(respbuf, "gpiocfg", strlen("gpiocfg")) == 0) {
		header_len = strlen("gpiocfg") + 1;
		parse_arguments(respbuf + header_len, data,
				sizeof(data) / sizeof(int), &user_data_len);
		if (user_data_len > 3) {
			PRINTM(MERROR, "Invalid parameter number\n");
			ret = -EINVAL;
			goto done;
		}
		if (data[0] != ROBUSTCOEX_GPIOCFG_ENABLE &&
		    data[0] != ROBUSTCOEX_GPIOCFG_DISABLE) {
			PRINTM(MERROR, "Invalid parameter number\n");
			ret = -EINVAL;
			goto done;
		}
		if (data[0] == ROBUSTCOEX_GPIOCFG_ENABLE) {
			if (user_data_len != 3) {
				PRINTM(MMSG,
				       "Please provide gpio num and gpio polarity for ROBUSTCOEX_GPIOCFG_ENABLE\n");
				ret = -EINVAL;
				goto done;
			}
			robust_coex_cfg->param.robustcoexparams.method =
				ROBUSTCOEX_GPIO_CFG;
			robust_coex_cfg->param.robustcoexparams.enable =
				ROBUSTCOEX_GPIOCFG_ENABLE;
			robust_coex_cfg->param.robustcoexparams.gpio_num =
				data[1];
			robust_coex_cfg->param.robustcoexparams.gpio_polarity =
				data[2];
		} else {
			robust_coex_cfg->param.robustcoexparams.method =
				ROBUSTCOEX_GPIO_CFG;
			robust_coex_cfg->param.robustcoexparams.enable =
				ROBUSTCOEX_GPIOCFG_DISABLE;
			robust_coex_cfg->param.robustcoexparams.gpio_num = 0;
			robust_coex_cfg->param.robustcoexparams.gpio_polarity =
				0;
		}
		req->action = MLAN_ACT_SET;
		req->req_id = MLAN_IOCTL_MISC_CFG;
		robust_coex_cfg->sub_command = MLAN_OID_MISC_ROBUSTCOEX;
	} else {
		PRINTM(MERROR, "Invalid parameter\n");
		ret = -EFAULT;
		goto done;
	}
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 * @brief               Set DMCS mapping policy or get DMCS status
 * @param priv          Pointer to moal_private structure
 * @param respbuf       Pointer to response buffer
 * @param resplen       Response buffer length
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_dmcs(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int header_len = 0, user_data_len = 0;
	int ret = 0, data[2] = { 0 };
	mlan_ds_misc_cfg *dmcs_cfg = NULL;
	mlan_ioctl_req *req = NULL;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}
	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_DMCS);
	dmcs_cfg = (mlan_ds_misc_cfg *)req->pbuf;
	parse_arguments(respbuf + header_len, data, ARRAY_SIZE(data),
			&user_data_len);
	if (user_data_len > 2) {
		PRINTM(MERROR, "Invalid number of args! %d\n", user_data_len);
		ret = -EINVAL;
		goto done;
	}
	req->req_id = MLAN_IOCTL_MISC_CFG;
	dmcs_cfg->sub_command = MLAN_OID_MISC_DMCS_CONFIG;
	dmcs_cfg->param.dmcs_policy.subcmd = data[0];
	switch (data[0]) {
	case 0:
		if (user_data_len != 2) {
			PRINTM(MERROR, "Please provide mapping policy\n");
			ret = -EINVAL;
			goto done;
		}
		req->action = MLAN_ACT_SET;
		dmcs_cfg->param.dmcs_policy.mapping_policy = data[1];
		break;
	case 1:
		req->action = MLAN_ACT_GET;
		break;
	default:
		break;
	}

	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}
	if (req->action == MLAN_ACT_GET) {
		moal_memcpy_ext(priv->phandle, respbuf,
				&dmcs_cfg->param.dmcs_status,
				sizeof(mlan_ds_misc_dmcs_status), respbuflen);
	}
	ret = sizeof(mlan_ds_misc_dmcs_status);
done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 * @brief               Set and get boot sleep configure
 * @param priv          Pointer to moal_private structure
 * @param respbuf       Pointer to response buffer
 * @param resplen       Response buffer length
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_bootsleep(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int ret = MLAN_STATUS_SUCCESS;
	int user_data_len = 0;
	int header_len = 0;
	int allowed = 1;
	int data[1] = { 0 };
	mlan_ioctl_req *req = NULL;
	mlan_ds_misc_cfg *misc = NULL;

	ENTER();

	if (!priv || !priv->phandle) {
		PRINTM(MERROR, "priv or handle is null\n");
		ret = -EFAULT;
		goto done;
	}

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (req == NULL) {
		LEAVE();
		return -ENOMEM;
	}

	misc = (mlan_ds_misc_cfg *)req->pbuf;
	misc->sub_command = MLAN_OID_MISC_BOOT_SLEEP;
	req->req_id = MLAN_IOCTL_MISC_CFG;

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_BOOTSLEEP);

	if ((int)strlen(respbuf) == header_len) {
		req->action = MLAN_ACT_GET;
	} else {
		req->action = MLAN_ACT_SET;
		parse_arguments(respbuf + header_len, data, ARRAY_SIZE(data),
				&user_data_len);
		if (user_data_len != allowed) {
			PRINTM(MERROR, "Invalid number of args! %d\n",
			       user_data_len);
			ret = -EINVAL;
			goto done;
		}
		misc->param.boot_sleep = data[0] ? 1 : 0;
		PRINTM(MIOCTL, "boot sleep cfg:%u\n", misc->param.boot_sleep);
	}

	ret = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT_TIMEOUT);
	if (ret != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	moal_memcpy_ext(priv->phandle, respbuf, &misc->param.boot_sleep,
			sizeof(misc->param.boot_sleep), respbuflen);
	ret = sizeof(misc->param.boot_sleep);

	PRINTM(MIOCTL, "boot sleep cfg: %u\n", misc->param.boot_sleep);

done:
	if (ret != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

#if defined(PCIE)
/**
 * @brief               Enable SSU support
 * @param priv          Pointer to moal_private structure
 * @param used_len 		used length
 * @param respbuf       Pointer to response buffer
 * @param resplen       Response buffer length
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_ssu_cmd(moal_private *priv, t_u8 used_len, t_u8 *respbuf,
		  t_u32 respbuflen)
{
	int ret = 0;
	mlan_ds_misc_cfg *ssu_cfg = NULL;
	mlan_ioctl_req *req = NULL;
	ssu_params_cfg *ssu_params;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}
	ssu_cfg = (mlan_ds_misc_cfg *)req->pbuf;
	memset(&ssu_cfg->param.ssu_params, 0, sizeof(mlan_ds_ssu_params));
	if (!used_len) {
		req->action = MLAN_ACT_SET;
		ssu_cfg->param.ssu_params.nskip = 0;
		ssu_cfg->param.ssu_params.nsel = 1;
		ssu_cfg->param.ssu_params.adcdownsample = 3;
		ssu_cfg->param.ssu_params.mask_adc_pkt = 0;
		ssu_cfg->param.ssu_params.out_16bits = 1;
	} else {
		ssu_params = (ssu_params_cfg *) respbuf;
		DBG_HEXDUMP(MCMD_D, "User SSU params:", respbuf,
			    sizeof(mlan_ds_ssu_params));
		if (ssu_params->ssu_mode == 2)
			req->action = MLAN_ACT_DEFAULT;
		else {
			req->action = MLAN_ACT_SET;
			ssu_cfg->param.ssu_params.nskip = ssu_params->nskip;
			ssu_cfg->param.ssu_params.nsel = ssu_params->nsel;
			ssu_cfg->param.ssu_params.adcdownsample =
				ssu_params->adcdownsample;
			ssu_cfg->param.ssu_params.mask_adc_pkt =
				ssu_params->mask_adc_pkt;
			ssu_cfg->param.ssu_params.out_16bits =
				ssu_params->out_16bits;
			ssu_cfg->param.ssu_params.spec_pwr_enable =
				ssu_params->spec_pwr_enable;
			ssu_cfg->param.ssu_params.rate_deduction =
				ssu_params->rate_deduction;
			ssu_cfg->param.ssu_params.n_pkt_avg =
				ssu_params->n_pkt_avg;
		}
	}
	req->req_id = MLAN_IOCTL_MISC_CFG;
	ssu_cfg->sub_command = MLAN_OID_MISC_SSU;

	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}
#endif

/**
 * @brief               Configure the hal/phy cfg params
 *
 *  The command structure contains the following parameters
 *      dot11b_psd_mask: 1: enable, 0: disable
 *      Reserved : reserved 7 params for future such use
 *
 *  @param priv    Pointer to the mlan_private driver data struct
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return         Number of bytes written if successful else negative value
 */
static int
woal_priv_hal_phy_cfg_cmd(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	mlan_ioctl_req *req = NULL;
	mlan_ds_misc_cfg *cfg = NULL;
	int ret = 0;
	mlan_ds_hal_phy_cfg_params *data_ptr;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	data_ptr = (mlan_ds_hal_phy_cfg_params *) respbuf;
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	req->req_id = MLAN_IOCTL_MISC_CFG;
	cfg = (mlan_ds_misc_cfg *)req->pbuf;
	cfg->sub_command = MLAN_OID_MISC_HAL_PHY_CFG;

	cfg->param.hal_phy_cfg_params.dot11b_psd_mask_cfg =
		data_ptr->dot11b_psd_mask_cfg;

	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 * @brief               configure 11ax HE capability or HE operation
 *
 *
 *  @param priv    Pointer to the mlan_private driver data struct
 *  @param respbuf      A pointer to response buffer
 *  @param len          length used
 *  @param respbuflen   Available length of response buffer
 *
 *  @return         Number of bytes written if successful else negative value
 */
static int
woal_priv_11axcfg_cmd(moal_private *priv, t_u8 *respbuf, t_u8 len,
		      t_u32 respbuflen)
{
	mlan_ioctl_req *req = NULL;
	mlan_ds_11ax_cfg *cfg = NULL;
	int ret = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11ax_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	req->req_id = MLAN_IOCTL_11AX_CFG;
	req->action = MLAN_ACT_SET;
	cfg = (mlan_ds_11ax_cfg *) req->pbuf;
	cfg->sub_command = MLAN_OID_11AX_HE_CFG;
	if (len)
		moal_memcpy_ext(priv->phandle, (t_u8 *)&cfg->param.he_cfg,
				respbuf, len, sizeof(mlan_ds_11ax_he_cfg));
	else
		req->action = MLAN_ACT_GET;
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}
	moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)&cfg->param.he_cfg,
			sizeof(mlan_ds_11ax_he_cfg), respbuflen);
	ret = sizeof(mlan_ds_11ax_he_cfg);
done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 * @brief               Configure TWT Setup parameters
 *
 * @param priv          Pointer to the mlan_private driver data struct
 * @param respbuf       A pointer to response buffer
 * @param len           Length used
 * @param respbuflen    Available length of response buffer
 *
 * @return              Number of bytes written if successful else negative
 * value
 */
static int
woal_priv_twt_setup(moal_private *priv, t_u8 *respbuf, t_u8 len,
		    t_u32 respbuflen)
{
	mlan_ioctl_req *req = NULL;
	mlan_ds_twtcfg *cfg = NULL;
	int ret = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_twtcfg));
	if (req == NULL) {
		PRINTM(MERROR, "Failed to allocate ioctl_req!\n");
		ret = -ENOMEM;
		goto done;
	}

	req->req_id = MLAN_IOCTL_11AX_CFG;
	req->action = MLAN_ACT_SET;
	cfg = (mlan_ds_twtcfg *) req->pbuf;
	cfg->sub_command = MLAN_OID_11AX_TWT_CFG;
	cfg->sub_id = MLAN_11AX_TWT_SETUP_SUBID;

	if (len) {
		moal_memcpy_ext(priv->phandle, (t_u8 *)&cfg->param.twt_setup,
				respbuf, len, sizeof(mlan_ds_twt_setup));
	}

	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		PRINTM(MERROR, "woal_request_ioctl failed!\n");
		ret = -EFAULT;
		goto done;
	}

	ret = sizeof(mlan_ds_twt_setup);
done:
	if (status != MLAN_STATUS_PENDING) {
		kfree(req);
	}
	LEAVE();
	return ret;
}

/**
 * @brief               Configure TWT Tear down parameters
 *
 * @param priv          Pointer to the mlan_private driver data struct
 * @param respbuf       A pointer to response buffer
 * @param len           Length used
 * @param respbuflen    Available length of response buffer
 *
 * @return              Number of bytes written if successful else negative
 * value
 */
static int
woal_priv_twt_teardown(moal_private *priv, t_u8 *respbuf, t_u8 len,
		       t_u32 respbuflen)
{
	mlan_ioctl_req *req = NULL;
	mlan_ds_twtcfg *cfg = NULL;
	int ret = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_twtcfg));
	if (req == NULL) {
		PRINTM(MERROR, "Failed to allocate ioctl_req!\n");
		ret = -ENOMEM;
		goto done;
	}

	req->req_id = MLAN_IOCTL_11AX_CFG;
	req->action = MLAN_ACT_SET;
	cfg = (mlan_ds_twtcfg *) req->pbuf;
	cfg->sub_command = MLAN_OID_11AX_TWT_CFG;
	cfg->sub_id = MLAN_11AX_TWT_TEARDOWN_SUBID;

	if (len) {
		moal_memcpy_ext(priv->phandle, (t_u8 *)&cfg->param.twt_teardown,
				respbuf, len, sizeof(mlan_ds_twt_teardown));
	}

	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		PRINTM(MERROR, "woal_request_ioctl failed!\n");
		ret = -EFAULT;
		goto done;
	}

	ret = sizeof(mlan_ds_twt_teardown);
done:
	if (status != MLAN_STATUS_PENDING) {
		kfree(req);
	}
	LEAVE();
	return ret;
}

#ifdef WIFI_DIRECT_SUPPORT
#if defined(UAP_CFG80211)
/**
 * @brief               Set/Get P2P NoA (Notice of Absence) parameters
 * @param priv          Pointer to moal_private structure
 * @param respbuf       Pointer to response buffer
 * @param resplen       Response buffer length
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_cfg_noa(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int header_len = 0, user_data_len = 0;
	int ret = 0, data[7];
	mlan_ds_wifi_direct_config noa_cfg;

	ENTER();

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_CFG_NOA);
	memset(&noa_cfg, 0, sizeof(noa_cfg));

	memset(data, 0, sizeof(data));
	parse_arguments(respbuf + header_len, data, ARRAY_SIZE(data),
			&user_data_len);

	if (user_data_len > 5) {
		PRINTM(MERROR, "invalid parameters\n");
		ret = -EINVAL;
		goto done;
	}

	noa_cfg.flags |= WIFI_DIRECT_NOA;

	if (woal_p2p_config(priv, MLAN_ACT_GET, &noa_cfg) !=
	    MLAN_STATUS_SUCCESS) {
		PRINTM(MERROR, "Could not get P2P noa config\n");
		ret = -EINVAL;
		goto done;
	}

	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		moal_memcpy_ext(priv->phandle, respbuf, &noa_cfg,
				sizeof(noa_cfg), respbuflen);
		ret = sizeof(noa_cfg);
	} else {
		switch (user_data_len) {
		case 5:
			noa_cfg.noa_interval = (t_u32)data[4];
			/* fall through */
		case 4:
			noa_cfg.noa_duration = (t_u32)data[3];
			/* fall through */
		case 3:
			if (data[2] < 1 || data[2] > 255) {
				PRINTM(MERROR,
				       "Invalid number of absence intervals\n");
				ret = -EINVAL;
				goto done;
			}
			noa_cfg.noa_count = (t_u8)data[2];
			/* fall through */
		case 2:
			if (data[1] < 0 || data[1] > 255) {
				PRINTM(MERROR, "Invalid Index\n");
				ret = -EINVAL;
				goto done;
			}
			noa_cfg.index = (t_u16)data[1];
			/* fall through */
		case 1:
			if (data[0] < 0 || data[0] > 1) {
				PRINTM(MERROR, "Invalid noa enable\n");
				ret = -EINVAL;
				goto done;
			}
			noa_cfg.noa_enable = (t_u8)data[0];
			noa_cfg.flags |= WIFI_DIRECT_NOA;
			break;
		default:
			break;
		}
		woal_p2p_config(priv, MLAN_ACT_SET, &noa_cfg);
	}

done:

	LEAVE();
	return ret;
}

/**
 * @brief               Set/Get P2P OPP-PS parameters
 * @param priv          Pointer to moal_private structure
 * @param respbuf       Pointer to response buffer
 * @param resplen       Response buffer length
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_cfg_opp_ps(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int header_len = 0, user_data_len = 0;
	int ret = 0, data[7];
	mlan_ds_wifi_direct_config opp_ps_cfg;

	ENTER();

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_CFG_OPP_PS);
	memset(&opp_ps_cfg, 0, sizeof(opp_ps_cfg));

	memset(data, 0, sizeof(data));
	parse_arguments(respbuf + header_len, data, ARRAY_SIZE(data),
			&user_data_len);

	if (user_data_len > 2) {
		PRINTM(MERROR, "invalid parameters\n");
		ret = -EINVAL;
		goto done;
	}

	opp_ps_cfg.flags |= WIFI_DIRECT_OPP_PS;

	if (woal_p2p_config(priv, MLAN_ACT_GET, &opp_ps_cfg) !=
	    MLAN_STATUS_SUCCESS) {
		PRINTM(MERROR, "Could not get P2P opp ps config\n");
		ret = -EINVAL;
		goto done;
	}

	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		moal_memcpy_ext(priv->phandle, respbuf, &opp_ps_cfg,
				sizeof(opp_ps_cfg), respbuflen);
		ret = sizeof(opp_ps_cfg);
	} else {
		switch (user_data_len) {
		case 2:
			opp_ps_cfg.ct_window = (t_u8)data[1];
			/* fall through */
		case 1:
			if (data[0] < 0 || data[0] > 1) {
				PRINTM(MERROR, "Invalid ps enable\n");
				ret = -EINVAL;
				goto done;
			}
			opp_ps_cfg.opp_ps_enable = (t_u8)data[0];
			opp_ps_cfg.flags |= WIFI_DIRECT_OPP_PS;
			/* fall through */
		default:
			break;
		}
		woal_p2p_config(priv, MLAN_ACT_SET, &opp_ps_cfg);
	}

done:

	LEAVE();
	return ret;
}
#endif
#endif

/**
 * @brief               Set/Get GPIO TSF latch clock sync config parameters
 * @param priv          Pointer to moal_private structure
 * @param respbuf       Pointer to response buffer
 * @param resplen       Response buffer length
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_cfg_clock_sync(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int header_len = 0, user_data_len = 0;
	int ret = 0, data[5];
	mlan_ds_gpio_tsf_latch *clock_sync_cfg = NULL;
	mlan_ioctl_req *req = NULL;
	mlan_ds_misc_cfg *misc_cfg = NULL;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_CFG_CLOCK_SYNC);

	memset(data, 0, sizeof(data));
	parse_arguments(respbuf + header_len, data, ARRAY_SIZE(data),
			&user_data_len);

	if (user_data_len > 5) {
		PRINTM(MERROR, "invalid parameters\n");
		ret = -EINVAL;
		goto done;
	}

	/* Allocate an IOCTL request buffer */
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	/* Fill request buffer */
	req->req_id = MLAN_IOCTL_MISC_CFG;
	misc_cfg = (mlan_ds_misc_cfg *)req->pbuf;
	misc_cfg->sub_command = MLAN_OID_MISC_GPIO_TSF_LATCH;
	clock_sync_cfg = &misc_cfg->param.gpio_tsf_latch_config;
	memset(clock_sync_cfg, 0, sizeof(mlan_ds_gpio_tsf_latch));

	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		req->action = MLAN_ACT_GET;
		user_data_len = 0;
	} else {
		req->action = MLAN_ACT_SET;
		switch (user_data_len) {
		case 5:
			clock_sync_cfg->clock_sync_gpio_pulse_width =
				(t_u16)data[4];
			/* fall through */
		case 4:
			if (data[3] < 0 || data[3] > 1) {
				PRINTM(MERROR, "Invalid Level/Trigger\n");
				ret = -EINVAL;
				goto done;
			}
			clock_sync_cfg->clock_sync_gpio_level_toggle =
				(t_u8)data[3];
			/* fall through */
		case 3:
			if (data[2] < 1 || data[2] > 255) {
				PRINTM(MERROR,
				       "Invalid number of GPIO Pin Number\n");
				ret = -EINVAL;
				goto done;
			}
			clock_sync_cfg->clock_sync_gpio_pin_number =
				(t_u8)data[2];
			/* fall through */
		case 2:
			if (data[1] < 0 || data[1] > 2) {
				PRINTM(MERROR, "Invalid Role\n");
				ret = -EINVAL;
				goto done;
			}
			clock_sync_cfg->clock_sync_Role = (t_u8)data[1];
			/* fall through */
		case 1:
			if (data[0] < 0 || data[0] > 2) {
				PRINTM(MERROR, "Invalid Mode\n");
				ret = -EINVAL;
				goto done;
			}
			clock_sync_cfg->clock_sync_mode = (t_u8)data[0];
			break;
		default:
			break;
		}
	}
	/* Send IOCTL request to MLAN */
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	if (!user_data_len) {
		moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)clock_sync_cfg,
				sizeof(mlan_ds_gpio_tsf_latch), respbuflen);
		ret = sizeof(mlan_ds_gpio_tsf_latch);
	}

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);

	LEAVE();
	return ret;
}

/**
 * @brief               Set/Get GPIO TSF latch get tsf info config parameters
 * @param priv          Pointer to moal_private structure
 * @param respbuf       Pointer to response buffer
 * @param resplen       Response buffer length
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_cfg_get_tsf_info(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int header_len = 0, user_data_len = 0;
	int ret = 0, data[1];
	mlan_ds_tsf_info *tsf_info;
	mlan_ioctl_req *req = NULL;
	mlan_ds_misc_cfg *misc_cfg = NULL;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_CFG_GET_TSF_INFO);

	memset(data, 0, sizeof(data));
	parse_arguments(respbuf + header_len, data, ARRAY_SIZE(data),
			&user_data_len);

	if (user_data_len > 1) {
		PRINTM(MERROR, "invalid parameters\n");
		ret = -EINVAL;
		goto done;
	}
	/* Allocate an IOCTL request buffer */
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	/* Fill request buffer */
	req->req_id = MLAN_IOCTL_MISC_CFG;
	req->action = MLAN_ACT_GET;
	misc_cfg = (mlan_ds_misc_cfg *)req->pbuf;
	misc_cfg->sub_command = MLAN_OID_MISC_GET_TSF_INFO;
	tsf_info = &misc_cfg->param.tsf_info;
	memset(tsf_info, 0, sizeof(mlan_ds_tsf_info));
	if (user_data_len == 1) {
		if (data[0] < 0 || data[0] > 1) {
			PRINTM(MERROR, "Invalid tsf Format\n");
			ret = -EINVAL;
			goto done;
		}
		tsf_info->tsf_format = data[0];
	}
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}
	moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)tsf_info,
			sizeof(mlan_ds_tsf_info), respbuflen);
	ret = sizeof(mlan_ds_tsf_info);
done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);

	LEAVE();
	return ret;
}

/**
 * @brief               Set/Get transition channel
 * @param priv          Pointer to moal_private structure
 * @param respbuf       Pointer to response buffer
 * @param resplen       Response buffer length
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_transition_channel(moal_private *priv, t_u8 *respbuf,
			     t_u32 respbuflen)
{
	int header_len = 0, user_data_len = 0;
	int ret = 0, data[1];

	ENTER();
	if (!priv || (priv->bss_type != MLAN_BSS_TYPE_UAP)) {
		PRINTM(MERROR, "priv is null or interface is not AP");
		ret = -EFAULT;
		LEAVE();
		return ret;
	}

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_TRANSITION_CHANNEL);
	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		user_data_len = 0;
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len, data,
				sizeof(data) / sizeof(int), &user_data_len);
		if (user_data_len > 1) {
			PRINTM(MERROR, "Invalid parameter number\n");
			ret = -EINVAL;
			goto done;
		}
		if (user_data_len)
			priv->trans_chan = data[0];
	}
	data[0] = priv->trans_chan;
	moal_memcpy_ext(priv->phandle, respbuf, &data, sizeof(data),
			respbuflen);
	ret = sizeof(int);
done:

	LEAVE();
	return ret;
}

#if defined(STA_CFG80211) || defined(UAP_CFG80211)
#ifdef WIFI_DIRECT_SUPPORT
#define DEF_NOA_INTERVAL 100
/**
 ** @brief               Set/Get P2P NoA (Notice of Absence) parameters
 ** @param priv          Pointer to moal_private structure
 ** @param respbuf       Pointer to response buffer
 ** @param resplen       Response buffer length
 **
 **  @return             Number of bytes written, negative for failure.
 **/
static int
woal_p2p_ps_cfg(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int user_data_len = 0;
	int ret = 0, data[2];
	u32 duration = priv->phandle->noa_duration;
	u32 interval = 0;

	ENTER();
	if (strlen(respbuf) > strlen("P2P_PERIODIC_SLEEP")) {
		memset((char *)data, 0, sizeof(data));
		parse_arguments(respbuf + strlen("P2P_PERIODIC_SLEEP") + 1,
				data, ARRAY_SIZE(data), &user_data_len);
	}
	if ((user_data_len != 1) && (user_data_len != 2)) {
		PRINTM(MERROR,
		       " Invalid parameter number for P2P_PERIODIC_SLEEP");
		ret = -EINVAL;
		goto done;
	}
	if (data[0] < DEF_NOA_INTERVAL)
		interval = DEF_NOA_INTERVAL;
	else
		interval = (data[0] + DEF_NOA_INTERVAL - 1) / DEF_NOA_INTERVAL *
			DEF_NOA_INTERVAL;

	if (user_data_len == 2)
		duration = data[1];
	if (duration >= interval) {
		PRINTM(MERROR,
		       " Invalid noa duration/interval! duration=%d interval=%d\n",
		       duration, interval);
		ret = -EINVAL;
		goto done;
	}
	priv->phandle->noa_interval = interval;
	priv->phandle->noa_duration = duration;
	PRINTM(MIOCTL, "configure noa interval=%d, duration=%d\n",
	       priv->phandle->noa_interval, priv->phandle->noa_duration);
done:
	LEAVE();
	return ret;
}
#endif
#endif

/**
 * @brief               Set/Get DFS repeater mode
 *
 * @param priv          Pointer to moal_private structure
 * @param respbuf       Pointer to response buffer
 * @param resplen       Response buffer length
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_dfs_repeater_cfg(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int ret = 0;
	int user_data_len = 0, header_len = 0, data[1] = { 0 };
	mlan_ioctl_req *req = NULL;
	mlan_ds_misc_cfg *misc_cfg = NULL;
	mlan_ds_misc_dfs_repeater *dfs_repeater = NULL;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_DFS_REPEATER_CFG);

	/* Allocate an IOCTL request buffer */
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	/* Fill request buffer */
	req->req_id = MLAN_IOCTL_MISC_CFG;
	misc_cfg = (mlan_ds_misc_cfg *)req->pbuf;
	misc_cfg->sub_command = MLAN_OID_MISC_DFS_REAPTER_MODE;
	dfs_repeater =
		(mlan_ds_misc_dfs_repeater *)&misc_cfg->param.dfs_repeater;

	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		user_data_len = 0;
		req->action = MLAN_ACT_GET;
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len, data, ARRAY_SIZE(data),
				&user_data_len);
		if (user_data_len != 1) {
			PRINTM(MERROR, "Invalid number of args! %d\n",
			       user_data_len);
			ret = -EINVAL;
			goto done;
		}
		if ((data[0] != MTRUE) && (data[0] != MFALSE)) {
			PRINTM(MERROR, "Invalid DFS repeater mode %d\n",
			       data[0]);
			ret = -EINVAL;
			goto done;
		}
		dfs_repeater->mode = (t_u16)data[0];

		req->action = MLAN_ACT_SET;
	}

	/* Send IOCTL request to MLAN */
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	if (!user_data_len) {
		moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)dfs_repeater,
				sizeof(mlan_ds_misc_dfs_repeater), respbuflen);
		ret = sizeof(mlan_ds_misc_dfs_repeater);
	}

	/* Store current value of DFS repeater mode for futher references. eg.,
	 * for avoiding CAC timers
	 */
	priv->phandle->dfs_repeater_mode = dfs_repeater->mode;

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);

	LEAVE();
	return ret;
}

#ifdef WIFI_DIRECT_SUPPORT
#if defined(STA_CFG80211) || defined(UAP_CFG80211)
/**
 * @brief               Set/Get MIRACAST configuration parameters
 *
 * @param priv          Pointer to moal_private structure
 * @param respbuf       Pointer to response buffer
 * @param resplen       Response buffer length
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_miracast_cfg(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int ret = 0;
	int user_data_len = 0, header_len = 0, data[3] = { 0, 0, 0 };

	ENTER();

	if (!priv || !priv->phandle) {
		PRINTM(MERROR, "priv or handle is null\n");
		ret = -EFAULT;
		goto done;
	}

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_MIRACAST_CFG);

	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		data[0] = priv->phandle->miracast_mode;
		data[1] = priv->phandle->miracast_scan_time;
		data[2] = priv->phandle->scan_chan_gap;

		moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)data,
				sizeof(data), respbuflen);
		ret = sizeof(data);
	} else {
		/* SET operation */
		memset(data, 0, sizeof(data));
		parse_arguments(respbuf + header_len, data, ARRAY_SIZE(data),
				&user_data_len);

		if (user_data_len > 3) {
			PRINTM(MERROR, "Too many arguments\n");
			ret = -EINVAL;
			goto done;
		}
		if (data[0] < 0 || data[0] > 2 || data[1] < 0 || data[2] < 0) {
			PRINTM(MERROR, "Invalid argument\n");
			ret = -EINVAL;
			goto done;
		}
	}

	if (user_data_len >= 1)
		priv->phandle->miracast_mode = (t_u8)data[0];
	if (user_data_len >= 2)
		priv->phandle->miracast_scan_time = (t_u16)data[1];
	if (user_data_len == 3)
		priv->phandle->scan_chan_gap = (t_u16)data[2];

done:
	LEAVE();
	return ret;
}

/**
 *   @brief Configuring scan gap for miracast mode
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             0 --success, otherwise failure
 */
static int
woal_set_scan_chan_gap(moal_private *priv, t_u8 *respbuf, int respbuflen)
{
	t_u32 data[2];
	int ret = 0;
	int user_data_len = 0;

	ENTER();

	if (strlen(respbuf) > strlen("SCAN_TIMING")) {
		memset((char *)data, 0, sizeof(data));
		parse_arguments(respbuf + strlen("SCAN_TIMING") + 1, data,
				ARRAY_SIZE(data), &user_data_len);
	}

	if (user_data_len != 2) {
		PRINTM(MERROR, "Invalid arguments for scan timing\n");
		ret = -EINVAL;
		goto done;
	}
	priv->phandle->miracast_scan_time = (t_u16)data[0];
	priv->phandle->scan_chan_gap = (t_u16)data[1];
done:
	LEAVE();
	return ret;
}
#endif
#endif

/**
 * @brief               Set/Get control to coex RX window size configuration
 *
 * @param priv          Pointer to moal_private structure
 * @param respbuf       Pointer to response buffer
 * @param resplen       Response buffer length
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_coex_rx_winsize(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int ret = 0;
	int user_data_len = 0, header_len = 0, data = 0;
	mlan_ioctl_req *req = NULL;
	mlan_ds_11n_cfg *cfg_11n = NULL;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	if (!priv || !priv->phandle) {
		PRINTM(MERROR, "priv or handle is null\n");
		ret = -EFAULT;
		goto done;
	}

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_COEX_RX_WINSIZE);

	/* Allocate an IOCTL request buffer */
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11n_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	/* Fill request buffer */
	req->req_id = MLAN_IOCTL_11N_CFG;
	cfg_11n = (mlan_ds_11n_cfg *)req->pbuf;
	cfg_11n->sub_command = MLAN_OID_11N_CFG_COEX_RX_WINSIZE;

	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		user_data_len = 0;
		req->action = MLAN_ACT_GET;
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len, &data,
				sizeof(data) / sizeof(int), &user_data_len);
		if (user_data_len != 1) {
			PRINTM(MERROR, "Invalid number of args! %d\n",
			       user_data_len);
			ret = -EINVAL;
			goto done;
		}
		if ((data != MTRUE) && (data != MFALSE)) {
			PRINTM(MERROR,
			       "Invalid coex RX window size parameter %d\n",
			       data);
			ret = -EINVAL;
			goto done;
		}
		cfg_11n->param.coex_rx_winsize = data;
		req->action = MLAN_ACT_SET;
	}

	/* Send IOCTL request to MLAN */
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	if (!user_data_len) {
		moal_memcpy_ext(priv->phandle, respbuf,
				(t_u8 *)&cfg_11n->param.coex_rx_winsize,
				sizeof(t_u32), respbuflen);
		ret = sizeof(t_u32);
	}

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);

	LEAVE();
	return ret;
}

/**
 * @brief               Set/Get control to TX AMPDU configuration on infra link
 *
 * @param priv          Pointer to moal_private structure
 * @param respbuf       Pointer to response buffer
 * @param resplen       Response buffer length
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_txaggrctrl(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int ret = 0;
	int user_data_len = 0, header_len = 0, data = 0;
	mlan_ioctl_req *req = NULL;
	mlan_ds_11n_cfg *cfg_11n = NULL;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	if (!priv || !priv->phandle) {
		PRINTM(MERROR, "priv or handle is null\n");
		ret = -EFAULT;
		goto done;
	}

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_TX_AGGR_CTRL);

	/* Allocate an IOCTL request buffer */
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11n_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	/* Fill request buffer */
	req->req_id = MLAN_IOCTL_11N_CFG;
	cfg_11n = (mlan_ds_11n_cfg *)req->pbuf;
	cfg_11n->sub_command = MLAN_OID_11N_CFG_TX_AGGR_CTRL;

	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		user_data_len = 0;
		req->action = MLAN_ACT_GET;
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len, &data,
				sizeof(data) / sizeof(int), &user_data_len);
		if (user_data_len != 1) {
			PRINTM(MERROR, "Invalid number of args! %d\n",
			       user_data_len);
			ret = -EINVAL;
			goto done;
		}
		if ((data != MTRUE) && (data != MFALSE)) {
			PRINTM(MERROR, "Invalid txaggrctrl parameter %d\n",
			       data);
			ret = -EINVAL;
			goto done;
		}
		cfg_11n->param.txaggrctrl = data;
		req->action = MLAN_ACT_SET;
	}

	/* Send IOCTL request to MLAN */
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	if (!user_data_len) {
		moal_memcpy_ext(priv->phandle, respbuf,
				(t_u8 *)&cfg_11n->param.txaggrctrl,
				sizeof(t_u32), respbuflen);
		ret = sizeof(t_u32);
	}

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);

	LEAVE();
	return ret;
}

/**
 * @brief               Set/Get control to enable/disable auto TDLS
 *
 * @param priv          Pointer to moal_private structure
 * @param respbuf       Pointer to response buffer
 * @param resplen       Response buffer length
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_auto_tdls(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int ret = 0;
	int user_data_len = 0, header_len = 0, data = 0;

	ENTER();

	if (!priv || !priv->phandle) {
		PRINTM(MERROR, "priv or handle is null\n");
		ret = -EFAULT;
		goto done;
	}

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_AUTO_TDLS);

	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		data = priv->enable_auto_tdls;
		moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)&data,
				sizeof(data), respbuflen);
		ret = sizeof(data);
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len, &data,
				sizeof(data) / sizeof(int), &user_data_len);
		if (user_data_len != 1) {
			PRINTM(MERROR, "Invalid number of args! %d\n",
			       user_data_len);
			ret = -EINVAL;
			goto done;
		}
		if ((data != MTRUE) && (data != MFALSE)) {
			PRINTM(MERROR, "Invalid autotdls parameter %d\n", data);
			ret = -EINVAL;
			goto done;
		}
		priv->enable_auto_tdls = (t_u8)data;
	}

done:
	LEAVE();
	return ret;
}

#ifdef PCIE
/**
 * @brief               Read/Write PCIE register
 *
 * @param priv          Pointer to moal_private structure
 * @param respbuf       Pointer to response buffer
 * @param resplen       Response buffer length
 *
 * @return              Number of bytes written, negative for failure.
 */
static int
woal_priv_pcie_reg_rw(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	moal_handle *handle = priv->phandle;
	int data[3];
	t_u32 reg;
	t_u32 value;
	int ret = MLAN_STATUS_SUCCESS;
	int user_data_len = 0, header_len = 0;

	ENTER();

	memset(data, 0, sizeof(data));
	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_PCIE_REG_RW);
	if ((int)strlen(respbuf) == header_len) {
		PRINTM(MERROR, "Invalid number of parameters\n");
		ret = -EINVAL;
		goto done;
	}

	parse_arguments(respbuf + header_len, data, ARRAY_SIZE(data),
			&user_data_len);
	if ((user_data_len != 1) && (user_data_len != 2)) {
		PRINTM(MERROR, "Invalid number of parameters\n");
		ret = -EINVAL;
		goto done;
	}

	reg = (t_u32)data[0];
	if (user_data_len == 1) {
		if (moal_read_reg(handle, reg, &value)) {
			ret = -EFAULT;
			goto done;
		}
		data[1] = value;
	} else {
		value = data[1];
		if (moal_write_reg(handle, reg, value)) {
			ret = -EFAULT;
			goto done;
		}
	}
	moal_memcpy_ext(handle, respbuf, (t_u8 *)data, sizeof(data),
			respbuflen);
	ret = sizeof(data);

done:
	LEAVE();
	return ret;
}

/**
 * @brief               Read/Write PCIE register/memory from BAR0
 *
 * @param priv          Pointer to moal_private structure
 * @param respbuf       Pointer to response buffer
 * @param resplen       Response buffer length
 *
 * @return              Number of bytes written, negative for failure.
 */
static int
woal_priv_pcie_bar0_reg_rw(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	moal_handle *handle = priv->phandle;
	pcie_service_card *card = (pcie_service_card *)handle->card;
	int data[3];
	t_u32 reg;
	t_u32 value;
	int ret = MLAN_STATUS_SUCCESS;
	int user_data_len = 0, header_len = 0;

	ENTER();

	memset(data, 0, sizeof(data));
	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_PCIE_BAR0_REG_RW);
	if ((int)strlen(respbuf) == header_len) {
		PRINTM(MERROR, "Invalid number of parameters\n");
		ret = -EINVAL;
		goto done;
	}

	parse_arguments(respbuf + header_len, data, ARRAY_SIZE(data),
			&user_data_len);
	if ((user_data_len != 1) && (user_data_len != 2)) {
		PRINTM(MERROR, "Invalid number of parameters\n");
		ret = -EINVAL;
		goto done;
	}

	reg = (t_u32)data[0];
	if (user_data_len == 1) {
		value = ioread32(card->pci_mmap + reg);
		if (value == MLAN_STATUS_FAILURE) {
			ret = -EFAULT;
			goto done;
		}
		data[1] = value;
	} else {
		value = data[1];
		iowrite32(value, card->pci_mmap + reg);
	}
	moal_memcpy_ext(handle, respbuf, (t_u8 *)data, sizeof(data),
			respbuflen);
	ret = sizeof(data);

done:
	LEAVE();
	return ret;
}
#endif

/**
 * @brief               Get SOC temperature
 *
 * @param priv          Pointer to moal_private structure
 * @param respbuf       Pointer to response buffer
 * @param resplen       Response buffer length
 *
 * @return              Number of bytes written, negative for failure.
 */
static int
woal_priv_get_sensor_temp(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	mlan_ioctl_req *req = NULL;
	mlan_ds_misc_cfg *pcfg = NULL;
	int ret = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	pcfg = (mlan_ds_misc_cfg *)req->pbuf;
	pcfg->sub_command = MLAN_OID_MISC_GET_SENSOR_TEMP;
	req->req_id = MLAN_IOCTL_MISC_CFG;
	req->action = MLAN_ACT_GET;

	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	memset(respbuf, 0, respbuflen);
	moal_memcpy_ext(priv->phandle, respbuf,
			&pcfg->param.sensor_temp.temperature, sizeof(t_u32),
			respbuflen);

	ret = sizeof(t_u32);

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
#if defined(STA_CFG80211) || defined(UAP_CFG80211)
/**
 * @brief               Enable/disable DFS offload
 *
 * @param priv          Pointer to moal_private structure
 * @param respbuf       Pointer to response buffer
 * @param resplen       Response buffer length
 *
 * @return              Number of bytes written, negative for failure.
 */
static int
woal_priv_dfs_offload_enable(moal_private *priv, t_u8 *respbuf,
			     t_u32 respbuflen)
{
	struct wiphy *wiphy = NULL;
	int ret = 0, dfs_offload_en = 0, user_data_len = 0, header_len = 0,
		dfs_offload;

	ENTER();

	if (priv && priv->wdev)
		wiphy = priv->wdev->wiphy;
	if (!wiphy) {
		PRINTM(MERROR, "wiphy is NULL\n");
		ret = -EFAULT;
		goto done;
	}
	dfs_offload = moal_extflg_isset(priv->phandle, EXT_DFS_OFFLOAD);
	if (woal_is_any_interface_active(priv->phandle)) {
		PRINTM(MERROR,
		       "DFS offload enable/disable do not allowed after BSS started!\n");
		ret = -EFAULT;
		goto done;
	}
	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_DFS_OFFLOAD);
	parse_arguments(respbuf + header_len, &dfs_offload_en,
			sizeof(dfs_offload_en) / sizeof(int), &user_data_len);
	if (user_data_len != 1) {
		PRINTM(MERROR, "Invalid number of args! %d\n", user_data_len);
		ret = -EINVAL;
		goto done;
	}

	if (dfs_offload_en != 0 && dfs_offload_en != 1) {
		PRINTM(MERROR, "Invalid args!\n");
		ret = -EINVAL;
		goto done;
	}
	if (dfs_offload != dfs_offload_en) {
		dfs_offload = dfs_offload_en;
		if (dfs_offload)
			moal_extflg_set(priv->phandle, EXT_DFS_OFFLOAD);
		else
			moal_extflg_clear(priv->phandle, EXT_DFS_OFFLOAD);
		woal_update_radar_chans_dfs_state(wiphy);
	}
done:
	LEAVE();
	return ret;
}
#endif
#endif

/**
 * @brief               Set/Get TDLS CS off channel value
 *
 * @param priv          Pointer to moal_private structure
 * @param respbuf       Pointer to response buffer
 * @param resplen       Response buffer length

 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_tdls_cs_chan(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	mlan_ioctl_req *ioctl_req = NULL;
	mlan_ds_misc_cfg *misc = NULL;
	mlan_status status = MLAN_STATUS_SUCCESS;
	int ret = 0;
	int user_data_len = 0, header_len = 0, data = 0;

	ENTER();

	if (!priv || !priv->phandle) {
		PRINTM(MERROR, "priv or handle is null\n");
		ret = -EFAULT;
		goto done;
	}

	ioctl_req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (ioctl_req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	misc = (mlan_ds_misc_cfg *)ioctl_req->pbuf;
	misc->sub_command = MLAN_OID_MISC_TDLS_CS_CHANNEL;
	ioctl_req->req_id = MLAN_IOCTL_MISC_CFG;

	header_len = strlen("TDLS_CS_CHAN");
	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		ioctl_req->action = MLAN_ACT_GET;
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len + 1, &data,
				sizeof(data) / sizeof(int), &user_data_len);
		if (user_data_len != 1) {
			PRINTM(MERROR, "Invalid number of args! %d\n",
			       user_data_len);
			ret = -EINVAL;
			goto done;
		}
		ioctl_req->action = MLAN_ACT_SET;
		misc->param.tdls_cs_channel = (t_u8)data;
	}

	status = woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	ret = sprintf(respbuf, "off channel %d\n",
		      misc->param.tdls_cs_channel) + 1;

	PRINTM(MIOCTL, "tdls CS channel %d\n", misc->param.tdls_cs_channel);
done:
	if (status != MLAN_STATUS_PENDING)
		kfree(ioctl_req);

	LEAVE();
	return ret;
}

/**
 * @brief               Set/Get TDLS idle timeout value
 *
 * @param priv          Pointer to moal_private structure
 * @param respbuf       Pointer to response buffer
 * @param resplen       Response buffer length

 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_tdls_idle_time(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	mlan_ioctl_req *ioctl_req = NULL;
	mlan_ds_misc_cfg *misc = NULL;
	mlan_status status = MLAN_STATUS_SUCCESS;
	int ret = 0;
	int user_data_len = 0, header_len = 0, data = 0;

	ENTER();

	if (!priv || !priv->phandle) {
		PRINTM(MERROR, "priv or handle is null\n");
		ret = -EFAULT;
		goto done;
	}

	ioctl_req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (ioctl_req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	misc = (mlan_ds_misc_cfg *)ioctl_req->pbuf;
	misc->sub_command = MLAN_OID_MISC_TDLS_IDLE_TIME;
	ioctl_req->req_id = MLAN_IOCTL_MISC_CFG;

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_TDLS_IDLE_TIME);
	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		ioctl_req->action = MLAN_ACT_GET;
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len, &data,
				sizeof(data) / sizeof(int), &user_data_len);
		if (user_data_len != 1) {
			PRINTM(MERROR, "Invalid number of args! %d\n",
			       user_data_len);
			ret = -EINVAL;
			goto done;
		}
		ioctl_req->action = MLAN_ACT_SET;
		misc->param.tdls_idle_time = (t_u16)data;
	}

	status = woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	moal_memcpy_ext(priv->phandle, respbuf,
			(t_u8 *)&misc->param.tdls_idle_time, sizeof(t_u16),
			respbuflen);
	ret = sizeof(t_u16);

	PRINTM(MIOCTL, "tdls idle time %d\n", misc->param.tdls_idle_time);
done:
	if (status != MLAN_STATUS_PENDING)
		kfree(ioctl_req);

	LEAVE();
	return ret;
}

/**
 * @brief               Set/Get dynamic bandwidth
 *
 * @param priv          Pointer to moal_private structure
 * @param respbuf       Pointer to response buffer
 * @param resplen       Response buffer length

 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_config_dyn_bw(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	mlan_ioctl_req *ioctl_req = NULL;
	mlan_ds_misc_cfg *misc = NULL;
	mlan_status status = MLAN_STATUS_SUCCESS;
	int ret = 0;
	int user_data_len = 0, header_len = 0, data = 0;

	ENTER();

	if (!priv || !priv->phandle) {
		PRINTM(MERROR, "priv or handle is null\n");
		ret = -EFAULT;
		goto done;
	}

	ioctl_req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (ioctl_req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	misc = (mlan_ds_misc_cfg *)ioctl_req->pbuf;
	misc->sub_command = MLAN_OID_MISC_DYN_BW;
	ioctl_req->req_id = MLAN_IOCTL_MISC_CFG;

	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_DYN_BW);
	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		ioctl_req->action = MLAN_ACT_GET;
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len, &data,
				sizeof(data) / sizeof(int), &user_data_len);
		if (user_data_len != 1) {
			PRINTM(MERROR, "Invalid number of args! %d\n",
			       user_data_len);
			ret = -EINVAL;
			goto done;
		}
		ioctl_req->action = MLAN_ACT_SET;
		misc->param.dyn_bw = (t_u16)data;
	}

	status = woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)&misc->param.dyn_bw,
			sizeof(t_u16), respbuflen);
	ret = sizeof(t_u16);

	PRINTM(MIOCTL, "Dynamic bandwidth %d\n", misc->param.dyn_bw);
done:
	if (status != MLAN_STATUS_PENDING)
		kfree(ioctl_req);

	LEAVE();
	return ret;
}

#if defined(UAP_SUPPORT)
/**
 * @brief               Check validation of channel and oper class
 *
 * @param priv          Pointer to moal_private structure
 * @param channel       channel
 * @param oper_class    oper_class

 *  @return             SUCCESS/FAIL
 */
static int
woal_check_valid_channel_operclass(moal_private *priv, int channel,
				   int oper_class)
{
	int ret = 0;
	mlan_ioctl_req *ioctl_req = NULL;
	mlan_ds_misc_cfg *misc = NULL;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	ioctl_req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (ioctl_req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	misc = (mlan_ds_misc_cfg *)ioctl_req->pbuf;
	misc->sub_command = MLAN_OID_MISC_OPER_CLASS_CHECK;
	ioctl_req->req_id = MLAN_IOCTL_MISC_CFG;
	ioctl_req->action = MLAN_ACT_GET;
	misc->param.bw_chan_oper.oper_class = (t_u8)oper_class;
	misc->param.bw_chan_oper.channel = (t_u8)channel;

	status = woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(ioctl_req);

	LEAVE();
	return ret;
}

/**
 *  @brief send CSA/ECSA action frame
 *
 ** @param priv          Pointer to moal_private structure
 *  @param block_tx      0-no need block traffic 1- need block traffic
 *  @param oper_class    oper_class
 *  @param channel       channel
 *  @param switch count  how many csa/ecsa beacon will send out
 *  @param wait_option
 *
 *  @return             channel center frequency center, if found; O, otherwise
 */
static int
woal_action_channel_switch(moal_private *priv, t_u8 block_tx, t_u8 oper_class,
			   t_u8 channel, t_u8 switch_count, t_u8 wait_option)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_ds_bss *bss = NULL;
	mlan_ioctl_req *req = NULL;

	ENTER();

	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss));
	if (req == NULL) {
		ret = MLAN_STATUS_FAILURE;
		goto done;
	}

	bss = (mlan_ds_bss *)req->pbuf;
	bss->sub_command = MLAN_OID_ACTION_CHAN_SWITCH;
	req->req_id = MLAN_IOCTL_BSS;
	req->action = MLAN_ACT_SET;
	bss->param.chanswitch.chan_switch_mode = block_tx;
	bss->param.chanswitch.new_channel_num = channel;
	bss->param.chanswitch.chan_switch_count = switch_count;
	bss->param.chanswitch.new_oper_class = oper_class;
	ret = woal_request_ioctl(priv, req, wait_option);
	if (ret != MLAN_STATUS_SUCCESS)
		goto done;
done:
	if (ret != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;

}

/**
 * @brief               Set extended channel switch ie
 *
 * @param priv          Pointer to moal_private structure
 * @param respbuf       Pointer to response buffer
 * @param resplen       Response buffer length
 *
 * @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_extend_channel_switch(moal_private *priv, t_u8 *respbuf,
				t_u32 respbuflen)
{
	int ret = 0;
	int user_data_len = 0;
	int data[5] = { 0 };
	ENTER();

	if (!priv || !priv->phandle ||
	    (priv->bss_role != MLAN_BSS_ROLE_UAP) ||
	    (priv->bss_started != MTRUE)) {
		PRINTM(MERROR,
		       "priv or handle is null or interface is not AP/GO"
		       "or AP is not started\n");
		ret = -EFAULT;
		LEAVE();
		return ret;
	}

	parse_arguments(respbuf + strlen(CMD_NXP) +
			strlen(PRIV_CMD_EXTEND_CHAN_SWITCH),
			data, ARRAY_SIZE(data), &user_data_len);

	if (sizeof(int) * user_data_len > sizeof(data)) {
		PRINTM(MERROR, "Too many arguments\n");
		ret = -EINVAL;
		LEAVE();
		return ret;
	}
	if (user_data_len < 4) {
		PRINTM(MERROR, "Too few arguments\n");
		ret = -EINVAL;
		LEAVE();
		return ret;
	}
	if (data[1]) {
		if (woal_check_valid_channel_operclass(priv, data[2], data[1])) {
			PRINTM(MERROR, "Wrong channel switch parameters!\n");
			ret = -EINVAL;
			goto done;
		}
	}
	if (data[3])
		woal_channel_switch(priv, data[0], data[1], data[2], data[3],
				    data[4], MFALSE);
	else
		woal_action_channel_switch(priv, data[0], data[1], data[2],
					   data[3], MOAL_IOCTL_WAIT);
done:
	LEAVE();
	return ret;
}

/**
 * @brief               P2P extended channel switch
 *
 * @param priv          Pointer to moal_private structure
 * @param respbuf       Pointer to response buffer
 * @param resplen       Response buffer length

 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_p2p_ecsa(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int ret = 0;
	int user_data_len = 0, header_len = 0;
	int data[2] = { 0 };
	t_u8 bw = 0, oper_class = 0, channel = 0;
	IEEEtypes_ExtChanSwitchAnn_t *ext_chan_switch = NULL;
	custom_ie *pcust_chansw_ie = NULL;
	mlan_ioctl_req *ioctl_req = NULL;
	mlan_ds_misc_cfg *misc = NULL;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	if (!priv || !priv->phandle) {
		PRINTM(MERROR, "priv or handle is null\n");
		ret = -EFAULT;
		goto done;
	}

	if (priv->bss_role != MLAN_BSS_ROLE_UAP) {
		PRINTM(MERROR,
		       "Extended Channel Switch is only allowed for AP/GO mode\n");
		ret = -EFAULT;
		goto done;
	}

	if (priv->bss_started != MTRUE) {
		PRINTM(MERROR, "AP is not started!\n");
		ret = -EFAULT;
		goto done;
	}

	ioctl_req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (ioctl_req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	misc = (mlan_ds_misc_cfg *)ioctl_req->pbuf;
	misc->sub_command = MLAN_OID_MISC_CUSTOM_IE;
	ioctl_req->req_id = MLAN_IOCTL_MISC_CFG;
	ioctl_req->action = MLAN_ACT_SET;
	misc->param.cust_ie.type = TLV_TYPE_MGMT_IE;
	misc->param.cust_ie.len = (sizeof(custom_ie) - MAX_IE_SIZE);

	pcust_chansw_ie = (custom_ie *)&misc->param.cust_ie.ie_data_list[0];
	pcust_chansw_ie->ie_index = 0xffff;	/*Auto index */
	pcust_chansw_ie->ie_length = sizeof(IEEEtypes_ExtChanSwitchAnn_t);
	pcust_chansw_ie->mgmt_subtype_mask = MGMT_MASK_BEACON | MGMT_MASK_PROBE_RESP;	/*Add IE for
											   BEACON/probe resp */
	ext_chan_switch =
		(IEEEtypes_ExtChanSwitchAnn_t *) pcust_chansw_ie->ie_buffer;

	header_len = strlen("P2P_ECSA");
	parse_arguments(respbuf + header_len + 1, data, ARRAY_SIZE(data),
			&user_data_len);

	if (user_data_len != 2) {
		PRINTM(MERROR, "Invalid parameters\n");
		ret = -EFAULT;
		goto done;
	}

	channel = data[0];
	/* bandwidth 20:20M 40:40M 80:80M */
	bw = data[1];
	if (bw != 20 && bw != 40 && bw != 80) {
		PRINTM(MERROR, "Unsupported bandwidth\n");
		ret = -EINVAL;
		goto done;
	}
	if (channel >= 52 && channel <= 144) {
		PRINTM(MERROR, "Switch to DFS channel is not allowed!\n");
		ret = -EINVAL;
		goto done;
	}

	woal_priv_get_nonglobal_operclass_by_bw_channel(priv, bw, channel,
							&oper_class);
	if (oper_class == 0) {
		PRINTM(MERROR, "Wrong parameters!\n");
		ret = -EFAULT;
		goto done;
	}
	ext_chan_switch->element_id = EXTEND_CHANNEL_SWITCH_ANN;
	ext_chan_switch->len = 4;
	ext_chan_switch->chan_switch_mode = 1;
	ext_chan_switch->new_oper_class = oper_class;
	ext_chan_switch->new_channel_num = channel;
	ext_chan_switch->chan_switch_count = DEF_CHAN_SWITCH_COUNT;

	if (ext_chan_switch->chan_switch_mode) {
		if (netif_carrier_ok(priv->netdev))
			netif_carrier_off(priv->netdev);
		woal_stop_queue(priv->netdev);
		priv->uap_tx_blocked = MTRUE;
	}

	DBG_HEXDUMP(MCMD_D, "ECSA IE", (t_u8 *)pcust_chansw_ie->ie_buffer,
		    pcust_chansw_ie->ie_length);

	status = woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	priv->phandle->chsw_wait_q_woken = MFALSE;
	/* wait for channel switch to complete  */
	wait_event_interruptible_timeout(priv->phandle->chsw_wait_q,
					 priv->phandle->chsw_wait_q_woken,
					 (u32)HZ *
					 (ext_chan_switch->chan_switch_count +
					  2) * 110 / 1000);

	pcust_chansw_ie->ie_index = 0xffff;	/*Auto index */
	pcust_chansw_ie->mgmt_subtype_mask = 0;
	status = woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		PRINTM(MERROR, "Failed to clear ECSA IE\n");
	}
done:
	if (status != MLAN_STATUS_PENDING)
		kfree(ioctl_req);

	LEAVE();
	return ret;
}
#endif

/**
* @brief               Set random mac configure value (ON/OFF)
*
* @param priv          Pointer to moal_private structure
* @param respbuf       Pointer to response buffer
* @param resplen       Response buffer length

*  @return             Number of bytes written, negative for failure.
*/
static int
woal_priv_config_random_mac(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int ret = 0;
	int header_len = 0, space_len = 0, i;
	t_u8 rand_data[3];
	const t_u8 zero_mac[MLAN_MAC_ADDR_LENGTH] = { 0, 0, 0, 0, 0, 0 };

	ENTER();

	if (!priv || !priv->phandle) {
		PRINTM(MERROR, "priv or handle is null\n");
		ret = -EFAULT;
		goto done;
	}

	header_len = strlen("FAKEMAC");
	if ((int)strlen(respbuf) >= header_len) {
		for (i = 0; i < (int)(strlen(respbuf) - header_len - 1); i++) {
			if (respbuf[header_len + 1 + i] != ' ')
				break;
		}
		space_len = i;

		if (strncmp(respbuf + header_len + 1 + space_len, "On",
			    strlen("On")) == 0) {
			if (memcmp(priv->random_mac, zero_mac,
				   MLAN_MAC_ADDR_LENGTH)) {
				ret = sprintf(respbuf,
					      "FAKEMAC has been On\n") + 1;
				goto done;
			}
			moal_memcpy_ext(priv->phandle, priv->random_mac,
					priv->current_addr, ETH_ALEN,
					MLAN_MAC_ADDR_LENGTH);
			get_random_bytes(rand_data, 3);
			moal_memcpy_ext(priv->phandle, priv->random_mac + 3,
					rand_data, 3, 3);
			PRINTM(MMSG, "FAKEMAC parameter is On\n");
		} else if (strncmp(respbuf + header_len + 1 + space_len, "Off",
				   strlen("Off")) == 0) {
			memset(priv->random_mac, 0, ETH_ALEN);
			PRINTM(MMSG, "FAKEMAC parameter is Off\n");
		} else {
			PRINTM(MERROR, "Invalid parameter!\n");
			ret = -EINVAL;
			goto done;
		}
	} else {
		PRINTM(MERROR, "Invalid parameter!\n");
		ret = -EINVAL;
		goto done;
	}

done:
	LEAVE();
	return ret;
}

/**
 * @brief               Download start keep alive parameters
 *
 * @param priv          Pointer to moal_private structure
 * @param mkeep_alive_id       keep alive ID number
 * @param ip_pke        IP packet from host
 * @param ip_pke_len    IP packet length from host
 * @param src_mac       Source MAC address
 * @param dst_mac       Destination MAC address
 * @param period_msec   Send keep alive packet interval

 * @return      0: success  fail otherwise
 */
int
woal_start_mkeep_alive(moal_private *priv, t_u8 mkeep_alive_id,
		       t_u8 *ip_pkt, t_u16 ip_pkt_len, t_u8 *src_mac,
		       t_u8 *dst_mac, t_u32 period_msec,
		       t_u32 retry_interval, t_u8 retry_cnt)
{
	mlan_ioctl_req *ioctl_req = NULL;
	mlan_ds_misc_cfg *misc = NULL;
	mlan_status status = MLAN_STATUS_SUCCESS;
	int ret = 0;

	ENTER();

	if (!priv || !priv->phandle) {
		PRINTM(MERROR, "priv or handle is null\n");
		ret = -EFAULT;
		goto done;
	}

	ioctl_req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (ioctl_req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	misc = (mlan_ds_misc_cfg *)ioctl_req->pbuf;
	misc->sub_command = MLAN_OID_MISC_CLOUD_KEEP_ALIVE;
	ioctl_req->req_id = MLAN_IOCTL_MISC_CFG;

	if (mkeep_alive_id >= MAX_KEEP_ALIVE_ID) {
		PRINTM(MERROR, "Invalid parameters\n");
		ret = -EFAULT;
		goto done;
	}

	/* SET operation */
	ioctl_req->action = MLAN_ACT_SET;
	misc->param.keep_alive.mkeep_alive_id = mkeep_alive_id;
	misc->param.keep_alive.enable = true;
	misc->param.keep_alive.send_interval = period_msec;
	misc->param.keep_alive.retry_interval = retry_interval;
	misc->param.keep_alive.retry_count = retry_cnt;
	moal_memcpy_ext(priv->phandle, misc->param.keep_alive.dst_mac, dst_mac,
			MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
	moal_memcpy_ext(priv->phandle, misc->param.keep_alive.src_mac, src_mac,
			MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
	misc->param.keep_alive.pkt_len =
		MIN(ip_pkt_len, MKEEP_ALIVE_IP_PKT_MAX);
	moal_memcpy_ext(priv->phandle, misc->param.keep_alive.packet, ip_pkt,
			ip_pkt_len, MKEEP_ALIVE_IP_PKT_MAX);

	status = woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(ioctl_req);

	LEAVE();
	return ret;
}

/**
 * @brief               Download stop keep alive parameters
 *
 * @param priv          Pointer to moal_private structure
 * @param mkeep_alive_id       keep alive ID number
 * @param ip_pkt        Last packet
 * @param ip_pkt_len    Last packet length

 * @return      0: success  fail otherwise
 */
int
woal_stop_mkeep_alive(moal_private *priv, t_u8 mkeep_alive_id, t_u8 reset,
		      t_u8 *ip_pkt, t_u8 *pkt_len)
{
	mlan_ioctl_req *ioctl_req = NULL;
	mlan_ds_misc_cfg *misc = NULL;
	mlan_status status = MLAN_STATUS_SUCCESS;
	mlan_ds_misc_keep_alive *misc_keep_alive = NULL;
	int ret = 0;

	ENTER();

	if (!priv || !priv->phandle) {
		PRINTM(MERROR, "priv or handle is null\n");
		ret = -EFAULT;
		goto done;
	}

	ioctl_req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (ioctl_req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	misc = (mlan_ds_misc_cfg *)ioctl_req->pbuf;
	misc->sub_command = MLAN_OID_MISC_CLOUD_KEEP_ALIVE;
	ioctl_req->req_id = MLAN_IOCTL_MISC_CFG;
	misc_keep_alive = &misc->param.keep_alive;

	if (mkeep_alive_id >= MAX_KEEP_ALIVE_ID) {
		PRINTM(MERROR, "Invalid parameters\n");
		ret = -EFAULT;
		goto done;
	}

	/* GET operation */
	ioctl_req->action = MLAN_ACT_GET;
	misc_keep_alive->mkeep_alive_id = mkeep_alive_id;
	misc_keep_alive->enable = false;

	status = woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	if (!misc_keep_alive->enable) {
		PRINTM(MERROR, "ID %d is already stop\n", mkeep_alive_id);
		goto done;
	}

	if (reset)
		ioctl_req->action = MLAN_ACT_RESET;
	else
		/* SET operation */
		ioctl_req->action = MLAN_ACT_SET;
	misc_keep_alive->mkeep_alive_id = mkeep_alive_id;
	misc_keep_alive->enable = false;

	status = woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}
#ifdef STA_CFG80211
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
	if (IS_STA_CFG80211(priv->phandle->params.cfg80211_wext)) {
		ret = woal_mkeep_alive_vendor_event(priv,
						    &misc->param.keep_alive);
		if (ret)
			PRINTM(MERROR,
			       "Keep alive vendor event upload failed\n");
	}
#endif
#endif
	if (pkt_len) {
		*pkt_len = MIN(misc_keep_alive->pkt_len,
			       (MKEEP_ALIVE_IP_PKT_MAX - 1));
		PRINTM(MINFO, "keep alive stop pkt_len is %d\n", *pkt_len);
	}
	if (*pkt_len && ip_pkt)
		moal_memcpy_ext(priv->phandle, ip_pkt, misc_keep_alive->packet,
				*pkt_len, *pkt_len);

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(ioctl_req);

	LEAVE();
	return ret;
}

/**
 * @brief               Save cloud keep alive params in driver handle
 *
 * @param priv          Pointer to moal_private structure
 * @params              Other params for keep alive

 *  @return             Number of bytes written, negative for failure.
 */
int
woal_priv_save_cloud_keep_alive_params(moal_private *priv,
				       t_u8 mkeep_alive_id, t_u8 enable,
				       t_u16 ether_type, t_u8 *ip_pkt,
				       t_u16 ip_pkt_len, t_u8 *src_mac,
				       t_u8 *dst_mac, t_u32 period_msec,
				       t_u32 retry_interval, t_u8 retry_cnt)
{
	mlan_ioctl_req *ioctl_req = NULL;
	mlan_ds_misc_cfg *misc = NULL;
	int ret = 0;
	mlan_ds_misc_keep_alive *keep_alive = NULL;
	moal_handle *phandle = NULL;

	ENTER();

	if (!priv || !priv->phandle) {
		PRINTM(MERROR, "priv or handle is null\n");
		ret = -EFAULT;
		goto done;
	}
	phandle = priv->phandle;

	ioctl_req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (ioctl_req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	misc = (mlan_ds_misc_cfg *)ioctl_req->pbuf;
	misc->sub_command = MLAN_OID_MISC_CLOUD_KEEP_ALIVE;
	ioctl_req->req_id = MLAN_IOCTL_MISC_CFG;

	if (mkeep_alive_id >= MAX_KEEP_ALIVE_ID) {
		PRINTM(MERROR, "Invalid parameters\n");
		ret = -EINVAL;
		goto done;
	}

	/* GET operation */
	ioctl_req->action = MLAN_ACT_GET;
	misc->param.keep_alive.mkeep_alive_id = mkeep_alive_id;
	misc->param.keep_alive.enable = true;

	ret = woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT);
	if (ret != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	if (misc->param.keep_alive.enable) {
		PRINTM(MERROR, "ID %d is in use\n", mkeep_alive_id);
		ret = -EINVAL;
		goto done;
	}

	keep_alive = &phandle->keep_alive[mkeep_alive_id];
	keep_alive->mkeep_alive_id = mkeep_alive_id;
	keep_alive->enable = enable;
	if (enable) {
		keep_alive->cached = true;
		keep_alive->send_interval = period_msec;
		keep_alive->retry_interval = retry_interval;
		keep_alive->retry_count = retry_cnt;
		moal_memcpy_ext(phandle, keep_alive->dst_mac, dst_mac,
				MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
		moal_memcpy_ext(phandle, keep_alive->src_mac, src_mac,
				MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
		keep_alive->pkt_len = MIN(ip_pkt_len, MKEEP_ALIVE_IP_PKT_MAX);
		moal_memcpy_ext(phandle, keep_alive->packet, ip_pkt, ip_pkt_len,
				MKEEP_ALIVE_IP_PKT_MAX);
		if (ether_type)
			keep_alive->ether_type = ether_type;
		else
			keep_alive->ether_type = 0;
	}

done:
	if (ret != MLAN_STATUS_PENDING)
		kfree(ioctl_req);

	LEAVE();
	return ret;
}

/**
 * @brief               Cloud keep alive feature
 *
 * @param priv          Pointer to moal_private structure
 * @param respbuf       Pointer to response buffer
 * @param resplen       Response buffer length

 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_cloud_keep_alive(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int ret = 0;
	cloud_keep_alive *keep_alive = NULL;
	int header_len = 0;

	ENTER();

	header_len = strlen(PRIV_CMD_CLOUD_KEEP_ALIVE);

	keep_alive = (cloud_keep_alive *) (respbuf + header_len);

	if (keep_alive->enable) {
		ret = woal_priv_save_cloud_keep_alive_params(priv,
							     keep_alive->
							     mkeep_alive_id,
							     keep_alive->enable,
							     0, keep_alive->pkt,
							     keep_alive->
							     pkt_len,
							     keep_alive->
							     src_mac,
							     keep_alive->
							     dst_mac,
							     keep_alive->
							     sendInterval,
							     keep_alive->
							     retryInterval,
							     keep_alive->
							     retryCount);
	} else {
		if (0 != woal_stop_mkeep_alive(priv, keep_alive->mkeep_alive_id,
					       keep_alive->reset,
					       keep_alive->pkt,
					       &keep_alive->pkt_len)) {
			ret = -EFAULT;
			return ret;
		}
		ret = respbuflen;
	}

	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get static rx abort config
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_rx_abort_cfg(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	mlan_ioctl_req *req = NULL;
	mlan_ds_misc_cfg *misc = NULL;
	int ret = 0;
	int data[2] = { 0 };
	int header_len = 0, user_data_len = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	if (!respbuf) {
		PRINTM(MERROR, "response buffer is not available!\n");
		ret = -EINVAL;
		goto done;
	}
	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_RX_ABORT_CFG);
	user_data_len = strlen(respbuf) - header_len;

	/* Allocate an IOCTL request buffer */
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	/* Fill request buffer */
	misc = (mlan_ds_misc_cfg *)req->pbuf;
	misc->sub_command = MLAN_OID_MISC_RX_ABORT_CFG;
	req->req_id = MLAN_IOCTL_MISC_CFG;
	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		user_data_len = 0;
		req->action = MLAN_ACT_GET;
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len, data, ARRAY_SIZE(data),
				&user_data_len);
		if (user_data_len > 2 ||
		    (data[0] == MTRUE && user_data_len != 2)) {
			PRINTM(MERROR, "Invalid number of args!\n");
			ret = -EINVAL;
			goto done;
		}
		if (data[0] == MTRUE && data[1] > 0x7f) {
			PRINTM(MERROR, "Invalid threshold value\n");
			ret = -EINVAL;
			goto done;
		}
		misc->param.rx_abort_cfg.enable = (t_u8)data[0];
		if (user_data_len == 2)
			misc->param.rx_abort_cfg.rssi_threshold = (t_s8)data[1];
		req->action = MLAN_ACT_SET;
	}
	/* Send IOCTL request to MLAN */
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	data[0] = misc->param.rx_abort_cfg.enable;
	data[1] = misc->param.rx_abort_cfg.rssi_threshold;
	moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)data, sizeof(data),
			respbuflen);
	ret = sizeof(data);
done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);

	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get dynamic rx abort config
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_rx_abort_cfg_ext(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	mlan_ioctl_req *req = NULL;
	mlan_ds_misc_cfg *misc = NULL;
	int ret = 0;
	int data[3] = { 0 };
	int header_len = 0, user_data_len = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	if (!respbuf) {
		PRINTM(MERROR, "response buffer is not available!\n");
		ret = -EINVAL;
		goto done;
	}
	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_RX_ABORT_CFG_EXT);
	user_data_len = strlen(respbuf) - header_len;

	/* Allocate an IOCTL request buffer */
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	/* Fill request buffer */
	misc = (mlan_ds_misc_cfg *)req->pbuf;
	misc->sub_command = MLAN_OID_MISC_RX_ABORT_CFG_EXT;
	req->req_id = MLAN_IOCTL_MISC_CFG;
	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		user_data_len = 0;
		req->action = MLAN_ACT_GET;
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len, data, ARRAY_SIZE(data),
				&user_data_len);
		if (user_data_len > 3 ||
		    (data[0] == MTRUE && user_data_len != 3)) {
			PRINTM(MERROR, "Invalid number of args!\n");
			ret = -EINVAL;
			goto done;
		}
		if (data[0] == MTRUE) {
			if (data[1] > 0x7f) {
				PRINTM(MERROR, "Invalid margin value\n");
				ret = -EINVAL;
				goto done;
			}
			if (data[2] > 0x7f) {
				PRINTM(MERROR,
				       "Invalid ceil threshold value\n");
				ret = -EINVAL;
				goto done;
			}
		}
		misc->param.rx_abort_cfg_ext.enable = (t_u8)data[0];
		if (user_data_len > 1) {
			misc->param.rx_abort_cfg_ext.rssi_margin =
				(t_s8)data[1];
			misc->param.rx_abort_cfg_ext.ceil_rssi_threshold =
				(t_s8)data[2];
		}
		req->action = MLAN_ACT_SET;
	}
	/* Send IOCTL request to MLAN */
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	data[0] = misc->param.rx_abort_cfg_ext.enable;
	data[1] = misc->param.rx_abort_cfg_ext.rssi_margin;
	data[2] = misc->param.rx_abort_cfg_ext.ceil_rssi_threshold;
	moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)data, sizeof(data),
			respbuflen);
	ret = sizeof(data);
done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);

	LEAVE();
	return ret;
}

/**
 *  @brief Enable/Disable Un-associated Dot11mc FTM Frame exchanges
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_dot11mc_unassoc_ftm_cfg(moal_private *priv, t_u8 *respbuf,
				  t_u32 respbuflen)
{
	mlan_ioctl_req *req = NULL;
	mlan_ds_misc_cfg *misc = NULL;
	int ret = 0;
	int data[1] = { 0 };
	int header_len = 0, user_data_len = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	if (!respbuf) {
		PRINTM(MERROR, "response buffer is not available!\n");
		ret = -EINVAL;
		goto done;
	}
	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_DOT11MC_UNASSOC_FTM_CFG);
	user_data_len = strlen(respbuf) - header_len;

	/* Allocate an IOCTL request buffer */
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	/* Fill request buffer */
	misc = (mlan_ds_misc_cfg *)req->pbuf;
	misc->sub_command = MLAN_OID_MISC_DOT11MC_UNASSOC_FTM_CFG;
	req->req_id = MLAN_IOCTL_MISC_CFG;
	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		user_data_len = 0;
		req->action = MLAN_ACT_GET;
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len, data, ARRAY_SIZE(data),
				&user_data_len);
		if (user_data_len > 1) {
			PRINTM(MERROR, "Invalid number of args!\n");
			ret = -EINVAL;
			goto done;
		}
		if ((data[0] != MTRUE) && (data[0] != MFALSE)) {
			PRINTM(MERROR, "Invalid state for unassoc ftm\n");
			ret = -EINVAL;
			goto done;
		}
		misc->param.dot11mc_unassoc_ftm_cfg.state = (t_u16)data[0];
		req->action = MLAN_ACT_SET;
	}
	/* Send IOCTL request to MLAN */
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	data[0] = misc->param.dot11mc_unassoc_ftm_cfg.state;
	moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)data, sizeof(data),
			respbuflen);
	ret = sizeof(data);
done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);

	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get Tx  AMPDU protection mode
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_tx_ampdu_prot_mode(moal_private *priv, t_u8 *respbuf,
			     t_u32 respbuflen)
{
	mlan_ioctl_req *req = NULL;
	mlan_ds_misc_cfg *misc = NULL;
	int ret = 0;
	int data[1] = { 0 };
	int header_len = 0, user_data_len = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	if (!respbuf) {
		PRINTM(MERROR, "response buffer is not available!\n");
		ret = -EINVAL;
		goto done;
	}
	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_TX_AMPDU_PROT_MODE);
	user_data_len = strlen(respbuf) - header_len;

	/* Allocate an IOCTL request buffer */
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	/* Fill request buffer */
	misc = (mlan_ds_misc_cfg *)req->pbuf;
	misc->sub_command = MLAN_OID_MISC_TX_AMPDU_PROT_MODE;
	req->req_id = MLAN_IOCTL_MISC_CFG;
	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		user_data_len = 0;
		req->action = MLAN_ACT_GET;
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len, data, ARRAY_SIZE(data),
				&user_data_len);
		if (user_data_len > 1) {
			PRINTM(MERROR, "Invalid number of args!\n");
			ret = -EINVAL;
			goto done;
		}
		if (data[0] > TX_AMPDU_DYNAMIC_RTS_CTS) {
			PRINTM(MERROR, "Invalid protection mode\n");
			ret = -EINVAL;
			goto done;
		}
		misc->param.tx_ampdu_prot_mode.mode = (t_u16)data[0];
		req->action = MLAN_ACT_SET;
	}
	/* Send IOCTL request to MLAN */
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	data[0] = misc->param.tx_ampdu_prot_mode.mode;
	moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)data, sizeof(data),
			respbuflen);
	ret = sizeof(data);
done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);

	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get Tx rate adapt config
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_rate_adapt_cfg(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	mlan_ioctl_req *req = NULL;
	mlan_ds_misc_cfg *misc = NULL;
	int ret = 0;
	int data[4] = { 0 };
	int header_len = 0, user_data_len = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	if (!respbuf) {
		PRINTM(MERROR, "response buffer is not available!\n");
		ret = -EINVAL;
		goto done;
	}
	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_RATE_ADAPT_CFG);
	user_data_len = strlen(respbuf) - header_len;

	/* Allocate an IOCTL request buffer */
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	/* Fill request buffer */
	misc = (mlan_ds_misc_cfg *)req->pbuf;
	misc->sub_command = MLAN_OID_MISC_RATE_ADAPT_CFG;
	req->req_id = MLAN_IOCTL_MISC_CFG;
	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		user_data_len = 0;
		req->action = MLAN_ACT_GET;
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len, data, ARRAY_SIZE(data),
				&user_data_len);
		if (user_data_len < 1) {
			PRINTM(MERROR, "Invalid number of args!\n");
			ret = -EINVAL;
			goto done;
		}
		if (data[0] > RATEADAPT_ALGO_SR) {
			PRINTM(MERROR, "Invalid Rateadapt Algorithm\n");
			ret = -EINVAL;
			goto done;
		}
		if (data[0] == RATEADAPT_ALGO_SR && user_data_len > 1) {
			if ((data[1] & data[2]) == 0xff) {
				/* dynamic CCA noise based rate adapation enable
				 * request nothing to do here
				 */
			} else if (data[1] > 100 || data[2] > 100) {
				PRINTM(MERROR,
				       "Invalid success rate threshold value\n");
				ret = -EINVAL;
				goto done;
			}
			if (data[3] < 10 || data[3] > 0xffff) {
				PRINTM(MERROR, "Invalid interval value\n");
				ret = -EINVAL;
				goto done;
			}
		}
		misc->param.rate_adapt_cfg.sr_rateadapt = (t_u8)data[0];
		if (data[0] == RATEADAPT_ALGO_SR && user_data_len > 1) {
			misc->param.rate_adapt_cfg.ra_low_thresh =
				(t_u8)data[1];
			misc->param.rate_adapt_cfg.ra_high_thresh =
				(t_u8)data[2];
			misc->param.rate_adapt_cfg.ra_interval = (t_u16)data[3];
		}
		req->action = MLAN_ACT_SET;
	}
	/* Send IOCTL request to MLAN */
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}
	data[0] = misc->param.rate_adapt_cfg.sr_rateadapt;
	data[1] = misc->param.rate_adapt_cfg.ra_low_thresh;
	data[2] = misc->param.rate_adapt_cfg.ra_high_thresh;
	data[3] = misc->param.rate_adapt_cfg.ra_interval;
	moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)data, sizeof(data),
			respbuflen);
	ret = sizeof(data);
done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);

	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get global cck desense config
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_cck_desense_cfg(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	mlan_ioctl_req *req = NULL;
	mlan_ds_misc_cfg *misc = NULL;
	int ret = 0;
	int data[5] = { 0 };
	int header_len = 0, user_data_len = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	if (!respbuf) {
		PRINTM(MERROR, "response buffer is not available!\n");
		ret = -EINVAL;
		goto done;
	}
	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_CCK_DESENSE_CFG);
	user_data_len = strlen(respbuf) - header_len;

	/* Allocate an IOCTL request buffer */
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	/* Fill request buffer */
	misc = (mlan_ds_misc_cfg *)req->pbuf;
	misc->sub_command = MLAN_OID_MISC_CCK_DESENSE_CFG;
	req->req_id = MLAN_IOCTL_MISC_CFG;
	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		user_data_len = 0;
		req->action = MLAN_ACT_GET;
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len, data, ARRAY_SIZE(data),
				&user_data_len);
		if (user_data_len > 5) {
			PRINTM(MERROR, "Invalid number of args!\n");
			ret = -EINVAL;
			goto done;
		}
		if (data[0] > CCK_DESENSE_MODE_DYN_ENH) {
			PRINTM(MERROR, "Invalid cck desense mode\n");
			ret = -EINVAL;
			goto done;
		}
		if ((data[0] == CCK_DESENSE_MODE_DISABLED &&
		     user_data_len > 1) ||
		    (data[0] == CCK_DESENSE_MODE_DYNAMIC &&
		     user_data_len != 3) ||
		    (data[0] == CCK_DESENSE_MODE_DYN_ENH &&
		     (user_data_len < 3 || user_data_len == 4))) {
			PRINTM(MERROR,
			       "Invalid number of args for requested mode\n");
			ret = -EINVAL;
			goto done;
		}
		if (user_data_len > 1) {
			if (data[1] > 0x7f) {
				PRINTM(MERROR, "Invalid margin value\n");
				ret = -EINVAL;
				goto done;
			}
			if (data[2] > 0x7f) {
				PRINTM(MERROR,
				       "Invalid ceil threshold value\n");
				ret = -EINVAL;
				goto done;
			}
		}
		if (user_data_len > 3) {
			if (data[3] > 0xff || data[4] > 0xff) {
				PRINTM(MERROR,
				       "Invalid ON/OFF intervals value\n");
				ret = -EINVAL;
				goto done;
			}
		}
		misc->param.cck_desense_cfg.mode = (t_u8)data[0];
		if (user_data_len > 1) {
			misc->param.cck_desense_cfg.margin = (t_s8)data[1];
			misc->param.cck_desense_cfg.ceil_thresh = (t_s8)data[2];
		}
		if (data[0] == CCK_DESENSE_MODE_DYN_ENH) {
			if (user_data_len > 3) {
				misc->param.cck_desense_cfg.num_on_intervals =
					(t_u8)data[3];
				misc->param.cck_desense_cfg.num_off_intervals =
					(t_u8)data[4];
			} else {
				/* set these to 0xff. This will indicate the FW
				 * to use previously set values.
				 */
				misc->param.cck_desense_cfg.num_on_intervals =
					0xff;
				misc->param.cck_desense_cfg.num_off_intervals =
					0xff;
			}
		}
		req->action = MLAN_ACT_SET;
	}
	/* Send IOCTL request to MLAN */
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	data[0] = misc->param.cck_desense_cfg.mode;
	data[1] = misc->param.cck_desense_cfg.margin;
	data[2] = misc->param.cck_desense_cfg.ceil_thresh;
	data[3] = misc->param.cck_desense_cfg.num_on_intervals;
	data[4] = misc->param.cck_desense_cfg.num_off_intervals;
	moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)data, sizeof(data),
			respbuflen);
	ret = sizeof(data);

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);

	LEAVE();
	return ret;
}

/**
 * @brief               set/get low power mode
 *
 * @param priv          Pointer to moal_private structure
 * @param respbuf       Pointer to response buffer
 * @param resplen       Response buffer length

 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_set_get_lpm(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	int ret = 0;
	mlan_ioctl_req *req = NULL;
	mlan_ds_power_cfg *cfg = NULL;
	int data = 0;
	int user_data_len = 0, header_len = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	if (IS_CARD9098(priv->phandle->card_type) ||
	    IS_CARD9097(priv->phandle->card_type)) {
		header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_LPM);
		if ((int)strlen(respbuf) == header_len) {
			/* GET operation */
			user_data_len = 0;
		} else {
			/* SET operation */
			parse_arguments(respbuf + header_len, &data, 1,
					&user_data_len);
		}
		if (user_data_len >= 2) {
			PRINTM(MERROR, "Too many arguments\n");
			ret = -EINVAL;
			goto done;
		} else {
			req = woal_alloc_mlan_ioctl_req(sizeof
							(mlan_ds_power_cfg));
			if (req == NULL) {
				ret = -ENOMEM;
				goto done;
			}

			cfg = (mlan_ds_power_cfg *)req->pbuf;
			if (user_data_len == 0) {
				req->action = MLAN_ACT_GET;
			} else {
				cfg->param.lpm = data;
				req->action = MLAN_ACT_SET;
			}
		}
		cfg->sub_command = MLAN_OID_POWER_LOW_POWER_MODE;
		req->req_id = MLAN_IOCTL_POWER_CFG;

		status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
		if (status != MLAN_STATUS_SUCCESS) {
			ret = -EFAULT;
			goto done;
		}

		data = cfg->param.lpm;
		moal_memcpy_ext(priv->phandle, respbuf, (t_u8 *)&data,
				sizeof(data), respbuflen);
		ret = sizeof(data);
	} else
		PRINTM(MERROR, "Low power mode command is not supported!\n");

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get HW ARB config
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_arbcfg(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	mlan_ioctl_req *req = NULL;
	mlan_ds_misc_cfg *misc = NULL;
	int ret = 0;
	int data[1];
	int header_len = 0, user_data_len = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	if (!respbuf) {
		PRINTM(MERROR, "response buffer is not available!\n");
		ret = -EINVAL;
		goto done;
	}
	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_ARB_CFG);
	user_data_len = strlen(respbuf) - header_len;

	/* Allocate an IOCTL request buffer */
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (req == NULL) {
		ret = -ENOMEM;
		goto done;
	}
	/* Fill request buffer */
	misc = (mlan_ds_misc_cfg *)req->pbuf;
	misc->sub_command = MLAN_OID_MISC_ARB_CONFIG;
	req->req_id = MLAN_IOCTL_MISC_CFG;
	if ((int)strlen(respbuf) == header_len) {
		/* GET operation */
		user_data_len = 0;
		req->action = MLAN_ACT_GET;
	} else {
		/* SET operation */
		parse_arguments(respbuf + header_len, data, ARRAY_SIZE(data),
				&user_data_len);
		if (user_data_len != 1) {
			PRINTM(MERROR, "Invalid Parameter\n");
			ret = -EFAULT;
			goto done;
		}
		if (data[0] < 0 || data[0] > 4) {
			PRINTM(MERROR, "Invalid Parameter: arb mode 0-4\n");
			ret = -EFAULT;
			goto done;
		}
		misc->param.arb_cfg.arb_mode = (t_u32)data[0];
		req->action = MLAN_ACT_SET;
	}
	/* Send IOCTL request to MLAN */
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

	data[0] = misc->param.arb_cfg.arb_mode;
	moal_memcpy_ext(priv->phandle, respbuf, (t_u32 *)data, sizeof(data),
			respbuflen);
	ret = sizeof(data);
done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);

	LEAVE();
	return ret;
}

/**
 *  @brief      Timer function for TP state command.
 *
 *  @param data pointer to a buffer
 *
 *  @return     N/A
 */
void
woal_tp_acnt_timer_func(void *context)
{
	moal_handle *phandle = (moal_handle *)context;
	int i = 0;

	if (phandle == NULL)
		return;
	PRINTM(MDATA, "####### CPU%d: tp acnt timer\n", smp_processor_id());
	/* Tx TP accounting */
	for (i = 0; i < MAX_TP_ACCOUNT_DROP_POINT_NUM; i++) {
		phandle->tp_acnt.tx_bytes_rate[i] =
			phandle->tp_acnt.tx_bytes[i] -
			phandle->tp_acnt.tx_bytes_last[i];
		phandle->tp_acnt.tx_bytes_last[i] =
			phandle->tp_acnt.tx_bytes[i];
		phandle->tp_acnt.tx_packets_rate[i] =
			phandle->tp_acnt.tx_packets[i] -
			phandle->tp_acnt.tx_packets_last[i];
		phandle->tp_acnt.tx_packets_last[i] =
			phandle->tp_acnt.tx_packets[i];
	}
	phandle->tp_acnt.tx_pending = atomic_read(&phandle->tx_pending);
	/* Tx Interrupt accounting */
	phandle->tp_acnt.tx_intr_rate =
		phandle->tp_acnt.tx_intr_cnt - phandle->tp_acnt.tx_intr_last;
	phandle->tp_acnt.tx_intr_last = phandle->tp_acnt.tx_intr_cnt;

	/* Rx TP accounting */
	for (i = 0; i < MAX_TP_ACCOUNT_DROP_POINT_NUM; i++) {
		phandle->tp_acnt.rx_bytes_rate[i] =
			phandle->tp_acnt.rx_bytes[i] -
			phandle->tp_acnt.rx_bytes_last[i];
		phandle->tp_acnt.rx_bytes_last[i] =
			phandle->tp_acnt.rx_bytes[i];
		phandle->tp_acnt.rx_packets_rate[i] =
			phandle->tp_acnt.rx_packets[i] -
			phandle->tp_acnt.rx_packets_last[i];
		phandle->tp_acnt.rx_packets_last[i] =
			phandle->tp_acnt.rx_packets[i];
	}
	phandle->tp_acnt.rx_pending = atomic_read(&phandle->rx_pending);
	// Interrupt accounting, RX
	phandle->tp_acnt.rx_intr_rate =
		phandle->tp_acnt.rx_intr_cnt - phandle->tp_acnt.rx_intr_last;
	phandle->tp_acnt.rx_intr_last = phandle->tp_acnt.rx_intr_cnt;
	phandle->tp_acnt.rx_amsdu_cnt_rate =
		phandle->tp_acnt.rx_amsdu_cnt -
		phandle->tp_acnt.rx_amsdu_cnt_last;
	phandle->tp_acnt.rx_amsdu_cnt_last = phandle->tp_acnt.rx_amsdu_cnt;

	phandle->tp_acnt.rx_amsdu_pkt_cnt_rate =
		phandle->tp_acnt.rx_amsdu_pkt_cnt -
		phandle->tp_acnt.rx_amsdu_pkt_cnt_last;
	phandle->tp_acnt.rx_amsdu_pkt_cnt_last =
		phandle->tp_acnt.rx_amsdu_pkt_cnt;

	phandle->tp_acnt.tx_amsdu_cnt_rate =
		phandle->tp_acnt.tx_amsdu_cnt -
		phandle->tp_acnt.tx_amsdu_cnt_last;
	phandle->tp_acnt.tx_amsdu_cnt_last = phandle->tp_acnt.tx_amsdu_cnt;

	phandle->tp_acnt.tx_amsdu_pkt_cnt_rate =
		phandle->tp_acnt.tx_amsdu_pkt_cnt -
		phandle->tp_acnt.tx_amsdu_pkt_cnt_last;
	phandle->tp_acnt.tx_amsdu_pkt_cnt_last =
		phandle->tp_acnt.tx_amsdu_pkt_cnt;

	/* re-arm timer */
	woal_mod_timer(&phandle->tp_acnt.timer, 1000);
}

/**
 *  @brief      set tp state to mlan
 *
 *  @param priv  pointer to moal_private
 *
 *  @return     N/A
 */
void
woal_set_tp_state(moal_private *priv)
{
	mlan_ioctl_req *req = NULL;
	mlan_ds_misc_cfg *misc = NULL;
	moal_handle *handle = priv->phandle;
	mlan_status status = MLAN_STATUS_SUCCESS;
	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
	if (req == NULL)
		return;
	/* Fill request buffer */
	misc = (mlan_ds_misc_cfg *)req->pbuf;
	misc->sub_command = MLAN_OID_MISC_TP_STATE;
	req->req_id = MLAN_IOCTL_MISC_CFG;
	misc->param.tp_state.on = handle->tp_acnt.on;
	misc->param.tp_state.drop_point = handle->tp_acnt.drop_point;
	req->action = MLAN_ACT_SET;
	/* Send IOCTL request to MLAN */
	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	return;
}

/**
 *  @brief Set/Get TP statistics.
 *
 *  @param priv         A pointer to moal_private structure
 *  @param respbuf      A pointer to response buffer
 *  @param respbuflen   Available length of response buffer
 *
 *  @return             Number of bytes written, negative for failure.
 */
static int
woal_priv_set_tp_state(moal_private *priv, t_u8 *respbuf, t_u32 respbuflen)
{
	moal_handle *handle = priv->phandle;
	int ret = 0;
	int data[2];
	int header_len = 0, user_data_len = 0;

	ENTER();

	if (!respbuf) {
		PRINTM(MERROR, "response buffer is not available!\n");
		ret = -EINVAL;
		goto done;
	}
	header_len = strlen(CMD_NXP) + strlen(PRIV_CMD_TP_STATE);
	user_data_len = strlen(respbuf) - header_len;
	parse_arguments(respbuf + header_len, data, ARRAY_SIZE(data),
			&user_data_len);
	if (user_data_len > 2) {
		PRINTM(MERROR, "Invalid number of args!\n");
		ret = -EINVAL;
		goto done;
	}
	if (user_data_len) {
		handle->tp_acnt.on = data[0];
		/* Enable TP statistics collection */
		if (data[0] == 1) {
			handle->tp_acnt.drop_point = data[1];
			if (handle->is_tp_acnt_timer_set == MFALSE) {
				woal_initialize_timer(&handle->tp_acnt.timer,
						      woal_tp_acnt_timer_func,
						      handle);
				handle->is_tp_acnt_timer_set = MTRUE;
				woal_mod_timer(&handle->tp_acnt.timer, 1000);
			}
		} else {
			if (handle->is_tp_acnt_timer_set) {
				woal_cancel_timer(&handle->tp_acnt.timer);
				handle->is_tp_acnt_timer_set = MFALSE;
			}
			memset((void *)&handle->tp_acnt, 0,
			       sizeof(moal_tp_acnt_t));
		}
		woal_set_tp_state(priv);
	}
	/* Get command results */
	if (user_data_len == 0) {
		moal_memcpy_ext(handle, respbuf, (t_u8 *)(&handle->tp_acnt),
				sizeof(handle->tp_acnt), respbuflen);
		ret = sizeof(handle->tp_acnt);
	}

done:
	LEAVE();
	return ret;
}

/**
 *  @brief Set priv command for Android
 *  @param dev          A pointer to net_device structure
 *  @param req          A pointer to ifreq structure
 *
 *  @return             0 --success, otherwise fail
 */
int
woal_android_priv_cmd(struct net_device *dev, struct ifreq *req)
{
	int ret = 0;
	android_wifi_priv_cmd priv_cmd;
	moal_private *priv = (moal_private *)netdev_priv(dev);
	char *buf = NULL;
	char *pdata;
#ifdef STA_SUPPORT
	int power_mode = 0;
	int band = 0;
	char *pband = NULL;
	mlan_bss_info bss_info;
	mlan_ds_get_signal signal;
	mlan_rate_cfg_t rate;
	t_u8 country_code[COUNTRY_CODE_LEN];
	int copy_len = 0;
#endif
	int len = 0;
	gfp_t flag;
	char *cmd_buf = NULL;
#if defined(STA_CFG80211) && defined(UAP_CFG80211)
	int cfg80211_wext;
#endif

	ENTER();
	if (!priv || !priv->phandle) {
		PRINTM(MERROR, "priv or handle is NULL\n");
		ret = -EFAULT;
		goto done;
	}
#if defined(STA_CFG80211) && defined(UAP_CFG80211)
	cfg80211_wext = priv->phandle->params.cfg80211_wext;
#endif
	if (copy_from_user(&priv_cmd, req->ifr_data,
			   sizeof(android_wifi_priv_cmd))) {
		ret = -EFAULT;
		goto done;
	}
#define CMD_BUF_LEN 4096
	if (priv_cmd.used_len < 0 || priv_cmd.total_len <= 0 ||
	    priv_cmd.used_len > priv_cmd.total_len) {
		PRINTM(MERROR,
		       "Invalid Android priv cmd len. used_len: %d, total_len: %d\n",
		       priv_cmd.used_len, priv_cmd.total_len);
		ret = -EINVAL;
		goto done;
	}
	if (priv_cmd.total_len + 1 > CMD_BUF_LEN)
		priv_cmd.total_len = CMD_BUF_LEN - 1;

	flag = (in_atomic() || irqs_disabled())? GFP_ATOMIC : GFP_KERNEL;
	buf = kzalloc(CMD_BUF_LEN, flag);
	if (!buf) {
		PRINTM(MERROR, "%s: failed to allocate memory\n", __FUNCTION__);
		ret = -ENOMEM;
		goto done;
	}
#ifdef USERSPACE_32BIT_OVER_KERNEL_64BIT
	moal_memcpy_ext(priv->phandle, &cmd_buf, &priv_cmd.buf, sizeof(cmd_buf),
			sizeof(cmd_buf));
#else
	cmd_buf = priv_cmd.buf;
#endif
	if (copy_from_user(buf, (const void __user *)cmd_buf,
			   priv_cmd.total_len)) {
		ret = -EFAULT;
		goto done;
	}
	buf[CMD_BUF_LEN - 1] = '\0';

	PRINTM(MIOCTL, "Android priv cmd: [%s] on [%s]\n", buf, req->ifr_name);

	if (strncmp(buf, CMD_NXP, strlen(CMD_NXP)) &&
	    woal_check_driver_status(priv->phandle)) {
		PRINTM(MERROR, "%s fail when driver hang\n", buf);
		ret = -EFAULT;
		goto done;
	}

	if (strncmp(buf, CMD_NXP, strlen(CMD_NXP)) == 0) {
		/* This command has come from mlanutl app */

		/* Check command */
		if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_VERSION,
			     strlen(PRIV_CMD_VERSION)) == 0) {
			/* Get version */
			len = woal_get_priv_driver_version(priv, buf,
							   priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_BANDCFG,
				    strlen(PRIV_CMD_BANDCFG)) == 0) {
			/* Set/Get band configuration */
			len = woal_setget_priv_bandcfg(priv, buf,
						       priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_HOSTCMD,
				    strlen(PRIV_CMD_HOSTCMD)) == 0) {
			/* hostcmd configuration */
			len = woal_priv_hostcmd(priv, buf, priv_cmd.total_len,
						MOAL_IOCTL_WAIT);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_11AXCMDCFG,
				    strlen(PRIV_CMD_11AXCMDCFG)) == 0) {
			/* 11ax command */
			pdata = buf + strlen(CMD_NXP) +
				strlen(PRIV_CMD_11AXCMDCFG);
			len = priv_cmd.total_len - strlen(CMD_NXP) +
				strlen(PRIV_CMD_11AXCMDCFG);
			len = woal_setget_priv_11axcmdcfg(priv, pdata, len,
							  MOAL_IOCTL_WAIT);
			len += strlen(CMD_NXP) + strlen(PRIV_CMD_11AXCMDCFG);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_RANGE_EXT,
				    strlen(PRIV_CMD_RANGE_EXT)) == 0) {
			len = woal_setget_priv_range_ext(priv, buf,
							 priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_HTTXCFG,
				    strlen(PRIV_CMD_HTTXCFG)) == 0) {
			/* Set/Get HT Tx configuration */
			len = woal_setget_priv_httxcfg(priv, buf,
						       priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_HTCAPINFO,
				    strlen(PRIV_CMD_HTCAPINFO)) == 0) {
			/* Set/Get HT Capability information */
			len = woal_setget_priv_htcapinfo(priv, buf,
							 priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_ADDBAPARA,
				    strlen(PRIV_CMD_ADDBAPARA)) == 0) {
			/* Set/Get Add BA parameters */
			len = woal_setget_priv_addbapara(priv, buf,
							 priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_AGGRPRIOTBL,
				    strlen(PRIV_CMD_AGGRPRIOTBL)) == 0) {
			/* Set/Get Aggregation priority table parameters */
			len = woal_setget_priv_aggrpriotbl(priv, buf,
							   priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_ADDBAREJECT,
				    strlen(PRIV_CMD_ADDBAREJECT)) == 0) {
			/* Set/Get Add BA reject parameters */
			len = woal_setget_priv_addbareject(priv, buf,
							   priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_DELBA,
				    strlen(PRIV_CMD_DELBA)) == 0) {
			/* Delete selective BA based on parameters */
			len = woal_priv_delba(priv, buf, priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP),
				    PRIV_CMD_REJECTADDBAREQ,
				    strlen(PRIV_CMD_REJECTADDBAREQ)) == 0) {
			/* Set/Get the reject addba requst conditions */
			len = woal_priv_rejectaddbareq(priv, buf,
						       priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_VHTCFG,
				    strlen(PRIV_CMD_VHTCFG)) == 0) {
			/* Set/Get 11AC configuration */
			len = woal_setget_priv_vhtcfg(priv, buf,
						      priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_OPERMODECFG,
				    strlen(PRIV_CMD_OPERMODECFG)) == 0) {
			/* Set/Get 11AC configuration */
			len = woal_setget_priv_opermodecfg(priv, buf,
							   priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_DATARATE,
				    strlen(PRIV_CMD_DATARATE)) == 0) {
			/* Get data rate */
			len = woal_get_priv_datarate(priv, buf,
						     priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_TXRATECFG,
				    strlen(PRIV_CMD_TXRATECFG)) == 0) {
			/* Set/Get tx rate cfg */
			len = woal_setget_priv_txratecfg(priv, buf,
							 priv_cmd.total_len);
			goto handled;
#if defined(STA_SUPPORT) || defined(UAP_SUPPORT)
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_GETLOG,
				    strlen(PRIV_CMD_GETLOG)) == 0) {
			/* Get wireless stats information */
			len = woal_get_priv_getlog(priv, buf,
						   priv_cmd.total_len);
			goto handled;
#endif
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_CUSTOMIE,
				    strlen(PRIV_CMD_CUSTOMIE)) == 0) {
			/* Custom IE configuration */
			len = woal_priv_customie(priv, buf, priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_ESUPPMODE,
				    strlen(PRIV_CMD_ESUPPMODE)) == 0) {
			/* Esupplicant mode configuration */
			len = woal_setget_priv_esuppmode(priv, buf,
							 priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_PASSPHRASE,
				    strlen(PRIV_CMD_PASSPHRASE)) == 0) {
			/* Esupplicant passphrase configuration */
			len = woal_setget_priv_passphrase(priv, buf,
							  priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_DEAUTH,
				    strlen(PRIV_CMD_DEAUTH)) == 0) {
			/* Deauth */
			len = woal_priv_deauth(priv, buf, priv_cmd.total_len);
			goto handled;
#ifdef UAP_SUPPORT
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_AP_DEAUTH,
				    strlen(PRIV_CMD_AP_DEAUTH)) == 0) {
			/* AP Deauth */
			len = woal_priv_ap_deauth(priv, buf,
						  priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP),
				    PRIV_CMD_GET_STA_LIST,
				    strlen(PRIV_CMD_GET_STA_LIST)) == 0) {
			/* Get STA list */
			len = woal_priv_get_sta_list(priv, buf,
						     priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_BSS_CONFIG,
				    strlen(PRIV_CMD_BSS_CONFIG)) == 0) {
			/* BSS config */
			len = woal_priv_bss_config(priv, buf,
						   priv_cmd.total_len);
			goto handled;
#endif
#ifdef WIFI_DIRECT_SUPPORT
#if defined(STA_SUPPORT) && defined(UAP_SUPPORT)
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_BSSROLE,
				    strlen(PRIV_CMD_BSSROLE)) == 0) {
			/* BSS Role */
			len = woal_priv_bssrole(priv, buf,
						(t_u32)priv_cmd.total_len);
			goto handled;
#endif
#endif
#ifdef STA_SUPPORT
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_SETUSERSCAN,
				    strlen(PRIV_CMD_SETUSERSCAN)) == 0) {
			/* Set user scan */
			len = woal_priv_setuserscan(priv, buf,
						    priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP),
				    PRIV_CMD_GETSCANTABLE,
				    strlen(PRIV_CMD_GETSCANTABLE)) == 0) {
			/* Get scan table */
			len = woal_priv_getscantable(priv, buf,
						     priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP),
				    PRIV_CMD_GETCHANSTATS,
				    strlen(PRIV_CMD_GETCHANSTATS)) == 0) {
			/* Get channel statistics */
			len = woal_priv_get_chanstats(priv, buf,
						      priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_EXTCAPCFG,
				    strlen(PRIV_CMD_EXTCAPCFG)) == 0) {
			/* Extended capabilities configure */
			len = woal_priv_extcapcfg(priv, buf,
						  (t_u32)priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_CANCELSCAN,
				    strlen(PRIV_CMD_CANCELSCAN)) == 0) {
			/* Cancel scan */
			len = woal_cancel_scan(priv, MOAL_IOCTL_WAIT);
			goto handled;
#endif
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_DEEPSLEEP,
				    strlen(PRIV_CMD_DEEPSLEEP)) == 0) {
			/* Deep sleep */
			len = woal_priv_setgetdeepsleep(priv, buf,
							priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_IPADDR,
				    strlen(PRIV_CMD_IPADDR)) == 0) {
			/* IP address */
			len = woal_priv_setgetipaddr(priv, buf,
						     (t_u32)priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_WPSSESSION,
				    strlen(PRIV_CMD_WPSSESSION)) == 0) {
			/* WPS Session */
			len = woal_priv_setwpssession(priv, buf,
						      priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_OTPUSERDATA,
				    strlen(PRIV_CMD_OTPUSERDATA)) == 0) {
			/* OTP user data */
			len = woal_priv_otpuserdata(priv, buf,
						    priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_COUNTRYCODE,
				    strlen(PRIV_CMD_COUNTRYCODE)) == 0) {
			/* Country code */
			len = woal_priv_set_get_countrycode(priv, buf,
							    priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_CFPINFO,
				    strlen(PRIV_CMD_CFPINFO)) == 0) {
			/* CFP info */
			len = woal_priv_get_cfpinfo(priv, buf,
						    priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_TCPACKENH,
				    strlen(PRIV_CMD_TCPACKENH)) == 0) {
			/* TCP ack enhancement */
			len = woal_priv_setgettcpackenh(priv, buf,
							priv_cmd.total_len);
			goto handled;
#ifdef REASSOCIATION
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_ASSOCBSSID,
				    strlen(PRIV_CMD_ASSOCBSSID)) == 0) {
			/* Associate to essid */
			len = woal_priv_assocessid(priv, buf,
						   priv_cmd.total_len, 1);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_ASSOCESSID,
				    strlen(PRIV_CMD_ASSOCESSID)) == 0) {
			/* Associate to essid */
			len = woal_priv_assocessid(priv, buf,
						   priv_cmd.total_len, 0);
			goto handled;
#endif
		} else if (strnicmp(buf + strlen(CMD_NXP),
				    PRIV_CMD_WAKEUPREASON,
				    strlen(PRIV_CMD_WAKEUPREASON)) == 0) {
			/* wakeup reason */
			len = woal_priv_getwakeupreason(priv, buf,
							priv_cmd.total_len);
			goto handled;
#ifdef STA_SUPPORT
		} else if (strnicmp(buf + strlen(CMD_NXP),
				    PRIV_CMD_LISTENINTERVAL,
				    strlen(PRIV_CMD_LISTENINTERVAL)) == 0) {
			/* Listen Interval */
			len = woal_priv_set_get_listeninterval(priv, buf,
							       priv_cmd.
							       total_len);
			goto handled;
#endif
#ifdef DEBUG_LEVEL1
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_DRVDBG,
				    strlen(PRIV_CMD_DRVDBG)) == 0) {
			/* Driver debug bit mask */
			len = woal_priv_set_get_drvdbg(priv, buf,
						       priv_cmd.total_len);
			goto handled;
#endif
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_HSCFG,
				    strlen(PRIV_CMD_HSCFG)) == 0) {
			/* HS configuration */
			len = woal_priv_hscfg(priv, buf, priv_cmd.total_len,
					      MTRUE);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_HSSETPARA,
				    strlen(PRIV_CMD_HSSETPARA)) == 0) {
			/* Set HS parameter */
			len = woal_priv_hssetpara(priv, buf,
						  priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_MGMT_FILTER,
				    strlen(PRIV_CMD_MGMT_FILTER)) == 0) {
			/* Management frame filter wakeup */
			len = woal_priv_mgmt_filter(priv, buf,
						    priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_SCANCFG,
				    strlen(PRIV_CMD_SCANCFG)) == 0) {
			/* Scan configuration */
			len = woal_priv_set_get_scancfg(priv, buf,
							priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_GETNLNUM,
				    strlen(PRIV_CMD_GETNLNUM)) == 0) {
			/* Scan configuration */
			len = woal_priv_getnlnum(priv, buf, priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_AGGRCTRL,
				    strlen(PRIV_CMD_AGGRCTRL)) == 0) {
			/* aggregation control */
			len = woal_priv_set_get_aggrctrl(priv, buf,
							 priv_cmd.total_len);
			goto handled;
#ifdef USB
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_USBAGGRCTRL,
				    strlen(PRIV_CMD_USBAGGRCTRL)) == 0) {
			/* USB aggregation control */
			len = woal_priv_set_get_usbaggrctrl(priv, buf,
							    priv_cmd.total_len);
			goto handled;
#endif
		} else if (strnicmp(buf + strlen(CMD_NXP),
				    PRIV_CMD_SET_BSS_MODE,
				    strlen(PRIV_CMD_SET_BSS_MODE)) == 0) {
			/* Set bss mode */
			len = woal_priv_set_bss_mode(priv, buf,
						     priv_cmd.total_len);
			goto handled;
#ifdef STA_SUPPORT
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_SET_AP,
				    strlen(PRIV_CMD_SET_AP)) == 0) {
			/* Set AP */
			len = woal_priv_set_ap(priv, buf, priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_SET_POWER,
				    strlen(PRIV_CMD_SET_POWER)) == 0) {
			/* Set power management parameters */
			len = woal_priv_set_power(priv, buf,
						  priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_SET_ESSID,
				    strlen(PRIV_CMD_SET_ESSID)) == 0) {
			/* Set essid */
			len = woal_priv_set_essid(priv, buf,
						  priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_SET_AUTH,
				    strlen(PRIV_CMD_SET_AUTH)) == 0) {
			/* Set authentication mode parameters */
			len = woal_priv_set_auth(priv, buf, priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_GET_AP,
				    strlen(PRIV_CMD_GET_AP)) == 0) {
			/* Get AP */
			len = woal_priv_get_ap(priv, buf, priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_GET_POWER,
				    strlen(PRIV_CMD_GET_POWER)) == 0) {
			/* Get power management parameters */
			len = woal_priv_get_power(priv, buf,
						  priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_PSMODE,
				    strlen(PRIV_CMD_PSMODE)) == 0) {
			/* Set/Get PS mode */
			len = woal_priv_set_get_psmode(priv, buf,
						       priv_cmd.total_len);
			goto handled;
#endif
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_WARMRESET,
				    strlen(PRIV_CMD_WARMRESET)) == 0) {
			/* Performs warm reset */
			len = woal_priv_warmreset(priv, buf,
						  priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_TXPOWERCFG,
				    strlen(PRIV_CMD_TXPOWERCFG)) == 0) {
			/* TX power configurations */
			len = woal_priv_txpowercfg(priv, buf,
						   priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP),
				    PRIV_CMD_RX_ABORT_CFG_EXT,
				    strlen(PRIV_CMD_RX_ABORT_CFG_EXT)) == 0) {
			/* dynamic Rx Abort config */
			len = woal_priv_rx_abort_cfg_ext(priv, buf,
							 priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP),
				    PRIV_CMD_RX_ABORT_CFG,
				    strlen(PRIV_CMD_RX_ABORT_CFG)) == 0) {
			/* static Rx Abort config */
			len = woal_priv_rx_abort_cfg(priv, buf,
						     priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP),
				    PRIV_CMD_TX_AMPDU_PROT_MODE,
				    strlen(PRIV_CMD_TX_AMPDU_PROT_MODE)) == 0) {
			/* tx ampdu protection mode setting */
			len = woal_priv_tx_ampdu_prot_mode(priv, buf,
							   priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP),
				    PRIV_CMD_DOT11MC_UNASSOC_FTM_CFG,
				    strlen(PRIV_CMD_DOT11MC_UNASSOC_FTM_CFG)) ==
			   0) {
			/* setting for dot11mc un-associated case FTM frame exchange */
			len = woal_priv_dot11mc_unassoc_ftm_cfg(priv, buf,
								priv_cmd.
								total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP),
				    PRIV_CMD_RATE_ADAPT_CFG,
				    strlen(PRIV_CMD_RATE_ADAPT_CFG)) == 0) {
			/* rate adapt config */
			len = woal_priv_rate_adapt_cfg(priv, buf,
						       priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP),
				    PRIV_CMD_CCK_DESENSE_CFG,
				    strlen(PRIV_CMD_CCK_DESENSE_CFG)) == 0) {
			/* cck desense config */
			len = woal_priv_cck_desense_cfg(priv, buf,
							priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_PSCFG,
				    strlen(PRIV_CMD_PSCFG)) == 0) {
			/* PS configurations */
			len = woal_priv_pscfg(priv, buf, priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP),
				    PRIV_CMD_BCNTIMEOUTCFG,
				    strlen(PRIV_CMD_BCNTIMEOUTCFG)) == 0) {
			/* Beacon timeout configurations */
			len = woal_priv_bcntimeoutcfg(priv, buf,
						      priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_SLEEPPD,
				    strlen(PRIV_CMD_SLEEPPD)) == 0) {
			/* Sleep period */
			len = woal_priv_sleeppd(priv, buf, priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_TXCONTROL,
				    strlen(PRIV_CMD_TXCONTROL)) == 0) {
			/* Tx control */
			len = woal_priv_txcontrol(priv, buf,
						  priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_REGRDWR,
				    strlen(PRIV_CMD_REGRDWR)) == 0) {
			/* Register Read/Write */
			len = woal_priv_regrdwr(priv, buf, priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_RDEEPROM,
				    strlen(PRIV_CMD_RDEEPROM)) == 0) {
			/* Read the EEPROM contents of the card */
			len = woal_priv_rdeeprom(priv, buf, priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_MEMRDWR,
				    strlen(PRIV_CMD_MEMRDWR)) == 0) {
			/* Memory Read/Write */
			len = woal_priv_memrdwr(priv, buf, priv_cmd.total_len);
			goto handled;
#ifdef SDIO
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_SDCMD52RW,
				    strlen(PRIV_CMD_SDCMD52RW)) == 0) {
			/* Cmd52 read/write register */
			len = woal_priv_sdcmd52rw(priv, buf,
						  priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_SDIO_CLOCK,
				    strlen(PRIV_CMD_SDIO_CLOCK)) == 0) {
			/* Turn on/off the sdio clock */
			len = woal_priv_sdio_clock_ioctl(priv, buf,
							 priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_MPA_CTRL,
				    strlen(PRIV_CMD_MPA_CTRL)) == 0) {
			/* Set SDIO Multi-point aggregation
			 * control parameters */
			len = woal_priv_sdio_mpa_ctrl(priv, buf,
						      priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_SD_CMD53_RW,
				    strlen(PRIV_CMD_SD_CMD53_RW)) == 0) {
			/* Cmd53 read/write register */
			len = woal_priv_cmd53rdwr(priv, buf,
						  priv_cmd.total_len);
			goto handled;
#endif
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_ROBUSTCOEX,
				    strlen(PRIV_CMD_ROBUSTCOEX)) == 0) {
			/* Set Robustcoex GPIOcfg */
			pdata = buf + strlen(CMD_NXP) +
				strlen(PRIV_CMD_ROBUSTCOEX);
			len = priv_cmd.total_len - strlen(PRIV_CMD_ROBUSTCOEX) -
				strlen(CMD_NXP);
			len = woal_priv_robustcoex(priv, pdata, len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_DMCS,
				    strlen(PRIV_CMD_DMCS)) == 0) {
			/* Set/Get DMCS config */
			len = woal_priv_dmcs(priv, buf, priv_cmd.total_len);
			goto handled;
#if defined(PCIE)
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_SSU,
				    strlen(PRIV_CMD_SSU)) == 0) {
			/* Set SSU config */
			pdata = buf + strlen(CMD_NXP) + strlen(PRIV_CMD_SSU);
			len = priv_cmd.used_len - strlen(PRIV_CMD_SSU) -
				strlen(CMD_NXP);
			len = woal_priv_ssu_cmd(priv, len, pdata,
						priv_cmd.total_len);
			goto handled;
#endif
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_HAL_PHY_CFG,
				    strlen(PRIV_CMD_HAL_PHY_CFG)) == 0) {
			/* Set hal_phy config */
			pdata = buf + strlen(CMD_NXP) +
				strlen(PRIV_CMD_HAL_PHY_CFG);
			len = priv_cmd.total_len -
				strlen(PRIV_CMD_HAL_PHY_CFG) - strlen(CMD_NXP);
			len = woal_priv_hal_phy_cfg_cmd(priv, pdata, len);
			goto handled;
#ifdef STA_SUPPORT
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_ARPFILTER,
				    strlen(PRIV_CMD_ARPFILTER)) == 0) {
			/* ARPFilter Configuration */
			len = woal_priv_arpfilter(priv, buf,
						  priv_cmd.total_len);
			goto handled;
#endif
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_AUTO_ARP,
				    strlen(PRIV_CMD_AUTO_ARP)) == 0) {
			/* Auto ARP enable/disable */
			len = woal_priv_set_get_auto_arp(priv, buf,
							 priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_HOTSPOTCFG,
				    strlen(PRIV_CMD_HOTSPOTCFG)) == 0) {
			/* Hotspot CFG */
			len = woal_priv_hotspotcfg(priv, buf,
						   priv_cmd.total_len);
			goto handled;
#ifdef RX_PACKET_COALESCE
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_RX_COAL_CFG,
				    strlen(PRIV_CMD_RX_COAL_CFG)) == 0) {
			/* RX packet coalescing Configuration */
			len = woal_priv_rx_pkt_coalesce_cfg(priv, buf,
							    priv_cmd.total_len);
			goto handled;
#endif

		} else if (strnicmp(buf + strlen(CMD_NXP),
				    PRIV_CMD_MGMT_FRAME_CTRL,
				    strlen(PRIV_CMD_MGMT_FRAME_CTRL)) == 0) {
			/* Mgmt Frame Passthrough Ctrl */
			len = woal_priv_mgmt_frame_passthru_ctrl(priv, buf,
								 priv_cmd.
								 total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_QCONFIG,
				    strlen(PRIV_CMD_QCONFIG)) == 0) {
			/* Queue config */
			len = woal_priv_qconfig(priv, buf, priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_ADDTS,
				    strlen(PRIV_CMD_ADDTS)) == 0) {
			/* Send an ADDTS TSPEC */
			len = woal_priv_wmm_addts_req_ioctl(priv, buf,
							    priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_DELTS,
				    strlen(PRIV_CMD_DELTS)) == 0) {
			/* Send a DELTS TSPE */
			len = woal_priv_wmm_delts_req_ioctl(priv, buf,
							    priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_QSTATUS,
				    strlen(PRIV_CMD_QSTATUS)) == 0) {
			/* Get the status of the WMM queues */
			len = woal_priv_wmm_queue_status_ioctl(priv, buf,
							       priv_cmd.
							       total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_TS_STATUS,
				    strlen(PRIV_CMD_TS_STATUS)) == 0) {
			/* Get the status of the WMM Traffic Streams */
			len = woal_priv_wmm_ts_status_ioctl(priv, buf,
							    priv_cmd.total_len);
			goto handled;
#ifdef STA_SUPPORT
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_QOS_CFG,
				    strlen(PRIV_CMD_QOS_CFG)) == 0) {
			t_u32 action = MLAN_ACT_GET;
			if (strlen(buf) ==
			    strlen(CMD_NXP) + strlen(PRIV_CMD_QOS_CFG)) {
				pdata = buf;	/* GET operation */
			} else {
				pdata = buf + strlen(CMD_NXP) +
					strlen(PRIV_CMD_QOS_CFG);
				action = MLAN_ACT_SET;	/* SET operation */
			}
			if (MLAN_STATUS_SUCCESS !=
			    woal_priv_qos_cfg(priv, action, pdata)) {
				ret = -EFAULT;
				goto done;
			}
			if (action == MLAN_ACT_GET)
				len = sizeof(t_u8);
			goto handled;
#endif
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_MAC_CTRL,
				    strlen(PRIV_CMD_MAC_CTRL)) == 0) {
			/* MAC CTRL */
			len = woal_priv_macctrl(priv, buf, priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_GETWAP,
				    strlen(PRIV_CMD_GETWAP)) == 0) {
			/* Get WAP */
			len = woal_priv_getwap(priv, buf, priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_REGION_CODE,
				    strlen(PRIV_CMD_REGION_CODE)) == 0) {
			/* Region Code */
			len = woal_priv_region_code(priv, buf,
						    priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_FWMACADDR,
				    strlen(PRIV_CMD_FWMACADDR)) == 0) {
			/* Set FW MAC address */
			len = woal_priv_fwmacaddr(priv, buf,
						  priv_cmd.total_len);
			goto handled;
#if defined(STA_CFG80211) || defined(UAP_CFG80211)
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_OFFCHANNEL,
				    strlen(PRIV_CMD_OFFCHANNEL)) == 0) {
			if (IS_STA_CFG80211(cfg80211_wext)) {
				/* Set offchannel */
				len = woal_priv_offchannel(priv, buf,
							   priv_cmd.total_len);
			} else
				len = sprintf(buf,
					      "CFG80211 is not enabled\n") + 1;
			goto handled;
#endif
#endif

		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_DSCP_MAP,
				    strlen(PRIV_CMD_DSCP_MAP)) == 0) {
			/* Set/Get DSCP Map */
			len = woal_priv_set_get_dscp_map(priv, buf,
							 priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_VEREXT,
				    strlen(PRIV_CMD_VEREXT)) == 0) {
			/* Get Extended version */
			len = woal_priv_get_driver_verext(priv, buf,
							  priv_cmd.total_len);
			goto handled;
#ifdef USB
#ifdef CONFIG_USB_SUSPEND
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_USB_SUSPEND,
				    strlen(PRIV_CMD_USB_SUSPEND)) == 0) {
			/* Makes USB device to suspend */
			len = woal_priv_enter_usb_suspend(priv, buf,
							  priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_USB_RESUME,
				    strlen(PRIV_CMD_USB_RESUME)) == 0) {
			/* Makes USB device to resume */
			len = woal_priv_exit_usb_suspend(priv, buf,
							 priv_cmd.total_len);
			goto handled;
#endif /* CONFIG_USB_SUSPEND */
#endif
#if defined(STA_SUPPORT) && defined(STA_WEXT)
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_RADIO_CTRL,
				    strlen(PRIV_CMD_RADIO_CTRL)) == 0) {
			/* Set/Get radio */
			len = woal_priv_radio_ctrl(priv, buf,
						   priv_cmd.total_len);
			goto handled;
#endif
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_WMM_CFG,
				    strlen(PRIV_CMD_WMM_CFG)) == 0) {
			/* Implement WMM enable command */
			len = woal_priv_wmm_cfg(priv, buf, priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP),
				    PRIV_CMD_MIN_BA_THRESH_CFG,
				    strlen(PRIV_CMD_MIN_BA_THRESH_CFG)) == 0) {
			/* Implement Minimum BA threshold configuration command
			 */
			len = woal_priv_min_ba_threshold_cfg(priv, buf,
							     priv_cmd.
							     total_len);
			goto handled;
#if defined(STA_SUPPORT)
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_11D_CFG,
				    strlen(PRIV_CMD_11D_CFG)) == 0) {
			/* Implement 802.11D enable command */
			len = woal_priv_11d_cfg(priv, buf, priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_11D_CLR_TBL,
				    strlen(PRIV_CMD_11D_CLR_TBL)) == 0) {
			/* Implement 802.11D clear chan table command */
			len = woal_priv_11d_clr_chan_tbl(priv, buf,
							 priv_cmd.total_len);
			goto handled;
#endif
#ifndef OPCHAN
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_WWS_CFG,
				    strlen(PRIV_CMD_WWS_CFG)) == 0) {
			/* Set/Get WWS configuration */
			len = woal_priv_wws_cfg(priv, buf, priv_cmd.total_len);
			goto handled;
#endif
#if defined(REASSOCIATION)
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_REASSOCTRL,
				    strlen(PRIV_CMD_REASSOCTRL)) == 0) {
			/* Set/Get reassociation settings */
			len = woal_priv_set_get_reassoc(priv, buf,
							priv_cmd.total_len);
			goto handled;
#endif
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_TXBUF_CFG,
				    strlen(PRIV_CMD_TXBUF_CFG)) == 0) {
			/* Get Transmit buffer size */
			len = woal_priv_txbuf_cfg(priv, buf,
						  priv_cmd.total_len);
			goto handled;
#ifdef STA_SUPPORT
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_AUTH_TYPE,
				    strlen(PRIV_CMD_AUTH_TYPE)) == 0) {
			/* Set/Get auth type */
			len = woal_priv_auth_type(priv, buf,
						  priv_cmd.total_len);
			goto handled;
#endif
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_POWER_CONS,
				    strlen(PRIV_CMD_POWER_CONS)) == 0) {
			/* Set/get user provisioned local power constraint */
			len = woal_priv_11h_local_pwr_constraint(priv, buf,
								 priv_cmd.
								 total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP),
				    PRIV_CMD_HT_STREAM_CFG,
				    strlen(PRIV_CMD_HT_STREAM_CFG)) == 0) {
			/* Set/get HT stream configurations */
			len = woal_priv_ht_stream_cfg(priv, buf,
						      priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_MIMO_SWITCH,
				    strlen(PRIV_CMD_MIMO_SWITCH)) == 0) {
			/* Set mimo switch configurations */
			len = woal_priv_mimo_switch(priv, buf,
						    priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_THERMAL,
				    strlen(PRIV_CMD_THERMAL)) == 0) {
			/* Get thermal reading */
			len = woal_priv_thermal(priv, buf, priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP),
				    PRIV_CMD_BCN_INTERVAL,
				    strlen(PRIV_CMD_BCN_INTERVAL)) == 0) {
			/* Set/Get beacon interval */
			len = woal_priv_beacon_interval(priv, buf,
							priv_cmd.total_len);
			goto handled;
#ifdef STA_SUPPORT
		} else if (strnicmp(buf + strlen(CMD_NXP),
				    PRIV_CMD_SIGNALEXT_CFG,
				    strlen(PRIV_CMD_SIGNALEXT_CFG)) == 0) {
			/* Set signalext flag */
			len = woal_priv_signalext_cfg(priv, buf,
						      priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP),
				    PRIV_CMD_GET_SIGNAL_EXT_V2,
				    strlen(PRIV_CMD_GET_SIGNAL_EXT_V2)) == 0) {
			/* Get signal info */
			len = woal_priv_get_signal_ext_v2(priv, buf,
							  priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP),
				    PRIV_CMD_GET_SIGNAL_EXT,
				    strlen(PRIV_CMD_GET_SIGNAL_EXT)) == 0) {
			/* Get signal info */
			len = woal_priv_get_signal_ext(priv, buf,
						       priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_GET_SIGNAL,
				    strlen(PRIV_CMD_GET_SIGNAL)) == 0) {
			/* Get signal */
			len = woal_priv_get_signal(priv, buf,
						   priv_cmd.total_len);
			goto handled;
#endif
#if defined(STA_SUPPORT)
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_PMFCFG,
				    strlen(PRIV_CMD_PMFCFG)) == 0) {
			/* Configure PMF */
			len = woal_priv_set_get_pmfcfg(priv, buf,
						       priv_cmd.total_len);
			goto handled;
#endif
		} else if (strnicmp(buf + strlen(CMD_NXP),
				    PRIV_CMD_INACTIVITYTO,
				    strlen(PRIV_CMD_INACTIVITYTO)) == 0) {
			/* Get/Set inactivity timeout extend */
			len = woal_priv_inactivity_timeout_ext(priv, buf,
							       priv_cmd.
							       total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP),
				    PRIV_CMD_AMSDU_AGGR_CTRL,
				    strlen(PRIV_CMD_AMSDU_AGGR_CTRL)) == 0) {
			/* Enable/Disable amsdu_aggr_ctrl */
			len = woal_priv_11n_amsdu_aggr_ctrl(priv, buf,
							    priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_TX_BF_CAP,
				    strlen(PRIV_CMD_TX_BF_CAP)) == 0) {
			/* Set/Get Transmit beamforming capabilities */
			len = woal_priv_tx_bf_cap_ioctl(priv, buf,
							priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP),
				    PRIV_CMD_SLEEP_PARAMS,
				    strlen(PRIV_CMD_SLEEP_PARAMS)) == 0) {
			/* Configure sleep parameters */
			len = woal_priv_sleep_params_ioctl(priv, buf,
							   priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_DFS_TESTING,
				    strlen(PRIV_CMD_DFS_TESTING)) == 0) {
			/* Set/Get DFS Testing settings */
			len = woal_priv_dfs_testing(priv, buf,
						    priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_DFS53_CFG,
				    strlen(PRIV_CMD_DFS53_CFG)) == 0) {
			/* Set/Get DFS W53 settings */
			len = woal_priv_dfs53cfg(priv, buf, priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_ARB_CFG,
				    strlen(PRIV_CMD_ARB_CFG)) == 0) {
			/* Set/Get CFP table codes */
			len = woal_priv_arbcfg(priv, buf, priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_CFP_CODE,
				    strlen(PRIV_CMD_CFP_CODE)) == 0) {
			/* Set/Get CFP table codes */
			len = woal_priv_cfp_code(priv, buf, priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_CWMODE,
				    strlen(PRIV_CMD_CWMODE)) == 0) {
			/* Set/Get Tx CWMode */
			len = woal_priv_set_get_cwmode(priv, buf,
						       priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_ANT_CFG,
				    strlen(PRIV_CMD_ANT_CFG)) == 0) {
			/* Set/Get Tx/Rx antenna */
			len = woal_priv_set_get_tx_rx_ant(priv, buf,
							  priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_SYSCLOCK,
				    strlen(PRIV_CMD_SYSCLOCK)) == 0) {
			/* Get/Set system clock */
			len = woal_priv_sysclock(priv, buf, priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_GET_KEY,
				    strlen(PRIV_CMD_GET_KEY)) == 0) {
			/* Get GTK/PTK */
			len = woal_priv_get_key(priv, buf, priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_ASSOCIATE,
				    strlen(PRIV_CMD_ASSOCIATE)) == 0) {
			/* Associate to a specific indexed entry in the
			 * ScanTable */
			len = woal_priv_associate_ssid_bssid(priv, buf,
							     priv_cmd.
							     total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_TX_BF_CFG,
				    strlen(PRIV_CMD_TX_BF_CFG)) == 0) {
			/* Set/Get Transmit beamforming configuration */
			len = woal_priv_tx_bf_cfg(priv, buf,
						  priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_BOOTSLEEP,
				    strlen(PRIV_CMD_BOOTSLEEP)) == 0) {
			len = woal_priv_bootsleep(priv, buf,
						  priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_PORT_CTRL,
				    strlen(PRIV_CMD_PORT_CTRL)) == 0) {
			/* Set/Get Port Control mode */
			len = woal_priv_port_ctrl(priv, buf,
						  priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_PB_BYPASS,
				    strlen(PRIV_CMD_PB_BYPASS)) == 0) {
			/* Private IOCTL entry to get the By-passed TX packet
			 * from upper layer */
			len = woal_priv_bypassed_packet(priv, buf,
							priv_cmd.total_len);
			goto handled;
#ifdef WIFI_DIRECT_SUPPORT
#if defined(UAP_CFG80211)
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_CFG_NOA,
				    strlen(PRIV_CMD_CFG_NOA)) == 0) {
			/* Set/Get P2P NoA (Notice of Absence) parameters */
			len = woal_priv_cfg_noa(priv, buf, priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_CFG_OPP_PS,
				    strlen(PRIV_CMD_CFG_OPP_PS)) == 0) {
			/* Set/Get P2P OPP-PS parameters */
			len = woal_priv_cfg_opp_ps(priv, buf,
						   priv_cmd.total_len);
			goto handled;
#endif
#endif
		} else if (strnicmp
			   (buf + strlen(CMD_NXP), PRIV_CMD_CFG_CLOCK_SYNC,
			    strlen(PRIV_CMD_CFG_CLOCK_SYNC)) == 0) {
			/* Set/Get P2P NoA (Notice of Absence) parameters */
			len = woal_priv_cfg_clock_sync(priv, buf,
						       priv_cmd.total_len);
			goto handled;
		} else if (strnicmp
			   (buf + strlen(CMD_NXP), PRIV_CMD_CFG_GET_TSF_INFO,
			    strlen(PRIV_CMD_CFG_GET_TSF_INFO)) == 0) {
			/* Get TSF info */
			len = woal_priv_cfg_get_tsf_info(priv, buf,
							 priv_cmd.total_len);
			goto handled;
		} else if (strnicmp
			   (buf + strlen(CMD_NXP), PRIV_CMD_TRANSITION_CHANNEL,
			    strlen(PRIV_CMD_TRANSITION_CHANNEL)) == 0) {
			/* Get/Set Transition channel */
			len = woal_priv_transition_channel(priv, buf,
							   priv_cmd.total_len);
			goto handled;

		} else if (strnicmp(buf + strlen(CMD_NXP),
				    PRIV_CMD_DFS_REPEATER_CFG,
				    strlen(PRIV_CMD_DFS_REPEATER_CFG)) == 0) {
			/* Set/Get DFS_REPEATER mode */
			len = woal_priv_dfs_repeater_cfg(priv, buf,
							 priv_cmd.total_len);
			goto handled;
#ifdef WIFI_DIRECT_SUPPORT
#if defined(STA_CFG80211) || defined(UAP_CFG80211)
		} else if (strnicmp(buf + strlen(CMD_NXP),
				    PRIV_CMD_MIRACAST_CFG,
				    strlen(PRIV_CMD_MIRACAST_CFG)) == 0) {
			/* Set/Get MIRACAST configuration parameters */
			len = woal_priv_miracast_cfg(priv, buf,
						     priv_cmd.total_len);
			goto handled;
#endif
#endif
		} else if (strnicmp(buf + strlen(CMD_NXP),
				    PRIV_CMD_COEX_RX_WINSIZE,
				    strlen(PRIV_CMD_COEX_RX_WINSIZE)) == 0) {
			/* Set/Get control to coex RX window size */
			len = woal_priv_coex_rx_winsize(priv, buf,
							priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP),
				    PRIV_CMD_TX_AGGR_CTRL,
				    strlen(PRIV_CMD_TX_AGGR_CTRL)) == 0) {
			/* Set/Get control to TX AMPDU on infra link */
			len = woal_priv_txaggrctrl(priv, buf,
						   priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_AUTO_TDLS,
				    strlen(PRIV_CMD_AUTO_TDLS)) == 0) {
			/* Set/Get control to enable/disable auto TDLS */
			len = woal_priv_auto_tdls(priv, buf,
						  priv_cmd.total_len);
			goto handled;
#ifdef PCIE
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_PCIE_REG_RW,
				    strlen(PRIV_CMD_PCIE_REG_RW)) == 0) {
			/* Read/Write PCIE register */
			len = woal_priv_pcie_reg_rw(priv, buf,
						    priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP),
				    PRIV_CMD_PCIE_BAR0_REG_RW,
				    strlen(PRIV_CMD_PCIE_BAR0_REG_RW)) == 0) {
			/* Read/Write PCIE register/memory from BAR0 */
			len = woal_priv_pcie_bar0_reg_rw(priv, buf,
							 priv_cmd.total_len);
			goto handled;
#endif
		} else if (strnicmp(buf + strlen(CMD_NXP),
				    PRIV_CMD_TDLS_IDLE_TIME,
				    strlen(PRIV_CMD_TDLS_IDLE_TIME)) == 0) {
			/* Set/Get TDLS idle timeout value */
			len = woal_priv_tdls_idle_time(priv, buf,
						       priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP),
				    PRIV_CMD_GET_SENSOR_TEMP,
				    strlen(PRIV_CMD_GET_SENSOR_TEMP)) == 0) {
			/* Get SOC temperature */
			len = woal_priv_get_sensor_temp(priv, buf,
							priv_cmd.total_len);
			goto handled;
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
#if defined(STA_CFG80211) || defined(UAP_CFG80211)
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_DFS_OFFLOAD,
				    strlen(PRIV_CMD_DFS_OFFLOAD)) == 0) {
			/* Enable/disable DFS offload */
			if (IS_STA_OR_UAP_CFG80211(cfg80211_wext))
				len = woal_priv_dfs_offload_enable(priv, buf,
								   priv_cmd.
								   total_len);
			else
				len = sprintf(buf,
					      "CFG80211 is not enabled\n") + 1;
			goto handled;
#endif
#endif
#if defined(UAP_SUPPORT)
		} else if (strnicmp(buf + strlen(CMD_NXP),
				    PRIV_CMD_EXTEND_CHAN_SWITCH,
				    strlen(PRIV_CMD_EXTEND_CHAN_SWITCH)) == 0) {
			/* Extended channel switch */
			len = woal_priv_extend_channel_switch(priv, buf,
							      priv_cmd.
							      total_len);
			goto handled;
#endif
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_DYN_BW,
				    strlen(PRIV_CMD_DYN_BW)) == 0) {
			/* Set/Get dynamic bandwidth */
			len = woal_priv_config_dyn_bw(priv, buf,
						      priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_IND_RST_CFG,
				    strlen(PRIV_CMD_IND_RST_CFG)) == 0) {
			/* Set/Get out band independent reset */
			len = woal_priv_ind_rst_cfg(priv, buf,
						    priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_PER_PKT_CFG,
				    strlen(PRIV_CMD_PER_PKT_CFG)) == 0) {
			/* Get/Set per packet Txctl and Rxinfo configuration */
			len = woal_priv_per_pkt_cfg(priv, buf,
						    priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_DEAUTH_CTRL,
				    strlen(PRIV_CMD_DEAUTH_CTRL)) == 0) {
			len = woal_priv_deauth_ctrl(priv, buf,
						    priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_11AXCFG,
				    strlen(PRIV_CMD_11AXCFG)) == 0) {
			pdata = buf + strlen(CMD_NXP) +
				strlen(PRIV_CMD_11AXCFG);
			len = priv_cmd.used_len - strlen(PRIV_CMD_11AXCFG) -
				strlen(CMD_NXP);
			len = woal_priv_11axcfg_cmd(priv, pdata, len,
						    priv_cmd.total_len);
			len += strlen(PRIV_CMD_11AXCFG) + strlen(CMD_NXP);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_TWT_SETUP,
				    strlen(PRIV_CMD_TWT_SETUP)) == 0) {
			pdata = buf + strlen(CMD_NXP) +
				strlen(PRIV_CMD_TWT_SETUP);
			len = priv_cmd.used_len - strlen(PRIV_CMD_TWT_SETUP) -
				strlen(CMD_NXP);
			len = woal_priv_twt_setup(priv, pdata, len,
						  priv_cmd.total_len);
			len += strlen(PRIV_CMD_TWT_SETUP) + strlen(CMD_NXP);
			goto handled;

		} else if (strnicmp(buf + strlen(CMD_NXP),
				    PRIV_CMD_TWT_TEARDOWN,
				    strlen(PRIV_CMD_TWT_TEARDOWN)) == 0) {
			pdata = buf + strlen(CMD_NXP) +
				strlen(PRIV_CMD_TWT_TEARDOWN);
			len = priv_cmd.used_len -
				strlen(PRIV_CMD_TWT_TEARDOWN) - strlen(CMD_NXP);
			len = woal_priv_twt_teardown(priv, pdata, len,
						     priv_cmd.total_len);
			len += strlen(PRIV_CMD_TWT_TEARDOWN) + strlen(CMD_NXP);
			goto handled;
#if defined(STA_CFG80211) || defined(UAP_CFG80211)
		} else if (strnicmp(buf + strlen(CMD_NXP),
				    PRIV_CMD_GET_CFG_CHAN_LIST,
				    strlen(PRIV_CMD_GET_CFG_CHAN_LIST)) == 0) {
			/* Get txpwrlimit */
			if (IS_STA_OR_UAP_CFG80211(cfg80211_wext))
				len = woal_priv_getcfgchanlist(priv, buf,
							       priv_cmd.
							       total_len);
			else
				len = sprintf(buf,
					      "CFG80211 is not enabled\n") + 1;
			goto handled;
#endif
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_LPM,
				    strlen(PRIV_CMD_LPM)) == 0) {
			/* Set/Get low power mode */
			len = woal_priv_set_get_lpm(priv, buf,
						    priv_cmd.total_len);
			goto handled;
		} else if (strnicmp(buf + strlen(CMD_NXP), PRIV_CMD_TP_STATE,
				    strlen(PRIV_CMD_TP_STATE)) == 0) {
			/* Set/Get TP accounting state */
			len = woal_priv_set_tp_state(priv, buf,
						     priv_cmd.total_len);
			goto handled;
		} else {
			PRINTM(MERROR,
			       "Unknown NXP PRIVATE command %s, ignored\n",
			       buf);
			ret = -EFAULT;
			goto done;
		}
	}
#ifdef STA_SUPPORT
	if (strncmp(buf, "RSSILOW-THRESHOLD", strlen("RSSILOW-THRESHOLD")) == 0) {
		pdata = buf + strlen("RSSILOW-THRESHOLD") + 1;
		if (MLAN_STATUS_SUCCESS !=
		    woal_set_rssi_low_threshold(priv, pdata, MOAL_IOCTL_WAIT)) {
			ret = -EFAULT;
			goto done;
		}
		len = sprintf(buf, "OK\n") + 1;
	} else if (strncmp(buf, "SCAN-CFG", strlen("SCAN-CFG")) == 0) {
		PRINTM(MIOCTL, "Set SCAN CFG\n");
		if (MLAN_STATUS_SUCCESS !=
		    woal_set_scan_cfg(priv, buf, priv_cmd.total_len)) {
			ret = -EFAULT;
			goto done;
		}
		len = sprintf(buf, "OK\n") + 1;
	} else if (strncmp(buf, "RSSI", strlen("RSSI")) == 0) {
		if (MLAN_STATUS_SUCCESS !=
		    woal_get_bss_info(priv, MOAL_IOCTL_WAIT, &bss_info)) {
			ret = -EFAULT;
			goto done;
		}
		if (bss_info.media_connected) {
			if (MLAN_STATUS_SUCCESS !=
			    woal_get_signal_info(priv, MOAL_IOCTL_WAIT,
						 &signal)) {
				ret = -EFAULT;
				goto done;
			}
			len = sprintf(buf, "%.32s rssi %d\n",
				      bss_info.ssid.ssid, signal.bcn_rssi_avg) +
				1;
		} else {
			len = sprintf(buf, "OK\n") + 1;
		}
	} else if (strncmp(buf, "LINKSPEED", strlen("LINKSPEED")) == 0) {
		if (MLAN_STATUS_SUCCESS !=
		    woal_set_get_data_rate(priv, MLAN_ACT_GET, &rate)) {
			ret = -EFAULT;
			goto done;
		}
		PRINTM(MIOCTL, "tx rate=%d\n", (int)rate.rate);
		len = sprintf(buf, "LinkSpeed %d\n",
			      (int)(rate.rate * 500000 / 1000000)) + 1;
	} else
#endif
	if (strncmp(buf, "MACADDR", strlen("MACADDR")) == 0) {
		len = sprintf(buf, "Macaddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
			      priv->current_addr[0], priv->current_addr[1],
			      priv->current_addr[2], priv->current_addr[3],
			      priv->current_addr[4], priv->current_addr[5]) + 1;
	}
#ifdef STA_SUPPORT
	else if (strncmp(buf, "GETPOWER", strlen("GETPOWER")) == 0) {
		if (MLAN_STATUS_SUCCESS !=
		    woal_get_powermode(priv, &power_mode)) {
			ret = -EFAULT;
			goto done;
		}
		len = sprintf(buf, "powermode = %d\n", power_mode) + 1;
	} else if (strncmp(buf, "SCAN-ACTIVE", strlen("SCAN-ACTIVE")) == 0) {
		if (MLAN_STATUS_SUCCESS !=
		    woal_set_scan_type(priv, MLAN_SCAN_TYPE_ACTIVE)) {
			ret = -EFAULT;
			goto done;
		}
		priv->scan_type = MLAN_SCAN_TYPE_ACTIVE;
		PRINTM(MIOCTL, "Set Active Scan\n");
		len = sprintf(buf, "OK\n") + 1;
	} else if (strncmp(buf, "SCAN-PASSIVE", strlen("SCAN-PASSIVE")) == 0) {
		if (MLAN_STATUS_SUCCESS !=
		    woal_set_scan_type(priv, MLAN_SCAN_TYPE_PASSIVE)) {
			ret = -EFAULT;
			goto done;
		}
		priv->scan_type = MLAN_SCAN_TYPE_PASSIVE;
		PRINTM(MIOCTL, "Set Passive Scan\n");
		len = sprintf(buf, "OK\n") + 1;
	} else if (strncmp(buf, "POWERMODE", strlen("POWERMODE")) == 0) {
		pdata = buf + strlen("POWERMODE") + 1;
		if (!moal_extflg_isset(priv->phandle, EXT_HW_TEST)) {
			if (MLAN_STATUS_SUCCESS !=
			    woal_set_powermode(priv, pdata)) {
				ret = -EFAULT;
				goto done;
			}
		}
		len = sprintf(buf, "OK\n") + 1;
	} else if (strncmp(buf, "SETROAMING", strlen("SETROAMING")) == 0) {
		pdata = buf + strlen("SETROAMING") + 1;
#ifdef STA_CFG80211
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
		if (moal_extflg_isset(priv->phandle, EXT_HOST_MLME))
			goto done;
#endif
#endif
#ifdef STA_CFG80211
		if (*pdata == '1') {
			priv->roaming_enabled = MTRUE;
			PRINTM(MIOCTL, "Roaming enabled\n");
		} else if (*pdata == '0') {
			priv->roaming_enabled = MFALSE;
			PRINTM(MIOCTL, "Roaming disabled\n");
		}
#endif
		len = sprintf(buf, "OK\n") + 1;
	} else if (strncmp(buf, "ROAM", strlen("ROAM")) == 0) {
		pdata = buf + strlen("ROAM") + 1;
#ifdef STA_CFG80211
#if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
		if (moal_extflg_isset(priv->phandle, EXT_HOST_MLME))
			goto done;
#endif
#endif
#ifdef STA_CFG80211
		if (*pdata == '1') {
			priv->roaming_enabled = MTRUE;
			PRINTM(MIOCTL, "Roaming enabled\n");
		} else if (*pdata == '0') {
			priv->roaming_enabled = MFALSE;
			PRINTM(MIOCTL, "Roaming disabled\n");
		}
#endif
		len = sprintf(buf, "OK\n") + 1;
	} else if (strncmp(buf, "COUNTRY", strlen("COUNTRY")) == 0) {
		copy_len = strlen(buf) - strlen("COUNTRY") - 1;
		if (copy_len > COUNTRY_CODE_LEN || copy_len <= 0) {
			PRINTM(MERROR, "Invalid country length\n");
			ret = -EFAULT;
			goto done;
		}
		memset(country_code, 0, sizeof(country_code));
		moal_memcpy_ext(priv->phandle, country_code,
				buf + strlen("COUNTRY") + 1, copy_len,
				COUNTRY_CODE_LEN);
		PRINTM(MIOCTL, "Set COUNTRY %s\n", country_code);
		if (priv->phandle->params.cntry_txpwr) {
			if (MLAN_STATUS_SUCCESS !=
			    woal_request_country_power_table(priv,
							     country_code)) {
				ret = -EFAULT;
				goto done;
			}
		}
#ifdef STA_CFG80211
		if (IS_STA_CFG80211(cfg80211_wext)) {
			PRINTM(MIOCTL, "Notify country code=%s\n",
			       country_code);
			if (!moal_extflg_isset(priv->phandle,
					       EXT_DISABLE_REGD_BY_DRIVER))
				regulatory_hint(priv->wdev->wiphy,
						country_code);
			len = sprintf(buf, "OK\n") + 1;
			goto done;
		}
#endif
		if (MLAN_STATUS_SUCCESS !=
		    woal_set_region_code(priv, country_code)) {
			ret = -EFAULT;
			goto done;
		}
		len = sprintf(buf, "OK\n") + 1;
	} else if (memcmp(buf, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE) == 0) {
		PRINTM(MIOCTL, "Set Combo Scan\n");
		if (MLAN_STATUS_SUCCESS !=
		    woal_set_combo_scan(priv, buf, priv_cmd.total_len)) {
			ret = -EFAULT;
			goto done;
		}
		len = sprintf(buf, "OK\n") + 1;
	} else if (strncmp(buf, "GETBAND", strlen("GETBAND")) == 0) {
		if (MLAN_STATUS_SUCCESS != woal_get_band(priv, &band)) {
			ret = -EFAULT;
			goto done;
		}
		len = sprintf(buf, "Band %d\n", band) + 1;
	} else if (strncmp(buf, "SETBAND", strlen("SETBAND")) == 0) {
		pband = buf + strlen("SETBAND") + 1;
		if (MLAN_STATUS_SUCCESS != woal_set_band(priv, pband)) {
			ret = -EFAULT;
			goto done;
		}
		len = sprintf(buf, "OK\n") + 1;
	}
#endif
	else if (strncmp(buf, "START", strlen("START")) == 0) {
		len = sprintf(buf, "OK\n") + 1;
	} else if (strncmp(buf, "STOP", strlen("STOP")) == 0) {
		len = sprintf(buf, "OK\n") + 1;
	}
#ifdef UAP_SUPPORT
	else if (strncmp(buf, "AP_BSS_START", strlen("AP_BSS_START")) == 0) {
		ret = woal_uap_bss_ctrl(priv, MOAL_IOCTL_WAIT, UAP_BSS_START);
		if (ret)
			goto done;
		len = sprintf(buf, "OK\n") + 1;
	} else if (strncmp(buf, "AP_BSS_STOP", strlen("AP_BSS_STOP")) == 0) {
		ret = woal_uap_bss_ctrl(priv, MOAL_IOCTL_WAIT, UAP_BSS_STOP);
		if (ret)
			goto done;
		len = sprintf(buf, "OK\n") + 1;
	} else if (strncmp(buf, "AP_SET_CFG", strlen("AP_SET_CFG")) == 0) {
		if (priv_cmd.total_len <= (int)strlen("AP_SET_CFG") + 1)
			goto done;
		pdata = buf + strlen("AP_SET_CFG") + 1;
		ret = woal_uap_set_ap_cfg(priv, pdata,
					  priv_cmd.total_len -
					  strlen("AP_SET_CFG") - 1);
		if (ret)
			goto done;
		len = sprintf(buf, "OK\n") + 1;
	} else if (strncmp(buf, "WL_FW_RELOAD", strlen("WL_FW_RELOAD")) == 0) {
		len = sprintf(buf, "OK\n") + 1;
	} else if (strncmp(buf, "AP_GET_STA_LIST", strlen("AP_GET_STA_LIST")) ==
		   0) {
		/* TODO Add STA list support */
		len = sprintf(buf, "OK\n") + 1;
	}
#endif
	else if (strncmp(buf, "SETSUSPENDOPT", strlen("SETSUSPENDOPT")) == 0) {
		/* it will be done by GUI */
		len = sprintf(buf, "OK\n") + 1;
	} else if (strncmp(buf, "SETSUSPENDMODE", strlen("SETSUSPENDMODE")) ==
		   0) {
		/* it will be done by GUI */
		len = sprintf(buf, "OK\n") + 1;
	} else if (strncmp(buf, "BTCOEXMODE", strlen("BTCOEXMODE")) == 0) {
		len = sprintf(buf, "OK\n") + 1;
	} else if (strncmp(buf, "BTCOEXSCAN-START",
			   strlen("BTCOEXSCAN-START")) == 0) {
		len = sprintf(buf, "OK\n") + 1;
	} else if (strncmp(buf, "BTCOEXSCAN-STOP", strlen("BTCOEXSCAN-STOP")) ==
		   0) {
		len = sprintf(buf, "OK\n") + 1;
	}
#ifdef STA_SUPPORT
	else if (strncmp(buf, "BGSCAN-START", strlen("BGSCAN-START")) == 0) {
		len = sprintf(buf, "OK\n") + 1;
	} else if (strncmp(buf, "BGSCAN-CONFIG", strlen("BGSCAN-CONFIG")) == 0) {
		if (MLAN_STATUS_SUCCESS !=
		    woal_set_bg_scan(priv, buf, priv_cmd.total_len)) {
			ret = -EFAULT;
			goto done;
		}
		priv->bg_scan_start = MTRUE;
		priv->bg_scan_reported = MFALSE;
		len = sprintf(buf, "OK\n") + 1;
	} else if (strncmp(buf, "BGSCAN-STOP", strlen("BGSCAN-STOP")) == 0) {
		if (priv->bg_scan_start && !priv->scan_cfg.rssi_threshold) {
			if (MLAN_STATUS_SUCCESS !=
			    woal_stop_bg_scan(priv, MOAL_NO_WAIT)) {
				ret = -EFAULT;
				goto done;
			}
			priv->bg_scan_start = MFALSE;
			priv->bg_scan_reported = MFALSE;
		}
		len = sprintf(buf, "OK\n") + 1;
	} else if (strncmp(buf, "RXFILTER-START", strlen("RXFILTER-START")) ==
		   0) {
#ifdef MEF_CFG_RX_FILTER
		ret = woal_set_rxfilter(priv, MTRUE);
		if (ret)
			goto done;
#endif
		len = sprintf(buf, "OK\n") + 1;
	} else if (strncmp(buf, "RXFILTER-STOP", strlen("RXFILTER-STOP")) == 0) {
#ifdef MEF_CFG_RX_FILTER
		ret = woal_set_rxfilter(priv, MFALSE);
		if (ret)
			goto done;
#endif
		len = sprintf(buf, "OK\n") + 1;
	}
#ifdef STA_CFG80211
	else if (strncmp(buf, "GET_EVENT", strlen("GET_EVENT")) == 0) {
		if (IS_STA_CFG80211(cfg80211_wext)) {
			if (priv->last_event & EVENT_BG_SCAN_REPORT)
				woal_inform_bss_from_scan_result(priv, NULL,
								 MOAL_IOCTL_WAIT);
		}
		len = sprintf(buf, "EVENT=%d\n", priv->last_event) + 1;
		priv->last_event = 0;
	} else if (strncmp(buf, "GET_802_11W", strlen("GET_802_11W")) == 0) {
		len = sprintf(buf, "802_11W=ENABLED\n") + 1;
	}
#endif /* STA_CFG80211 */
	else if (strncmp(buf, "RXFILTER-ADD", strlen("RXFILTER-ADD")) == 0) {
		pdata = buf + strlen("RXFILTER-ADD") + 1;
		if (MLAN_STATUS_SUCCESS != woal_add_rxfilter(priv, pdata)) {
			ret = -EFAULT;
			goto done;
		}
		len = sprintf(buf, "OK\n") + 1;
	} else if (strncmp(buf, "RXFILTER-REMOVE", strlen("RXFILTER-REMOVE")) ==
		   0) {
		pdata = buf + strlen("RXFILTER-REMOVE") + 1;
		if (MLAN_STATUS_SUCCESS != woal_remove_rxfilter(priv, pdata)) {
			ret = -EFAULT;
			goto done;
		}
		len = sprintf(buf, "OK\n") + 1;
	} else if (strncmp(buf, "QOSINFO", strlen("QOSINFO")) == 0) {
		pdata = buf + strlen("QOSINFO") + 1;
#ifdef STA_SUPPORT
		if (MLAN_STATUS_SUCCESS !=
		    woal_priv_qos_cfg(priv, MLAN_ACT_SET, pdata)) {
			ret = -EFAULT;
			goto done;
		}
#endif
		len = sprintf(buf, "OK\n") + 1;
	} else if (strncmp(buf, "SLEEPPD", strlen("SLEEPPD")) == 0) {
		pdata = buf + strlen("SLEEPPD") + 1;
		if (MLAN_STATUS_SUCCESS != woal_set_sleeppd(priv, pdata)) {
			ret = -EFAULT;
			goto done;
		}
		len = sprintf(buf, "OK\n") + 1;
	} else if (strncmp(buf, "SET_AP_WPS_P2P_IE",
			   strlen("SET_AP_WPS_P2P_IE")) == 0) {
		pdata = buf + strlen("SET_AP_WPS_P2P_IE") + 1;
		/* Android cmd format:
		 * "SET_AP_WPS_P2P_IE 1"  -- beacon IE
		 * "SET_AP_WPS_P2P_IE 2"  -- proberesp IE
		 * "SET_AP_WPS_P2P_IE 4"  -- assocresp IE
		 */
#if defined(STA_CFG80211) && defined(UAP_CFG80211)
#if CFG80211_VERSION_CODE < KERNEL_VERSION(3, 2, 0)
		if (MLAN_STATUS_SUCCESS !=
		    woal_set_ap_wps_p2p_ie(priv, (t_u8 *)pdata,
					   priv_cmd.used_len -
					   strlen("SET_AP_WPS_P2P_IE") - 1)) {
			ret = -EFAULT;
			goto done;
		}
#endif
#endif
		len = sprintf(buf, "OK\n") + 1;
	}
#endif
	else if (strncmp(buf, "P2P_DEV_ADDR", strlen("P2P_DEV_ADDR")) == 0) {
		memset(buf, 0x0, (size_t) priv_cmd.total_len);
		moal_memcpy_ext(priv->phandle, buf, priv->current_addr,
				ETH_ALEN, (t_u32)priv_cmd.total_len);
		len = ETH_ALEN;
	} else if (strncmp(buf, ("P2P_GET_NOA"), strlen("P2P_GET_NOA")) == 0) {
		/* TODO
		 * Just return '\0'
		 */
		memset(buf, 0x0, (size_t) priv_cmd.total_len);
		*buf = 0;
		len = 1;
	} else if (strnicmp(buf, "MIRACAST", strlen("MIRACAST")) == 0) {
		pdata = buf + strlen("MIRACAST");
		/* Android cmd format:
		 * "MIRACAST 0"  -- disabled
		 * "MIRACAST 1"  -- operating as source
		 * "MIRACAST 2"  -- operating as sink
		 */
#ifdef WIFI_DIRECT_SUPPORT
#if defined(STA_CFG80211) || defined(UAP_CFG80211)
		if (MLAN_STATUS_SUCCESS !=
		    woal_set_miracast_mode(priv, (t_u8 *)pdata,
					   priv_cmd.used_len -
					   strlen("MIRACAST"))) {
			ret = -EFAULT;
			goto done;
		}
#endif
#endif
		len = sprintf(buf, "OK\n") + 1;
	} else if (strnicmp(buf, "SCAN_TIMING", strlen("SCAN_TIMING")) == 0) {
#ifdef WIFI_DIRECT_SUPPORT
#if defined(STA_CFG80211) || defined(UAP_CFG80211)
		if (MLAN_STATUS_SUCCESS !=
		    woal_set_scan_chan_gap(priv, buf, priv_cmd.total_len)) {
			ret = -EFAULT;
			goto done;
		}
#endif
#endif
		len = sprintf(buf, "OK\n") + 1;
	} else if (strnicmp(buf, "BA_WSIZE_RX", strlen("BA_WSIZE_RX")) == 0) {
		pdata = buf + strlen("BA_WSIZE_RX") + 1;
		len = priv_cmd.total_len - strlen("BA_WSIZE_RX") - 1;
		if (MLAN_STATUS_SUCCESS !=
		    woal_set_rx_ba_winsize(priv, pdata, len)) {
			ret = -EFAULT;
			goto done;
		}
		len = sprintf(buf, "OK\n") + 1;
	} else if (strnicmp(buf, "BA_WSIZE_TX", strlen("BA_WSIZE_TX")) == 0) {
		pdata = buf + strlen("BA_WSIZE_TX") + 1;
		len = priv_cmd.total_len - strlen("BA_WSIZE_TX") - 1;
		if (MLAN_STATUS_SUCCESS !=
		    woal_set_tx_ba_winsize(priv, pdata, len)) {
			ret = -EFAULT;
			goto done;
		}
		len = sprintf(buf, "OK\n") + 1;
	} else if (strncmp(buf, "FAKE_SCAN_COMPLETE",
			   strlen("FAKE_SCAN_COMPLETE")) == 0) {
		pdata = buf + strlen("FAKE_SCAN_COMPLETE") + 1;
#ifdef STA_CFG80211
		if (*pdata == '1') {
			priv->fake_scan_complete = MTRUE;
			PRINTM(MIOCTL, "fake scan complete enabled\n");
		} else if (*pdata == '0') {
			priv->fake_scan_complete = MFALSE;
			PRINTM(MIOCTL, "fake scan complete disabled\n");
		}
#endif
		len = sprintf(buf, "OK\n") + 1;
	}
#if defined(STA_CFG80211) || defined(UAP_CFG80211)
#ifdef WIFI_DIRECT_SUPPORT
	else if (strncmp(buf, "P2P_PERIODIC_SLEEP",
			 strlen("P2P_PERIODIC_SLEEP")) == 0) {
		if (MLAN_STATUS_SUCCESS !=
		    woal_p2p_ps_cfg(priv, buf, priv_cmd.total_len)) {
			ret = -EFAULT;
			goto done;
		}
		len = sprintf(buf, "OK\n") + 1;
	}
#endif
#endif
	else if (strncmp(buf, "WLS_BATCHING", strlen("WLS_BATCHING")) == 0) {
		/* TODO */
		len = sprintf(buf, "OK\n") + 1;
	} else if (strncmp(buf, "TDLS_CS_CHAN", strlen("TDLS_CS_CHAN")) == 0) {
		len = woal_priv_tdls_cs_chan(priv, buf, priv_cmd.total_len);
	}
#if defined(UAP_SUPPORT)
	else if (strncmp(buf, "P2P_ECSA", strlen("P2P_ECSA")) == 0) {
		len = woal_priv_p2p_ecsa(priv, buf, priv_cmd.total_len);
	}
#endif
	else if (strncmp(buf, "FAKEMAC", strlen("FAKEMAC")) == 0) {
		len = woal_priv_config_random_mac(priv, buf,
						  priv_cmd.total_len);
	} else if (strncmp(buf, PRIV_CMD_CLOUD_KEEP_ALIVE,
			   strlen(PRIV_CMD_CLOUD_KEEP_ALIVE)) == 0) {
		len = woal_priv_cloud_keep_alive(priv, buf, priv_cmd.total_len);
	} else if (strnicmp(buf, PRIV_CMD_TX_RX_HISTOGRAM,
			    strlen(PRIV_CMD_TX_RX_HISTOGRAM)) == 0) {
		/* Get TX/RX histogram statistic */
		len = woal_priv_get_rx_tx_histogram(priv, buf,
						    priv_cmd.total_len);
		goto handled;
	} else if (strnicmp(buf, PRIV_CMD_GET_CHNRGPWR,
			    strlen(PRIV_CMD_GET_CHNRGPWR)) == 0) {
		/* Get chnrgpwr */
		len = woal_priv_get_chnrgpwr(priv, buf, priv_cmd.total_len);
		goto handled;
	} else if (strnicmp(buf, PRIV_CMD_GET_TXPWR_LIMIT,
			    strlen(PRIV_CMD_GET_TXPWR_LIMIT)) == 0) {
		/* Get txpwrlimit */
		len = woal_priv_get_txpwrlimit(priv, buf, priv_cmd.total_len);
		goto handled;
	} else {
		PRINTM(MIOCTL, "Unknown PRIVATE command: %s, ignored\n", buf);
		ret = -EFAULT;
		goto done;
	}

handled:
	PRINTM(MIOCTL, "PRIV Command return: %s, length=%d\n", buf, len);

	if (len > 0) {
		priv_cmd.used_len = len;
		if (priv_cmd.used_len <= priv_cmd.total_len) {
			memset(buf + priv_cmd.used_len, 0,
			       (size_t) (CMD_BUF_LEN - priv_cmd.used_len));
			if (copy_to_user((void __user *)cmd_buf, buf,
					 priv_cmd.total_len)) {
				PRINTM(MERROR,
				       "%s: failed to copy data to user buffer\n",
				       __FUNCTION__);
				ret = -EFAULT;
				goto done;
			}
			if (copy_to_user(req->ifr_data, &priv_cmd,
					 sizeof(android_wifi_priv_cmd))) {
				PRINTM(MERROR,
				       "%s: failed to copy command header to user buffer\n",
				       __FUNCTION__);
				ret = -EFAULT;
			}
		} else {
			PRINTM(MERROR,
			       "%s: the buffer supplied by appl is too small (supplied: %d, used: %d)\n",
			       __FUNCTION__, priv_cmd.total_len,
			       priv_cmd.used_len);
			ret = -EFAULT;
		}
	} else {
		ret = len;
	}

done:
	kfree(buf);
	LEAVE();
	return ret;
}

/********************************************************
			Global Functions
********************************************************/
/**
 *  @brief Create a brief scan resp to relay basic BSS info to the app layer
 *
 *  When the beacon/probe response has not been buffered, use the saved BSS
 *    information available to provide a minimum response for the application
 *    ioctl retrieval routines.  Include:
 *        - Timestamp
 *        - Beacon Period
 *        - Capabilities (including WMM Element if available)
 *        - SSID
 *
 *  @param ppbuffer  Output parameter: Buffer used to create basic scan rsp
 *  @param pbss_desc Pointer to a BSS entry in the scan table to create
 *                   scan response from for delivery to the application layer
 *
 *  @return          N/A
 */
void
wlan_scan_create_brief_table_entry(t_u8 **ppbuffer, BSSDescriptor_t *pbss_desc)
{
	t_u8 *ptmp_buf = *ppbuffer;
	t_u8 tmp_ssid_hdr[2];
	t_u8 ie_len = 0;

	ENTER();

	moal_memcpy_ext(NULL, ptmp_buf, pbss_desc->time_stamp,
			sizeof(pbss_desc->time_stamp),
			sizeof(pbss_desc->time_stamp));
	ptmp_buf += sizeof(pbss_desc->time_stamp);

	moal_memcpy_ext(NULL, ptmp_buf, &pbss_desc->beacon_period,
			sizeof(pbss_desc->beacon_period),
			sizeof(pbss_desc->beacon_period));
	ptmp_buf += sizeof(pbss_desc->beacon_period);

	moal_memcpy_ext(NULL, ptmp_buf, &pbss_desc->cap_info,
			sizeof(pbss_desc->cap_info),
			sizeof(pbss_desc->cap_info));
	ptmp_buf += sizeof(pbss_desc->cap_info);

	tmp_ssid_hdr[0] = 0;	/* Element ID for SSID is zero */
	tmp_ssid_hdr[1] = pbss_desc->ssid.ssid_len;
	moal_memcpy_ext(NULL, ptmp_buf, tmp_ssid_hdr, sizeof(tmp_ssid_hdr),
			sizeof(tmp_ssid_hdr));
	ptmp_buf += sizeof(tmp_ssid_hdr);

	moal_memcpy_ext(NULL, ptmp_buf, pbss_desc->ssid.ssid,
			pbss_desc->ssid.ssid_len, pbss_desc->ssid.ssid_len);
	ptmp_buf += pbss_desc->ssid.ssid_len;

	if (pbss_desc->wmm_ie.vend_hdr.element_id == WMM_IE) {
		ie_len = sizeof(IEEEtypes_Header_t) +
			pbss_desc->wmm_ie.vend_hdr.len;
		moal_memcpy_ext(NULL, ptmp_buf, &pbss_desc->wmm_ie, ie_len,
				ie_len);
		ptmp_buf += ie_len;
	}

	if (pbss_desc->pwpa_ie) {
		if ((*(pbss_desc->pwpa_ie)).vend_hdr.element_id == WPA_IE) {
			ie_len = sizeof(IEEEtypes_Header_t) +
				(*(pbss_desc->pwpa_ie)).vend_hdr.len;
			moal_memcpy_ext(NULL, ptmp_buf, pbss_desc->pwpa_ie,
					ie_len, ie_len);
		}

		ptmp_buf += ie_len;
	}
	if (pbss_desc->prsn_ie) {
		if ((*(pbss_desc->prsn_ie)).ieee_hdr.element_id == RSN_IE) {
			ie_len = sizeof(IEEEtypes_Header_t) +
				(*(pbss_desc->prsn_ie)).ieee_hdr.len;
			moal_memcpy_ext(NULL, ptmp_buf, pbss_desc->prsn_ie,
					ie_len, ie_len);
		}

		ptmp_buf += ie_len;
	}
	*ppbuffer = ptmp_buf;
	LEAVE();
}

/**
 *  @brief Create a wlan_ioctl_get_scan_table_entry for a given BSS
 *         Descriptor for inclusion in the ioctl response to the user space
 *         application.
 *
 *
 *  @param pbss_desc   Pointer to a BSS entry in the scan table to form
 *                     scan response from for delivery to the application layer
 *  @param ppbuffer    Output parameter: Buffer used to output scan return
 * struct
 *  @param pspace_left Output parameter: Number of bytes available in the
 *                     response buffer.
 *
 *  @return MLAN_STATUS_SUCCESS, or < 0 with IOCTL error code
 */
int
wlan_get_scan_table_ret_entry(BSSDescriptor_t *pbss_desc, t_u8 **ppbuffer,
			      int *pspace_left)
{
	wlan_ioctl_get_scan_table_entry *prsp_entry;
	wlan_ioctl_get_scan_table_entry tmp_rsp_entry;
	int space_needed;
	t_u8 *pcurrent;
	int variable_size;

	const int fixed_size = sizeof(wlan_ioctl_get_scan_table_entry);

	ENTER();

	pcurrent = *ppbuffer;

	/* The variable size returned is the stored beacon size */
	variable_size = pbss_desc->beacon_buf_size;

	/* If we stored a beacon and its size was zero, set the variable
	 *  size return value to the size of the brief scan response
	 *  wlan_scan_create_brief_table_entry creates.  Also used if
	 *  we are not configured to store beacons in the first place
	 */
	if (!variable_size) {
		variable_size = pbss_desc->ssid.ssid_len + 2;
		variable_size += (sizeof(pbss_desc->beacon_period) +
				  sizeof(pbss_desc->time_stamp) +
				  sizeof(pbss_desc->cap_info));
		if (pbss_desc->wmm_ie.vend_hdr.element_id == WMM_IE) {
			variable_size += (sizeof(IEEEtypes_Header_t) +
					  pbss_desc->wmm_ie.vend_hdr.len);
		}

		if (pbss_desc->pwpa_ie) {
			if ((*(pbss_desc->pwpa_ie)).vend_hdr.element_id ==
			    WPA_IE) {
				variable_size +=
					(sizeof(IEEEtypes_Header_t) +
					 (*(pbss_desc->pwpa_ie)).vend_hdr.len);
			}
		}

		if (pbss_desc->prsn_ie) {
			if ((*(pbss_desc->prsn_ie)).ieee_hdr.element_id ==
			    RSN_IE) {
				variable_size +=
					(sizeof(IEEEtypes_Header_t) +
					 (*(pbss_desc->prsn_ie)).ieee_hdr.len);
			}
		}
	}

	space_needed = fixed_size + variable_size;

	PRINTM(MINFO, "GetScanTable: need(%d), left(%d)\n", space_needed,
	       *pspace_left);

	if (space_needed >= *pspace_left) {
		*pspace_left = 0;
		LEAVE();
		return -E2BIG;
	}

	*pspace_left -= space_needed;

	tmp_rsp_entry.fixed_field_length =
		(sizeof(tmp_rsp_entry) -
		 sizeof(tmp_rsp_entry.fixed_field_length) -
		 sizeof(tmp_rsp_entry.bss_info_length));

	moal_memcpy_ext(NULL, tmp_rsp_entry.fixed_fields.bssid,
			pbss_desc->mac_address,
			sizeof(prsp_entry->fixed_fields.bssid),
			sizeof(prsp_entry->fixed_fields.bssid));

	tmp_rsp_entry.fixed_fields.rssi = pbss_desc->rssi;
	tmp_rsp_entry.fixed_fields.channel = pbss_desc->channel;
	tmp_rsp_entry.fixed_fields.chan_load = pbss_desc->chan_load;
	tmp_rsp_entry.fixed_fields.network_tsf = pbss_desc->network_tsf;
	tmp_rsp_entry.bss_info_length = variable_size;

	/*
	 *  Copy fixed fields to user space
	 */
	moal_memcpy_ext(NULL, pcurrent, &tmp_rsp_entry, fixed_size, fixed_size);
	pcurrent += fixed_size;

	if (pbss_desc->pbeacon_buf) {
		/*
		 *  Copy variable length elements to user space
		 */
		moal_memcpy_ext(NULL, pcurrent, pbss_desc->pbeacon_buf,
				pbss_desc->beacon_buf_size,
				pbss_desc->beacon_buf_size);

		pcurrent += pbss_desc->beacon_buf_size;
	} else {
		wlan_scan_create_brief_table_entry(&pcurrent, pbss_desc);
	}

	*ppbuffer = pcurrent;

	LEAVE();

	return MLAN_STATUS_SUCCESS;
}

/**
 *  @brief ioctl function - entry point
 *
 *  @param dev      A pointer to net_device structure
 *  @param req      A pointer to ifreq structure
 *  @param cmd      Command
 *
 *  @return          0 --success, otherwise fail
 */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
int
woal_do_ioctl(struct net_device *dev, struct ifreq *req, void __user * data,
	      int cmd)
#else
int
woal_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
#endif
{
	int ret = 0;

	ENTER();

#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
	if (in_compat_syscall())	/* not implemented yet */
		return -EOPNOTSUPP;
#endif

	PRINTM(MINFO, "woal_do_ioctl: ioctl cmd = 0x%x\n", cmd);
	switch (cmd) {
	case WOAL_ANDROID_DEF_CMD:
		/** android default ioctl ID is SIOCDEVPRIVATE + 1 */
		ret = woal_android_priv_cmd(dev, req);
		break;
	case WOAL_CUSTOM_IE_CFG:
		ret = woal_custom_ie_ioctl(dev, req);
		break;
	case WOAL_MGMT_FRAME_TX:
		ret = woal_send_host_packet(dev, req);
		break;
	case WOAL_TDLS_CONFIG:
		ret = woal_tdls_config_ioctl(dev, req);
		break;
	case WOAL_ANDROID_PRIV_CMD:
		ret = woal_android_priv_cmd(dev, req);
		break;
	case WOAL_GET_BSS_TYPE:
		ret = woal_get_bss_type(dev, req);
		break;
	default:
#if defined(STA_WEXT)
#ifdef STA_SUPPORT
		ret = woal_wext_do_ioctl(dev, req, cmd);
#else
		ret = -EINVAL;
#endif
#else
		ret = -EINVAL;
#endif
		break;
	}

	LEAVE();
	return ret;
}
