/** @file mlan_sta_ioctl.c
 *
 *  @brief This file contains the functions for station ioctl.
 *
 *
 *  Copyright 2008-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:
    10/21/2008: initial version
******************************************************/

#include "mlan.h"
#include "mlan_join.h"
#include "mlan_util.h"
#include "mlan_fw.h"
#include "mlan_main.h"
#include "mlan_wmm.h"
#include "mlan_11n.h"
#include "mlan_11ac.h"
#include "mlan_11ax.h"
#include "mlan_11h.h"
#ifdef DRV_EMBEDDED_SUPPLICANT
#include "authenticator_api.h"
#endif

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

/********************************************************
			Global Variables
********************************************************/

/********************************************************
			Local Functions
********************************************************/

/**
 *  @brief Get signal information
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_PENDING --success, otherwise fail
 */
static mlan_status
wlan_get_info_signal(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	pmlan_private pmpriv = MNULL;
	mlan_status ret = MLAN_STATUS_SUCCESS;

	ENTER();

	if (pioctl_req != MNULL) {
		pmpriv = pmadapter->priv[pioctl_req->bss_index];
	} else {
		PRINTM(MERROR, "MLAN IOCTL information is not present\n");
		ret = MLAN_STATUS_FAILURE;
		goto exit;
	}

	/* Check information buffer length of MLAN IOCTL */
	if (pioctl_req->buf_len < sizeof(mlan_ds_get_signal)) {
		PRINTM(MWARN,
		       "MLAN IOCTL information buffer length is too short.\n");
		pioctl_req->data_read_written = 0;
		pioctl_req->buf_len_needed = sizeof(mlan_ds_get_signal);
		pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
		ret = MLAN_STATUS_RESOURCE;
		goto exit;
	}

	/* Signal info can be obtained only if connected */
	if (pmpriv->media_connected == MFALSE) {
		PRINTM(MINFO, "Can not get signal in disconnected state\n");
		pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID;
		ret = MLAN_STATUS_FAILURE;
		goto exit;
	}

	/* Send request to firmware */
	ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_RSSI_INFO,
			       HostCmd_ACT_GEN_GET, 0, (t_void *)pioctl_req,
			       MNULL);

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

exit:
	LEAVE();
	return ret;
}

/**
 *  @brief Get signal information
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_PENDING --success, otherwise fail
 */
static mlan_status
wlan_get_info_signal_ext(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	pmlan_private pmpriv = MNULL;
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_ds_get_info *info = MNULL;

	ENTER();

	if (pioctl_req != MNULL) {
		pmpriv = pmadapter->priv[pioctl_req->bss_index];
	} else {
		PRINTM(MERROR, "MLAN IOCTL information is not present\n");
		ret = MLAN_STATUS_FAILURE;
		goto exit;
	}
	info = (mlan_ds_get_info *)pioctl_req->pbuf;

	/* Check information buffer length of MLAN IOCTL */
	if (pioctl_req->buf_len < sizeof(mlan_ds_get_info)) {
		PRINTM(MWARN,
		       "MLAN IOCTL information buffer length is too short.\n");
		pioctl_req->data_read_written = 0;
		pioctl_req->buf_len_needed = sizeof(mlan_ds_get_info);
		pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
		ret = MLAN_STATUS_RESOURCE;
		goto exit;
	}

	/* Send request to firmware */
	ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_RSSI_INFO_EXT,
			       HostCmd_ACT_GEN_GET, 0, (t_void *)pioctl_req,
			       (t_void *)info);

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

exit:
	LEAVE();
	return ret;
}

/**
 *  @brief Get statistics information
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_PENDING --success, otherwise fail
 */
static mlan_status
wlan_get_info_stats(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	pmlan_private pmpriv = MNULL;
	mlan_status ret = MLAN_STATUS_SUCCESS;

	ENTER();

	if (pioctl_req != MNULL) {
		pmpriv = pmadapter->priv[pioctl_req->bss_index];
	} else {
		PRINTM(MERROR, "MLAN IOCTL information is not present\n");
		ret = MLAN_STATUS_FAILURE;
		goto exit;
	}

	/* Check information buffer length of MLAN IOCTL */
	if (pioctl_req->buf_len < sizeof(mlan_ds_get_stats)) {
		PRINTM(MWARN,
		       "MLAN IOCTL information buffer length is too short.\n");
		pioctl_req->data_read_written = 0;
		pioctl_req->buf_len_needed = sizeof(mlan_ds_get_stats);
		pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
		ret = MLAN_STATUS_RESOURCE;
		goto exit;
	}

	/* Send request to firmware */
	ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_GET_LOG,
			       HostCmd_ACT_GEN_GET, 0, (t_void *)pioctl_req,
			       MNULL);

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

exit:
	LEAVE();
	return ret;
}

/**
 *  @brief Get sta channel information
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_PENDING --success, otherwise fail
 */
static mlan_status
wlan_bss_ioctl_get_chan_info(pmlan_adapter pmadapter,
			     pmlan_ioctl_req pioctl_req)
{
	pmlan_private pmpriv = MNULL;
	mlan_status ret = MLAN_STATUS_SUCCESS;

	ENTER();

	if (pioctl_req != MNULL) {
		pmpriv = pmadapter->priv[pioctl_req->bss_index];
	} else {
		PRINTM(MERROR, "MLAN IOCTL information is not present\n");
		ret = MLAN_STATUS_FAILURE;
		goto exit;
	}

	/* Check information buffer length of MLAN IOCTL */
	if (pioctl_req->buf_len < sizeof(chan_band_info)) {
		PRINTM(MWARN,
		       "MLAN IOCTL information buffer length is too short.\n");
		pioctl_req->data_read_written = 0;
		pioctl_req->buf_len_needed = sizeof(chan_band_info);
		pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
		ret = MLAN_STATUS_RESOURCE;
		goto exit;
	}

	/* Send request to firmware */
	ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_STA_CONFIGURE,
			       HostCmd_ACT_GEN_GET, 0, (t_void *)pioctl_req,
			       MNULL);

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

exit:
	LEAVE();
	return ret;
}

/**
 *  @brief Get BSS information
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS --success
 */
static mlan_status
wlan_get_info_bss_info(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_ds_get_info *info;
	BSSDescriptor_t *pbss_desc;
	t_s32 tbl_idx = 0;

	ENTER();

	/* Get current BSS info */
	pbss_desc = &pmpriv->curr_bss_params.bss_descriptor;
	info = (mlan_ds_get_info *)pioctl_req->pbuf;

	/* BSS mode */
	info->param.bss_info.bss_mode = pmpriv->bss_mode;

	/* SSID */
	memcpy_ext(pmadapter, &info->param.bss_info.ssid, &pbss_desc->ssid,
		   sizeof(mlan_802_11_ssid), sizeof(mlan_802_11_ssid));

	/* BSSID */
	memcpy_ext(pmadapter, &info->param.bss_info.bssid,
		   &pbss_desc->mac_address, MLAN_MAC_ADDR_LENGTH,
		   MLAN_MAC_ADDR_LENGTH);

	/* Channel */
	info->param.bss_info.bss_chan = pbss_desc->channel;

	/* Beacon interval */
	info->param.bss_info.beacon_interval = pbss_desc->beacon_period;

	/* Band */
	info->param.bss_info.bss_band = (t_u8)pbss_desc->bss_band;

	/* Region code */
	info->param.bss_info.region_code = pmadapter->region_code;

	/* Scan table index if connected */
	info->param.bss_info.scan_table_idx = 0;
	info->param.bss_info.scan_block = pmadapter->scan_block;
	if (pmpriv->media_connected == MTRUE) {
		tbl_idx = wlan_find_ssid_in_list(pmpriv, &pbss_desc->ssid,
						 pbss_desc->mac_address,
						 pmpriv->bss_mode);
		if (tbl_idx >= 0)
			info->param.bss_info.scan_table_idx = tbl_idx;
	}

	/* Connection status */
	info->param.bss_info.media_connected = pmpriv->media_connected;

	/* Radio status */
	info->param.bss_info.radio_on = pmadapter->radio_on;

	/* Tx power information */
	info->param.bss_info.max_power_level = pmpriv->max_tx_power_level;
	info->param.bss_info.min_power_level = pmpriv->min_tx_power_level;

	/* AdHoc state */
	info->param.bss_info.adhoc_state = pmpriv->adhoc_state;

	/* Last beacon NF */
	info->param.bss_info.bcn_nf_last = pmpriv->bcn_nf_last;

	/* wep status */
	if (pmpriv->sec_info.wep_status == Wlan802_11WEPEnabled)
		info->param.bss_info.wep_status = MTRUE;
	else
		info->param.bss_info.wep_status = MFALSE;

	info->param.bss_info.is_hs_configured = pmadapter->is_hs_configured;
	info->param.bss_info.is_deep_sleep = pmadapter->is_deep_sleep;

	/* Capability Info */
	info->param.bss_info.capability_info = 0;
	memcpy_ext(pmadapter, &info->param.bss_info.capability_info,
		   &pbss_desc->cap_info,
		   sizeof(info->param.bss_info.capability_info),
		   sizeof(info->param.bss_info.capability_info));

	memset(pmadapter, &info->param.bss_info.ext_cap, 0, sizeof(ExtCap_t));
	if (pbss_desc->pext_cap) {
		memcpy_ext(pmadapter, &info->param.bss_info.ext_cap,
			   (t_u8 *)pbss_desc->pext_cap +
			   sizeof(IEEEtypes_Header_t),
			   pbss_desc->pext_cap->ieee_hdr.len,
			   sizeof(info->param.bss_info.ext_cap));
	}

	/* Listen Interval */
	info->param.bss_info.listen_interval = pmpriv->listen_interval;

	/* Association ID */
	info->param.bss_info.assoc_id =
		(t_u16)((IEEEtypes_AssocRsp_t *)pmpriv->assoc_rsp_buf)
		->a_id;

	/* AP/Peer supported rates */
	memset(pmadapter, info->param.bss_info.peer_supp_rates, 0,
	       sizeof(info->param.bss_info.peer_supp_rates));
	memcpy_ext(pmadapter, info->param.bss_info.peer_supp_rates,
		   pbss_desc->supported_rates,
		   sizeof(pbss_desc->supported_rates),
		   sizeof(info->param.bss_info.peer_supp_rates));
	if (pbss_desc->pmd_ie) {
		info->param.bss_info.mdid = pbss_desc->pmd_ie->mdid;
		info->param.bss_info.ft_cap = pbss_desc->pmd_ie->ft_cap;
	}
	pioctl_req->data_read_written =
		sizeof(mlan_bss_info) + MLAN_SUB_COMMAND_SIZE;

	LEAVE();
	return ret;
}

/**
 *  @brief Get information handler
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
 */
static mlan_status
wlan_get_info_ioctl(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_status status = MLAN_STATUS_SUCCESS;
	mlan_ds_get_info *pget_info = MNULL;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];

	ENTER();

	pget_info = (mlan_ds_get_info *)pioctl_req->pbuf;

	switch (pget_info->sub_command) {
	case MLAN_OID_GET_STATS:
		status = wlan_get_info_stats(pmadapter, pioctl_req);
		break;
	case MLAN_OID_GET_SIGNAL:
		status = wlan_get_info_signal(pmadapter, pioctl_req);
		break;
	case MLAN_OID_GET_SIGNAL_EXT:
		status = wlan_get_info_signal_ext(pmadapter, pioctl_req);
		break;
	case MLAN_OID_GET_FW_INFO:
		pioctl_req->data_read_written =
			sizeof(mlan_fw_info) + MLAN_SUB_COMMAND_SIZE;
		pget_info->param.fw_info.fw_ver = pmadapter->fw_release_number;
		pget_info->param.fw_info.hotfix_version =
			pmadapter->fw_hotfix_ver;
		memcpy_ext(pmadapter, &pget_info->param.fw_info.mac_addr,
			   pmpriv->curr_addr, MLAN_MAC_ADDR_LENGTH,
			   MLAN_MAC_ADDR_LENGTH);
		pget_info->param.fw_info.fw_bands = pmadapter->fw_bands;
		pget_info->param.fw_info.region_code = pmadapter->region_code;
		if (pmadapter->otp_region && pmadapter->otp_region->force_reg)
			pget_info->param.fw_info.force_reg = MTRUE;
		else
			pget_info->param.fw_info.force_reg = MFALSE;
		pget_info->param.fw_info.ecsa_enable = pmadapter->ecsa_enable;
		pget_info->param.fw_info.getlog_enable =
			pmadapter->getlog_enable;
		pget_info->param.fw_info.hw_dev_mcs_support =
			pmadapter->hw_dev_mcs_support;
		pget_info->param.fw_info.hw_dot_11n_dev_cap =
			pmadapter->hw_dot_11n_dev_cap;
		pget_info->param.fw_info.usr_dev_mcs_support =
			pmpriv->usr_dev_mcs_support;
		if (IS_FW_SUPPORT_NO_80MHZ(pmadapter))
			pget_info->param.fw_info.prohibit_80mhz = MTRUE;
		else
			pget_info->param.fw_info.prohibit_80mhz = MFALSE;
		pget_info->param.fw_info.hw_dot_11ac_mcs_support =
			pmadapter->hw_dot_11ac_mcs_support;
		pget_info->param.fw_info.hw_dot_11ac_dev_cap =
			pmadapter->hw_dot_11ac_dev_cap;
		pget_info->param.fw_info.usr_dot_11ac_dev_cap_bg =
			pmpriv->usr_dot_11ac_dev_cap_bg;
		pget_info->param.fw_info.usr_dot_11ac_mcs_support =
			pmpriv->usr_dot_11ac_mcs_support;
		pget_info->param.fw_info.usr_dot_11ac_dev_cap_a =
			pmpriv->usr_dot_11ac_dev_cap_a;
		pget_info->param.fw_info.hw_hecap_len = pmadapter->hw_hecap_len;
		pget_info->param.fw_info.hw_2g_hecap_len =
			pmadapter->hw_2g_hecap_len;
		memcpy_ext(pmadapter, pget_info->param.fw_info.hw_he_cap,
			   pmadapter->hw_he_cap, pmadapter->hw_hecap_len,
			   sizeof(pget_info->param.fw_info.hw_he_cap));
		memcpy_ext(pmadapter, pget_info->param.fw_info.hw_2g_he_cap,
			   pmadapter->hw_2g_he_cap, pmadapter->hw_2g_hecap_len,
			   sizeof(pget_info->param.fw_info.hw_2g_he_cap));
		pget_info->param.fw_info.fw_supplicant_support =
			IS_FW_SUPPORT_SUPPLICANT(pmadapter) ? 0x01 : 0x00;
		pget_info->param.fw_info.antinfo = pmadapter->antinfo;
		pget_info->param.fw_info.max_ap_assoc_sta =
			pmadapter->max_sta_conn;
		pget_info->param.fw_info.fw_beacon_prot =
			IS_FW_SUPPORT_BEACON_PROT(pmadapter) ? 0x01 : 0x00;
		break;
	case MLAN_OID_GET_BSS_INFO:
		status = wlan_get_info_bss_info(pmadapter, pioctl_req);
		break;
	case MLAN_OID_GET_DEBUG_INFO:
		status = wlan_get_info_debug_info(pmadapter, pioctl_req);
		break;
	case MLAN_OID_GET_VER_EXT:
		status = wlan_get_info_ver_ext(pmadapter, pioctl_req);
		break;
	case MLAN_OID_LINK_STATS:
		status = wlan_ioctl_link_statistic(pmpriv, pioctl_req);
		break;
	default:
		pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID;
		status = MLAN_STATUS_FAILURE;
		break;
	}

	LEAVE();
	return status;
}

/**
 *  @brief Set/Get SNMP MIB handler
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_PENDING --success, otherwise fail
 */
static mlan_status
wlan_snmp_mib_ioctl(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_status ret = MLAN_STATUS_SUCCESS;
	t_u16 cmd_action = 0;
	t_u16 cmd_oid = 0;
	mlan_ds_snmp_mib *mib = MNULL;
	t_u32 value = 0;

	ENTER();

	if (pioctl_req->buf_len < sizeof(mlan_ds_snmp_mib)) {
		PRINTM(MWARN,
		       "MLAN IOCTL information buffer length is too short.\n");
		pioctl_req->data_read_written = 0;
		pioctl_req->buf_len_needed = sizeof(mlan_ds_snmp_mib);
		pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
		ret = MLAN_STATUS_RESOURCE;
		goto exit;
	}

	mib = (mlan_ds_snmp_mib *)pioctl_req->pbuf;
	if (pioctl_req->action == MLAN_ACT_SET)
		cmd_action = HostCmd_ACT_GEN_SET;
	else
		cmd_action = HostCmd_ACT_GEN_GET;

	switch (mib->sub_command) {
	case MLAN_OID_SNMP_MIB_RTS_THRESHOLD:
		value = mib->param.rts_threshold;
		cmd_oid = RtsThresh_i;
		break;
	case MLAN_OID_SNMP_MIB_FRAG_THRESHOLD:
		value = mib->param.frag_threshold;
		cmd_oid = FragThresh_i;
		break;
	case MLAN_OID_SNMP_MIB_RETRY_COUNT:
		value = mib->param.retry_count;
		cmd_oid = ShortRetryLim_i;
		break;
	case MLAN_OID_SNMP_MIB_DTIM_PERIOD:
		value = mib->param.dtim_period;
		cmd_oid = DtimPeriod_i;
		break;
	case MLAN_OID_SNMP_MIB_SIGNALEXT_ENABLE:
		value = mib->param.signalext_enable;
		cmd_oid = SignalextEnable_i;
		break;
	}

	/* Send request to firmware */
	ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_SNMP_MIB, cmd_action,
			       cmd_oid, (t_void *)pioctl_req, &value);

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

exit:
	LEAVE();
	return ret;
}

/**
 *  @brief Radio command handler
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
 */
static mlan_status
wlan_radio_ioctl(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_status status = MLAN_STATUS_SUCCESS;
	mlan_ds_radio_cfg *radio_cfg = MNULL;

	ENTER();

	if (pioctl_req->buf_len < sizeof(mlan_ds_radio_cfg)) {
		PRINTM(MWARN,
		       "MLAN IOCTL information buffer length is too short.\n");
		pioctl_req->data_read_written = 0;
		pioctl_req->buf_len_needed = sizeof(mlan_ds_radio_cfg);
		pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
		LEAVE();
		return MLAN_STATUS_RESOURCE;
	}
	radio_cfg = (mlan_ds_radio_cfg *)pioctl_req->pbuf;
	switch (radio_cfg->sub_command) {
	case MLAN_OID_RADIO_CTRL:
		status = wlan_radio_ioctl_radio_ctl(pmadapter, pioctl_req);
		break;
	case MLAN_OID_BAND_CFG:
		status = wlan_radio_ioctl_band_cfg(pmadapter, pioctl_req);
		break;
	case MLAN_OID_ANT_CFG:
		status = wlan_radio_ioctl_ant_cfg(pmadapter, pioctl_req);
		break;
	case MLAN_OID_REMAIN_CHAN_CFG:
		status = wlan_radio_ioctl_remain_chan_cfg(pmadapter,
							  pioctl_req);
		break;
	case MLAN_OID_MIMO_SWITCH:
		status = wlan_radio_ioctl_mimo_switch_cfg(pmadapter,
							  pioctl_req);
		break;
	default:
		pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID;
		status = MLAN_STATUS_FAILURE;
		break;
	}

	LEAVE();
	return status;
}

/**
 *  @brief Set/Get MAC address
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_PENDING --success, otherwise fail
 */
static mlan_status
wlan_bss_ioctl_mac_address(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_bss *bss = MNULL;
	t_u16 cmd_action;
	mlan_status ret = MLAN_STATUS_SUCCESS;

	ENTER();

	bss = (mlan_ds_bss *)pioctl_req->pbuf;
	if (pioctl_req->action == MLAN_ACT_GET) {
		cmd_action = HostCmd_ACT_GEN_GET;
	} else {
		cmd_action = HostCmd_ACT_GEN_SET;
		memcpy_ext(pmadapter, pmpriv->curr_addr, &bss->param.mac_addr,
			   MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
	}

	/* Send request to firmware */
	ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_MAC_ADDRESS,
			       cmd_action, 0, (t_void *)pioctl_req, MNULL);
	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief Set multicast list
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS/MLAN_STATUS_PENDING --success,
 * otherwise fail
 */
static mlan_status
wlan_bss_ioctl_set_multicast_list(pmlan_adapter pmadapter,
				  pmlan_ioctl_req pioctl_req)
{
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_bss *bss = MNULL;
	mlan_status ret = MLAN_STATUS_SUCCESS;
	t_u16 old_pkt_filter;

	ENTER();

	old_pkt_filter = pmpriv->curr_pkt_filter;
	bss = (mlan_ds_bss *)pioctl_req->pbuf;
	if (pioctl_req->action == MLAN_ACT_GET) {
		pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID;
		ret = MLAN_STATUS_FAILURE;
		goto exit;
	}
	pioctl_req->data_read_written =
		sizeof(mlan_multicast_list) + MLAN_SUB_COMMAND_SIZE;
	if (bss->param.multicast_list.mode == MLAN_PROMISC_MODE) {
		PRINTM(MINFO, "Enable Promiscuous mode\n");
		pmpriv->curr_pkt_filter |= HostCmd_ACT_MAC_PROMISCUOUS_ENABLE;
		pmpriv->curr_pkt_filter &=
			~HostCmd_ACT_MAC_ALL_MULTICAST_ENABLE;
	} else {
		/* Multicast */
		pmpriv->curr_pkt_filter &= ~HostCmd_ACT_MAC_PROMISCUOUS_ENABLE;
		if (bss->param.multicast_list.mode == MLAN_ALL_MULTI_MODE) {
			PRINTM(MINFO, "Enabling All Multicast!\n");
			pmpriv->curr_pkt_filter |=
				HostCmd_ACT_MAC_ALL_MULTICAST_ENABLE;
		} else {
			pmpriv->curr_pkt_filter &=
				~HostCmd_ACT_MAC_ALL_MULTICAST_ENABLE;
			if (bss->param.multicast_list.num_multicast_addr) {
				PRINTM(MINFO, "Set multicast list=%d\n",
				       bss->param.multicast_list.
				       num_multicast_addr);
				/* Set multicast addresses to firmware */
				if (old_pkt_filter == pmpriv->curr_pkt_filter) {
					/* Send request to firmware */
					ret = wlan_prepare_cmd(pmpriv,
							       HostCmd_CMD_MAC_MULTICAST_ADR,
							       HostCmd_ACT_GEN_SET,
							       0,
							       (t_void *)
							       pioctl_req,
							       &bss->param.
							       multicast_list);
					if (ret == MLAN_STATUS_SUCCESS)
						ret = MLAN_STATUS_PENDING;
				} else {
					/* Send request to firmware */
					ret = wlan_prepare_cmd(pmpriv,
							       HostCmd_CMD_MAC_MULTICAST_ADR,
							       HostCmd_ACT_GEN_SET,
							       0, MNULL,
							       &bss->param.
							       multicast_list);
				}
				if (ret)
					goto exit;
			}
		}
	}
	PRINTM(MINFO, "old_pkt_filter=0x%x, curr_pkt_filter=0x%x\n",
	       old_pkt_filter, pmpriv->curr_pkt_filter);
	if (old_pkt_filter != pmpriv->curr_pkt_filter) {
		ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_MAC_CONTROL,
				       HostCmd_ACT_GEN_SET, 0,
				       (t_void *)pioctl_req,
				       &pmpriv->curr_pkt_filter);
		if (ret == MLAN_STATUS_SUCCESS)
			ret = MLAN_STATUS_PENDING;
	}

exit:
	LEAVE();
	return ret;
}

/**
 *  @brief Get channel list
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
 */
static mlan_status
wlan_bss_ioctl_get_channel_list(pmlan_adapter pmadapter,
				pmlan_ioctl_req pioctl_req)
{
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_bss *bss = MNULL;
	mlan_status ret = MLAN_STATUS_SUCCESS;
	chan_freq_power_t *cfp;
	t_u32 i, j;

	ENTER();

	bss = (mlan_ds_bss *)pioctl_req->pbuf;
	if (pioctl_req->action != MLAN_ACT_GET) {
		pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID;
		LEAVE();
		return MLAN_STATUS_FAILURE;
	}
	if ((wlan_11d_is_enabled(pmpriv) && pmpriv->media_connected == MTRUE) &&
	    ((pmpriv->bss_mode == MLAN_BSS_MODE_INFRA) ||
	     (pmpriv->bss_mode == MLAN_BSS_MODE_IBSS &&
	      pmpriv->adhoc_state != ADHOC_STARTED))) {
		t_u8 chan_no;
		t_u8 band;

		parsed_region_chan_11d_t *parsed_region_chan = MNULL;
		parsed_region_chan_11d_t region_chan;

		BSSDescriptor_t *pbss_desc =
			&pmpriv->curr_bss_params.bss_descriptor;

		memset(pmadapter, &region_chan, 0,
		       sizeof(parsed_region_chan_11d_t));

		/*If country IE is present in the associated AP then return the
		   channel list from country IE
		   else return it from the learning table */

		if (wlan_11d_parse_domain_info
		    (pmadapter, &pbss_desc->country_info,
		     (t_u8)pbss_desc->bss_band,
		     &region_chan) == MLAN_STATUS_SUCCESS) {
			parsed_region_chan = &region_chan;
		} else {
			parsed_region_chan = &pmadapter->parsed_region_chan;
		}

		PRINTM(MINFO, "no_of_chan=%d\n",
		       parsed_region_chan->no_of_chan);

		for (i = 0;
		     (bss->param.chanlist.num_of_chan < MLAN_MAX_CHANNEL_NUM) &&
		     (i < parsed_region_chan->no_of_chan); i++) {
			chan_no = parsed_region_chan->chan_pwr[i].chan;
			band = parsed_region_chan->chan_pwr[i].band;
			PRINTM(MINFO, "band=%d, chan_no=%d\n", band, chan_no);
			bss->param.chanlist.cf[bss->param.chanlist.num_of_chan]
				.channel = (t_u32)chan_no;
			bss->param.chanlist.cf[bss->param.chanlist.num_of_chan]
				.freq =
				(t_u32)wlan_11d_chan_2_freq(pmadapter, chan_no,
							    band);
			bss->param.chanlist.num_of_chan++;
		}
	} else {
		for (j = 0;
		     (bss->param.chanlist.num_of_chan < MLAN_MAX_CHANNEL_NUM) &&
		     (j < MAX_REGION_CHANNEL_NUM); j++) {
			cfp = pmadapter->region_channel[j].pcfp;
			for (i = 0; (bss->param.chanlist.num_of_chan <
				     MLAN_MAX_CHANNEL_NUM) &&
			     pmadapter->region_channel[j].valid && cfp &&
			     (i < pmadapter->region_channel[j].num_cfp); i++) {
				bss->param.chanlist.cf[bss->param.chanlist.
						       num_of_chan]
					.channel = (t_u32)cfp->channel;
				bss->param.chanlist.cf[bss->param.chanlist.
						       num_of_chan]
					.freq = (t_u32)cfp->freq;
				bss->param.chanlist.num_of_chan++;
				cfp++;
			}
		}
	}

	PRINTM(MINFO, "num of channel=%d\n", bss->param.chanlist.num_of_chan);

	LEAVE();
	return ret;
}

/** Highest channel used in 2.4GHz band */
#define MAX_CHANNEL_BAND_B (14)

/** Highest frequency used in 2.4GHz band */
#define MAX_FREQUENCY_BAND_B (2484)

/**
 *  @brief Set/Get BSS channel
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
 */
static mlan_status
wlan_bss_ioctl_channel(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_private *pmpriv = MNULL;
	mlan_ds_bss *bss = MNULL;
	mlan_status ret = MLAN_STATUS_SUCCESS;
	chan_freq_power_t *cfp = MNULL;
	ENTER();

	if ((pioctl_req == MNULL) || (pioctl_req->pbuf == MNULL)) {
		PRINTM(MERROR, "Request buffer not found!\n");
		LEAVE();
		return MLAN_STATUS_FAILURE;
	}
	pmpriv = pmadapter->priv[pioctl_req->bss_index];
	bss = (mlan_ds_bss *)pioctl_req->pbuf;
	if (pioctl_req->action == MLAN_ACT_GET) {
		cfp = wlan_find_cfp_by_band_and_channel(pmadapter,
							pmpriv->curr_bss_params.
							band,
							(t_u16)pmpriv->
							curr_bss_params.
							bss_descriptor.channel);
		if (cfp) {
			bss->param.bss_chan.channel = cfp->channel;
			bss->param.bss_chan.freq = cfp->freq;
		} else {
			pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
			ret = MLAN_STATUS_FAILURE;
		}
		pioctl_req->data_read_written =
			sizeof(chan_freq) + MLAN_SUB_COMMAND_SIZE;
		LEAVE();
		return ret;
	}
	if (!bss->param.bss_chan.channel && !bss->param.bss_chan.freq) {
		pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
		LEAVE();
		return MLAN_STATUS_FAILURE;
	}
	if (pmadapter->adhoc_start_band & BAND_A)
		pmadapter->adhoc_start_band = BAND_G | BAND_B;
	if (bss->param.bss_chan.channel) {
		if (bss->param.bss_chan.channel <= MAX_CHANNEL_BAND_B)
			cfp = wlan_find_cfp_by_band_and_channel(pmadapter,
								BAND_B,
								(t_u16)bss->
								param.bss_chan.
								channel);
		if (!cfp) {
			cfp = wlan_find_cfp_by_band_and_channel(pmadapter,
								BAND_A,
								(t_u16)bss->
								param.bss_chan.
								channel);
			if (cfp) {
				pmadapter->adhoc_start_band = BAND_A;
			}
		}
	} else {
		if (bss->param.bss_chan.freq <= MAX_FREQUENCY_BAND_B)
			cfp = wlan_find_cfp_by_band_and_freq(pmadapter, BAND_B,
							     bss->param.
							     bss_chan.freq);
		if (!cfp) {
			cfp = wlan_find_cfp_by_band_and_freq(pmadapter, BAND_A,
							     bss->param.
							     bss_chan.freq);
			if (cfp) {
				pmadapter->adhoc_start_band = BAND_A;
			}
		}
	}
	if (!cfp || !cfp->channel) {
		PRINTM(MERROR, "Invalid channel/freq\n");
		if (pioctl_req)
			pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
		LEAVE();
		return MLAN_STATUS_FAILURE;
	}
	pmpriv->adhoc_channel = (t_u8)cfp->channel;
	pmpriv->intf_state_11h.adhoc_auto_sel_chan = MFALSE;
	bss->param.bss_chan.channel = cfp->channel;
	bss->param.bss_chan.freq = cfp->freq;

	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get BSS mode
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS/MLAN_STATUS_PENDING --success,
 * otherwise fail
 */
static mlan_status
wlan_bss_ioctl_mode(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_bss *bss = MNULL;
	mlan_status ret = MLAN_STATUS_SUCCESS;
	bss = (mlan_ds_bss *)pioctl_req->pbuf;

	ENTER();

	if (pioctl_req->action == MLAN_ACT_GET) {
		bss->param.bss_mode = pmpriv->bss_mode;
		pioctl_req->data_read_written =
			sizeof(t_u32) + MLAN_SUB_COMMAND_SIZE;
		goto exit;
	}

	if ((pmpriv->bss_mode == bss->param.bss_mode) ||
	    (bss->param.bss_mode == MLAN_BSS_MODE_AUTO)) {
		PRINTM(MINFO, "Already set to required mode! No change!\n");
		pmpriv->bss_mode = bss->param.bss_mode;
		goto exit;
	}

	if (pmpriv->bss_mode != MLAN_BSS_MODE_AUTO)
		ret = wlan_disconnect(pmpriv, MNULL, MNULL);
	else
		ret = wlan_disconnect(pmpriv, pioctl_req, MNULL);

	if (pmpriv->sec_info.authentication_mode != MLAN_AUTH_MODE_AUTO)
		pmpriv->sec_info.authentication_mode = MLAN_AUTH_MODE_OPEN;
	pmpriv->bss_mode = bss->param.bss_mode;
	if (pmpriv->bss_mode == MLAN_BSS_MODE_INFRA)
		pmpriv->port_ctrl_mode = MTRUE;
	else
		pmpriv->port_ctrl_mode = MFALSE;
	if (pmpriv->bss_mode != MLAN_BSS_MODE_AUTO) {
		ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_SET_BSS_MODE,
				       HostCmd_ACT_GEN_SET, 0,
				       (t_void *)pioctl_req, MNULL);
		if (ret == MLAN_STATUS_SUCCESS)
			ret = MLAN_STATUS_PENDING;
	}
exit:
	LEAVE();
	return ret;
}

/**
 *  @brief Start BSS
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_PENDING --success, otherwise fail
 */
static mlan_status
wlan_bss_ioctl_start(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_bss *bss = (mlan_ds_bss *)pioctl_req->pbuf;
	t_s32 i = -1;
	t_u8 zero_mac[] = { 0, 0, 0, 0, 0, 0 };

	ENTER();

	/* Before ASSOC REQ, If "port ctrl" mode is enabled,
	 * move the port to CLOSED state */
	if (pmpriv->port_ctrl_mode == MTRUE) {
		PRINTM(MINFO, "bss_ioctl_start(): port_state=CLOSED\n");
		pmpriv->prior_port_status = pmpriv->port_open;
		pmpriv->port_open = MFALSE;
	}
	pmadapter->scan_block = MFALSE;

	if (pmpriv->bss_mode == MLAN_BSS_MODE_INFRA) {
		if (!bss->param.ssid_bssid.idx ||
		    bss->param.ssid_bssid.idx > pmadapter->num_in_scan_table) {
			/* Search for the requested SSID in the scan table */
			if (bss->param.ssid_bssid.ssid.ssid_len) {
				if (memcmp(pmadapter,
					   &bss->param.ssid_bssid.bssid,
					   zero_mac, sizeof(zero_mac)))
					i = wlan_find_ssid_in_list(pmpriv,
								   &bss->param.
								   ssid_bssid.
								   ssid,
								   (t_u8 *)
								   &bss->param.
								   ssid_bssid.
								   bssid,
								   MLAN_BSS_MODE_INFRA);
				else
					i = wlan_find_ssid_in_list(pmpriv,
								   &bss->param.
								   ssid_bssid.
								   ssid, MNULL,
								   MLAN_BSS_MODE_INFRA);
			} else {
				i = wlan_find_bssid_in_list(pmpriv,
							    (t_u8 *)&bss->param.
							    ssid_bssid.bssid,
							    MLAN_BSS_MODE_INFRA);
			}
		} else {
			/* use bsslist index number to assoicate */
			i = wlan_is_network_compatible(pmpriv,
						       bss->param.ssid_bssid.
						       idx - 1,
						       pmpriv->bss_mode);
		}
		if (i >= 0) {
			/* block if upper-layer tries to reconnect before new
			 * scan */
			if (wlan_11h_get_csa_closed_channel(pmpriv) ==
			    (t_u8)pmadapter->pscan_table[i].channel) {
				PRINTM(MINFO,
				       "Attempt to reconnect on csa_closed_chan(%d)\n",
				       pmadapter->pscan_table[i].channel);
				pioctl_req->status_code =
					MLAN_ERROR_INVALID_PARAMETER;
				ret = MLAN_STATUS_FAILURE;
				goto start_ssid_done;
			}
			PRINTM(MINFO,
			       "SSID found in scan list ... associating...\n");
			pmpriv->curr_bss_params.host_mlme =
				bss->param.ssid_bssid.host_mlme;
			memcpy_ext(pmpriv->adapter,
				   &pmpriv->curr_bss_params.prev_bssid,
				   &bss->param.ssid_bssid.prev_bssid,
				   MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
			/* Clear any past association response stored for
			 * application retrieval */
			pmpriv->assoc_rsp_size = 0;
			pmpriv->curr_chan_flags =
				bss->param.ssid_bssid.channel_flags;
			if (IS_FW_SUPPORT_NO_80MHZ(pmadapter))
				pmpriv->curr_chan_flags |= CHAN_FLAGS_NO_80MHZ;
			ret = wlan_associate(pmpriv, pioctl_req,
					     &pmadapter->pscan_table[i]);
			if (ret)
				goto start_ssid_done;
		} else {	/* i >= 0 */
			PRINTM(MERROR,
			       "SSID not found in scan list: ssid=%s, " MACSTR
			       ", idx=%d\n",
			       bss->param.ssid_bssid.ssid.ssid,
			       MAC2STR(bss->param.ssid_bssid.bssid),
			       (int)bss->param.ssid_bssid.idx);
			pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
			ret = MLAN_STATUS_FAILURE;
			goto start_ssid_done;
		}
	} else {
		/* Adhoc mode */
		/* If the requested SSID matches current SSID, return */
		if (bss->param.ssid_bssid.ssid.ssid_len &&
		    (!wlan_ssid_cmp(pmadapter,
				    &pmpriv->curr_bss_params.bss_descriptor.
				    ssid, &bss->param.ssid_bssid.ssid))) {
			ret = MLAN_STATUS_SUCCESS;
			goto start_ssid_done;
		}

		/* Exit Adhoc mode first */
		PRINTM(MINFO, "Sending Adhoc Stop\n");
		ret = wlan_disconnect(pmpriv, MNULL, MNULL);
		if (ret)
			goto start_ssid_done;

		pmpriv->adhoc_is_link_sensed = MFALSE;

		if (!bss->param.ssid_bssid.idx ||
		    bss->param.ssid_bssid.idx > pmadapter->num_in_scan_table) {
			/* Search for the requested network in the scan table */
			if (bss->param.ssid_bssid.ssid.ssid_len) {
				i = wlan_find_ssid_in_list(pmpriv,
							   &bss->param.
							   ssid_bssid.ssid,
							   MNULL,
							   MLAN_BSS_MODE_IBSS);
			} else {
				i = wlan_find_bssid_in_list(pmpriv,
							    (t_u8 *)&bss->param.
							    ssid_bssid.bssid,
							    MLAN_BSS_MODE_IBSS);
			}
		} else {
			/* use bsslist index number to assoicate */
			i = wlan_is_network_compatible(pmpriv,
						       bss->param.ssid_bssid.
						       idx - 1,
						       pmpriv->bss_mode);
		}

		if (i >= 0) {
			PRINTM(MINFO,
			       "Network found in scan list ... joining ...\n");
			pmpriv->curr_chan_flags =
				bss->param.ssid_bssid.channel_flags;
			ret = wlan_adhoc_join(pmpriv, pioctl_req,
					      &pmadapter->pscan_table[i]);
			if (ret)
				goto start_ssid_done;
		} else {	/* i >= 0 */
			PRINTM(MINFO,
			       "Network not found in the list, "
			       "creating adhoc with ssid = %s\n",
			       bss->param.ssid_bssid.ssid.ssid);
			pmpriv->curr_chan_flags =
				bss->param.ssid_bssid.channel_flags;
			ret = wlan_adhoc_start(pmpriv, pioctl_req,
					       &bss->param.ssid_bssid.ssid);
			if (ret)
				goto start_ssid_done;
		}
	}

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

start_ssid_done:
	LEAVE();
	return ret;
}

/**
 *  @brief Stop BSS
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS/MLAN_STATUS_PENDING --success,
 * otherwise fail
 */
static mlan_status
wlan_bss_ioctl_stop(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_bss *bss = (mlan_ds_bss *)pioctl_req->pbuf;

	ENTER();

	ret = wlan_disconnect(pmpriv, pioctl_req, &bss->param.deauth_param);

	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get IBSS channel
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS/MLAN_STATUS_PENDING --success,
 * otherwise fail
 */
static mlan_status
wlan_bss_ioctl_ibss_channel(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_bss *bss = MNULL;
	mlan_status ret = MLAN_STATUS_SUCCESS;
	t_u16 cmd_action;

	ENTER();

	bss = (mlan_ds_bss *)pioctl_req->pbuf;
	if (pioctl_req->action == MLAN_ACT_GET) {
		if (pmpriv->media_connected == MFALSE) {
			bss->param.bss_chan.channel = pmpriv->adhoc_channel;
			goto exit;
		}
		cmd_action = HostCmd_ACT_GEN_GET;
	} else {
		cmd_action = HostCmd_ACT_GEN_SET;
		pmpriv->adhoc_channel = (t_u8)bss->param.bss_chan.channel;
		pmpriv->intf_state_11h.adhoc_auto_sel_chan = MFALSE;
	}

	/* Send request to firmware */
	ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_RF_CHANNEL,
			       cmd_action, 0, (t_void *)pioctl_req,
			       &bss->param.bss_chan.channel);
	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

exit:
	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get Listen Interval
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS/MLAN_STATUS_PENDING --success,
 * otherwise fail
 */
static mlan_status
wlan_bss_ioctl_listen_interval(pmlan_adapter pmadapter,
			       pmlan_ioctl_req pioctl_req)
{
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_bss *bss = MNULL;

	ENTER();

	bss = (mlan_ds_bss *)pioctl_req->pbuf;
	if (pioctl_req->action == MLAN_ACT_GET)
		bss->param.listen_interval = pmpriv->listen_interval;
	else
		pmpriv->listen_interval = bss->param.listen_interval;

	LEAVE();
	return MLAN_STATUS_SUCCESS;
}

/*
 *  @brief Set/Get beacon interval
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS --success
 */
static mlan_status
wlan_bss_ioctl_beacon_interval(pmlan_adapter pmadapter,
			       pmlan_ioctl_req pioctl_req)
{
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_bss *bss = MNULL;
	mlan_status ret = MLAN_STATUS_SUCCESS;
	ENTER();
	bss = (mlan_ds_bss *)pioctl_req->pbuf;
	if (pioctl_req->action == MLAN_ACT_GET) {
		bss->param.bcn_interval = pmpriv->beacon_period;
		if (pmpriv->media_connected == MTRUE)
			bss->param.bcn_interval =
				pmpriv->curr_bss_params.bss_descriptor.
				beacon_period;
	} else
		pmpriv->beacon_period = (t_u16)bss->param.bcn_interval;
	pioctl_req->data_read_written = sizeof(t_u32) + MLAN_SUB_COMMAND_SIZE;
	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get ATIM window
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS --success
 */
static mlan_status
wlan_bss_ioctl_atim_window(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_bss *bss = MNULL;
	mlan_status ret = MLAN_STATUS_SUCCESS;
	ENTER();
	bss = (mlan_ds_bss *)pioctl_req->pbuf;
	if (pioctl_req->action == MLAN_ACT_GET) {
		bss->param.atim_window = pmpriv->atim_window;
		if (pmpriv->media_connected == MTRUE)
			bss->param.atim_window =
				pmpriv->curr_bss_params.bss_descriptor.
				atim_window;
	} else
		pmpriv->atim_window = (t_u16)bss->param.atim_window;

	pioctl_req->data_read_written = sizeof(t_u32) + MLAN_SUB_COMMAND_SIZE;
	LEAVE();
	return ret;
}

/**
 *  @brief Query embe
 *
 *  @param priv                 A pointer to mlan_private structure
 *  @param pioctl_req           A pointer to ioctl request buffer
 *
 *  @return                     MLAN_STATUS_SUCCESS -- success, otherwise fail
 */
static mlan_status
wlan_query_passphrase(mlan_private *priv, pmlan_ioctl_req pioctl_req)
{
	mlan_adapter *pmadapter = priv->adapter;
	pmlan_callbacks pcb = &pmadapter->callbacks;
	mlan_ds_bss *bss = MNULL;
	mlan_ssid_bssid *ssid_bssid = MNULL;
	mlan_ds_sec_cfg *sec = MNULL;
	mlan_ds_passphrase *sec_pp;
	int i = 0;
	BSSDescriptor_t *pbss_desc;
	mlan_status ret = MLAN_STATUS_SUCCESS;

	ENTER();

	bss = (mlan_ds_bss *)pioctl_req->pbuf;
	ssid_bssid = &bss->param.ssid_bssid;

	ret = pcb->moal_malloc(pmadapter->pmoal_handle, sizeof(mlan_ds_sec_cfg),
			       MLAN_MEM_DEF, (t_u8 **)&sec);
	if (ret || !sec) {
		PRINTM(MERROR, "Could not allocate sec!\n");
		LEAVE();
		return ret;
	}
	memset(pmadapter, sec, 0, sizeof(mlan_ds_sec_cfg));
	sec_pp = (mlan_ds_passphrase *)&sec->param.passphrase;
	sec_pp->psk_type = MLAN_PSK_QUERY;
	if (ssid_bssid->ssid.ssid_len == 0) {
		i = wlan_find_bssid_in_list(priv, (t_u8 *)&ssid_bssid->bssid,
					    MLAN_BSS_MODE_AUTO);
		if (i >= 0) {
			pbss_desc = &pmadapter->pscan_table[i];
			memcpy_ext(pmadapter, (t_u8 *)&sec_pp->ssid,
				   &pbss_desc->ssid, sizeof(mlan_802_11_ssid),
				   sizeof(mlan_802_11_ssid));
		} else
			memcpy_ext(pmadapter, (t_u8 *)&sec_pp->bssid,
				   &ssid_bssid->bssid, MLAN_MAC_ADDR_LENGTH,
				   MLAN_MAC_ADDR_LENGTH);
	} else {
		memcpy_ext(pmadapter, (t_u8 *)&sec_pp->ssid, &ssid_bssid->ssid,
			   sizeof(mlan_802_11_ssid), sizeof(mlan_802_11_ssid));
	}

	/* Send request to firmware */
	ret = wlan_prepare_cmd(priv, HostCmd_CMD_SUPPLICANT_PMK,
			       HostCmd_ACT_GEN_GET, 0, (t_void *)pioctl_req,
			       (t_void *)sec);
	if (sec)
		pcb->moal_mfree(pmadapter->pmoal_handle, (t_u8 *)sec);
	LEAVE();
	return ret;
}

/**
 *  @brief Search for a BSS
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS/MLAN_STATUS_PENDING --success,
 * otherwise fail
 */
static mlan_status
wlan_bss_ioctl_find_bss(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_status ret = MLAN_STATUS_SUCCESS;
#ifdef DRV_EMBEDDED_SUPPLICANT
	mlan_ds_bss *bss = MNULL;
	mlan_ssid_bssid *ssid_bssid = MNULL;
#endif

	ENTER();

	if (pmpriv->ewpa_query) {
		if (wlan_query_passphrase(pmpriv, pioctl_req) ==
		    MLAN_STATUS_SUCCESS) {
			PRINTM(MINFO, "Find BSS ioctl: query passphrase\n");
			LEAVE();
			return MLAN_STATUS_PENDING;
		}
	}
#ifdef DRV_EMBEDDED_SUPPLICANT
	if (!IS_FW_SUPPORT_SUPPLICANT(pmpriv->adapter)) {
		bss = (mlan_ds_bss *)pioctl_req->pbuf;
		ssid_bssid = &bss->param.ssid_bssid;
		supplicantQueryPassphraseAndEnable(pmpriv->psapriv,
						   (t_u8 *)ssid_bssid);
	}
#endif

	ret = wlan_find_bss(pmpriv, pioctl_req);

	LEAVE();
	return ret;
}

/**
 *  @brief Search for a BSS
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS/MLAN_STATUS_PENDING --success,
 * otherwise fail
 */
static mlan_status
wlan_bss_ioctl_find_bssid(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_bss *bss = MNULL;
	mlan_status ret = MLAN_STATUS_SUCCESS;
	int i = 0;

	ENTER();
	bss = (mlan_ds_bss *)pioctl_req->pbuf;
	i = wlan_find_bssid_in_list(pmpriv, (t_u8 *)&bss->param.bssid,
				    MLAN_BSS_MODE_AUTO);
	if (i < 0) {
		PRINTM(MCMND, "Can not find bssid " MACSTR "\n",
		       MAC2STR((t_u8 *)&bss->param.bssid));
		pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
		LEAVE();
		return MLAN_STATUS_FAILURE;
	}
	PRINTM(MCMND, "Find bssid " MACSTR "\n",
	       MAC2STR((t_u8 *)&bss->param.bssid));
	LEAVE();
	return ret;
}

/**
 *  @brief Check if BSS channel is valid for Station's region
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS/MLAN_STATUS_PENDING --success,
 * otherwise fail
 */
static mlan_status
wlan_bss_ioctl_bss_11d_check_channel(pmlan_adapter pmadapter,
				     pmlan_ioctl_req pioctl_req)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_ds_bss *bss = MNULL;
	mlan_ssid_bssid *ssid_bssid = MNULL;

	ENTER();

	bss = (mlan_ds_bss *)pioctl_req->pbuf;
	ssid_bssid = &bss->param.ssid_bssid;

	PRINTM(MINFO, "ssid: %s idx:%d\n", ssid_bssid->ssid.ssid,
	       ssid_bssid->idx);
	PRINTM(MINFO, "band:%d channel:%d\n", (t_u8)ssid_bssid->bss_band,
	       (t_u32)ssid_bssid->channel);

	/* check if this channel is supported in the region */
	if (!wlan_find_cfp_by_band_and_channel(pmadapter,
					       (t_u8)ssid_bssid->bss_band,
					       (t_u32)ssid_bssid->channel)) {
		PRINTM(MERROR, "Unsupported Channel for region 0x%x\n",
		       pmadapter->region_code);
		ret = MLAN_STATUS_FAILURE;
	}

	LEAVE();
	return ret;
}

/**
 *  @brief BSS command handler
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
 */
static mlan_status
wlan_bss_ioctl(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_status status = MLAN_STATUS_SUCCESS;
	mlan_ds_bss *bss = MNULL;

	ENTER();

	if (pioctl_req->buf_len < sizeof(mlan_ds_bss)) {
		PRINTM(MWARN, "MLAN bss IOCTL length is too short.\n");
		pioctl_req->data_read_written = 0;
		pioctl_req->buf_len_needed = sizeof(mlan_ds_bss);
		pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
		LEAVE();
		return MLAN_STATUS_RESOURCE;
	}

	bss = (mlan_ds_bss *)pioctl_req->pbuf;

	switch (bss->sub_command) {
	case MLAN_OID_BSS_START:
		status = wlan_bss_ioctl_start(pmadapter, pioctl_req);
		break;
	case MLAN_OID_BSS_STOP:
		status = wlan_bss_ioctl_stop(pmadapter, pioctl_req);
		break;
	case MLAN_OID_BSS_MODE:
		status = wlan_bss_ioctl_mode(pmadapter, pioctl_req);
		break;
	case MLAN_OID_BSS_CHANNEL:
		status = wlan_bss_ioctl_channel(pmadapter, pioctl_req);
		break;
	case MLAN_OID_BSS_CHANNEL_LIST:
		status = wlan_bss_ioctl_get_channel_list(pmadapter, pioctl_req);
		break;
	case MLAN_OID_BSS_MAC_ADDR:
		status = wlan_bss_ioctl_mac_address(pmadapter, pioctl_req);
		break;
	case MLAN_OID_BSS_MULTICAST_LIST:
		status = wlan_bss_ioctl_set_multicast_list(pmadapter,
							   pioctl_req);
		break;
	case MLAN_OID_BSS_FIND_BSS:
		status = wlan_bss_ioctl_find_bss(pmadapter, pioctl_req);
		break;
	case MLAN_OID_BSS_FIND_BSSID:
		status = wlan_bss_ioctl_find_bssid(pmadapter, pioctl_req);
		break;
	case MLAN_OID_IBSS_BCN_INTERVAL:
		status = wlan_bss_ioctl_beacon_interval(pmadapter, pioctl_req);
		break;
	case MLAN_OID_IBSS_ATIM_WINDOW:
		status = wlan_bss_ioctl_atim_window(pmadapter, pioctl_req);
		break;
	case MLAN_OID_IBSS_CHANNEL:
		status = wlan_bss_ioctl_ibss_channel(pmadapter, pioctl_req);
		break;
#if defined(STA_SUPPORT) && defined(UAP_SUPPORT)
	case MLAN_OID_BSS_ROLE:
		util_enqueue_list_tail(pmadapter->pmoal_handle,
				       &pmadapter->ioctl_pending_q,
				       (pmlan_linked_list)pioctl_req,
				       pmadapter->callbacks.moal_spin_lock,
				       pmadapter->callbacks.moal_spin_unlock);
		pmadapter->pending_ioctl = MTRUE;
		status = MLAN_STATUS_PENDING;
		break;
#endif
#ifdef WIFI_DIRECT_SUPPORT
	case MLAN_OID_WIFI_DIRECT_MODE:
		status = wlan_bss_ioctl_wifi_direct_mode(pmadapter, pioctl_req);
		break;
#endif
	case MLAN_OID_BSS_LISTEN_INTERVAL:
		status = wlan_bss_ioctl_listen_interval(pmadapter, pioctl_req);
		break;
	case MLAN_OID_BSS_REMOVE:
		status = wlan_bss_ioctl_bss_remove(pmadapter, pioctl_req);
		break;

	case MLAN_OID_BSS_11D_CHECK_CHANNEL:
		status = wlan_bss_ioctl_bss_11d_check_channel(pmadapter,
							      pioctl_req);
		break;
	case MLAN_OID_BSS_CHAN_INFO:
		status = wlan_bss_ioctl_get_chan_info(pmadapter, pioctl_req);
		break;
	default:
		status = MLAN_STATUS_FAILURE;
		break;
	}

	LEAVE();
	return status;
}

/**
 *  @brief Get supported rates
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
 */
static mlan_status
wlan_rate_ioctl_get_supported_rate(pmlan_adapter pmadapter,
				   pmlan_ioctl_req pioctl_req)
{
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_rate *rate = MNULL;
	mlan_status ret = MLAN_STATUS_SUCCESS;

	ENTER();
	if (pioctl_req->action != MLAN_ACT_GET) {
		pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID;
		LEAVE();
		return MLAN_STATUS_FAILURE;
	}
	rate = (mlan_ds_rate *)pioctl_req->pbuf;
	if (rate->param.rate_band_cfg.config_bands &&
	    rate->param.rate_band_cfg.bss_mode)
		wlan_get_active_data_rates(pmpriv,
					   rate->param.rate_band_cfg.bss_mode,
					   rate->param.rate_band_cfg.
					   config_bands, rate->param.rates);
	else
		wlan_get_active_data_rates(pmpriv, pmpriv->bss_mode,
					   (pmpriv->bss_mode ==
					    MLAN_BSS_MODE_INFRA) ?
					   pmpriv->config_bands :
					   pmadapter->adhoc_start_band,
					   rate->param.rates);
	pioctl_req->data_read_written =
		MLAN_SUPPORTED_RATES + MLAN_SUB_COMMAND_SIZE;
	LEAVE();
	return ret;
}

/**
 *  @brief Rate command handler
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS/MLAN_STATUS_PENDING --success,
 * otherwise fail
 */
static mlan_status
wlan_rate_ioctl(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_status status = MLAN_STATUS_SUCCESS;
	mlan_ds_rate *rate = MNULL;

	ENTER();

	if (pioctl_req->buf_len < sizeof(mlan_ds_rate)) {
		PRINTM(MWARN, "MLAN bss IOCTL length is too short.\n");
		pioctl_req->data_read_written = 0;
		pioctl_req->buf_len_needed = sizeof(mlan_ds_rate);
		pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
		LEAVE();
		return MLAN_STATUS_RESOURCE;
	}
	rate = (mlan_ds_rate *)pioctl_req->pbuf;
	switch (rate->sub_command) {
	case MLAN_OID_RATE_CFG:
		status = wlan_rate_ioctl_cfg(pmadapter, pioctl_req);
		break;
	case MLAN_OID_GET_DATA_RATE:
		status = wlan_rate_ioctl_get_data_rate(pmadapter, pioctl_req);
		break;
	case MLAN_OID_SUPPORTED_RATES:
		status = wlan_rate_ioctl_get_supported_rate(pmadapter,
							    pioctl_req);
		break;
	default:
		pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID;
		status = MLAN_STATUS_FAILURE;
		break;
	}
	LEAVE();
	return status;
}

/**
 *  @brief Get Tx power configuration
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param cmd_no	Firmware command number used to retrieve power values
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_PENDING --success, otherwise fail
 */
static mlan_status
wlan_power_ioctl_get_power(pmlan_adapter pmadapter,
			   t_u16 cmd_no, pmlan_ioctl_req pioctl_req)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];

	ENTER();

	/* Send request to firmware */
	ret = wlan_prepare_cmd(pmpriv, cmd_no, HostCmd_ACT_GEN_GET, 0,
			       (t_void *)pioctl_req, MNULL);

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief Set Tx power configuration
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_PENDING --success, otherwise fail
 */
static mlan_status
wlan_power_ioctl_set_power(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_ds_power_cfg *power = MNULL;
	mlan_status ret = MLAN_STATUS_SUCCESS;

	HostCmd_DS_TXPWR_CFG *txp_cfg = MNULL;
	MrvlTypes_Power_Group_t *pg_tlv = MNULL;
	Power_Group_t *pg = MNULL;
	pmlan_callbacks pcb = &pmadapter->callbacks;
	t_u8 *buf = MNULL;
	t_s8 dbm = 0;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];

	ENTER();

	power = (mlan_ds_power_cfg *)pioctl_req->pbuf;
	if (!power->param.power_cfg.is_power_auto) {
		dbm = (t_s8)power->param.power_cfg.power_level;
		if ((dbm < pmpriv->min_tx_power_level) ||
		    (dbm > pmpriv->max_tx_power_level)) {
			PRINTM(MERROR,
			       "The set txpower value %d dBm is out of range (%d dBm-%d dBm)!\n",
			       dbm, pmpriv->min_tx_power_level,
			       pmpriv->max_tx_power_level);
			pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
			ret = MLAN_STATUS_FAILURE;
			goto exit;
		}
	}

	ret = pcb->moal_malloc(pmadapter->pmoal_handle,
			       MRVDRV_SIZE_OF_CMD_BUFFER, MLAN_MEM_DEF, &buf);
	if (ret != MLAN_STATUS_SUCCESS || buf == MNULL) {
		PRINTM(MERROR,
		       "ALLOC_CMD_BUF: Failed to allocate command buffer\n");
		pioctl_req->status_code = MLAN_ERROR_NO_MEM;
		ret = MLAN_STATUS_FAILURE;
		goto exit;
	}
	memset(pmadapter, buf, 0, MRVDRV_SIZE_OF_CMD_BUFFER);
	txp_cfg = (HostCmd_DS_TXPWR_CFG *)buf;
	txp_cfg->action = HostCmd_ACT_GEN_SET;
	if (!power->param.power_cfg.is_power_auto) {
		txp_cfg->mode = 1;
		pg_tlv = (MrvlTypes_Power_Group_t
			  *)(buf + sizeof(HostCmd_DS_TXPWR_CFG));
		pg_tlv->type = TLV_TYPE_POWER_GROUP;
		pg_tlv->length = 4 * sizeof(Power_Group_t);
		pg = (Power_Group_t *)(buf + sizeof(HostCmd_DS_TXPWR_CFG) +
				       sizeof(MrvlTypes_Power_Group_t));
		/* Power group for modulation class HR/DSSS */
		pg->first_rate_code = 0x00;
		pg->last_rate_code = 0x03;
		pg->modulation_class = MOD_CLASS_HR_DSSS;
		pg->power_step = 0;
		pg->power_min = (t_s8)dbm;
		pg->power_max = (t_s8)dbm;
		pg++;
		/* Power group for modulation class OFDM */
		pg->first_rate_code = 0x00;
		pg->last_rate_code = 0x07;
		pg->modulation_class = MOD_CLASS_OFDM;
		pg->power_step = 0;
		pg->power_min = (t_s8)dbm;
		pg->power_max = (t_s8)dbm;
		pg++;
		/* Power group for modulation class HTBW20 */
		pg->first_rate_code = 0x00;
		pg->last_rate_code = 0x20;
		pg->modulation_class = MOD_CLASS_HT;
		pg->power_step = 0;
		pg->power_min = (t_s8)dbm;
		pg->power_max = (t_s8)dbm;
		pg->ht_bandwidth = HT_BW_20;
		pg++;
		/* Power group for modulation class HTBW40 */
		pg->first_rate_code = 0x00;
		pg->last_rate_code = 0x20;
		pg->modulation_class = MOD_CLASS_HT;
		pg->power_step = 0;
		pg->power_min = (t_s8)dbm;
		pg->power_max = (t_s8)dbm;
		pg->ht_bandwidth = HT_BW_40;
	}

	/* Send request to firmware */
	ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_TXPWR_CFG,
			       HostCmd_ACT_GEN_SET, 0, (t_void *)pioctl_req,
			       buf);

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	if (buf)
		pcb->moal_mfree(pmadapter->pmoal_handle, buf);

exit:
	LEAVE();
	return ret;
}

/**
 *  @brief Set extended power configuration
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_PENDING --success, otherwise fail
 */
static mlan_status
wlan_power_ioctl_set_power_ext(pmlan_adapter pmadapter,
			       pmlan_ioctl_req pioctl_req)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_power_cfg *power = MNULL;
	pmlan_callbacks pcb = &pmadapter->callbacks;
	t_u8 *buf = MNULL;
	HostCmd_DS_TXPWR_CFG *txp_cfg = MNULL;
	MrvlTypes_Power_Group_t *pg_tlv = MNULL;
	Power_Group_t *pg = MNULL;
	mlan_power_group *pwr_grp = MNULL;

	ENTER();

	power = (mlan_ds_power_cfg *)pioctl_req->pbuf;
	ret = pcb->moal_malloc(pmadapter->pmoal_handle,
			       MRVDRV_SIZE_OF_CMD_BUFFER, MLAN_MEM_DEF, &buf);
	if (ret != MLAN_STATUS_SUCCESS || buf == MNULL) {
		PRINTM(MERROR,
		       "ALLOC_CMD_BUF: Failed to allocate command buffer\n");
		pioctl_req->status_code = MLAN_ERROR_NO_MEM;
		ret = MLAN_STATUS_FAILURE;
		goto exit;
	}
	memset(pmadapter, buf, 0, MRVDRV_SIZE_OF_CMD_BUFFER);
	txp_cfg = (HostCmd_DS_TXPWR_CFG *)buf;
	txp_cfg->action = HostCmd_ACT_GEN_SET;
	pwr_grp = &power->param.power_ext.power_group[0];
	if (pwr_grp->rate_format == TX_PWR_CFG_AUTO_CTRL_OFF)
		txp_cfg->mode = 0;
	else {
		txp_cfg->mode = 1;

		pg_tlv = (MrvlTypes_Power_Group_t
			  *)(buf + sizeof(HostCmd_DS_TXPWR_CFG));
		pg_tlv->type = TLV_TYPE_POWER_GROUP;
		pg_tlv->length = sizeof(Power_Group_t);
		pg = (Power_Group_t *)(buf + sizeof(HostCmd_DS_TXPWR_CFG) +
				       sizeof(MrvlTypes_Power_Group_t));
		pg->ht_bandwidth = pwr_grp->bandwidth;
		pg->power_min = (t_s8)pwr_grp->power_min;
		pg->power_max = (t_s8)pwr_grp->power_max;
		pg->power_step = (t_s8)pwr_grp->power_step;

		if (pwr_grp->rate_format == MLAN_RATE_FORMAT_LG) {
			if (pwr_grp->first_rate_ind <= MLAN_RATE_INDEX_HRDSSS3) {
				pg->modulation_class = MOD_CLASS_HR_DSSS;
			} else {
				pg->modulation_class = MOD_CLASS_OFDM;
				pwr_grp->first_rate_ind -=
					MLAN_RATE_INDEX_OFDM0;
				pwr_grp->last_rate_ind -= MLAN_RATE_INDEX_OFDM0;
			}
			pg->first_rate_code = (t_u8)pwr_grp->first_rate_ind;
			pg->last_rate_code = (t_u8)pwr_grp->last_rate_ind;
		} else if (pwr_grp->rate_format == MLAN_RATE_FORMAT_HT) {
			pg->modulation_class = MOD_CLASS_HT;
			pg->first_rate_code = (t_u8)pwr_grp->first_rate_ind;
			pg->last_rate_code = (t_u8)pwr_grp->last_rate_ind;
		} else if (pwr_grp->rate_format == MLAN_RATE_FORMAT_VHT) {
			pg->modulation_class = MOD_CLASS_VHT;
			pg->first_rate_code =
				(t_u8)((pwr_grp->first_rate_ind & 0xF) |
				       ((pwr_grp->nss - 1) << 4));
			pg->last_rate_code =
				(t_u8)((pwr_grp->last_rate_ind & 0xF) |
				       ((pwr_grp->nss - 1) << 4));
		} else {
			pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
			ret = MLAN_STATUS_FAILURE;
		}
	}
	if (ret == MLAN_STATUS_FAILURE) {
		if (buf)
			pcb->moal_mfree(pmadapter->pmoal_handle, buf);
		goto exit;
	}

	/* Send request to firmware */
	ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_TXPWR_CFG,
			       HostCmd_ACT_GEN_SET, 0, (t_void *)pioctl_req,
			       buf);
	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;
	if (buf)
		pcb->moal_mfree(pmadapter->pmoal_handle, buf);

exit:
	LEAVE();
	return ret;
}

/**
 *  @brief Power configuration command handler
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
 */
static mlan_status
wlan_power_ioctl(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_status status = MLAN_STATUS_SUCCESS;
	mlan_ds_power_cfg *power = MNULL;

	ENTER();

	if (pioctl_req->buf_len < sizeof(mlan_ds_power_cfg)) {
		PRINTM(MWARN, "MLAN bss IOCTL length is too short.\n");
		pioctl_req->data_read_written = 0;
		pioctl_req->buf_len_needed = sizeof(mlan_ds_power_cfg);
		pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
		LEAVE();
		return MLAN_STATUS_RESOURCE;
	}
	power = (mlan_ds_power_cfg *)pioctl_req->pbuf;
	switch (power->sub_command) {
	case MLAN_OID_POWER_CFG:
		if (pioctl_req->action == MLAN_ACT_GET)
			status = wlan_power_ioctl_get_power(pmadapter,
							    HostCmd_CMD_TXPWR_CFG,
							    pioctl_req);
		else
			status = wlan_power_ioctl_set_power(pmadapter,
							    pioctl_req);
		break;

	case MLAN_OID_POWER_CFG_EXT:
		if (pioctl_req->action == MLAN_ACT_GET)
			status = wlan_power_ioctl_get_power(pmadapter,
							    HostCmd_CMD_TXPWR_CFG,
							    pioctl_req);
		else
			status = wlan_power_ioctl_set_power_ext(pmadapter,
								pioctl_req);
		break;
	case MLAN_OID_POWER_LOW_POWER_MODE:
		status = wlan_power_ioctl_set_get_lpm(pmadapter, pioctl_req);
		break;
	default:
		pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID;
		status = MLAN_STATUS_FAILURE;
		break;
	}
	LEAVE();
	return status;
}

/**
 *  @brief Set power save configurations
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *  @param ps_mode	Power save mode
 *
 *  @return		MLAN_STATUS_PENDING --success, otherwise fail
 */
static mlan_status
wlan_pm_ioctl_ps_mode(pmlan_adapter pmadapter,
		      pmlan_ioctl_req pioctl_req, t_u16 ps_mode)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	t_u16 sub_cmd;

	ENTER();

	if (pioctl_req->action == MLAN_ACT_SET) {
		sub_cmd = (pmadapter->ps_mode == Wlan802_11PowerModePSP) ?
			EN_AUTO_PS : DIS_AUTO_PS;
		ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_PS_MODE_ENH,
				       sub_cmd, BITMAP_STA_PS,
				       (t_void *)pioctl_req, MNULL);
		if ((ret == MLAN_STATUS_SUCCESS) && (sub_cmd == DIS_AUTO_PS)) {
			ret = wlan_prepare_cmd(pmpriv,
					       HostCmd_CMD_802_11_PS_MODE_ENH,
					       GET_PS, 0, MNULL, MNULL);
		}
	} else {
		ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_PS_MODE_ENH,
				       GET_PS, 0, (t_void *)pioctl_req, MNULL);
	}

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get Inactivity timeout extend
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_PENDING --success, otherwise fail
 */
static mlan_status
wlan_pm_ioctl_inactivity_timeout(pmlan_adapter pmadapter,
				 pmlan_ioctl_req pioctl_req)
{
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_pm_cfg *pmcfg = MNULL;
	mlan_status ret = MLAN_STATUS_SUCCESS;
	t_u16 cmd_action = 0;

	ENTER();

	pmcfg = (mlan_ds_pm_cfg *)pioctl_req->pbuf;
	cmd_action = HostCmd_ACT_GEN_GET;
	if (pioctl_req->action == MLAN_ACT_SET)
		cmd_action = HostCmd_ACT_GEN_SET;

	/* Send request to firmware */
	ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_INACTIVITY_TIMEOUT_EXT,
			       cmd_action, 0, (t_void *)pioctl_req,
			       (t_void *)&pmcfg->param.inactivity_to);

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief Enable/Disable Auto Deep Sleep
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_PENDING --success, otherwise fail
 */
static mlan_status
wlan_set_auto_deep_sleep(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	pmlan_private pmpriv =
		(pmlan_private)pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_auto_ds auto_ds;
	t_u32 mode;

	ENTER();

	if (((mlan_ds_pm_cfg *)pioctl_req->pbuf)
	    ->param.auto_deep_sleep.auto_ds == DEEP_SLEEP_ON) {
		auto_ds.auto_ds = DEEP_SLEEP_ON;
		PRINTM(MINFO, "Auto Deep Sleep: on\n");
		mode = EN_AUTO_PS;
	} else {
		auto_ds.auto_ds = DEEP_SLEEP_OFF;
		PRINTM(MINFO, "Auto Deep Sleep: off\n");
		mode = DIS_AUTO_PS;
	}
	if (((mlan_ds_pm_cfg *)pioctl_req->pbuf)->param.auto_deep_sleep.
	    idletime)
		auto_ds.idletime = ((mlan_ds_pm_cfg *)pioctl_req->pbuf)
			->param.auto_deep_sleep.idletime;
	else
		auto_ds.idletime = pmadapter->idle_time;
	/* note: the command could be queued and executed
	   later if there is command in progress. */
	ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_PS_MODE_ENH,
			       (t_u16)mode, BITMAP_AUTO_DS,
			       (t_void *)pioctl_req, &auto_ds);
	if (ret) {
		LEAVE();
		return ret;
	}
	ret = MLAN_STATUS_PENDING;
	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get sleep period
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_PENDING --success, otherwise fail
 */
static mlan_status
wlan_set_get_sleep_pd(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_pm_cfg *pm_cfg = MNULL;
	t_u16 cmd_action = 0, sleep_pd = 0;

	ENTER();

	pm_cfg = (mlan_ds_pm_cfg *)pioctl_req->pbuf;
	cmd_action = HostCmd_ACT_GEN_GET;
	if (pioctl_req->action == MLAN_ACT_SET) {
		cmd_action = HostCmd_ACT_GEN_SET;
		sleep_pd = (t_u16)pm_cfg->param.sleep_period;
	}

	ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_SLEEP_PERIOD,
			       cmd_action, 0, (t_void *)pioctl_req, &sleep_pd);

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get PS configuration parameter
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS --success
 */
static mlan_status
wlan_set_get_ps_cfg(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_ds_pm_cfg *pm_cfg = MNULL;

	ENTER();

	pm_cfg = (mlan_ds_pm_cfg *)pioctl_req->pbuf;
	if (pioctl_req->action == MLAN_ACT_GET) {
		pm_cfg->param.ps_cfg.ps_null_interval =
			(t_u32)pmadapter->null_pkt_interval;
		pm_cfg->param.ps_cfg.multiple_dtim_interval =
			(t_u32)pmadapter->multiple_dtim;
		pm_cfg->param.ps_cfg.listen_interval =
			(t_u32)pmadapter->local_listen_interval;
		pm_cfg->param.ps_cfg.bcn_miss_timeout =
			(t_u32)pmadapter->bcn_miss_time_out;
		pm_cfg->param.ps_cfg.delay_to_ps =
			(t_u32)pmadapter->delay_to_ps;
		pm_cfg->param.ps_cfg.ps_mode =
			(t_u32)pmadapter->enhanced_ps_mode;
	} else {
		if (pm_cfg->param.ps_cfg.ps_null_interval)
			pmadapter->null_pkt_interval =
				(t_u16)pm_cfg->param.ps_cfg.ps_null_interval;
		else
			pm_cfg->param.ps_cfg.ps_null_interval =
				(t_u32)pmadapter->null_pkt_interval;
		if (pm_cfg->param.ps_cfg.multiple_dtim_interval)
			pmadapter->multiple_dtim =
				(t_u16)pm_cfg->param.ps_cfg.
				multiple_dtim_interval;
		else
			pm_cfg->param.ps_cfg.multiple_dtim_interval =
				(t_u32)pmadapter->multiple_dtim;
		if (((t_s32)pm_cfg->param.ps_cfg.listen_interval) ==
		    MRVDRV_LISTEN_INTERVAL_DISABLE)
			pmadapter->local_listen_interval = 0;
		else if (pm_cfg->param.ps_cfg.listen_interval)
			pmadapter->local_listen_interval =
				(t_u16)pm_cfg->param.ps_cfg.listen_interval;
		else
			pm_cfg->param.ps_cfg.listen_interval =
				(t_u32)pmadapter->local_listen_interval;
		if (pm_cfg->param.ps_cfg.bcn_miss_timeout)
			pmadapter->bcn_miss_time_out =
				(t_u16)pm_cfg->param.ps_cfg.bcn_miss_timeout;
		else
			pm_cfg->param.ps_cfg.bcn_miss_timeout =
				(t_u32)pmadapter->bcn_miss_time_out;
		if (pm_cfg->param.ps_cfg.delay_to_ps != DELAY_TO_PS_UNCHANGED)
			pmadapter->delay_to_ps =
				(t_u16)pm_cfg->param.ps_cfg.delay_to_ps;
		else
			pm_cfg->param.ps_cfg.delay_to_ps =
				(t_u32)pmadapter->delay_to_ps;
		if (pm_cfg->param.ps_cfg.ps_mode)
			pmadapter->enhanced_ps_mode =
				(t_u16)pm_cfg->param.ps_cfg.ps_mode;
		else
			pm_cfg->param.ps_cfg.ps_mode =
				(t_u32)pmadapter->enhanced_ps_mode;
	}
	pioctl_req->data_read_written = sizeof(t_u32) + MLAN_SUB_COMMAND_SIZE;

	LEAVE();
	return MLAN_STATUS_SUCCESS;
}

/**
 *  @brief Set/Get PS configuration parameter
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS --success
 */
static mlan_status
wlan_set_get_bcn_timeout(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_pm_cfg *pm_cfg = MNULL;

	ENTER();

	pm_cfg = (mlan_ds_pm_cfg *)pioctl_req->pbuf;

	/* Send command to firmware */
	ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_PS_MODE_ENH,
			       EN_AUTO_PS, BITMAP_BCN_TMO, (t_void *)pioctl_req,
			       &pm_cfg->param.bcn_timeout);

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief Get/Set the sleep parameters
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		        MLAN_STATUS_PENDING --success, otherwise fail
 */
static mlan_status
wlan_set_get_sleep_params(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_pm_cfg *pm_cfg = MNULL;
	t_u16 cmd_action = 0;

	ENTER();

	pm_cfg = (mlan_ds_pm_cfg *)pioctl_req->pbuf;
	cmd_action = HostCmd_ACT_GEN_GET;
	if (pioctl_req->action == MLAN_ACT_SET)
		cmd_action = HostCmd_ACT_GEN_SET;

	/* Send command to firmware */
	ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_SLEEP_PARAMS,
			       cmd_action, 0, (t_void *)pioctl_req,
			       &pm_cfg->param.sleep_params);

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief config management frame wakeup filter
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		        MLAN_STATUS_PENDING --success, otherwise fail
 */
mlan_status
wlan_config_mgmt_filter(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_ds_pm_cfg *pm_cfg = MNULL;
	int i = 0;

	ENTER();

	memset(pmadapter, pmadapter->mgmt_filter, 0,
	       sizeof(mlan_mgmt_frame_wakeup) * MAX_MGMT_FRAME_FILTER);
	pm_cfg = (mlan_ds_pm_cfg *)pioctl_req->pbuf;
	if (pioctl_req->action == MLAN_ACT_SET) {
		for (i = 0; i < MAX_MGMT_FRAME_FILTER; i++)
			if (!pm_cfg->param.mgmt_filter[i].type)
				break;
		memcpy_ext(pmadapter, (t_u8 *)pmadapter->mgmt_filter,
			   (t_u8 *)pm_cfg->param.mgmt_filter,
			   (i + 1) * sizeof(mlan_mgmt_frame_wakeup),
			   sizeof(pmadapter->mgmt_filter));
	} else if (pioctl_req->action == MLAN_ACT_GET)
		PRINTM(MERROR, "Get not support\n");
	LEAVE();
	return ret;
}

/**
 *  @brief Power save command handler
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
 */
static mlan_status
wlan_pm_ioctl(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_status status = MLAN_STATUS_SUCCESS;
	mlan_ds_pm_cfg *pm = MNULL;

	ENTER();

	if (pioctl_req->buf_len < sizeof(mlan_ds_pm_cfg)) {
		PRINTM(MWARN, "MLAN bss IOCTL length is too short.\n");
		pioctl_req->data_read_written = 0;
		pioctl_req->buf_len_needed = sizeof(mlan_ds_pm_cfg);
		LEAVE();
		return MLAN_STATUS_RESOURCE;
	}
	pm = (mlan_ds_pm_cfg *)pioctl_req->pbuf;
	switch (pm->sub_command) {
	case MLAN_OID_PM_CFG_IEEE_PS:
		switch (pioctl_req->action) {
		case MLAN_ACT_SET:
			/**Block ieee power save disable command when bt coex
			 * enable*/
			if (pmadapter->coex_scan && !pm->param.ps_mode)
				break;
			if (pm->param.ps_mode)
				pmadapter->ps_mode = Wlan802_11PowerModePSP;
			else
				pmadapter->ps_mode = Wlan802_11PowerModeCAM;
			status = wlan_pm_ioctl_ps_mode(pmadapter, pioctl_req,
						       pmadapter->ps_mode);
			break;
		case MLAN_ACT_GET:
			status = wlan_pm_ioctl_ps_mode(pmadapter, pioctl_req,
						       pmadapter->ps_mode);
			break;
		default:
			pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID;
			status = MLAN_STATUS_FAILURE;
			break;
		}
		break;
	case MLAN_OID_PM_CFG_HS_CFG:
		status = wlan_pm_ioctl_hscfg(pmadapter, pioctl_req);
		break;
	case MLAN_OID_PM_CFG_INACTIVITY_TO:
		status = wlan_pm_ioctl_inactivity_timeout(pmadapter,
							  pioctl_req);
		break;
	case MLAN_OID_PM_CFG_DEEP_SLEEP:
		switch (pioctl_req->action) {
		case MLAN_ACT_SET:
			if (pmadapter->is_deep_sleep &&
			    pm->param.auto_deep_sleep.auto_ds ==
			    DEEP_SLEEP_ON) {
				PRINTM(MMSG,
				       "Station already in enhanced deep sleep mode\n");
				status = MLAN_STATUS_FAILURE;
				break;
			} else if (!pmadapter->is_deep_sleep &&
				   pm->param.auto_deep_sleep.auto_ds ==
				   DEEP_SLEEP_OFF) {
				PRINTM(MMSG,
				       "Station already not in enhanced deep sleep mode\n");
				status = MLAN_STATUS_FAILURE;
				break;
			}
			status = wlan_set_auto_deep_sleep(pmadapter,
							  pioctl_req);
			break;
		case MLAN_ACT_GET:
			if (pmadapter->is_deep_sleep) {
				pm->param.auto_deep_sleep.auto_ds =
					DEEP_SLEEP_ON;
				pm->param.auto_deep_sleep.idletime =
					pmadapter->idle_time;
			} else
				pm->param.auto_deep_sleep.auto_ds =
					DEEP_SLEEP_OFF;
			break;
		default:
			pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID;
			status = MLAN_STATUS_FAILURE;
			break;
		}
		break;
	case MLAN_OID_PM_CFG_PS_CFG:
		status = wlan_set_get_ps_cfg(pmadapter, pioctl_req);
		break;
	case MLAN_OID_PM_CFG_SLEEP_PD:
		status = wlan_set_get_sleep_pd(pmadapter, pioctl_req);
		break;
	case MLAN_OID_PM_CFG_SLEEP_PARAMS:
		status = wlan_set_get_sleep_params(pmadapter, pioctl_req);
		break;
	case MLAN_OID_PM_INFO:
		status = wlan_get_pm_info(pmadapter, pioctl_req);
		break;
	case MLAN_OID_PM_HS_WAKEUP_REASON:
		status = wlan_get_hs_wakeup_reason(pmadapter, pioctl_req);
		break;
	case MLAN_OID_PM_MGMT_FILTER:
		status = wlan_config_mgmt_filter(pmadapter, pioctl_req);
		break;
	case MLAN_OID_PM_CFG_BCN_TIMEOUT:
		status = wlan_set_get_bcn_timeout(pmadapter, pioctl_req);
		break;
	default:
		pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID;
		status = MLAN_STATUS_FAILURE;
		break;
	}
	LEAVE();
	return status;
}

/**
 *  @brief Set/Get WPA IE
 *
 *  @param priv         A pointer to mlan_private structure
 *  @param ie_data_ptr  A pointer to IE
 *  @param ie_len       Length of the IE
 *
 *  @return             MLAN_STATUS_SUCCESS --success, otherwise fail
 */
static mlan_status
wlan_set_wpa_ie_helper(mlan_private *priv, t_u8 *ie_data_ptr, t_u16 ie_len)
{
	ENTER();

	if (ie_len) {
		if (ie_len > sizeof(priv->wpa_ie)) {
			PRINTM(MERROR, "failed to copy, WPA IE is too big\n");
			LEAVE();
			return MLAN_STATUS_FAILURE;
		}
		memcpy_ext(priv->adapter, priv->wpa_ie, ie_data_ptr, ie_len,
			   sizeof(priv->wpa_ie));
		priv->wpa_ie_len = (t_u8)ie_len;
		PRINTM(MIOCTL, "Set Wpa_ie_len=%d IE=%#x\n", priv->wpa_ie_len,
		       priv->wpa_ie[0]);
		DBG_HEXDUMP(MCMD_D, "Wpa_ie", priv->wpa_ie, priv->wpa_ie_len);
		if (priv->wpa_ie[0] == WPA_IE) {
			priv->sec_info.wpa_enabled = MTRUE;
		} else if (priv->wpa_ie[0] == RSN_IE) {
			priv->sec_info.wpa2_enabled = MTRUE;
		} else {
			priv->sec_info.wpa_enabled = MFALSE;
			priv->sec_info.wpa2_enabled = MFALSE;
		}
	} else {
		memset(priv->adapter, priv->wpa_ie, 0, sizeof(priv->wpa_ie));
		priv->wpa_ie_len = 0;
		PRINTM(MINFO, "Reset Wpa_ie_len=%d IE=%#x\n", priv->wpa_ie_len,
		       priv->wpa_ie[0]);
		priv->sec_info.wpa_enabled = MFALSE;
		priv->sec_info.wpa2_enabled = MFALSE;
	}

	LEAVE();
	return MLAN_STATUS_SUCCESS;
}

/**
 *  @brief Set OSEN IE
 *
 *  @param priv         A pointer to mlan_private structure
 *  @param ie_data_ptr  A pointer to IE
 *  @param ie_len       Length of the IE
 *
 *  @return             MLAN_STATUS_SUCCESS --success, otherwise fail
 */
static mlan_status
wlan_set_osen_ie(mlan_private *priv, t_u8 *ie_data_ptr, t_u16 ie_len)
{
	ENTER();
	if (ie_len) {
		if (ie_len > sizeof(priv->osen_ie)) {
			PRINTM(MWARN, "failed to copy, WAPI IE is too big\n");
			LEAVE();
			return MLAN_STATUS_FAILURE;
		}
		memcpy_ext(priv->adapter, priv->osen_ie, ie_data_ptr, ie_len,
			   sizeof(priv->osen_ie));
		priv->osen_ie_len = (t_u8)ie_len;
		PRINTM(MIOCTL, "Set osen_ie_len=%d IE=%#x\n", priv->osen_ie_len,
		       priv->osen_ie[0]);
		DBG_HEXDUMP(MCMD_D, "osen_ie", priv->osen_ie,
			    priv->osen_ie_len);
		priv->sec_info.osen_enabled = MTRUE;
	} else {
		memset(priv->adapter, priv->osen_ie, 0, sizeof(priv->osen_ie));
		priv->osen_ie_len = (t_u8)ie_len;
		PRINTM(MINFO, "Reset osen_ie_len=%d IE=%#x\n",
		       priv->osen_ie_len, priv->osen_ie[0]);
		priv->sec_info.osen_enabled = MFALSE;
	}
	LEAVE();
	return MLAN_STATUS_SUCCESS;
}

/**
 *  @brief Set WAPI IE
 *
 *  @param priv         A pointer to mlan_private structure
 *  @param ie_data_ptr  A pointer to IE
 *  @param ie_len       Length of the IE
 *
 *  @return             MLAN_STATUS_SUCCESS --success, otherwise fail
 */
static mlan_status
wlan_set_wapi_ie(mlan_private *priv, t_u8 *ie_data_ptr, t_u16 ie_len)
{
	ENTER();
	if (ie_len) {
		if (ie_len > sizeof(priv->wapi_ie)) {
			PRINTM(MWARN, "failed to copy, WAPI IE is too big\n");
			LEAVE();
			return MLAN_STATUS_FAILURE;
		}
		memcpy_ext(priv->adapter, priv->wapi_ie, ie_data_ptr, ie_len,
			   sizeof(priv->wapi_ie));
		priv->wapi_ie_len = (t_u8)ie_len;
		PRINTM(MIOCTL, "Set wapi_ie_len=%d IE=%#x\n", priv->wapi_ie_len,
		       priv->wapi_ie[0]);
		DBG_HEXDUMP(MCMD_D, "wapi_ie", priv->wapi_ie,
			    priv->wapi_ie_len);
		if (priv->wapi_ie[0] == WAPI_IE)
			priv->sec_info.wapi_enabled = MTRUE;
	} else {
		memset(priv->adapter, priv->wapi_ie, 0, sizeof(priv->wapi_ie));
		priv->wapi_ie_len = (t_u8)ie_len;
		PRINTM(MINFO, "Reset wapi_ie_len=%d IE=%#x\n",
		       priv->wapi_ie_len, priv->wapi_ie[0]);
		priv->sec_info.wapi_enabled = MFALSE;
	}
	LEAVE();
	return MLAN_STATUS_SUCCESS;
}

/**
 *  @brief Set/Get WAPI status
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS --success
 */
static mlan_status
wlan_sec_ioctl_wapi_enable(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_sec_cfg *sec = MNULL;
	ENTER();
	sec = (mlan_ds_sec_cfg *)pioctl_req->pbuf;
	if (pioctl_req->action == MLAN_ACT_GET) {
		if (pmpriv->wapi_ie_len)
			sec->param.wapi_enabled = MTRUE;
		else
			sec->param.wapi_enabled = MFALSE;
	} else {
		if (sec->param.wapi_enabled == MFALSE)
			wlan_set_wapi_ie(pmpriv, MNULL, 0);
	}
	pioctl_req->data_read_written = sizeof(t_u32) + MLAN_SUB_COMMAND_SIZE;
	LEAVE();
	return ret;
}

/**
 *  @brief Set WAPI key
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_PENDING --success, otherwise fail
 */
static mlan_status
wlan_sec_ioctl_set_wapi_key(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_sec_cfg *sec = MNULL;
	ENTER();

	sec = (mlan_ds_sec_cfg *)pioctl_req->pbuf;
	ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_KEY_MATERIAL,
			       HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED,
			       (t_void *)pioctl_req, &sec->param.encrypt_key);
	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get Port Control status
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
 */
static mlan_status
wlan_sec_ioctl_port_ctrl_enable(pmlan_adapter pmadapter,
				pmlan_ioctl_req pioctl_req)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_ds_sec_cfg *sec = MNULL;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];

	ENTER();

	sec = (mlan_ds_sec_cfg *)pioctl_req->pbuf;
	if (pioctl_req->action == MLAN_ACT_GET) {
		if (pmpriv->port_ctrl_mode)
			sec->param.port_ctrl_enabled = MTRUE;
		else
			sec->param.port_ctrl_enabled = MFALSE;
	} else {
		if (sec->param.port_ctrl_enabled) {
			pmpriv->port_ctrl_mode = MTRUE;
			pmpriv->port_open = MFALSE;
		} else {
			if (pmpriv->port_ctrl_mode == MTRUE) {
				pmpriv->port_ctrl_mode = MFALSE;
				/* Cleanup the bypass TX queue */
				wlan_cleanup_bypass_txq(pmpriv);
			}
		}
	}
	PRINTM(MINFO, "port_ctrl: port_ctrl_mode=%d port_open=%d\n",
	       pmpriv->port_ctrl_mode, pmpriv->port_open);

	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get authentication mode
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS --success
 */
static mlan_status
wlan_sec_ioctl_auth_mode(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_sec_cfg *sec = MNULL;
	ENTER();
	sec = (mlan_ds_sec_cfg *)pioctl_req->pbuf;
	if (pioctl_req->action == MLAN_ACT_GET)
		sec->param.auth_mode = pmpriv->sec_info.authentication_mode;
	else
		pmpriv->sec_info.authentication_mode = sec->param.auth_mode;

	pioctl_req->data_read_written = sizeof(t_u32) + MLAN_SUB_COMMAND_SIZE;
	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get encryption mode
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS --success
 */
static mlan_status
wlan_sec_ioctl_encrypt_mode(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_sec_cfg *sec = MNULL;
	ENTER();
	sec = (mlan_ds_sec_cfg *)pioctl_req->pbuf;
	if (pioctl_req->action == MLAN_ACT_GET)
		sec->param.encrypt_mode = pmpriv->sec_info.encryption_mode;
	else
		pmpriv->sec_info.encryption_mode = sec->param.encrypt_mode;

	pioctl_req->data_read_written = sizeof(t_u32) + MLAN_SUB_COMMAND_SIZE;
	LEAVE();
	return ret;
}

/**
 *  @brief Get Random charactor
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *
 *  @return		random charactor
 */
static t_u8
wlan_get_random_charactor(pmlan_adapter pmadapter)
{
	t_u32 sec, usec;
	t_u8 ch = 0;

	ENTER();

	pmadapter->callbacks.moal_get_system_time(pmadapter->pmoal_handle, &sec,
						  &usec);
	sec = (sec & 0xFFFF) + (sec >> 16);
	usec = (usec & 0xFFFF) + (usec >> 16);
	ch = (((sec << 16) + usec) % 26) + 'a';
	LEAVE();
	return ch;
}

/**
 *  @brief Set/Get WPA status
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS --success
 */
static mlan_status
wlan_sec_ioctl_wpa_enable(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_sec_cfg *sec = MNULL;
	ENTER();
	sec = (mlan_ds_sec_cfg *)pioctl_req->pbuf;
	if (pioctl_req->action == MLAN_ACT_GET) {
		if (pmpriv->wpa_ie_len)
			sec->param.wpa_enabled = MTRUE;
		else
			sec->param.wpa_enabled = MFALSE;
	} else {
		if (sec->param.wpa_enabled == MFALSE)
			wlan_set_wpa_ie_helper(pmpriv, MNULL, 0);
	}
	pioctl_req->data_read_written = sizeof(t_u32) + MLAN_SUB_COMMAND_SIZE;
	LEAVE();
	return ret;
}

/**
 *  @brief Set WEP keys
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_PENDING --success, otherwise fail
 */
static mlan_status
wlan_sec_ioctl_set_wep_key(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_sec_cfg *sec = MNULL;
	mrvl_wep_key_t *pwep_key = MNULL;
	int index;
	int i = 0;

	ENTER();

	if (pmpriv->wep_key_curr_index >= MRVL_NUM_WEP_KEY)
		pmpriv->wep_key_curr_index = 0;
	pwep_key = &pmpriv->wep_key[pmpriv->wep_key_curr_index];
	sec = (mlan_ds_sec_cfg *)pioctl_req->pbuf;
	if (sec->param.encrypt_key.key_index == MLAN_KEY_INDEX_DEFAULT) {
		index = pmpriv->wep_key_curr_index;
		sec->param.encrypt_key.key_index = index;
	} else {
		if (sec->param.encrypt_key.key_index >= MRVL_NUM_WEP_KEY) {
			if ((sec->param.encrypt_key.key_remove == MTRUE)&&
			    (sec->param.encrypt_key.key_index <= 5)) {
				/* call firmware remove key */
				ret = wlan_prepare_cmd(pmpriv,
						       HostCmd_CMD_802_11_KEY_MATERIAL,
						       HostCmd_ACT_GEN_SET, 0,
						       (t_void *)pioctl_req,
						       &sec->param.encrypt_key);
				if (ret == MLAN_STATUS_SUCCESS)
					ret = MLAN_STATUS_PENDING;
				goto exit;
			}
			PRINTM(MERROR, "Key_index is invalid\n");
			ret = MLAN_STATUS_FAILURE;
			goto exit;
		}
		index = sec->param.encrypt_key.key_index;
	}

	if ((sec->param.encrypt_key.key_disable == MTRUE)||
	    (sec->param.encrypt_key.key_remove == MTRUE)) {
		pmpriv->sec_info.wep_status = Wlan802_11WEPDisabled;
		/* remove key */
		if (sec->param.encrypt_key.key_remove == MTRUE) {
			memset(pmadapter, &pmpriv->wep_key[index], 0,
			       sizeof(mrvl_wep_key_t));
			/* call firmware remove key */
			ret = wlan_prepare_cmd(pmpriv,
					       HostCmd_CMD_802_11_KEY_MATERIAL,
					       HostCmd_ACT_GEN_SET, 0, MNULL,
					       &sec->param.encrypt_key);
			if (ret)
				goto exit;
		}
	} else {
		if (sec->param.encrypt_key.key_len) {
			if ((sec->param.encrypt_key.key_len !=
			     WEP_104_BIT_LEN)&&
			    (sec->param.encrypt_key.key_len !=
			     WEP_40_BIT_LEN)) {
				PRINTM(MERROR, "Invalid wep key len=%d\n",
				       sec->param.encrypt_key.key_len);
				/* We will use random key to clear the key
				 * buffer in FW */
				if (sec->param.encrypt_key.key_len <
				    WEP_40_BIT_LEN)
					sec->param.encrypt_key.key_len =
						WEP_40_BIT_LEN;
				else
					sec->param.encrypt_key.key_len =
						WEP_104_BIT_LEN;
				for (i = 0;
				     i < (int)sec->param.encrypt_key.key_len;
				     i++)
					sec->param.encrypt_key.key_material[i] =
						wlan_get_random_charactor
						(pmadapter);
			}
			pwep_key = &pmpriv->wep_key[index];
			/* Cleanup */
			memset(pmadapter, pwep_key, 0, sizeof(mrvl_wep_key_t));
			/* Copy the key in the driver */

			memcpy_ext(pmadapter, pwep_key->key_material,
				   sec->param.encrypt_key.key_material,
				   sec->param.encrypt_key.key_len,
				   MRVL_KEY_BUFFER_SIZE_IN_BYTE);
			pwep_key->key_index = index;
			pwep_key->key_length = sec->param.encrypt_key.key_len;
			if (pmpriv->sec_info.wep_status != Wlan802_11WEPEnabled) {
				/*
				 * The status is set as Key Absent
				 * so as to make sure we display the
				 * keys when iwlist mlanX key is used
				 */
				pmpriv->sec_info.wep_status =
					Wlan802_11WEPKeyAbsent;
			}
		}
		if (sec->param.encrypt_key.is_current_wep_key == MTRUE) {
			/* Copy the required key as the current key */
			pwep_key = &pmpriv->wep_key[index];
			if (!pwep_key->key_length) {
				if (pmpriv->sec_info.wpa_enabled ||
				    pmpriv->sec_info.wpa2_enabled
				    || pmpriv->sec_info.wapi_enabled) {
					ret = MLAN_STATUS_SUCCESS;
					goto exit;
				}
				PRINTM(MERROR,
				       "Key %d not set,so cannot enable it\n",
				       index);
				pioctl_req->status_code =
					MLAN_ERROR_CMD_RESP_FAIL;
				ret = MLAN_STATUS_FAILURE;
				goto exit;
			}
			pmpriv->wep_key_curr_index = (t_u16)index;
			pmpriv->sec_info.wep_status = Wlan802_11WEPEnabled;
		}
		if (sec->param.encrypt_key.key_flags && pwep_key->key_length) {
			pmpriv->wep_key_curr_index = (t_u16)index;
			// Only do this if the key is an xmit key.  If the key
			// is a group key, we might be in wpa/wep mixed mode in
			// which case we don't want to set wep_status =
			// Wlan802_11WEPEnabled because that enables WEP at the
			// MAC controller level and WPA stops working properly.
			if (sec->param.encrypt_key.key_flags &
			    KEY_FLAG_SET_TX_KEY) {
				pmpriv->sec_info.wep_status =
					Wlan802_11WEPEnabled;
			}
		}
	}
	if (pmpriv->sec_info.wep_status == Wlan802_11WEPEnabled)
		pmpriv->curr_pkt_filter |= HostCmd_ACT_MAC_WEP_ENABLE;
	else
		pmpriv->curr_pkt_filter &= ~HostCmd_ACT_MAC_WEP_ENABLE;

	/* Send request to firmware */
	if (pmpriv->sec_info.wep_status == Wlan802_11WEPEnabled &&
	    pwep_key->key_length) {
		ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_MAC_CONTROL,
				       HostCmd_ACT_GEN_SET, 0, MNULL,
				       &pmpriv->curr_pkt_filter);
		if (ret)
			goto exit;
		if (!sec->param.encrypt_key.key_len) {
			sec->param.encrypt_key.key_index = pwep_key->key_index;
			sec->param.encrypt_key.key_len = pwep_key->key_length;
			memcpy_ext(pmadapter,
				   sec->param.encrypt_key.key_material,
				   pwep_key->key_material,
				   sec->param.encrypt_key.key_len,
				   MLAN_MAX_KEY_LENGTH);
		}
		ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_KEY_MATERIAL,
				       HostCmd_ACT_GEN_SET, 0,
				       (t_void *)pioctl_req,
				       &sec->param.encrypt_key);
	} else {
		if (pwep_key->key_length) {
			if (!sec->param.encrypt_key.key_len) {
				sec->param.encrypt_key.key_index =
					pwep_key->key_index;
				sec->param.encrypt_key.key_len =
					pwep_key->key_length;
				memcpy_ext(pmadapter,
					   sec->param.encrypt_key.key_material,
					   pwep_key->key_material,
					   sec->param.encrypt_key.key_len,
					   MLAN_MAX_KEY_LENGTH);
			}
			ret = wlan_prepare_cmd(pmpriv,
					       HostCmd_CMD_802_11_KEY_MATERIAL,
					       HostCmd_ACT_GEN_SET, 0, MNULL,
					       &sec->param.encrypt_key);
			if (ret)
				goto exit;
		}
		ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_MAC_CONTROL,
				       HostCmd_ACT_GEN_SET, 0,
				       (t_void *)pioctl_req,
				       &pmpriv->curr_pkt_filter);
	}
	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

exit:
	LEAVE();
	return ret;
}

/**
 *  @brief Set WPA key
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_PENDING --success, otherwise fail
 */
static mlan_status
wlan_sec_ioctl_set_wpa_key(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_sec_cfg *sec = MNULL;

	ENTER();

	sec = (mlan_ds_sec_cfg *)pioctl_req->pbuf;
	/* Current driver only supports key length of up to 32 bytes */
	if (sec->param.encrypt_key.key_len > MLAN_MAX_KEY_LENGTH) {
		PRINTM(MERROR, "Key length is incorrect\n");
		pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
		ret = MLAN_STATUS_FAILURE;
		goto exit;
	}

	ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_KEY_MATERIAL,
			       HostCmd_ACT_GEN_SET, 0, (t_void *)pioctl_req,
			       &sec->param.encrypt_key);

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

exit:
	LEAVE();
	return ret;
}

/**
 *  @brief Get security keys
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
 */
static mlan_status
wlan_sec_ioctl_get_key(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_sec_cfg *sec = MNULL;
	int index;
	ENTER();

	sec = (mlan_ds_sec_cfg *)pioctl_req->pbuf;

	if (pmpriv->wep_key_curr_index >= MRVL_NUM_WEP_KEY)
		pmpriv->wep_key_curr_index = 0;

	if ((pmpriv->sec_info.wep_status == Wlan802_11WEPEnabled) ||
	    (pmpriv->sec_info.wep_status == Wlan802_11WEPKeyAbsent)
	    || pmpriv->sec_info.ewpa_enabled
	    || pmpriv->sec_info.wpa_enabled || pmpriv->sec_info.wpa2_enabled) {
		sec->param.encrypt_key.key_disable = MFALSE;
	} else {
		sec->param.encrypt_key.key_disable = MTRUE;
	}
	if (sec->param.encrypt_key.key_index == MLAN_KEY_INDEX_DEFAULT) {
		if ((pmpriv->wep_key[pmpriv->wep_key_curr_index].key_length)&&
		    (pmpriv->sec_info.wep_status == Wlan802_11WEPEnabled)) {
			index = pmpriv->wep_key_curr_index;
			sec->param.encrypt_key.key_index =
				pmpriv->wep_key[index].key_index;
			memcpy_ext(pmadapter,
				   sec->param.encrypt_key.key_material,
				   pmpriv->wep_key[index].key_material,
				   pmpriv->wep_key[index].key_length,
				   MLAN_MAX_KEY_LENGTH);
			sec->param.encrypt_key.key_len =
				MIN(MLAN_MAX_KEY_LENGTH,
				    pmpriv->wep_key[index].key_length);
		} else if ((pmpriv->sec_info.wpa_enabled)
			   || (pmpriv->sec_info.ewpa_enabled)
			   || (pmpriv->sec_info.wpa2_enabled)
			   || (pmpriv->sec_info.wapi_enabled)
			) {
			/* Return WPA enabled */
			sec->param.encrypt_key.key_disable = MFALSE;
			memcpy_ext(pmadapter,
				   sec->param.encrypt_key.key_material,
				   pmpriv->aes_key.key_material,
				   pmpriv->aes_key.key_len,
				   MLAN_MAX_KEY_LENGTH);
			sec->param.encrypt_key.key_len =
				MIN(MLAN_MAX_KEY_LENGTH,
				    pmpriv->aes_key.key_len);
		} else {
			sec->param.encrypt_key.key_disable = MTRUE;
		}
	} else {
		index = sec->param.encrypt_key.key_index;
		if (pmpriv->wep_key[index].key_length) {
			sec->param.encrypt_key.key_index =
				pmpriv->wep_key[index].key_index;
			memcpy_ext(pmadapter,
				   sec->param.encrypt_key.key_material,
				   pmpriv->wep_key[index].key_material,
				   pmpriv->wep_key[index].key_length,
				   MLAN_MAX_KEY_LENGTH);
			sec->param.encrypt_key.key_len =
				MIN(MLAN_MAX_KEY_LENGTH,
				    pmpriv->wep_key[index].key_length);
		} else if ((pmpriv->sec_info.wpa_enabled)
			   || (pmpriv->sec_info.ewpa_enabled)
			   || (pmpriv->sec_info.wpa2_enabled)
			   || (pmpriv->sec_info.wapi_enabled)
			) {
			/* Return WPA enabled */
			sec->param.encrypt_key.key_disable = MFALSE;
		} else {
			sec->param.encrypt_key.key_disable = MTRUE;
		}
	}

	LEAVE();
	return ret;
}

/**
 *  @brief Set security key(s)
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS/MLAN_STATUS_PENDING --success,
 * otherwise fail
 */
static mlan_status
wlan_sec_ioctl_encrypt_key(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_status status = MLAN_STATUS_SUCCESS;
	mlan_ds_sec_cfg *sec = MNULL;
	ENTER();
	sec = (mlan_ds_sec_cfg *)pioctl_req->pbuf;
	if (pioctl_req->action == MLAN_ACT_SET) {
		if (sec->param.encrypt_key.is_wapi_key)
			status = wlan_sec_ioctl_set_wapi_key(pmadapter,
							     pioctl_req);
		else if (sec->param.encrypt_key.key_len > MAX_WEP_KEY_SIZE)
			status = wlan_sec_ioctl_set_wpa_key(pmadapter,
							    pioctl_req);
		else
			status = wlan_sec_ioctl_set_wep_key(pmadapter,
							    pioctl_req);
	} else {
		status = wlan_sec_ioctl_get_key(pmadapter, pioctl_req);
	}
	LEAVE();
	return status;
}

/**
 *  @brief Query Encrpyt key
 *
 *  @param pmadapter    A pointer to mlan_adapter structure
 *  @param pioctl_req   A pointer to ioctl request buffer
 *
 *  @return     MLAN_STATUS_PENDING --success, otherwise fail
 */
static mlan_status
wlan_sec_ioctl_query_key(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_sec_cfg *sec = MNULL;

	ENTER();

	sec = (mlan_ds_sec_cfg *)pioctl_req->pbuf;
	/* Current driver only supports get PTK/GTK */
	if (pmpriv->port_open &&
	    (pmpriv->sec_info.wpa_enabled || pmpriv->sec_info.wpa2_enabled
	     || pmpriv->sec_info.wapi_enabled)) {
		/* Send request to firmware */
		ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_KEY_MATERIAL,
				       HostCmd_ACT_GEN_GET, KEY_INFO_ENABLED,
				       (t_void *)pioctl_req,
				       &sec->param.encrypt_key);

		if (ret == MLAN_STATUS_SUCCESS)
			ret = MLAN_STATUS_PENDING;
	}
	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get esupplicant status
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS --success
 */
static mlan_status
wlan_sec_ioctl_ewpa_enable(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_sec_cfg *sec = MNULL;
	ENTER();
	sec = (mlan_ds_sec_cfg *)pioctl_req->pbuf;
	if (pioctl_req->action == MLAN_ACT_GET) {
		sec->param.ewpa_enabled = pmpriv->sec_info.ewpa_enabled;
	} else {
		pmpriv->sec_info.ewpa_enabled = (t_u8)sec->param.ewpa_enabled;
		PRINTM(MINFO, "Set: ewpa_enabled = %d\n",
		       (int)pmpriv->sec_info.ewpa_enabled);
	}
	pioctl_req->data_read_written = sizeof(t_u32) + MLAN_SUB_COMMAND_SIZE;
	LEAVE();
	return ret;
}

/**
 *  @brief Get esupplicant mode
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_PENDING --success, otherwise fail
 */
static mlan_status
wlan_sec_ioctl_esupp_mode(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	t_u16 cmd_action = 0;
	mlan_ds_sec_cfg *sec = MNULL;

	ENTER();

	sec = (mlan_ds_sec_cfg *)pioctl_req->pbuf;
	if (pioctl_req->action == MLAN_ACT_SET) {
		cmd_action = HostCmd_ACT_GEN_SET;
		if (pmpriv->media_connected == MTRUE) {
			PRINTM(MERROR,
			       "Cannot set esupplicant mode configuration while connected.\n");
			pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID;
			ret = MLAN_STATUS_FAILURE;
			goto exit;
		}
		if (!sec->param.esupp_mode.rsn_mode ||
		    (sec->param.esupp_mode.rsn_mode & RSN_TYPE_VALID_BITS) !=
		    sec->param.esupp_mode.rsn_mode) {
			PRINTM(MERROR, "Invalid RSN mode\n");
			pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID;
			ret = MLAN_STATUS_FAILURE;
			goto exit;
		}
		if (!sec->param.esupp_mode.act_paircipher ||
		    (sec->param.esupp_mode.act_paircipher &
		     EMBED_CIPHER_VALID_BITS) !=
		    sec->param.esupp_mode.act_paircipher) {
			PRINTM(MERROR, "Invalid pairwise cipher\n");
			pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID;
			ret = MLAN_STATUS_FAILURE;
			goto exit;
		}
		if (!sec->param.esupp_mode.act_groupcipher ||
		    (sec->param.esupp_mode.act_groupcipher &
		     EMBED_CIPHER_VALID_BITS) !=
		    sec->param.esupp_mode.act_groupcipher) {
			PRINTM(MERROR, "Invalid group cipher\n");
			pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID;
			ret = MLAN_STATUS_FAILURE;
			goto exit;
		}
	} else {
		cmd_action = HostCmd_ACT_GEN_GET_CURRENT;
	}

	/* Send request to firmware */
	if (sec) {
		ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_SUPPLICANT_PROFILE,
				       cmd_action, 0, (t_void *)pioctl_req,
				       &sec->param.esupp_mode);
	} else {
		ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_SUPPLICANT_PROFILE,
				       cmd_action, 0, (t_void *)pioctl_req,
				       MNULL);
	}
	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

exit:
	LEAVE();
	return ret;
}

/**
 *  @brief Security configuration handler
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS/MLAN_STATUS_PENDING --success,
 * otherwise fail
 */
static mlan_status
wlan_sec_cfg_ioctl(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_status status = MLAN_STATUS_SUCCESS;
	mlan_ds_sec_cfg *sec = MNULL;

	ENTER();

	if (pioctl_req->buf_len < sizeof(mlan_ds_sec_cfg)) {
		PRINTM(MWARN, "MLAN bss IOCTL length is too short.\n");
		pioctl_req->data_read_written = 0;
		pioctl_req->buf_len_needed = sizeof(mlan_ds_sec_cfg);
		pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
		LEAVE();
		return MLAN_STATUS_RESOURCE;
	}
	sec = (mlan_ds_sec_cfg *)pioctl_req->pbuf;
	switch (sec->sub_command) {
	case MLAN_OID_SEC_CFG_AUTH_MODE:
		status = wlan_sec_ioctl_auth_mode(pmadapter, pioctl_req);
		break;
	case MLAN_OID_SEC_CFG_ENCRYPT_MODE:
		status = wlan_sec_ioctl_encrypt_mode(pmadapter, pioctl_req);
		break;
	case MLAN_OID_SEC_CFG_WPA_ENABLED:
		status = wlan_sec_ioctl_wpa_enable(pmadapter, pioctl_req);
		break;
	case MLAN_OID_SEC_CFG_WAPI_ENABLED:
		status = wlan_sec_ioctl_wapi_enable(pmadapter, pioctl_req);
		break;
	case MLAN_OID_SEC_CFG_PORT_CTRL_ENABLED:
		status = wlan_sec_ioctl_port_ctrl_enable(pmadapter, pioctl_req);
		break;
	case MLAN_OID_SEC_CFG_ENCRYPT_KEY:
		status = wlan_sec_ioctl_encrypt_key(pmadapter, pioctl_req);
		break;
	case MLAN_OID_SEC_QUERY_KEY:
		status = wlan_sec_ioctl_query_key(pmadapter, pioctl_req);
		break;
	case MLAN_OID_SEC_CFG_PASSPHRASE:
		status = wlan_sec_ioctl_passphrase(pmadapter, pioctl_req);
		break;
	case MLAN_OID_SEC_CFG_EWPA_ENABLED:
		status = wlan_sec_ioctl_ewpa_enable(pmadapter, pioctl_req);
		break;
	case MLAN_OID_SEC_CFG_ESUPP_MODE:
		status = wlan_sec_ioctl_esupp_mode(pmadapter, pioctl_req);
		break;

	default:
		pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID;
		status = MLAN_STATUS_FAILURE;
		break;
	}
	LEAVE();
	return status;
}

/**
 *  @brief  Append/Reset IE buffer.
 *
 *  Pass an opaque block of data, expected to be IEEE IEs, to the driver
 *    for eventual passthrough to the firmware in an associate/join
 *    (and potentially start) command.  This function is the main body
 *    for both wlan_set_gen_ie_ioctl and wlan_set_gen_ie
 *
 *  Data is appended to an existing buffer and then wrapped in a passthrough
 *    TLV in the command API to the firmware.  The firmware treats the data
 *    as a transparent passthrough to the transmitted management frame.
 *
 *  @param priv         A pointer to mlan_private structure
 *  @param ie_data_ptr  A pointer to iwreq structure
 *  @param ie_len       Length of the IE or IE block passed in ie_data_ptr
 *
 *  @return             MLAN_STATUS_SUCCESS --success, otherwise fail
 */
static int
wlan_set_gen_ie_helper(mlan_private *priv, t_u8 *ie_data_ptr, t_u16 ie_len)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	IEEEtypes_VendorHeader_t *pvendor_ie;
	const t_u8 wpa_oui[] = { 0x00, 0x50, 0xf2, 0x01 };
	const t_u8 wps_oui[] = { 0x00, 0x50, 0xf2, 0x04 };
	const t_u8 osen_oui[] = { 0x50, 0x6f, 0x9a, 0x12 };
	t_u8 i = 0, temp[12] = { 0 };

	ENTER();

	/* If the passed length is zero, reset the buffer */
	if (!ie_len) {
		priv->gen_ie_buf_len = 0;
		priv->wps.session_enable = MFALSE;
		wlan_set_wpa_ie_helper(priv, MNULL, 0);
		wlan_set_wapi_ie(priv, MNULL, 0);
		wlan_set_osen_ie(priv, MNULL, 0);
	} else if (!ie_data_ptr) {
		/* MNULL check */
		ret = MLAN_STATUS_FAILURE;
	} else {
		pvendor_ie = (IEEEtypes_VendorHeader_t *)ie_data_ptr;
		if (pvendor_ie->element_id == EXT_CAPABILITY) {
			memcpy_ext(priv->adapter, temp, &priv->ext_cap,
				   sizeof(priv->ext_cap), sizeof(temp));
			for (i = 0;
			     i < MIN(sizeof(priv->ext_cap), pvendor_ie->len);
			     i++)
				temp[i] |= ie_data_ptr[2 + i];
			memcpy_ext(priv->adapter, &priv->ext_cap, temp,
				   sizeof(temp), sizeof(priv->ext_cap));
		} else
			/* Test to see if it is a WPA IE, if not, then it is a
			   gen IE */
		if (((pvendor_ie->element_id == WPA_IE) &&
			     (!memcmp
				      (priv->adapter, pvendor_ie->oui,
					       wpa_oui,
					       sizeof(wpa_oui)))) ||
			    (pvendor_ie->element_id == RSN_IE)) {
			/* IE is a WPA/WPA2 IE so call set_wpa function */
			ret = wlan_set_wpa_ie_helper(priv, ie_data_ptr, ie_len);
			priv->wps.session_enable = MFALSE;
		} else if (pvendor_ie->element_id == WAPI_IE) {
			/* IE is a WAPI IE so call set_wapi function */
			ret = wlan_set_wapi_ie(priv, ie_data_ptr, ie_len);
		} else if ((pvendor_ie->element_id == VENDOR_SPECIFIC_221) &&
			   (!memcmp(priv->adapter, pvendor_ie->oui, osen_oui,
				    sizeof(osen_oui)))) {
			/* IE is a OSEN IE so call set_osen function */
			ret = wlan_set_osen_ie(priv, ie_data_ptr, ie_len);

		} else if ((pvendor_ie->element_id == WPS_IE) &&
			   (priv->wps.session_enable == MFALSE) &&
			   (!memcmp(priv->adapter, pvendor_ie->oui, wps_oui,
				    sizeof(wps_oui)))) {
			/*
			 * Discard first two byte (Element ID and Length)
			 * because they are not needed in the case of setting
			 * WPS_IE
			 */
			if (pvendor_ie->len > 4) {
				memcpy_ext(priv->adapter,
					   (t_u8 *)&priv->wps.wps_ie,
					   ie_data_ptr, ie_len,
					   sizeof(IEEEtypes_VendorSpecific_t));
				HEXDUMP("wps_ie", (t_u8 *)&priv->wps.wps_ie,
					priv->wps.wps_ie.vend_hdr.len + 2);
			} else {
				/* Only wps oui exist, reset driver wps buffer
				 */
				memset(priv->adapter, (t_u8 *)&priv->wps.wps_ie,
				       0x00, sizeof(priv->wps.wps_ie));
				PRINTM(MINFO, "wps_ie cleared\n");
			}
		} else {
			/*
			 * Verify that the passed length is not larger than
			 * the available space remaining in the buffer
			 */
			if (ie_len <
			    (sizeof(priv->gen_ie_buf) - priv->gen_ie_buf_len)) {
				/* Test to see if it is a WPS IE, if so, enable
				 * wps session flag */
				pvendor_ie =
					(IEEEtypes_VendorHeader_t *)ie_data_ptr;
				if ((pvendor_ie->element_id == WPS_IE) &&
				    (!memcmp(priv->adapter, pvendor_ie->oui,
					     wps_oui, sizeof(wps_oui)))) {
					priv->wps.session_enable = MTRUE;
					PRINTM(MINFO, "WPS Session Enabled.\n");
				}

				/* Append the passed data to the end of
				 * the genIeBuffer */
				memcpy_ext(priv->adapter,
					   priv->gen_ie_buf +
					   priv->gen_ie_buf_len,
					   ie_data_ptr, ie_len,
					   MRVDRV_GENIE_BUF_SIZE -
					   priv->gen_ie_buf_len);
				/* Increment the stored buffer length by
				 * the size passed */
				priv->gen_ie_buf_len += ie_len;
			} else {
				/* Passed data does not fit in the
				 * remaining buffer space */
				ret = MLAN_STATUS_FAILURE;
			}
		}
	}

	/* Return MLAN_STATUS_SUCCESS, or MLAN_STATUS_FAILURE for error case */
	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get WWS mode
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_PENDING --success, otherwise fail
 */
static mlan_status
wlan_misc_ioctl_wws_cfg(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_ds_misc_cfg *misc_cfg = MNULL;
	t_u16 cmd_action = 0;
	t_u32 enable = 0;

	ENTER();

	if (pioctl_req->buf_len < sizeof(mlan_ds_misc_cfg)) {
		PRINTM(MWARN,
		       "MLAN IOCTL information buffer length is too short.\n");
		pioctl_req->data_read_written = 0;
		pioctl_req->buf_len_needed = sizeof(mlan_ds_misc_cfg);
		pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
		ret = MLAN_STATUS_RESOURCE;
		goto exit;
	}

	misc_cfg = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
	if (pioctl_req->action == MLAN_ACT_SET)
		cmd_action = HostCmd_ACT_GEN_SET;
	else
		cmd_action = HostCmd_ACT_GEN_GET;

	enable = misc_cfg->param.wws_cfg;

	/* Send request to firmware */
	ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_SNMP_MIB, cmd_action,
			       WwsMode_i, (t_void *)pioctl_req, &enable);

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

exit:
	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get 11D status
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS/MLAN_STATUS_PENDING --success,
 * otherwise fail
 */
static mlan_status
wlan_11d_cfg_ioctl_enable(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_11d_cfg *pcfg_11d = MNULL;

	ENTER();

	pcfg_11d = (mlan_ds_11d_cfg *)pioctl_req->pbuf;

	if (pioctl_req->action == MLAN_ACT_SET) {
		if (pmpriv->media_connected == MTRUE) {
			PRINTM(MIOCTL,
			       "11D setting cannot be changed while interface is active.\n");
			ret = MLAN_STATUS_FAILURE;
			goto done;
		}

		PRINTM(MINFO, "11D: 11dcfg SET=%d\n",
		       pcfg_11d->param.enable_11d);

		/* Compare with current settings */
		if (pmpriv->state_11d.user_enable_11d !=
		    pcfg_11d->param.enable_11d) {
			ret = wlan_11d_enable(pmpriv, pioctl_req,
					      (state_11d_t)pcfg_11d->param.
					      enable_11d);
			if (ret == MLAN_STATUS_SUCCESS)
				ret = MLAN_STATUS_PENDING;
		} else {
			PRINTM(MINFO,
			       "11D: same as current setting, do nothing\n");
		}
	} else {
		pcfg_11d->param.enable_11d =
			(t_u32)pmpriv->state_11d.user_enable_11d;
		pioctl_req->data_read_written =
			sizeof(t_u32) + MLAN_SUB_COMMAND_SIZE;
		PRINTM(MINFO, "11D: 11dcfg GET=%d\n",
		       pcfg_11d->param.enable_11d);
	}

done:
	LEAVE();
	return ret;
}

/**
 *  @brief Clear 11D chan table
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS --success
 */
static mlan_status
wlan_11d_clr_chan_table(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];

	ENTER();

	if (pioctl_req->action == MLAN_ACT_SET) {
		PRINTM(MINFO, "11D: 11dclrtbl SET\n");

		if (wlan_11d_clear_parsedtable(pmpriv) == MLAN_STATUS_SUCCESS)
			PRINTM(MINFO,
			       "11D: cleared parsed_region_chan (now no_of_chan=%d)\n",
			       pmadapter->parsed_region_chan.no_of_chan);
	}

	LEAVE();
	return ret;
}

/**
 *  @brief 11D configuration handler
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS/MLAN_STATUS_PENDING --success,
 * otherwise fail
 */
static mlan_status
wlan_11d_cfg_ioctl(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_status status = MLAN_STATUS_SUCCESS;
	mlan_ds_11d_cfg *pcfg_11d = MNULL;

	ENTER();

	if (pioctl_req->buf_len < sizeof(mlan_ds_11d_cfg)) {
		PRINTM(MWARN, "MLAN bss IOCTL length is too short.\n");
		pioctl_req->data_read_written = 0;
		pioctl_req->buf_len_needed = sizeof(mlan_ds_11d_cfg);
		pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
		status = MLAN_STATUS_RESOURCE;
		goto exit;
	}

	pcfg_11d = (mlan_ds_11d_cfg *)pioctl_req->pbuf;
	switch (pcfg_11d->sub_command) {
	case MLAN_OID_11D_CFG_ENABLE:
		status = wlan_11d_cfg_ioctl_enable(pmadapter, pioctl_req);
		break;
	case MLAN_OID_11D_CLR_CHAN_TABLE:
		status = wlan_11d_clr_chan_table(pmadapter, pioctl_req);
		break;
	case MLAN_OID_11D_DOMAIN_INFO_EXT:
		status = wlan_11d_cfg_domain_info(pmadapter, pioctl_req);
		break;
	default:
		pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID;
		status = MLAN_STATUS_FAILURE;
		break;
	}

exit:
	LEAVE();
	return status;
}

/**
 *  @brief WPS configuration handler
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
 */
static mlan_status
wlan_wps_cfg_ioctl(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_status status = MLAN_STATUS_SUCCESS;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_wps_cfg *pwps = MNULL;

	ENTER();

	if (pioctl_req->buf_len < sizeof(mlan_ds_wps_cfg)) {
		PRINTM(MWARN, "MLAN bss IOCTL length is too short.\n");
		pioctl_req->data_read_written = 0;
		pioctl_req->buf_len_needed = sizeof(mlan_ds_wps_cfg);
		pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
		LEAVE();
		return MLAN_STATUS_RESOURCE;
	}

	pwps = (mlan_ds_wps_cfg *)pioctl_req->pbuf;
	switch (pwps->sub_command) {
	case MLAN_OID_WPS_CFG_SESSION:
		if (pioctl_req->action == MLAN_ACT_SET) {
			if (pwps->param.wps_session ==
			    MLAN_WPS_CFG_SESSION_START)
				pmpriv->wps.session_enable = MTRUE;
			else
				pmpriv->wps.session_enable = MFALSE;
		} else {
			pwps->param.wps_session =
				(t_u32)pmpriv->wps.session_enable;
			pioctl_req->data_read_written = sizeof(t_u32);
			PRINTM(MINFO, "wpscfg GET=%d\n",
			       pwps->param.wps_session);
		}
		break;
	default:
		pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID;
		status = MLAN_STATUS_FAILURE;
		break;
	}

	LEAVE();
	return status;
}

/**
 *  @brief register memory access handler
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_PENDING --success, otherwise fail
 */
static mlan_status
wlan_reg_mem_ioctl(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_status status = MLAN_STATUS_SUCCESS;
	mlan_ds_reg_mem *reg_mem = MNULL;

	ENTER();

	if (pioctl_req->buf_len < sizeof(mlan_ds_reg_mem)) {
		PRINTM(MWARN, "MLAN REG_MEM IOCTL length is too short\n");
		pioctl_req->data_read_written = 0;
		pioctl_req->buf_len_needed = sizeof(mlan_ds_reg_mem);
		pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
		LEAVE();
		return MLAN_STATUS_RESOURCE;
	}
	reg_mem = (mlan_ds_reg_mem *)pioctl_req->pbuf;
	switch (reg_mem->sub_command) {
	case MLAN_OID_REG_RW:
		status = wlan_reg_mem_ioctl_reg_rw(pmadapter, pioctl_req);
		break;
	case MLAN_OID_EEPROM_RD:
		status = wlan_reg_mem_ioctl_read_eeprom(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MEM_RW:
		status = wlan_reg_mem_ioctl_mem_rw(pmadapter, pioctl_req);
		break;
	default:
		pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID;
		status = MLAN_STATUS_FAILURE;
		break;
	}
	LEAVE();
	return status;
}

/**
 *  @brief 802.11h ad-hoc start channel check
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_PENDING --success, otherwise fail
 */
static mlan_status
wlan_11h_channel_check_req(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	pmlan_private pmpriv = MNULL;
	mlan_status ret = MLAN_STATUS_FAILURE;
	t_u8 chan_width = CHAN_BW_20MHZ;
	Band_Config_t bandcfg;

	ENTER();

	if (pioctl_req != MNULL) {
		pmpriv = pmadapter->priv[pioctl_req->bss_index];
	} else {
		PRINTM(MERROR, "MLAN IOCTL information is not present\n");
		LEAVE();
		return MLAN_STATUS_FAILURE;
	}

	memset(pmadapter, &bandcfg, 0, sizeof(Band_Config_t));
	pmpriv->adhoc_state = ADHOC_STARTING;

	if ((pmadapter->adhoc_start_band & BAND_A)
		) {
		if (pmpriv->intf_state_11h.adhoc_auto_sel_chan)
			pmpriv->adhoc_channel =
				wlan_11h_get_adhoc_start_channel(pmpriv);

		/*
		 * Check if the region and channel requires a channel
		 * availability check.
		 */
		if (wlan_11h_radar_detect_required(pmpriv,
						   pmpriv->adhoc_channel)
		    && !wlan_11h_is_channel_under_nop(pmadapter,
						      pmpriv->adhoc_channel)
			) {
			/*
			 * Radar detection is required for this channel, make
			 * sure 11h is activated in the firmware
			 */
			ret = wlan_11h_activate(pmpriv, MNULL, MTRUE);
			ret = wlan_11h_config_master_radar_det(pmpriv, MTRUE);
			ret = wlan_11h_check_update_radar_det_state(pmpriv);

			/* Check for radar on the channel */
			if ((pmadapter->chan_bandwidth ==
			     CHANNEL_BW_40MHZ_ABOVE) ||
			    (pmadapter->chan_bandwidth ==
			     CHANNEL_BW_40MHZ_BELOW)) {
				chan_width = CHAN_BW_40MHZ;
				if (pmadapter->chanrpt_param_bandcfg) {
					bandcfg.chan2Offset =
						pmadapter->chan_bandwidth;
				}
			} else if (pmadapter->chan_bandwidth ==
				   CHANNEL_BW_80MHZ)
				chan_width = CHAN_BW_80MHZ;
			if (pmadapter->chanrpt_param_bandcfg) {
				bandcfg.chanWidth = chan_width;
				bandcfg.chanBand = BAND_5GHZ;
			} else {
				*((t_u8 *)&bandcfg) = chan_width;
			}

			ret = wlan_11h_issue_radar_detect(pmpriv, pioctl_req,
							  pmpriv->adhoc_channel,
							  bandcfg);
			if (ret == MLAN_STATUS_SUCCESS)
				ret = MLAN_STATUS_PENDING;
		}
	}

	LEAVE();
	return ret;
}

/**
 *  @brief 802.11h set/get local power constraint
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS
 */
static mlan_status
wlan_11h_ioctl_local_power_constraint(pmlan_adapter pmadapter,
				      pmlan_ioctl_req pioctl_req)
{
	mlan_ds_11h_cfg *ds_11hcfg = MNULL;
	t_s8 *plocalpower = &pmadapter->state_11h.usr_def_power_constraint;

	ENTER();

	ds_11hcfg = (mlan_ds_11h_cfg *)pioctl_req->pbuf;

	if (pioctl_req->action == MLAN_ACT_GET)
		ds_11hcfg->param.usr_local_power_constraint = *plocalpower;
	else
		*plocalpower = ds_11hcfg->param.usr_local_power_constraint;

	LEAVE();
	return MLAN_STATUS_SUCCESS;
}

/**
 *  @brief 11h configuration handler
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS/MLAN_STATUS_PENDING --success,
 * otherwise fail
 */
static mlan_status
wlan_11h_cfg_ioctl(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_status status = MLAN_STATUS_SUCCESS;
	mlan_ds_11h_cfg *ds_11hcfg = MNULL;

	ENTER();

	if (pioctl_req->buf_len < sizeof(mlan_ds_11h_cfg)) {
		PRINTM(MWARN, "MLAN 11H IOCTL length is too short.\n");
		pioctl_req->data_read_written = 0;
		pioctl_req->buf_len_needed = sizeof(mlan_ds_11h_cfg);
		pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
		LEAVE();
		return MLAN_STATUS_RESOURCE;
	}
	ds_11hcfg = (mlan_ds_11h_cfg *)pioctl_req->pbuf;

	switch (ds_11hcfg->sub_command) {
	case MLAN_OID_11H_CHANNEL_CHECK:
		status = wlan_11h_channel_check_req(pmadapter, pioctl_req);
		break;
	case MLAN_OID_11H_LOCAL_POWER_CONSTRAINT:
		status = wlan_11h_ioctl_local_power_constraint(pmadapter,
							       pioctl_req);
		break;
	case MLAN_OID_11H_DFS_TESTING:
		status = wlan_11h_ioctl_dfs_testing(pmadapter, pioctl_req);
		break;
	case MLAN_OID_11H_DFS_W53_CFG:
		status = wlan_11h_ioctl_dfs_w53_cfg(pmadapter, pioctl_req);
		break;
	default:
		pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID;
		status = MLAN_STATUS_FAILURE;
		break;
	}

	LEAVE();
	return status;
}

/**
 *  @brief Set/Get generic IE
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
 */
static mlan_status
wlan_misc_ioctl_gen_ie(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_misc_cfg *misc = MNULL;

	ENTER();

	misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
	switch (misc->param.gen_ie.type) {
	case MLAN_IE_TYPE_GEN_IE:
		if (pioctl_req->action == MLAN_ACT_GET) {
			misc->param.gen_ie.len = pmpriv->wpa_ie_len;
			memcpy_ext(pmadapter, misc->param.gen_ie.ie_data,
				   pmpriv->wpa_ie, misc->param.gen_ie.len,
				   MAX_IE_SIZE);
		} else {
			wlan_set_gen_ie_helper(pmpriv,
					       misc->param.gen_ie.ie_data,
					       (t_u16)misc->param.gen_ie.len);
		}
		break;
	case MLAN_IE_TYPE_ARP_FILTER:
		memset(pmadapter, pmadapter->arp_filter, 0,
		       sizeof(pmadapter->arp_filter));
		if (misc->param.gen_ie.len > ARP_FILTER_MAX_BUF_SIZE) {
			pmadapter->arp_filter_size = 0;
			PRINTM(MERROR, "Invalid ARP Filter Size\n");
			pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
			ret = MLAN_STATUS_FAILURE;
		} else if (misc->param.gen_ie.len <=
			   sizeof(MrvlIEtypesHeader_t)) {
			pmadapter->arp_filter_size = 0;
			PRINTM(MINFO, "Clear ARP filter\n");
		} else {
			memcpy_ext(pmadapter, pmadapter->arp_filter,
				   misc->param.gen_ie.ie_data,
				   misc->param.gen_ie.len,
				   ARP_FILTER_MAX_BUF_SIZE);
			pmadapter->arp_filter_size = misc->param.gen_ie.len;
			HEXDUMP("ArpFilter", pmadapter->arp_filter,
				pmadapter->arp_filter_size);
		}
		break;
	default:
		PRINTM(MERROR, "Invalid IE type\n");
		pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
		ret = MLAN_STATUS_FAILURE;
	}
	pioctl_req->data_read_written =
		sizeof(mlan_ds_misc_gen_ie) + MLAN_SUB_COMMAND_SIZE;
	LEAVE();
	return ret;
}

/**
 *  @brief Perform warm reset
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_PENDING --success, MLAN_STATUS_FAILURE
 */
mlan_status
wlan_misc_ioctl_warm_reset(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_status ret = MLAN_STATUS_SUCCESS;
	pmlan_callbacks pcb = &pmadapter->callbacks;
	pmlan_buffer pmbuf;
	t_s32 i = 0;
	mlan_ds_misc_cfg *misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;

	ENTER();
	mlan_block_rx_process(pmadapter, MTRUE);

	/* Cancel all pending commands and complete ioctls */
	if (misc->param.fw_reload)
		wlan_cancel_all_pending_cmd(pmadapter, MTRUE);

	/** Init all the head nodes and free all the locks here */
	for (i = 0; i < pmadapter->priv_num; i++)
		wlan_free_priv(pmadapter->priv[i]);

	while ((pmbuf =
		(pmlan_buffer)util_dequeue_list(pmadapter->pmoal_handle,
						&pmadapter->rx_data_queue,
						pcb->moal_spin_lock,
						pcb->moal_spin_unlock))) {
		pmadapter->ops.data_complete(pmadapter, pmbuf,
					     MLAN_STATUS_FAILURE);
	}
	pmadapter->rx_pkts_queued = 0;

	/* Initialize adapter structure */
	wlan_init_adapter(pmadapter);
	pmadapter->hw_status = WlanHardwareStatusInitializing;

	/* Initialize private structures */
	for (i = 0; i < pmadapter->priv_num; i++) {
		if (pmadapter->priv[i])
			wlan_init_priv(pmadapter->priv[i]);
	}
	mlan_block_rx_process(pmadapter, MFALSE);

	if (misc->param.fw_reload != MTRUE) {
		/* Restart the firmware */
		ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_FUNC_SHUTDOWN,
				       HostCmd_ACT_GEN_SET, 0, MNULL, MNULL);
		if (ret)
			goto done;
	}

	/* Issue firmware initialize commands for first BSS,
	 * for other interfaces it will be called after getting
	 * the last init command response of previous interface
	 */
	pmpriv = wlan_get_priv(pmadapter, MLAN_BSS_ROLE_ANY);
	if (!pmpriv) {
		ret = MLAN_STATUS_FAILURE;
		LEAVE();
		return ret;
	}
	ret = wlan_adapter_get_hw_spec(pmpriv->adapter);
	if (ret == MLAN_STATUS_FAILURE) {
		LEAVE();
		return ret;
	}
	ret = pmpriv->ops.init_cmd(pmpriv, MTRUE);
	if (ret == MLAN_STATUS_FAILURE) {
		LEAVE();
		return ret;
	}
	if (ret == MLAN_STATUS_PENDING)
		pmadapter->pwarm_reset_ioctl_req = pioctl_req;
done:
	LEAVE();
	return ret;
}

#ifdef SDIO
/**
 *  @brief Reconfigure SDIO multiport aggregation parameters
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
 */
static mlan_status
wlan_misc_ioctl_sdio_mpa_ctrl(pmlan_adapter pmadapter,
			      pmlan_ioctl_req pioctl_req)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_misc_cfg *misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
	mlan_ds_misc_sdio_mpa_ctrl *mpa_ctrl = MNULL;

	ENTER();

	mpa_ctrl = &misc->param.mpa_ctrl;

	if (pioctl_req->action == MLAN_ACT_SET) {
		if (pmpriv->media_connected == MTRUE) {
			PRINTM(MMSG,
			       "SDIO MPA CTRL: not allowed in connected state\n");
			pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID;
			ret = MLAN_STATUS_FAILURE;
			goto exit;
		}

		if (mpa_ctrl->tx_enable > 1) {
			pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
			ret = MLAN_STATUS_FAILURE;
			goto exit;
		}

		if (mpa_ctrl->rx_enable > 1) {
			pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
			ret = MLAN_STATUS_FAILURE;
			goto exit;
		}

		if (mpa_ctrl->tx_max_ports > SDIO_MP_AGGR_DEF_PKT_LIMIT) {
			pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
			ret = MLAN_STATUS_FAILURE;
			goto exit;
		}

		if (mpa_ctrl->rx_max_ports > SDIO_MP_AGGR_DEF_PKT_LIMIT) {
			pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
			ret = MLAN_STATUS_FAILURE;
			goto exit;
		}

		if (mpa_ctrl->tx_buf_size || mpa_ctrl->rx_buf_size) {
			wlan_free_sdio_mpa_buffers(pmadapter);

			if (mpa_ctrl->tx_buf_size > 0)
				pmadapter->pcard_sd->mpa_tx.buf_size =
					mpa_ctrl->tx_buf_size;

			if (mpa_ctrl->rx_buf_size > 0)
				pmadapter->pcard_sd->mpa_rx.buf_size =
					mpa_ctrl->rx_buf_size;

			if (wlan_alloc_sdio_mpa_buffers(pmadapter,
							pmadapter->pcard_sd->
							mpa_tx.buf_size,
							pmadapter->pcard_sd->
							mpa_rx.buf_size) !=
			    MLAN_STATUS_SUCCESS) {
				PRINTM(MERROR,
				       "Failed to allocate sdio mp-a buffers\n");
				pioctl_req->status_code = MLAN_ERROR_NO_MEM;
				ret = MLAN_STATUS_FAILURE;
				goto exit;
			}
		}

		if (mpa_ctrl->tx_max_ports > 0)
			pmadapter->pcard_sd->mpa_tx.pkt_aggr_limit =
				mpa_ctrl->tx_max_ports;
		if (mpa_ctrl->rx_max_ports > 0)
			pmadapter->pcard_sd->mpa_rx.pkt_aggr_limit =
				mpa_ctrl->rx_max_ports;

		pmadapter->pcard_sd->mpa_tx.enabled = (t_u8)mpa_ctrl->tx_enable;
		pmadapter->pcard_sd->mpa_rx.enabled = (t_u8)mpa_ctrl->rx_enable;

	} else {
		mpa_ctrl->tx_enable =
			(t_u16)pmadapter->pcard_sd->mpa_tx.enabled;
		mpa_ctrl->rx_enable =
			(t_u16)pmadapter->pcard_sd->mpa_rx.enabled;
		mpa_ctrl->tx_buf_size =
			(t_u16)pmadapter->pcard_sd->mpa_tx.buf_size;
		mpa_ctrl->rx_buf_size =
			(t_u16)pmadapter->pcard_sd->mpa_rx.buf_size;
		mpa_ctrl->tx_max_ports =
			(t_u16)pmadapter->pcard_sd->mpa_tx.pkt_aggr_limit;
		mpa_ctrl->rx_max_ports =
			(t_u16)pmadapter->pcard_sd->mpa_rx.pkt_aggr_limit;
	}

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

/**
 *  @brief Set/Get system clock configuration
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_PENDING --success, otherwise fail
 */
static mlan_status
wlan_misc_ioctl_sysclock(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_misc_cfg *misc = MNULL;
	mlan_status ret = MLAN_STATUS_SUCCESS;
	t_u16 cmd_action = 0;

	ENTER();

	misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
	if (pioctl_req->action == MLAN_ACT_GET)
		cmd_action = HostCmd_ACT_GEN_GET;
	else
		cmd_action = HostCmd_ACT_GEN_SET;

	/* Send request to firmware */
	ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_ECL_SYSTEM_CLOCK_CONFIG,
			       cmd_action, 0, (t_void *)pioctl_req,
			       (t_void *)&misc->param.sys_clock);

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief Get the associate response
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS --success
 */
static mlan_status
wlan_misc_ioctl_get_assoc_rsp(pmlan_adapter pmadapter,
			      pmlan_ioctl_req pioctl_req)
{
	mlan_ds_misc_cfg *misc = MNULL;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_status ret = MLAN_STATUS_SUCCESS;

	ENTER();

	misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
	if ((pioctl_req->action == MLAN_ACT_GET) && pmpriv->assoc_rsp_size) {
		memcpy_ext(pmadapter, misc->param.assoc_resp.assoc_resp_buf,
			   pmpriv->assoc_rsp_buf, pmpriv->assoc_rsp_size,
			   ASSOC_RSP_BUF_SIZE);
		misc->param.assoc_resp.assoc_resp_len =
			MIN(ASSOC_RSP_BUF_SIZE, pmpriv->assoc_rsp_size);
	}

	LEAVE();
	return ret;
}

/**
 *  @brief Send function softreset command to firmware
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_PENDING --success, otherwise fail
 */
static mlan_status
wlan_misc_ioctl_soft_reset(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_status ret = MLAN_STATUS_SUCCESS;

	ENTER();
	/* Send command to firmware */
	ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_SOFT_RESET,
			       HostCmd_ACT_GEN_SET, 0, (t_void *)pioctl_req,
			       MNULL);

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;
	LEAVE();
	return ret;
}

/**
 *  @brief Get the thermal reading
 *
 *  @param pmadapter    A pointer to mlan_adapter structure
 *  @param pioctl_req   A pointer to ioctl request buffer
 *
 *  @return             MLAN_STATUS_PENDING -- success, otherwise fail
 */
static mlan_status
wlan_misc_ioctl_thermal(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_status ret = MLAN_STATUS_SUCCESS;
	t_u16 cmd_action = 0;

	ENTER();

	if (pioctl_req->buf_len < sizeof(mlan_ds_misc_cfg)) {
		PRINTM(MWARN,
		       "MLAN IOCTL information buffer length is too short.\n");
		pioctl_req->data_read_written = 0;
		pioctl_req->buf_len_needed = sizeof(mlan_ds_misc_cfg);
		pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
		LEAVE();
		return MLAN_STATUS_RESOURCE;
	}

	if (pioctl_req->action == MLAN_ACT_SET) {
		PRINTM(MERROR, "Thermal reading setting is not allowed!\n");
		LEAVE();
		return MLAN_STATUS_FAILURE;
	} else {
		cmd_action = HostCmd_ACT_GEN_GET;
	}

	/* Send command to firmware */
	ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_SNMP_MIB, cmd_action,
			       Thermal_i, (t_void *)pioctl_req, MNULL);

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief Get/Set subscribe event
 *
 *  @param pmadapter    A pointer to mlan_adapter structure
 *  @param pioctl_req   A pointer to ioctl request buffer
 *
 *  @return             MLAN_STATUS_PENDING -- success, otherwise fail
 */
static mlan_status
wlan_misc_ioctl_subscribe_evt(pmlan_adapter pmadapter,
			      pmlan_ioctl_req pioctl_req)
{
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_ds_misc_cfg *misc = MNULL;
	t_u16 cmd_action = 0;

	ENTER();

	misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
	if (pioctl_req->action == MLAN_ACT_SET)
		cmd_action = HostCmd_ACT_GEN_SET;
	else
		cmd_action = HostCmd_ACT_GEN_GET;

	/* Send command to firmware */
	ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_SUBSCRIBE_EVENT,
			       cmd_action, 0, (t_void *)pioctl_req,
			       &misc->param.subscribe_event);

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief Set ARP filter based on IP address
 *
 *  @param pmadapter    A pointer to mlan_adapter structure
 *  @param pioctl_req   A pointer to ioctl request buffer
 *  @param ipv4_addr    ipv4 Address
 *
 *  @return             MLAN_STATUS_PENDING --success, otherwise fail
 */
static mlan_status
wlan_ipaddr_arp_filter(pmlan_adapter pmadapter,
		       pmlan_ioctl_req pioctl_req, t_u32 ipv4_addr)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	pmlan_callbacks pcb = &pmadapter->callbacks;
	t_u8 *buf;
	arpfilter_header *arpfilter = MNULL;
	filter_entry *entry = MNULL;
	t_u32 len;

	ENTER();

	pcb->moal_malloc(pmadapter->pmoal_handle, MRVDRV_SIZE_OF_CMD_BUFFER,
			 MLAN_MEM_DEF, &buf);
	if (!buf) {
		ret = MLAN_STATUS_FAILURE;
		goto done;
	}

	/* Construct the ARP filter TLV */
	arpfilter = (arpfilter_header *)buf;
	arpfilter->type = wlan_cpu_to_le16(TLV_TYPE_ARP_FILTER);

	if (ipv4_addr) {
		arpfilter->len = wlan_cpu_to_le16(sizeof(filter_entry) * 3);
		entry = (filter_entry *)(buf + sizeof(arpfilter_header));
		entry->addr_type = wlan_cpu_to_le16(ADDR_TYPE_BROADCAST);
		entry->eth_type = wlan_cpu_to_le16(ETHER_TYPE_ARP);
		entry->ipv4_addr = wlan_cpu_to_le32(ipv4_addr);
		entry++;
		entry->addr_type = wlan_cpu_to_le16(ADDR_TYPE_UNICAST);
		entry->eth_type = wlan_cpu_to_le16(ETHER_TYPE_ANY);
		entry->ipv4_addr = wlan_cpu_to_le32(IPV4_ADDR_ANY);
		entry++;
		entry->addr_type = wlan_cpu_to_le16(ADDR_TYPE_MULTICAST);
		entry->eth_type = wlan_cpu_to_le16(ETHER_TYPE_ANY);
		entry->ipv4_addr = wlan_cpu_to_le32(IPV4_ADDR_ANY);
	} else
		arpfilter->len = 0;

	/* Update the total length */
	len = sizeof(arpfilter_header) + wlan_le16_to_cpu(arpfilter->len);

	memset(pmadapter, pmadapter->arp_filter, 0,
	       sizeof(pmadapter->arp_filter));
	if (len > ARP_FILTER_MAX_BUF_SIZE) {
		pmadapter->arp_filter_size = 0;
		PRINTM(MERROR, "Invalid ARP Filter Size\n");
		pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
		ret = MLAN_STATUS_FAILURE;
	} else if (len <= sizeof(MrvlIEtypesHeader_t)) {
		pmadapter->arp_filter_size = 0;
		PRINTM(MINFO, "Clear ARP filter\n");
	} else {
		memcpy_ext(pmadapter, pmadapter->arp_filter, buf, len,
			   ARP_FILTER_MAX_BUF_SIZE);
		pmadapter->arp_filter_size = len;
		HEXDUMP("ArpFilter", pmadapter->arp_filter,
			pmadapter->arp_filter_size);
	}

done:
	if (buf)
		pcb->moal_mfree(pmadapter->pmoal_handle, buf);
	LEAVE();
	return ret;
}

/**
 *  @brief MEF configuration
 *
 *  @param pmadapter    A pointer to mlan_adapter structure
 *  @param pioctl_req   A pointer to ioctl request buffer
 *
 *  @return             MLAN_STATUS_PENDING --success, otherwise fail
 */
static mlan_status
wlan_misc_ioctl_mef_cfg(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_misc_mef_cfg *mef_cfg =
		&((mlan_ds_misc_cfg *)pioctl_req->pbuf)->param.mef_cfg;
	pmlan_callbacks pcb = &pmadapter->callbacks;
	HostCmd_DS_GEN *hostcmd_hdr;
	HostCmd_DS_MEF_CFG *mefcmd;
	mlan_ds_misc_cmd *hostcmd = MNULL;
	t_u32 buf_len = 0;
	t_u8 *buf, *filter;
	t_u8 fltr_buf[] = { 0x02, 0x00, 0x2f, 0x00, 0x01, 0x00, 0x00, 0x00,
		0x01, 0x01, 0x00, 0x5e, 0x03, 0x02, 0x00, 0x00,
		0x00, 0x00, 0x01, 0x41, 0x06, 0x00, 0x00, 0x00,
		0x01, 0xff, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00,
		0x01, 0x41, 0x45, 0x01, 0x00, 0x00, 0x00, 0x01,
		0x33, 0x33, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00,
		0x01, 0x41, 0x45
	};

	ENTER();

	/* GET operation */
	if (pioctl_req->action == MLAN_ACT_GET) {
		/* TODO: need to store for get operation */
		goto done;
	}

	ret = pcb->moal_malloc(pmadapter->pmoal_handle,
			       sizeof(mlan_ds_misc_cmd), MLAN_MEM_DEF,
			       (t_u8 **)&hostcmd);

	if (ret != MLAN_STATUS_SUCCESS || hostcmd == MNULL) {
		PRINTM(MERROR, "Failed to allocate hostcmd  buffer\n");
		pioctl_req->status_code = MLAN_ERROR_NO_MEM;
		ret = MLAN_STATUS_FAILURE;
		goto done;
	}

	memset(pmpriv->adapter, hostcmd, 0, sizeof(mlan_ds_misc_cmd));
	buf = hostcmd->cmd;

	/* Prepare hostcmd buffer */
	hostcmd_hdr = (HostCmd_DS_GEN *)(buf);
	hostcmd_hdr->command = wlan_cpu_to_le16(HostCmd_CMD_MEF_CFG);
	mefcmd = (HostCmd_DS_MEF_CFG *)(buf + S_DS_GEN);
	buf_len = S_DS_GEN;

	switch (mef_cfg->sub_id) {
	case MEF_CFG_DISABLE:
		PRINTM(MINFO, "Disable MEF\n");
		mefcmd->criteria = wlan_cpu_to_le32(0);
		mefcmd->nentries = wlan_cpu_to_le16(0);
		buf_len += sizeof(HostCmd_DS_MEF_CFG);
		break;
	case MEF_CFG_RX_FILTER_ENABLE:
		PRINTM(MINFO, "Enable Rx filter\n");
		mefcmd->criteria = wlan_cpu_to_le32((MBIT(3) | MBIT(0)));
		mefcmd->nentries = wlan_cpu_to_le16(1);
		buf_len += sizeof(HostCmd_DS_MEF_CFG);
		filter = buf + buf_len;
		memcpy_ext(pmpriv->adapter, filter, fltr_buf, sizeof(fltr_buf),
			   MRVDRV_SIZE_OF_CMD_BUFFER - buf_len);
		buf_len += sizeof(fltr_buf);
		break;
	case MEF_CFG_AUTO_ARP_RESP:
		PRINTM(MINFO, "Enable auto ARP response\n");
		/* TODO */
		break;
	case MEF_CFG_HOSTCMD:
		PRINTM(MINFO, "MEF hostcmd from MOAL\n");
		filter = buf + buf_len;
		memcpy_ext(pmpriv->adapter, filter, mef_cfg->param.cmd_buf.cmd,
			   mef_cfg->param.cmd_buf.len,
			   MRVDRV_SIZE_OF_CMD_BUFFER - buf_len);
		buf_len += mef_cfg->param.cmd_buf.len;
		break;
	default:
		PRINTM(MERROR, "Invalid sub ID parameter\n");
		pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
		ret = MLAN_STATUS_FAILURE;
		goto done;
		break;
	}
	hostcmd_hdr->size = wlan_cpu_to_le16(buf_len);
	hostcmd->len = buf_len;

	/* Send command to firmware */
	ret = wlan_prepare_cmd(pmpriv, 0, 0, 0, (t_void *)pioctl_req,
			       (t_void *)hostcmd);
	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

done:
	if (hostcmd)
		pcb->moal_mfree(pmadapter->pmoal_handle, (t_u8 *)hostcmd);

	LEAVE();
	return ret;
}

/**
 *  @brief ipaddr configuration
 *
 *  @param pmadapter    A pointer to mlan_adapter structure
 *  @param pioctl_req   A pointer to ioctl request buffer
 *
 *  @return             MLAN_STATUS_PENDING --success, otherwise fail
 */
static mlan_status
wlan_misc_ioctl_ipaddr_cfg(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_misc_cfg *misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
	mlan_status ret = MLAN_STATUS_SUCCESS;
	t_u32 ipv4_addr[MAX_IPADDR] = { 0 };
	int i = 0;

	ENTER();

	/* GET operation */
	if (pioctl_req->action == MLAN_ACT_GET) {
		memcpy_ext(pmadapter, misc->param.ipaddr_cfg.ip_addr,
			   pmpriv->ip_addr, IPADDR_LEN, IPADDR_LEN);
		misc->param.ipaddr_cfg.op_code = pmpriv->op_code;
		goto done;
	}
	/* only one IP is supported in current firmware */
	for (i = 0; i < (int)misc->param.ipaddr_cfg.ip_addr_num; i++) {
		memcpy_ext(pmadapter, &ipv4_addr[i],
			   misc->param.ipaddr_cfg.ip_addr[i], sizeof(t_u32),
			   sizeof(t_u32));
	}

	if (misc->param.ipaddr_cfg.op_code != MLAN_IPADDR_OP_IP_REMOVE &&
	    !misc->param.ipaddr_cfg.ip_addr_num) {
		PRINTM(MERROR, "Invalid IPv4 address\n");
		pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
		ret = MLAN_STATUS_FAILURE;
		goto done;
	}
	if (misc->param.ipaddr_cfg.op_code & MLAN_IPADDR_OP_ARP_FILTER)
		ret = wlan_ipaddr_arp_filter(pmadapter, pioctl_req,
					     ipv4_addr[0]);
	else if (pmpriv->op_code & MLAN_IPADDR_OP_ARP_FILTER)
		ret = wlan_ipaddr_arp_filter(pmadapter, pioctl_req, 0);
	if (ret == MLAN_STATUS_FAILURE)
		goto done;

	/* Save the values in MLAN */
	if (pioctl_req->action == MLAN_ACT_SET) {
		pmpriv->op_code = misc->param.ipaddr_cfg.op_code;
		memcpy_ext(pmadapter, pmpriv->ip_addr,
			   misc->param.ipaddr_cfg.ip_addr, IPADDR_LEN,
			   IPADDR_LEN);
	}

done:
	LEAVE();
	return ret;
}

/**
 *  @brief CFP code configuration
 *
 *  @param pmadapter    A pointer to mlan_adapter structure
 *  @param pioctl_req   A pointer to ioctl request buffer
 *
 *  @return             MLAN_STATUS_PENDING --success, otherwise fail
 */
static mlan_status
wlan_misc_ioctl_cfp_code_cfg(pmlan_adapter pmadapter,
			     pmlan_ioctl_req pioctl_req)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_misc_cfg *misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
	mlan_ds_misc_cfp_code *cfp_code = MNULL;
	t_u32 region_bg = 0;
	t_u32 region_a = 0;
	int i;

	ENTER();

	cfp_code = &misc->param.cfp_code;
	if (pioctl_req->action == MLAN_ACT_SET) {
		if (pmadapter->otp_region && pmadapter->otp_region->force_reg) {
			PRINTM(MERROR,
			       "ForceRegionRule is set in the on-chip OTP"
			       "memory\n");
			ret = MLAN_STATUS_FAILURE;
			goto done;
		}
		/* Save the values in MLAN */
		if (!cfp_code->cfp_code_bg)
			cfp_code->cfp_code_bg = pmadapter->cfp_code_bg;
		for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) {
			/* Use the region code to search for the index */
			if (cfp_code->cfp_code_bg == region_code_index[i]) {
				region_bg = cfp_code->cfp_code_bg;
				break;
			}
		}
		if (!cfp_code->cfp_code_a)
			cfp_code->cfp_code_a = pmadapter->cfp_code_a;
		for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) {
			/* Use the region code to search for the index */
			if (cfp_code->cfp_code_a == region_code_index[i]) {
				region_a = cfp_code->cfp_code_a;
				break;
			}
		}
		if (!region_a) {
			for (i = 0; i < MRVDRV_MAX_CFP_CODE_A; i++) {
				/* Use the CFP code to search for the index */
				if (cfp_code->cfp_code_a == cfp_code_index_a[i])
					break;
			}
			if (i >= MRVDRV_MAX_CFP_CODE_A) {
				PRINTM(MERROR,
				       "CFP Code not identified for A\n");
				pioctl_req->status_code =
					MLAN_ERROR_INVALID_PARAMETER;
				ret = MLAN_STATUS_FAILURE;
				goto done;
			}
		}
		pmadapter->cfp_code_bg = (t_u8)cfp_code->cfp_code_bg;
		pmadapter->cfp_code_a = (t_u8)cfp_code->cfp_code_a;
		if (region_bg && region_a && (region_bg == region_a))
			pmadapter->region_code = pmadapter->cfp_code_a;
		else
			pmadapter->region_code = 0;
		if (wlan_set_regiontable(pmpriv, (t_u8)pmadapter->region_code,
					 pmadapter->config_bands |
					 pmadapter->adhoc_start_band)) {
			pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
			ret = MLAN_STATUS_FAILURE;
			goto done;
		}
	} else {
		/* GET operation */
		cfp_code->cfp_code_bg = pmadapter->cfp_code_bg;
		cfp_code->cfp_code_a = pmadapter->cfp_code_a;
	}

done:
	LEAVE();
	return ret;
}

/**
 *  @brief This function sets up country code and downloads CMD to FW
 *
 *  @param pmadapter    A pointer to mlan_adapter structure
 *  @param pioctl_req   Pointer to the IOCTL request buffer
 *
 *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
static mlan_status
wlan_misc_ioctl_country_code(pmlan_adapter pmadapter,
			     mlan_ioctl_req *pioctl_req)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_misc_country_code *country_code = MNULL;
	mlan_ds_misc_cfg *cfg_misc = MNULL;
	t_u8 cfp_bg = 0, cfp_a = 0;

	ENTER();

	cfg_misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
	country_code = &cfg_misc->param.country_code;

	if (pioctl_req->action == MLAN_ACT_SET) {
		if (pmadapter->otp_region && pmadapter->otp_region->force_reg) {
			PRINTM(MERROR,
			       "ForceRegionRule is set in the on-chip OTP"
			       "memory\n");
			ret = MLAN_STATUS_FAILURE;
			goto done;
		}
		/* Update region code and table based on country code */
		if (wlan_misc_country_2_cfp_table_code
		    (pmadapter, country_code->country_code, &cfp_bg, &cfp_a)) {
			PRINTM(MERROR, "Country code not found!\n");
			pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
			ret = MLAN_STATUS_FAILURE;
			goto done;
		}
		pmadapter->cfp_code_bg = cfp_bg;
		pmadapter->cfp_code_a = cfp_a;
		if (cfp_a)
			pmadapter->region_code = cfp_a;
		else if (cfp_bg)
			pmadapter->region_code = cfp_bg;
		else
			pmadapter->region_code = 0;
		if (wlan_set_regiontable(pmpriv, pmadapter->region_code,
					 pmadapter->config_bands |
					 pmadapter->adhoc_start_band)) {
			pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
			ret = MLAN_STATUS_FAILURE;
			goto done;
		}
		memcpy_ext(pmadapter, pmadapter->country_code,
			   country_code->country_code, COUNTRY_CODE_LEN,
			   COUNTRY_CODE_LEN);
	} else {
		/* GET operation */
		memcpy_ext(pmadapter, country_code->country_code,
			   pmadapter->country_code, COUNTRY_CODE_LEN,
			   COUNTRY_CODE_LEN);
	}

done:
	LEAVE();
	return ret;
}

/**
 *  @brief Configure MFPC and MFPR for management frame protection
 *
 *  @param pmadapter    A pointer to mlan_adapter structure
 *  @param pioctl_req   Pointer to the IOCTL request buffer
 *
 *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
static mlan_status
wlan_misc_pmfcfg(pmlan_adapter pmadapter, mlan_ioctl_req *pioctl_req)
{
	pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_ds_misc_cfg *cfg_misc = MNULL;
	mlan_ds_misc_pmfcfg *pmfcfg;

	cfg_misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
	pmfcfg = &cfg_misc->param.pmfcfg;

	if (pioctl_req->action == MLAN_ACT_SET) {
		pmpriv->pmfcfg.mfpc = pmfcfg->mfpc;
		pmpriv->pmfcfg.mfpr = pmfcfg->mfpr;
	} else {
		/* GET operation */
		pmfcfg->mfpc = pmpriv->pmfcfg.mfpc;
		pmfcfg->mfpr = pmpriv->pmfcfg.mfpr;
	}

	LEAVE();
	return ret;
}

/**
 *  @brief HW ARB Cfg
 *
 *  @param pmadapter   A pointer to mlan_adapter structure
 *  @param pioctl_req  A pointer to ioctl request buffer
 *
 *  @return        MLAN_STATUS_PENDING --success, otherwise fail
 */
mlan_status
wlan_misc_ioctl_arb_cfg(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_misc_cfg *pmisc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
	mlan_status ret = MLAN_STATUS_SUCCESS;
	t_u16 cmd_action = 0;

	ENTER();

	if (pioctl_req->action == MLAN_ACT_SET)
		cmd_action = HostCmd_ACT_GEN_SET;
	else
		cmd_action = HostCmd_ACT_GEN_GET;
	ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_ARB_CONFIG, cmd_action, 0,
			       (t_void *)pioctl_req, &(pmisc->param.arb_cfg));
	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief Save tp accounting command configurations.
 *
 *  @param pmadapter   A pointer to mlan_adapter structure
 *  @param pioctl_req  A pointer to ioctl request buffer
 *
 *  @return        MLAN_STATUS_PENDING --success, otherwise fail
 */
mlan_status
wlan_misc_ioctl_tp_state(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_ds_misc_cfg *pmisc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
	mlan_status ret = MLAN_STATUS_SUCCESS;

	ENTER();

	pmadapter->tp_state_on = pmisc->param.tp_state.on;
	pmadapter->tp_state_drop_point = pmisc->param.tp_state.drop_point;

	LEAVE();
	return ret;
}

static mlan_status
wlan_misc_ioctl_get_sensor_temp(pmlan_adapter pmadapter,
				pmlan_ioctl_req pioctl_req)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	t_u16 cmd_action = 0;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];

	ENTER();

	if (pioctl_req->action == MLAN_ACT_GET)
		cmd_action = HostCmd_ACT_GEN_GET;
	else {
		PRINTM(MERROR, " sensor temp only support get operation \n");
		LEAVE();
		return MLAN_STATUS_FAILURE;
	}

	/* Send request to firmware */
	ret = wlan_prepare_cmd(pmpriv, HostCmd_DS_GET_SENSOR_TEMP, cmd_action,
			       0, (t_void *)pioctl_req, MNULL);

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief IPv6 Router Advertisement offload configuration
 *
 *  @param pmadapter    A pointer to mlan_adapter structure
 *  @param pioctl_req   Pointer to the IOCTL request buffer
 *
 *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
mlan_status
wlan_misc_ioctl_ipv6_ra_offload(pmlan_adapter pmadapter,
				mlan_ioctl_req *pioctl_req)
{
	pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_misc_cfg *misc = MNULL;
	t_u16 cmd_action = 0;
	mlan_status ret = MLAN_STATUS_SUCCESS;

	ENTER();

	misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
	if (pioctl_req->action == MLAN_ACT_SET)
		cmd_action = HostCmd_ACT_GEN_SET;
	else if (pioctl_req->action == MLAN_ACT_GET)
		cmd_action = HostCmd_ACT_GEN_GET;

	ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_IPV6_RA_OFFLOAD_CFG,
			       cmd_action, 0, (t_void *)pioctl_req,
			       &misc->param.ipv6_ra_offload);
	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief Gtk Rekey Offload
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
 */
static mlan_status
wlan_misc_ioctl_gtk_rekey_offload(pmlan_adapter pmadapter,
				  pmlan_ioctl_req pioctl_req)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_ds_misc_cfg *misc_cfg = MNULL;
	t_u16 cmd_action = 0;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];

	ENTER();
	misc_cfg = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
	if (pioctl_req->action == MLAN_ACT_SET)
		cmd_action = HostCmd_ACT_GEN_SET;
	else if (pioctl_req->action == MLAN_ACT_CLEAR)
		cmd_action = HostCmd_ACT_GEN_REMOVE;
	else
		cmd_action = HostCmd_ACT_GEN_GET;

	if (!pmpriv->wpa_is_gtk_set) {
		/* Store the gtk rekey data if it has already set gtk */
		memcpy_ext(pmadapter, &pmpriv->gtk_rekey,
			   &misc_cfg->param.gtk_rekey,
			   sizeof(mlan_ds_misc_gtk_rekey_data),
			   sizeof(mlan_ds_misc_gtk_rekey_data));
		LEAVE();
		return ret;
	}
	/* Send request to firmware if it hasn't set gtk yet */
	ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_GTK_REKEY_OFFLOAD_CFG,
			       cmd_action, 0, (t_void *)pioctl_req,
			       &misc_cfg->param.gtk_rekey);

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief cloud keep alive
 *
 *  @param pmadapter    A pointer to mlan_adapter structure
 *  @param pioctl_req   Pointer to the IOCTL request buffer
 *
 *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
static mlan_status
wlan_misc_cloud_keep_alive(pmlan_adapter pmadapter, mlan_ioctl_req *pioctl_req)
{
	pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_misc_cfg *misc = MNULL;
	t_u16 cmd_action = 0;
	mlan_status ret = MLAN_STATUS_SUCCESS;

	ENTER();

	misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;

	if (pioctl_req->action == MLAN_ACT_SET)
		cmd_action = HostCmd_ACT_GEN_SET;
	else if (pioctl_req->action == MLAN_ACT_GET) {
		cmd_action = HostCmd_ACT_GEN_GET;
	} else if (pioctl_req->action == MLAN_ACT_RESET) {
		cmd_action = HostCmd_ACT_GEN_RESET;
	} else {
		cmd_action = HostCmd_ACT_GEN_REMOVE;
	}

	/* Send request to firmware */
	ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_AUTO_TX, cmd_action,
			       OID_CLOUD_KEEP_ALIVE, (t_void *)pioctl_req,
			       &misc->param.keep_alive);

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief Miscellaneous configuration handler
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS/MLAN_STATUS_PENDING --success,
 * otherwise fail
 */
static mlan_status
wlan_misc_cfg_ioctl(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_status status = MLAN_STATUS_SUCCESS;
	mlan_ds_misc_cfg *misc = MNULL;

	ENTER();

	if ((pioctl_req == MNULL) || (pioctl_req->pbuf == MNULL)) {
		PRINTM(MERROR, "Request buffer not found!\n");
		LEAVE();
		return MLAN_STATUS_FAILURE;
	}
	if (pioctl_req->buf_len < sizeof(mlan_ds_misc_cfg)) {
		PRINTM(MWARN, "MLAN bss IOCTL length is too short.\n");
		pioctl_req->data_read_written = 0;
		pioctl_req->buf_len_needed = sizeof(mlan_ds_misc_cfg);
		pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
		LEAVE();
		return MLAN_STATUS_RESOURCE;
	}
	misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
	switch (misc->sub_command) {
	case MLAN_OID_MISC_GEN_IE:
		status = wlan_misc_ioctl_gen_ie(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_REGION:
		status = wlan_misc_ioctl_region(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_WARM_RESET:
		PRINTM(MCMND, "Request WARM RESET\n");
		util_enqueue_list_tail(pmadapter->pmoal_handle,
				       &pmadapter->ioctl_pending_q,
				       (pmlan_linked_list)pioctl_req,
				       pmadapter->callbacks.moal_spin_lock,
				       pmadapter->callbacks.moal_spin_unlock);
		pmadapter->pending_ioctl = MTRUE;
		status = MLAN_STATUS_PENDING;
		break;
#ifdef SDIO
	case MLAN_OID_MISC_SDIO_MPA_CTRL:
		status = wlan_misc_ioctl_sdio_mpa_ctrl(pmadapter, pioctl_req);
		break;
#endif
	case MLAN_OID_MISC_HOST_CMD:
		status = wlan_misc_ioctl_host_cmd(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_SYS_CLOCK:
		status = wlan_misc_ioctl_sysclock(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_WWS:
		status = wlan_misc_ioctl_wws_cfg(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_ASSOC_RSP:
		status = wlan_misc_ioctl_get_assoc_rsp(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_INIT_SHUTDOWN:
		status = wlan_misc_ioctl_init_shutdown(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_SOFT_RESET:
		status = wlan_misc_ioctl_soft_reset(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_CUSTOM_IE:
		status = wlan_misc_ioctl_custom_ie_list(pmadapter, pioctl_req,
							MTRUE);
		break;
	case MLAN_OID_MISC_TDLS_CONFIG:
		status = wlan_misc_ioctl_tdls_config(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_TDLS_OPER:
		status = wlan_misc_ioctl_tdls_oper(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_GET_TDLS_IES:
		status = wlan_misc_ioctl_tdls_get_ies(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_TDLS_CS_CHANNEL:
		status = wlan_misc_ioctl_tdls_cs_channel(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_TDLS_IDLE_TIME:
		status = wlan_misc_ioctl_tdls_idle_time(pmadapter, pioctl_req);
		break;

	case MLAN_OID_MISC_MAC_CONTROL:
		status = wlan_misc_ioctl_mac_control(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_MEF_CFG:
		status = wlan_misc_ioctl_mef_cfg(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_RX_MGMT_IND:
		status = wlan_reg_rx_mgmt_ind(pmadapter, pioctl_req);
		break;
#ifdef DEBUG_LEVEL1
	case MLAN_OID_MISC_DRVDBG:
		status = wlan_set_drvdbg(pmadapter, pioctl_req);
		break;
#endif
	case MLAN_OID_MISC_IP_ADDR:
		status = wlan_misc_ioctl_ipaddr_cfg(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_CFP_CODE:
		status = wlan_misc_ioctl_cfp_code_cfg(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_COUNTRY_CODE:
		status = wlan_misc_ioctl_country_code(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_THERMAL:
		status = wlan_misc_ioctl_thermal(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_SUBSCRIBE_EVENT:
		status = wlan_misc_ioctl_subscribe_evt(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_HOTSPOT_CFG:
		status = wlan_misc_hotspot_cfg(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_OTP_USER_DATA:
		status = wlan_misc_otp_user_data(pmadapter, pioctl_req);
		break;
#ifdef USB
	case MLAN_OID_MISC_USB_AGGR_CTRL:
		status = wlan_misc_ioctl_usb_aggr_ctrl(pmadapter, pioctl_req);
		break;
#endif
	case MLAN_OID_MISC_AGGR_CTRL:
		status = wlan_misc_ioctl_aggr_ctrl(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_TXCONTROL:
		status = wlan_misc_ioctl_txcontrol(pmadapter, pioctl_req);
		break;
#ifdef STA_SUPPORT
	case MLAN_OID_MISC_EXT_CAP_CFG:
		status = wlan_misc_ext_capa_cfg(pmadapter, pioctl_req);
		break;
#endif
	case MLAN_OID_MISC_PMFCFG:
		status = wlan_misc_pmfcfg(pmadapter, pioctl_req);
		break;
#ifdef RX_PACKET_COALESCE
	case MLAN_OID_MISC_RX_PACKET_COALESCE:
		status = wlan_misc_ioctl_rx_pkt_coalesce_config(pmadapter,
								pioctl_req);
		break;
#endif
	case MLAN_OID_MISC_LOW_PWR_MODE:
		status = wlan_misc_ioctl_low_pwr_mode(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_PMIC_CFG:
		status = wlan_misc_ioctl_pmic_configure(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_CWMODE_CTRL:
		status = wlan_misc_ioctl_cwmode_ctrl(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_MEF_FLT_CFG:
		status = wlan_misc_ioctl_mef_flt_cfg(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_DFS_REAPTER_MODE:
		status = wlan_misc_ioctl_dfs_repeater_cfg(pmadapter,
							  pioctl_req);
		break;
	case MLAN_OID_MISC_COALESCE_CFG:
		status = wlan_misc_ioctl_coalesce_cfg(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_GET_SENSOR_TEMP:
		status = wlan_misc_ioctl_get_sensor_temp(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_OPER_CLASS:
		status = wlan_misc_ioctl_oper_class(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_OPER_CLASS_CHECK:
		status = wlan_misc_ioctl_operclass_validation(pmadapter,
							      pioctl_req);
		break;
	case MLAN_OID_MISC_IPV6_RA_OFFLOAD:
		status = wlan_misc_ioctl_ipv6_ra_offload(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_GTK_REKEY_OFFLOAD:
		status = wlan_misc_ioctl_gtk_rekey_offload(pmadapter,
							   pioctl_req);
		break;
	case MLAN_OID_MISC_IND_RST_CFG:
		status = wlan_misc_ioctl_ind_rst_cfg(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_GET_TSF:
		status = wlan_misc_ioctl_get_tsf(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_GET_CHAN_REGION_CFG:
		status = wlan_misc_chan_reg_cfg(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_CLOUD_KEEP_ALIVE:
		status = wlan_misc_cloud_keep_alive(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_DYN_BW:
		status = wlan_misc_ioctl_dyn_bw(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_FW_DUMP_EVENT:
		status = wlan_misc_ioctl_fw_dump_event(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_PER_PKT_CFG:
		status = wlan_misc_per_pkt_cfg(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_ROBUSTCOEX:
		status = wlan_misc_robustcoex(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_DMCS_CONFIG:
		status = wlan_misc_dmcs_config(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_GET_TX_RX_HISTOGRAM:
		status = wlan_get_tx_rx_histogram(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_BOOT_SLEEP:
		status = wlan_misc_bootsleep(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_CFP_INFO:
		status = wlan_get_cfpinfo(pmadapter, pioctl_req);
		break;
#if defined(PCIE)
	case MLAN_OID_MISC_SSU:
		if (pmadapter->ssu_buf)
			status = MLAN_STATUS_FAILURE;
		else
			status = wlan_misc_ssu(pmadapter, pioctl_req);
		break;
#endif
	case MLAN_OID_MISC_HAL_PHY_CFG:
		status = wlan_misc_hal_phy_cfg(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_GPIO_TSF_LATCH:
		status = wlan_misc_gpio_tsf_latch_config(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_GET_TSF_INFO:
		status = wlan_misc_get_tsf_info(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_RX_ABORT_CFG:
		status = wlan_misc_ioctl_rxabortcfg(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_RX_ABORT_CFG_EXT:
		status = wlan_misc_ioctl_rxabortcfg_ext(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_TX_AMPDU_PROT_MODE:
		status = wlan_misc_ioctl_tx_ampdu_prot_mode(pmadapter,
							    pioctl_req);
		break;
	case MLAN_OID_MISC_DOT11MC_UNASSOC_FTM_CFG:
		status = wlan_misc_ioctl_dot11mc_unassoc_ftm_cfg(pmadapter,
								 pioctl_req);
		break;
	case MLAN_OID_MISC_RATE_ADAPT_CFG:
		status = wlan_misc_ioctl_rate_adapt_cfg(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_CCK_DESENSE_CFG:
		status = wlan_misc_ioctl_cck_desense_cfg(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_GET_REGIONPWR_CFG:
		status = wlan_get_rgchnpwr_cfg(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_GET_CHAN_TRPC_CFG:
		status = wlan_get_chan_trpc_cfg(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_RF_TEST_GENERIC:
	case MLAN_OID_MISC_RF_TEST_TX_CONT:
	case MLAN_OID_MISC_RF_TEST_TX_FRAME:
	case MLAN_OID_MISC_RF_TEST_HE_POWER:
		status = wlan_misc_ioctl_rf_test_cfg(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_ARB_CONFIG:
		status = wlan_misc_ioctl_arb_cfg(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_RANGE_EXT:
		status = wlan_misc_ioctl_range_ext(pmadapter, pioctl_req);
		break;
	case MLAN_OID_MISC_TP_STATE:
		status = wlan_misc_ioctl_tp_state(pmadapter, pioctl_req);
		break;
	default:
		if (pioctl_req)
			pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID;
		status = MLAN_STATUS_FAILURE;
		break;
	}
	LEAVE();
	return status;
}

/**
 *  @brief Set/Get scan configuration parameter
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *  @param action	    Set/Get
 *
 *  @return		MLAN_STATUS_SUCCESS --success
 */
static mlan_status
wlan_set_get_scan_cfg(pmlan_adapter pmadapter,
		      pmlan_ioctl_req pioctl_req, t_u32 action)
{
	mlan_ds_scan *scan = MNULL;

	ENTER();

	scan = (mlan_ds_scan *)pioctl_req->pbuf;
	if (action == MLAN_ACT_SET) {
		if (scan->param.scan_cfg.scan_type)
			pmadapter->scan_type =
				(t_u8)scan->param.scan_cfg.scan_type;
		if (scan->param.scan_cfg.scan_mode)
			pmadapter->scan_mode = scan->param.scan_cfg.scan_mode;
		if (scan->param.scan_cfg.scan_probe)
			pmadapter->scan_probes =
				(t_u16)scan->param.scan_cfg.scan_probe;
		if (scan->param.scan_cfg.scan_time.specific_scan_time)
			pmadapter->specific_scan_time =
				(t_u16)scan->param.scan_cfg.scan_time.
				specific_scan_time;
		if (scan->param.scan_cfg.scan_time.active_scan_time)
			pmadapter->active_scan_time =
				(t_u16)scan->param.scan_cfg.scan_time.
				active_scan_time;
		if (scan->param.scan_cfg.scan_time.passive_scan_time)
			pmadapter->passive_scan_time =
				(t_u16)scan->param.scan_cfg.scan_time.
				passive_scan_time;
		if (scan->param.scan_cfg.passive_to_active_scan)
			pmadapter->passive_to_active_scan =
				scan->param.scan_cfg.passive_to_active_scan;
		if (scan->param.scan_cfg.ext_scan)
			pmadapter->ext_scan = scan->param.scan_cfg.ext_scan - 1;
		pmadapter->scan_chan_gap = scan->param.scan_cfg.scan_chan_gap;
	}
	scan->param.scan_cfg.scan_type = (t_u32)pmadapter->scan_type;
	scan->param.scan_cfg.scan_mode = pmadapter->scan_mode;
	scan->param.scan_cfg.scan_probe = (t_u32)pmadapter->scan_probes;
	scan->param.scan_cfg.scan_time.specific_scan_time =
		(t_u32)pmadapter->specific_scan_time;
	scan->param.scan_cfg.scan_time.active_scan_time =
		(t_u32)pmadapter->active_scan_time;
	scan->param.scan_cfg.scan_time.passive_scan_time =
		(t_u32)pmadapter->passive_scan_time;
	scan->param.scan_cfg.passive_to_active_scan =
		pmadapter->passive_to_active_scan;
	scan->param.scan_cfg.ext_scan = pmadapter->ext_scan + 1;
	scan->param.scan_cfg.scan_chan_gap = pmadapter->scan_chan_gap;
	pioctl_req->data_read_written = sizeof(t_u32) + MLAN_SUB_COMMAND_SIZE;

	LEAVE();
	return MLAN_STATUS_SUCCESS;
}

/**
 *  @brief Set/Get scan
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS/MLAN_STATUS_PENDING --success,
 * otherwise fail
 */
static mlan_status
wlan_scan_ioctl(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_status status = MLAN_STATUS_SUCCESS;
	mlan_ds_scan *pscan;

	ENTER();

	pscan = (mlan_ds_scan *)pioctl_req->pbuf;
	if (pscan->sub_command == MLAN_OID_SCAN_CONFIG
	    || pscan->sub_command == MLAN_OID_SCAN_BGSCAN_CONFIG)
		goto start_config;
	if (pmadapter->scan_processing && pioctl_req->action == MLAN_ACT_SET &&
	    pscan->sub_command != MLAN_OID_SCAN_CANCEL) {
		PRINTM(MINFO, "Scan already in process...\n");
		LEAVE();
		return status;
	}

	if (pmadapter->scan_block && pioctl_req->action == MLAN_ACT_SET) {
		PRINTM(MERROR, "Scan is blocked during association...\n");
		LEAVE();
		return MLAN_STATUS_FAILURE;
	}
start_config:
	/* Set scan */
	if (pioctl_req->action == MLAN_ACT_SET) {
		switch (pscan->sub_command) {
		case MLAN_OID_SCAN_NORMAL:
			status = wlan_scan_networks(pmpriv, pioctl_req, MNULL);
			break;
		case MLAN_OID_SCAN_SPECIFIC_SSID:
			status = wlan_scan_specific_ssid(pmpriv, pioctl_req,
							 &pscan->param.scan_req.
							 scan_ssid);
			break;
		case MLAN_OID_SCAN_USER_CONFIG:
			status = wlan_scan_networks(pmpriv, pioctl_req,
						    (wlan_user_scan_cfg *)
						    pscan->param.user_scan.
						    scan_cfg_buf);
			break;
		case MLAN_OID_SCAN_CONFIG:
			status = wlan_set_get_scan_cfg(pmadapter, pioctl_req,
						       MLAN_ACT_SET);
			break;
		case MLAN_OID_SCAN_CANCEL:
			status = wlan_cancel_pending_scan_cmd(pmadapter,
							      pioctl_req);
			break;
		case MLAN_OID_SCAN_TABLE_FLUSH:
			status = wlan_flush_scan_table(pmadapter);
			break;
		case MLAN_OID_SCAN_BGSCAN_CONFIG:
			/* Send request to firmware */
			status = wlan_prepare_cmd(pmpriv,
						  HostCmd_CMD_802_11_BG_SCAN_CONFIG,
						  HostCmd_ACT_GEN_SET, 0,
						  (t_void *)pioctl_req,
						  pscan->param.user_scan.
						  scan_cfg_buf);
			break;
		default:
			pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID;
			status = MLAN_STATUS_FAILURE;
			break;
		}

		if ((status == MLAN_STATUS_SUCCESS)
		    && (pscan->sub_command != MLAN_OID_SCAN_TABLE_FLUSH)
		    && (pscan->sub_command != MLAN_OID_SCAN_CANCEL)
		    && (pscan->sub_command != MLAN_OID_SCAN_CONFIG)) {
			PRINTM(MINFO,
			       "wlan_scan_ioctl: return MLAN_STATUS_PENDING\n");
			status = MLAN_STATUS_PENDING;
		}
	}
	/* Get scan */
	else {
		if (pscan->sub_command == MLAN_OID_SCAN_CONFIG) {
			status = wlan_set_get_scan_cfg(pmadapter, pioctl_req,
						       MLAN_ACT_GET);
		} else if (pscan->sub_command == MLAN_OID_SCAN_GET_CURRENT_BSS) {
			pscan->param.scan_resp.num_in_scan_table =
				pmadapter->num_in_scan_table;
			pscan->param.scan_resp.pscan_table =
				(t_u8 *)&pmpriv->curr_bss_params.bss_descriptor;
			pioctl_req->data_read_written =
				sizeof(mlan_scan_resp) + MLAN_SUB_COMMAND_SIZE;
		} else {
			if (pmadapter->bgscan_reported) {
				pmadapter->bgscan_reported = MFALSE;
				/* Clear the previous scan result */
				memset(pmadapter, pmadapter->pscan_table, 0x00,
				       sizeof(BSSDescriptor_t) *
				       MRVDRV_MAX_BSSID_LIST);
				pmadapter->num_in_scan_table = 0;
				pmadapter->pbcn_buf_end = pmadapter->bcn_buf;
				status = wlan_prepare_cmd(pmpriv,
							  HostCmd_CMD_802_11_BG_SCAN_QUERY,
							  HostCmd_ACT_GEN_GET,
							  0,
							  (t_void *)pioctl_req,
							  MNULL);
				if (status == MLAN_STATUS_SUCCESS) {
					PRINTM(MINFO,
					       "wlan_scan_ioctl: return MLAN_STATUS_PENDING\n");
					status = MLAN_STATUS_PENDING;
				}
			} else {
				pscan->param.scan_resp.pscan_table =
					(t_u8 *)pmadapter->pscan_table;
				pscan->param.scan_resp.num_in_scan_table =
					pmadapter->num_in_scan_table;
				pscan->param.scan_resp.age_in_secs =
					pmadapter->age_in_secs;
				pioctl_req->data_read_written =
					sizeof(mlan_scan_resp) +
					MLAN_SUB_COMMAND_SIZE;
				pscan->param.scan_resp.pchan_stats =
					(t_u8 *)pmadapter->pchan_stats;
				pscan->param.scan_resp.num_in_chan_stats =
					pmadapter->num_in_chan_stats;
			}
		}
	}

	LEAVE();
	return status;
}

/********************************************************
			Global Functions
********************************************************/

/**
 *  @brief Set ewpa mode
 *
 *  @param priv                 A pointer to mlan_private structure
 *  @param psec_pp              A pointer to mlan_ds_passphrase structure
 *
 *  @return                     MLAN_STATUS_SUCCESS
 */
mlan_status
wlan_set_ewpa_mode(mlan_private *priv, mlan_ds_passphrase *psec_pp)
{
	ENTER();

	if ((psec_pp->psk_type == MLAN_PSK_PASSPHRASE &&
	     psec_pp->psk.passphrase.passphrase_len > 0) ||
	    (psec_pp->psk_type == MLAN_PSK_PMK))
		priv->sec_info.ewpa_enabled = MTRUE;
	else
		priv->sec_info.ewpa_enabled = MFALSE;

	PRINTM(MINFO, "Set ewpa mode = %d\n", priv->sec_info.ewpa_enabled);

	LEAVE();
	return MLAN_STATUS_SUCCESS;
}

/**
 *  @brief Search for a BSS
 *
 *  @param pmpriv           A pointer to mlan_private structure
 *  @param pioctl_req       A pointer to ioctl request buffer
 *
 *  @return		            MLAN_STATUS_SUCCESS --success, otherwise
 * fail
 */
mlan_status
wlan_find_bss(mlan_private *pmpriv, pmlan_ioctl_req pioctl_req)
{
	mlan_adapter *pmadapter = pmpriv->adapter;
	mlan_ds_bss *bss = MNULL;
	mlan_status ret = MLAN_STATUS_SUCCESS;
	t_u8 zero_mac[] = { 0, 0, 0, 0, 0, 0 };
	t_u8 mac[MLAN_MAC_ADDR_LENGTH];
	int i = 0;
	BSSDescriptor_t *pbss_desc = MNULL;

	ENTER();

	bss = (mlan_ds_bss *)pioctl_req->pbuf;

	if (memcmp(pmadapter, &bss->param.ssid_bssid.bssid, zero_mac,
		   sizeof(zero_mac))) {
		if (bss->param.ssid_bssid.ssid.ssid_len)	/* ssid & bssid */
			i = wlan_find_ssid_in_list(pmpriv,
						   &bss->param.ssid_bssid.ssid,
						   (t_u8 *)&bss->param.
						   ssid_bssid.bssid,
						   pmpriv->bss_mode);
		else
			i = wlan_find_bssid_in_list(pmpriv,
						    (t_u8 *)&bss->param.
						    ssid_bssid.bssid,
						    pmpriv->bss_mode);
		if (i < 0) {
			memcpy_ext(pmadapter, mac, &bss->param.ssid_bssid.bssid,
				   sizeof(mac), MLAN_MAC_ADDR_LENGTH);
			PRINTM(MIOCTL, "Can not find bssid " MACSTR "\n",
			       MAC2STR(mac));
			pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
			LEAVE();
			return MLAN_STATUS_FAILURE;
		}
		pbss_desc = &pmadapter->pscan_table[i];
		memcpy_ext(pmadapter, &bss->param.ssid_bssid.ssid,
			   &pbss_desc->ssid, sizeof(mlan_802_11_ssid),
			   sizeof(mlan_802_11_ssid));
		bss->param.ssid_bssid.rssi = pbss_desc->rssi;
		bss->param.ssid_bssid.channel = (t_u16)pbss_desc->channel;

		bss->param.ssid_bssid.bss_band = pbss_desc->bss_band;
		/* index in bss list,start from 1 */
		bss->param.ssid_bssid.idx = i + 1;
	} else if (bss->param.ssid_bssid.ssid.ssid_len) {
		i = wlan_find_ssid_in_list(pmpriv, &bss->param.ssid_bssid.ssid,
					   MNULL, pmpriv->bss_mode);
		if (i < 0) {
			PRINTM(MIOCTL, "Can not find ssid %s\n",
			       bss->param.ssid_bssid.ssid.ssid);
			pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
			LEAVE();
			return MLAN_STATUS_FAILURE;
		}
		pbss_desc = &pmadapter->pscan_table[i];
		memcpy_ext(pmadapter, (t_u8 *)&bss->param.ssid_bssid.bssid,
			   (t_u8 *)&pbss_desc->mac_address,
			   MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
		bss->param.ssid_bssid.rssi = pbss_desc->rssi;
		bss->param.ssid_bssid.channel = (t_u16)pbss_desc->channel;

		bss->param.ssid_bssid.bss_band = pbss_desc->bss_band;
		/* index in bss list, start from 1 */
		bss->param.ssid_bssid.idx = i + 1;
	} else {
		ret = wlan_find_best_network(pmpriv, &bss->param.ssid_bssid);
	}

	if (pbss_desc) {
		/**if rsn do not have ft akm, don't set ft cap and ft md*/
		if (pbss_desc->pmd_ie
		    && wlan_ft_akm_is_used(pmpriv, (t_u8 *)pbss_desc->prsn_ie)
			) {
			bss->param.ssid_bssid.ft_md = pbss_desc->pmd_ie->mdid;
			bss->param.ssid_bssid.ft_cap =
				pbss_desc->pmd_ie->ft_cap;
		}
	}

	LEAVE();
	return ret;
}

/**
 *  @brief MLAN station ioctl handler
 *
 *  @param adapter  A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS/MLAN_STATUS_PENDING --success,
 * otherwise fail
 */
mlan_status
wlan_ops_sta_ioctl(t_void *adapter, pmlan_ioctl_req pioctl_req)
{
	pmlan_adapter pmadapter = (pmlan_adapter)adapter;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	switch (pioctl_req->req_id) {
	case MLAN_IOCTL_SCAN:
		status = wlan_scan_ioctl(pmadapter, pioctl_req);
		break;
	case MLAN_IOCTL_BSS:
		status = wlan_bss_ioctl(pmadapter, pioctl_req);
		break;
	case MLAN_IOCTL_RADIO_CFG:
		status = wlan_radio_ioctl(pmadapter, pioctl_req);
		break;
	case MLAN_IOCTL_SNMP_MIB:
		status = wlan_snmp_mib_ioctl(pmadapter, pioctl_req);
		break;
	case MLAN_IOCTL_GET_INFO:
		status = wlan_get_info_ioctl(pmadapter, pioctl_req);
		break;
	case MLAN_IOCTL_SEC_CFG:
		status = wlan_sec_cfg_ioctl(pmadapter, pioctl_req);
		break;
	case MLAN_IOCTL_RATE:
		status = wlan_rate_ioctl(pmadapter, pioctl_req);
		break;
	case MLAN_IOCTL_POWER_CFG:
		status = wlan_power_ioctl(pmadapter, pioctl_req);
		break;
	case MLAN_IOCTL_PM_CFG:
		status = wlan_pm_ioctl(pmadapter, pioctl_req);
		break;
	case MLAN_IOCTL_WMM_CFG:
		status = wlan_wmm_cfg_ioctl(pmadapter, pioctl_req);
		break;
	case MLAN_IOCTL_WPS_CFG:
		status = wlan_wps_cfg_ioctl(pmadapter, pioctl_req);
		break;
	case MLAN_IOCTL_11N_CFG:
		status = wlan_11n_cfg_ioctl(pmadapter, pioctl_req);
		break;
	case MLAN_IOCTL_11D_CFG:
		status = wlan_11d_cfg_ioctl(pmadapter, pioctl_req);
		break;
	case MLAN_IOCTL_REG_MEM:
		status = wlan_reg_mem_ioctl(pmadapter, pioctl_req);
		break;
	case MLAN_IOCTL_MISC_CFG:
		status = wlan_misc_cfg_ioctl(pmadapter, pioctl_req);
		break;
	case MLAN_IOCTL_11H_CFG:
		status = wlan_11h_cfg_ioctl(pmadapter, pioctl_req);
		break;
	case MLAN_IOCTL_11AC_CFG:
		status = wlan_11ac_cfg_ioctl(pmadapter, pioctl_req);
		break;
	case MLAN_IOCTL_11AX_CFG:
		status = wlan_11ax_cfg_ioctl(pmadapter, pioctl_req);
		break;
	default:
		pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID;
		status = MLAN_STATUS_FAILURE;
		break;
	}
	LEAVE();
	return status;
}
