/**
 * @file mlan_misc.c
 *
 *  @brief This file include miscellaneous functions for MLAN module
 *
 *
 *  Copyright 2009-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:
    05/11/2009: initial version
************************************************************/
#include "mlan.h"
#ifdef STA_SUPPORT
#include "mlan_join.h"
#endif /* STA_SUPPORT */
#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"
#ifdef UAP_SUPPORT
#include "mlan_uap.h"
#endif
#ifdef DRV_EMBEDDED_AUTHENTICATOR
#include "authenticator_api.h"
#endif
/********************************************************
			Local Variables
********************************************************/

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

/********************************************************
			Local Functions
********************************************************/
#if defined(PCIE) || defined(SDIO)
/**
 *  @brief Check pending irq
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *
 *  @return        MTRUE/MFALSE;
 */
static t_u8
wlan_pending_interrupt(pmlan_adapter pmadapter)
{
	if (!IS_USB(pmadapter->card_type) && pmadapter->ireg)
		return MTRUE;
	return MFALSE;
}
#endif

/** Custom IE auto index and mask */
#define MLAN_CUSTOM_IE_AUTO_IDX_MASK 0xffff
/** Custom IE mask for delete operation */
#define MLAN_CUSTOM_IE_DELETE_MASK 0
/** Custom IE mask for create new index */
#define MLAN_CUSTOM_IE_NEW_MASK 0x8000
/** Custom IE header size */
#define MLAN_CUSTOM_IE_HDR_SIZE (sizeof(custom_ie) - MAX_IE_SIZE)

/**
 *  @brief Check if current custom IE index is used on other interfaces.
 *
 *  @param pmpriv   A pointer to mlan_private structure
 *  @param idx		index to check for in use
 *
 *  @return		MLAN_STATUS_SUCCESS --unused, otherwise used.
 */
static mlan_status
wlan_is_custom_ie_index_unused(pmlan_private pmpriv, t_u16 idx)
{
	t_u8 i = 0;
	pmlan_adapter pmadapter = pmpriv->adapter;
	pmlan_private priv;
	ENTER();

	for (i = 0; i < pmadapter->priv_num; i++) {
		priv = pmadapter->priv[i];
		/* Check for other interfaces only */
		if (priv && priv->bss_index != pmpriv->bss_index) {
			if (priv->mgmt_ie[idx].mgmt_subtype_mask &&
			    priv->mgmt_ie[idx].ie_length) {
				/* used entry found */
				LEAVE();
				return MLAN_STATUS_FAILURE;
			}
		}
	}
	LEAVE();
	return MLAN_STATUS_SUCCESS;
}

/**
 *  @brief Get the custom IE index
 *
 *  @param pmpriv       A pointer to mlan_private structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *  @param mask	mask value for which the index to be returned
 *  @param ie_data	a pointer to custom_ie structure
 *  @param idx		will hold the computed index
 *
 *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
 */
static mlan_status
wlan_custom_ioctl_get_autoidx(pmlan_private pmpriv,
			      pmlan_ioctl_req pioctl_req,
			      t_u16 mask, custom_ie *ie_data, t_u16 *idx)
{
	t_u16 index = 0, insert = MFALSE;
	mlan_status ret = MLAN_STATUS_SUCCESS;

	ENTER();
	/* Determine the index where the IE needs to be inserted */
	while (!insert) {
		while (index < MIN(pmpriv->adapter->max_mgmt_ie_index,
				   MAX_MGMT_IE_INDEX)) {
			if (pmpriv->mgmt_ie[index].mgmt_subtype_mask ==
			    MLAN_CUSTOM_IE_AUTO_IDX_MASK) {
				index++;
				continue;
			}
			if (pmpriv->mgmt_ie[index].mgmt_subtype_mask == mask) {
				/* Duplicate IE should be avoided */
				if (pmpriv->mgmt_ie[index].ie_length) {
					if (!memcmp(pmpriv->adapter,
						    pmpriv->mgmt_ie[index]
						    .ie_buffer,
						    ie_data->ie_buffer,
						    pmpriv->mgmt_ie[index]
						    .ie_length)) {
						PRINTM(MINFO,
						       "IE with the same mask exists at index %d mask=0x%x\n",
						       index, mask);
						*idx = MLAN_CUSTOM_IE_AUTO_IDX_MASK;
						goto done;
					}
				}
				/* Check if enough space is available */
				if (pmpriv->mgmt_ie[index].ie_length +
				    ie_data->ie_length > MAX_IE_SIZE) {
					index++;
					continue;
				}
				insert = MTRUE;
				break;
			}
			index++;
		}
		if (!insert) {
			for (index = 0;
			     index < MIN(pmpriv->adapter->max_mgmt_ie_index,
					 MAX_MGMT_IE_INDEX); index++) {
				if (pmpriv->mgmt_ie[index].ie_length == 0) {
					/*
					 * Check if this index is in use
					 * by other interface If yes,
					 * move ahead to next index
					 */
					if (MLAN_STATUS_SUCCESS ==
					    wlan_is_custom_ie_index_unused
					    (pmpriv, index)) {
						insert = MTRUE;
						break;
					} else {
						PRINTM(MINFO,
						       "Skipping IE index %d in use.\n",
						       index);
					}
				}
			}
		}
		if (index == pmpriv->adapter->max_mgmt_ie_index && !insert) {
			PRINTM(MERROR, "Failed to Set the IE buffer\n");
			if (pioctl_req)
				pioctl_req->status_code = MLAN_ERROR_IOCTL_FAIL;
			ret = MLAN_STATUS_FAILURE;
			goto done;
		}
	}

	*idx = index;
done:
	LEAVE();
	return ret;
}

/**
 *  @brief Delete custom IE
 *
 *  @param pmpriv       A pointer to mlan_private structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *  @param ie_data	a pointer to custom_ie structure
 *  @param idx		index supplied
 *
 *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
 */

static mlan_status
wlan_custom_ioctl_auto_delete(pmlan_private pmpriv,
			      pmlan_ioctl_req pioctl_req,
			      custom_ie *ie_data, t_u16 idx)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	pmlan_adapter pmadapter = pmpriv->adapter;
	t_u16 index = 0, insert = MFALSE, del_len;
	t_u8 del_ie[MAX_IE_SIZE], ie[MAX_IE_SIZE];
	t_s32 cnt, tmp_len = 0;
	t_u8 *tmp_ie;

	ENTER();
	memset(pmpriv->adapter, del_ie, 0, MAX_IE_SIZE);
	memcpy_ext(pmpriv->adapter, del_ie, ie_data->ie_buffer,
		   ie_data->ie_length, MAX_IE_SIZE);
	del_len = MIN(MAX_IE_SIZE - 1, ie_data->ie_length);

	if (MLAN_CUSTOM_IE_AUTO_IDX_MASK == idx)
		ie_data->ie_index = 0;

	for (index = 0;
	     index < MIN(pmadapter->max_mgmt_ie_index, MAX_MGMT_IE_INDEX);
	     index++) {
		if (MLAN_CUSTOM_IE_AUTO_IDX_MASK != idx &&
		    idx < MAX_MGMT_IE_INDEX)
			index = idx;
		tmp_ie = pmpriv->mgmt_ie[index].ie_buffer;
		tmp_len = pmpriv->mgmt_ie[index].ie_length;
		cnt = 0;
		while (tmp_len) {
			if (!memcmp(pmpriv->adapter, tmp_ie, del_ie, del_len)) {
				memcpy_ext(pmpriv->adapter, ie,
					   pmpriv->mgmt_ie[index].ie_buffer,
					   cnt, MAX_IE_SIZE);
				if (pmpriv->mgmt_ie[index].ie_length >
				    (cnt + del_len))
					memcpy_ext(pmpriv->adapter, &ie[cnt],
						   &pmpriv->mgmt_ie[index].
						   ie_buffer[MIN
							     ((MAX_IE_SIZE - 1),
							      (cnt + del_len))],
						   (pmpriv->mgmt_ie[index]
						    .ie_length - (cnt +
								  del_len)),
						   MAX_IE_SIZE - cnt);
				memset(pmpriv->adapter,
				       &pmpriv->mgmt_ie[index].ie_buffer, 0,
				       sizeof(pmpriv->mgmt_ie[index].
					      ie_buffer));
				memcpy_ext(pmpriv->adapter,
					   &pmpriv->mgmt_ie[index].ie_buffer,
					   ie,
					   pmpriv->mgmt_ie[index].ie_length -
					   del_len, MAX_IE_SIZE);
				pmpriv->mgmt_ie[index].ie_length -= del_len;
				if (MLAN_CUSTOM_IE_AUTO_IDX_MASK == idx)
					/* set a bit to indicate caller about
					 * update */
					ie_data->ie_index |=
						(((t_u16)1) << index);
				insert = MTRUE;
				tmp_ie = pmpriv->mgmt_ie[index].ie_buffer;
				tmp_len = pmpriv->mgmt_ie[index].ie_length;
				cnt = 0;
				continue;
			}
			tmp_ie++;
			tmp_len--;
			cnt++;
		}
		if (MLAN_CUSTOM_IE_AUTO_IDX_MASK != idx)
			break;
	}
	if (index == pmadapter->max_mgmt_ie_index && !insert) {
		PRINTM(MERROR, "Failed to Clear IE buffer\n");
		if (pioctl_req)
			pioctl_req->status_code = MLAN_ERROR_IOCTL_FAIL;
		ret = MLAN_STATUS_FAILURE;
	}
	LEAVE();
	return ret;
}

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

/**
 *  @brief send host cmd
 *
 *  @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_host_cmd(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;

	/* Send request to firmware */
	ret = wlan_prepare_cmd(pmpriv, 0, 0, 0, (t_void *)pioctl_req,
			       (t_void *)&misc->param.hostcmd);
	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief Send function init/shutdown 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
 */
mlan_status
wlan_misc_ioctl_init_shutdown(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_cfg = MNULL;
	t_u16 cmd;

	ENTER();

	misc_cfg = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
	if (misc_cfg->param.func_init_shutdown == MLAN_FUNC_INIT)
		cmd = HostCmd_CMD_FUNC_INIT;
	else if (misc_cfg->param.func_init_shutdown == MLAN_FUNC_SHUTDOWN)
		cmd = HostCmd_CMD_FUNC_SHUTDOWN;
	else {
		PRINTM(MERROR, "Unsupported parameter\n");
		pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
		ret = MLAN_STATUS_FAILURE;
		goto exit;
	}

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

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

exit:
	LEAVE();
	return ret;
}

/**
 *  @brief Get debug information
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS --success
 */
mlan_status
wlan_get_info_debug_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;
	mlan_debug_info *debug_info = MNULL;
	t_u32 i;
	t_u8 *ptid;

	ENTER();

	info = (mlan_ds_get_info *)pioctl_req->pbuf;
	debug_info = (mlan_debug_info *)info->param.debug_info;

	if (pioctl_req->action == MLAN_ACT_GET) {
		ptid = ac_to_tid[WMM_AC_BK];
		debug_info->wmm_ac_bk = pmpriv->wmm.packets_out[ptid[0]] +
			pmpriv->wmm.packets_out[ptid[1]];
		ptid = ac_to_tid[WMM_AC_BE];
		debug_info->wmm_ac_be = pmpriv->wmm.packets_out[ptid[0]] +
			pmpriv->wmm.packets_out[ptid[1]];
		ptid = ac_to_tid[WMM_AC_VI];
		debug_info->wmm_ac_vi = pmpriv->wmm.packets_out[ptid[0]] +
			pmpriv->wmm.packets_out[ptid[1]];
		ptid = ac_to_tid[WMM_AC_VO];
		debug_info->wmm_ac_vo = pmpriv->wmm.packets_out[ptid[0]] +
			pmpriv->wmm.packets_out[ptid[1]];
		debug_info->max_tx_buf_size = (t_u32)pmadapter->max_tx_buf_size;
		debug_info->tx_buf_size = (t_u32)pmadapter->tx_buf_size;
		debug_info->curr_tx_buf_size =
			(t_u32)pmadapter->curr_tx_buf_size;
		debug_info->rx_tbl_num =
			wlan_get_rxreorder_tbl(pmpriv, debug_info->rx_tbl);
		debug_info->tx_tbl_num =
			wlan_get_txbastream_tbl(pmpriv, debug_info->tx_tbl);
		debug_info->ralist_num =
			wlan_get_ralist_info(pmpriv, debug_info->ralist);
		debug_info->tdls_peer_num =
			wlan_get_tdls_list(pmpriv, debug_info->tdls_peer_list);
		debug_info->ps_mode = pmadapter->ps_mode;
		debug_info->ps_state = pmadapter->ps_state;
#ifdef STA_SUPPORT
		debug_info->is_deep_sleep = pmadapter->is_deep_sleep;
#endif /* STA_SUPPORT */
		debug_info->pm_wakeup_card_req = pmadapter->pm_wakeup_card_req;
		debug_info->pm_wakeup_fw_try = pmadapter->pm_wakeup_fw_try;
		debug_info->pm_wakeup_in_secs = pmadapter->pm_wakeup_in_secs;
		debug_info->pm_wakeup_timeout = pmadapter->pm_wakeup_timeout;
		debug_info->is_hs_configured = pmadapter->is_hs_configured;
		debug_info->hs_activated = pmadapter->hs_activated;
		debug_info->pps_uapsd_mode = pmadapter->pps_uapsd_mode;
		debug_info->sleep_pd = pmadapter->sleep_period.period;
		debug_info->qos_cfg = pmpriv->wmm_qosinfo;
		debug_info->tx_lock_flag = pmadapter->tx_lock_flag;
		debug_info->port_open = pmpriv->port_open;
		debug_info->bypass_pkt_count = pmadapter->bypass_pkt_count;
		debug_info->scan_processing = pmadapter->scan_processing;
		debug_info->mlan_processing = pmadapter->mlan_processing;
		debug_info->main_lock_flag = pmadapter->main_lock_flag;
		debug_info->main_process_cnt = pmadapter->main_process_cnt;
		debug_info->delay_task_flag = pmadapter->delay_task_flag;
		debug_info->num_cmd_host_to_card_failure =
			pmadapter->dbg.num_cmd_host_to_card_failure;
		debug_info->num_cmd_sleep_cfm_host_to_card_failure =
			pmadapter->dbg.num_cmd_sleep_cfm_host_to_card_failure;
		debug_info->num_tx_host_to_card_failure =
			pmadapter->dbg.num_tx_host_to_card_failure;
		debug_info->num_alloc_buffer_failure =
			pmadapter->dbg.num_alloc_buffer_failure;
		debug_info->num_pkt_dropped = pmadapter->dbg.num_pkt_dropped;

		debug_info->num_event_deauth = pmadapter->dbg.num_event_deauth;
		debug_info->num_event_disassoc =
			pmadapter->dbg.num_event_disassoc;
		debug_info->num_event_link_lost =
			pmadapter->dbg.num_event_link_lost;
		debug_info->num_cmd_deauth = pmadapter->dbg.num_cmd_deauth;
		debug_info->num_cmd_assoc_success =
			pmadapter->dbg.num_cmd_assoc_success;
		debug_info->num_cmd_assoc_failure =
			pmadapter->dbg.num_cmd_assoc_failure;
		debug_info->num_cmd_timeout = pmadapter->num_cmd_timeout;
		debug_info->timeout_cmd_id = pmadapter->dbg.timeout_cmd_id;
		debug_info->timeout_cmd_act = pmadapter->dbg.timeout_cmd_act;
		memcpy_ext(pmadapter, debug_info->last_cmd_id,
			   pmadapter->dbg.last_cmd_id,
			   sizeof(pmadapter->dbg.last_cmd_id),
			   sizeof(debug_info->last_cmd_id));
		memcpy_ext(pmadapter, debug_info->last_cmd_act,
			   pmadapter->dbg.last_cmd_act,
			   sizeof(pmadapter->dbg.last_cmd_act),
			   sizeof(debug_info->last_cmd_act));
		debug_info->last_cmd_index = pmadapter->dbg.last_cmd_index;
		memcpy_ext(pmadapter, debug_info->last_cmd_resp_id,
			   pmadapter->dbg.last_cmd_resp_id,
			   sizeof(pmadapter->dbg.last_cmd_resp_id),
			   sizeof(debug_info->last_cmd_resp_id));
		debug_info->last_cmd_resp_index =
			pmadapter->dbg.last_cmd_resp_index;
		memcpy_ext(pmadapter, debug_info->last_event,
			   pmadapter->dbg.last_event,
			   sizeof(pmadapter->dbg.last_event),
			   sizeof(debug_info->last_event));
		debug_info->last_event_index = pmadapter->dbg.last_event_index;
		debug_info->num_no_cmd_node = pmadapter->dbg.num_no_cmd_node;
		debug_info->pending_cmd =
			(pmadapter->curr_cmd) ?
			pmadapter->dbg.last_cmd_id
			[pmadapter->dbg.last_cmd_index] : 0;
		debug_info->dnld_cmd_in_secs = pmadapter->dnld_cmd_in_secs;
#ifdef SDIO
		if (IS_SD(pmadapter->card_type)) {
			debug_info->num_cmdevt_card_to_host_failure =
				pmadapter->dbg.num_cmdevt_card_to_host_failure;
			debug_info->num_rx_card_to_host_failure =
				pmadapter->dbg.num_rx_card_to_host_failure;
			debug_info->num_int_read_failure =
				pmadapter->dbg.num_int_read_failure;
			debug_info->last_int_status =
				pmadapter->dbg.last_int_status;
			debug_info->mp_rd_bitmap =
				pmadapter->pcard_sd->mp_rd_bitmap;
			debug_info->mp_wr_bitmap =
				pmadapter->pcard_sd->mp_wr_bitmap;
			debug_info->curr_rd_port =
				pmadapter->pcard_sd->curr_rd_port;
			debug_info->curr_wr_port =
				pmadapter->pcard_sd->curr_wr_port;
			debug_info->mp_invalid_update =
				pmadapter->pcard_sd->mp_invalid_update;
			debug_info->num_of_irq =
				pmadapter->pcard_sd->num_of_irq;
			memcpy_ext(pmadapter, debug_info->mp_update,
				   pmadapter->pcard_sd->mp_update,
				   sizeof(pmadapter->pcard_sd->mp_update),
				   sizeof(debug_info->mp_update));
			memcpy_ext(pmadapter, debug_info->mpa_tx_count,
				   pmadapter->pcard_sd->mpa_tx_count,
				   sizeof(pmadapter->pcard_sd->mpa_tx_count),
				   sizeof(debug_info->mpa_tx_count));
			debug_info->mpa_sent_last_pkt =
				pmadapter->pcard_sd->mpa_sent_last_pkt;
			debug_info->mpa_sent_no_ports =
				pmadapter->pcard_sd->mpa_sent_no_ports;
			debug_info->last_recv_wr_bitmap =
				pmadapter->pcard_sd->last_recv_wr_bitmap;
			debug_info->last_recv_rd_bitmap =
				pmadapter->pcard_sd->last_recv_rd_bitmap;
			debug_info->mp_data_port_mask =
				pmadapter->pcard_sd->mp_data_port_mask;
			debug_info->last_mp_index =
				pmadapter->pcard_sd->last_mp_index;
			memcpy_ext(pmadapter, debug_info->last_mp_wr_bitmap,
				   pmadapter->pcard_sd->last_mp_wr_bitmap,
				   sizeof(pmadapter->pcard_sd->
					  last_mp_wr_bitmap),
				   sizeof(debug_info->last_mp_wr_bitmap));
			memcpy_ext(pmadapter, debug_info->last_mp_wr_ports,
				   pmadapter->pcard_sd->last_mp_wr_ports,
				   sizeof(pmadapter->pcard_sd->
					  last_mp_wr_ports),
				   sizeof(debug_info->last_mp_wr_ports));
			memcpy_ext(pmadapter, debug_info->last_mp_wr_len,
				   pmadapter->pcard_sd->last_mp_wr_len,
				   sizeof(pmadapter->pcard_sd->last_mp_wr_len),
				   sizeof(debug_info->last_mp_wr_len));
			memcpy_ext(pmadapter, debug_info->last_mp_wr_info,
				   pmadapter->pcard_sd->last_mp_wr_info,
				   sizeof(pmadapter->pcard_sd->last_mp_wr_info),
				   sizeof(debug_info->last_mp_wr_info));
			memcpy_ext(pmadapter, debug_info->last_curr_wr_port,
				   pmadapter->pcard_sd->last_curr_wr_port,
				   sizeof(pmadapter->pcard_sd->
					  last_curr_wr_port),
				   sizeof(debug_info->last_curr_wr_port));
			debug_info->mpa_buf = pmadapter->pcard_sd->mpa_buf;
			debug_info->mpa_buf_size =
				pmadapter->pcard_sd->mpa_buf_size;
			debug_info->sdio_rx_aggr =
				pmadapter->pcard_sd->sdio_rx_aggr_enable;
			memcpy_ext(pmadapter, debug_info->mpa_rx_count,
				   pmadapter->pcard_sd->mpa_rx_count,
				   sizeof(pmadapter->pcard_sd->mpa_rx_count),
				   sizeof(debug_info->mpa_rx_count));
			debug_info->mp_aggr_pkt_limit =
				pmadapter->pcard_sd->mp_aggr_pkt_limit;
		}
#endif
#ifdef PCIE
		if (IS_PCIE(pmadapter->card_type)) {
			debug_info->txbd_rdptr =
				pmadapter->pcard_pcie->txbd_rdptr;
			debug_info->txbd_wrptr =
				pmadapter->pcard_pcie->txbd_wrptr;
			debug_info->rxbd_rdptr =
				pmadapter->pcard_pcie->rxbd_rdptr;
			debug_info->rxbd_wrptr =
				pmadapter->pcard_pcie->rxbd_wrptr;
			debug_info->eventbd_rdptr =
				pmadapter->pcard_pcie->evtbd_rdptr;
			debug_info->eventbd_wrptr =
				pmadapter->pcard_pcie->evtbd_wrptr;
			debug_info->txbd_ring_vbase =
				pmadapter->pcard_pcie->txbd_ring_vbase;
			debug_info->txbd_ring_size =
				pmadapter->pcard_pcie->txbd_ring_size;
			debug_info->rxbd_ring_vbase =
				pmadapter->pcard_pcie->rxbd_ring_vbase;
			debug_info->rxbd_ring_size =
				pmadapter->pcard_pcie->rxbd_ring_size;
			debug_info->evtbd_ring_vbase =
				pmadapter->pcard_pcie->evtbd_ring_vbase;
			debug_info->evtbd_ring_size =
				pmadapter->pcard_pcie->evtbd_ring_size;
			debug_info->txrx_bd_size =
				pmadapter->pcard_pcie->txrx_bd_size;
		}
#endif
		debug_info->data_sent = pmadapter->data_sent;
		debug_info->data_sent_cnt = pmadapter->data_sent_cnt;
		debug_info->cmd_sent = pmadapter->cmd_sent;
		debug_info->cmd_resp_received = pmadapter->cmd_resp_received;
		debug_info->tx_pkts_queued =
			util_scalar_read(pmadapter->pmoal_handle,
					 &pmpriv->wmm.tx_pkts_queued, MNULL,
					 MNULL);
#ifdef UAP_SUPPORT
		debug_info->num_bridge_pkts =
			util_scalar_read(pmadapter->pmoal_handle,
					 &pmadapter->pending_bridge_pkts,
					 pmadapter->callbacks.moal_spin_lock,
					 pmadapter->callbacks.moal_spin_unlock);
		debug_info->num_drop_pkts = pmpriv->num_drop_pkts;
#endif
		debug_info->fw_hang_report = pmadapter->fw_hang_report;
		debug_info->mlan_processing = pmadapter->mlan_processing;
		debug_info->mlan_rx_processing = pmadapter->mlan_rx_processing;
		debug_info->rx_pkts_queued = pmadapter->rx_pkts_queued;
		debug_info->mlan_adapter = pmadapter;
		debug_info->mlan_adapter_size = sizeof(mlan_adapter);
		debug_info->mlan_priv_num = pmadapter->priv_num;
		for (i = 0; i < pmadapter->priv_num; i++) {
			debug_info->mlan_priv[i] = pmadapter->priv[i];
			debug_info->mlan_priv_size[i] = sizeof(mlan_private);
		}
	}

	pioctl_req->data_read_written =
		sizeof(mlan_debug_info) + MLAN_SUB_COMMAND_SIZE;

	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get the MAC control 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
 */
mlan_status
wlan_misc_ioctl_mac_control(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_u16 cmd_action = 0;

	ENTER();

	misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;

	if (pioctl_req->action == MLAN_ACT_GET) {
		misc->param.mac_ctrl = pmpriv->curr_pkt_filter;
	} else {
		pmpriv->curr_pkt_filter = misc->param.mac_ctrl;
		cmd_action = HostCmd_ACT_GEN_SET;

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

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

	LEAVE();
	return ret;
}

/**
 *  @brief This timer function handles wakeup card timeout.
 *
 *  @param function_context   A pointer to function_context
 *  @return        N/A
 */
t_void
wlan_wakeup_card_timeout_func(void *function_context)
{
	pmlan_adapter pmadapter = (pmlan_adapter)function_context;
	mlan_private *pmpriv = wlan_get_priv(pmadapter, MLAN_BSS_ROLE_ANY);

	ENTER();

	PRINTM(MERROR, "%s: ps_state=%d\n", __FUNCTION__, pmadapter->ps_state);
	if (pmadapter->ps_state != PS_STATE_AWAKE) {
		PRINTM_NETINTF(MERROR, pmpriv);
		PRINTM(MERROR, "Wakeup card timeout!\n");
		pmadapter->pm_wakeup_timeout++;
		wlan_recv_event(pmpriv, MLAN_EVENT_ID_DRV_DBG_DUMP, MNULL);
	}
	pmadapter->wakeup_fw_timer_is_set = MFALSE;

	LEAVE();
}

/**
 *  @brief Set/Get HS configuration
 *
 *  @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
 */
mlan_status
wlan_pm_ioctl_hscfg(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_pm_cfg *pm = MNULL;
	mlan_status status = MLAN_STATUS_SUCCESS;
	t_u32 prev_cond = 0;

	ENTER();

	pm = (mlan_ds_pm_cfg *)pioctl_req->pbuf;

	switch (pioctl_req->action) {
	case MLAN_ACT_SET:
#ifdef STA_SUPPORT
		if (pmadapter->pps_uapsd_mode) {
			PRINTM(MINFO,
			       "Host Sleep IOCTL is blocked in UAPSD/PPS mode\n");
			pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID;
			status = MLAN_STATUS_FAILURE;
			break;
		}
#endif /* STA_SUPPORT */
		if (pm->param.hs_cfg.is_invoke_hostcmd == MTRUE) {
			if (pm->param.hs_cfg.conditions ==
			    HOST_SLEEP_CFG_CANCEL) {
				if (pmadapter->is_hs_configured == MFALSE) {
					/* Already cancelled */
					break;
				}
				/* Save previous condition */
				prev_cond = pmadapter->hs_cfg.conditions;
				pmadapter->hs_cfg.conditions =
					pm->param.hs_cfg.conditions;
			} else if (pmadapter->hs_cfg.conditions ==
				   HOST_SLEEP_CFG_CANCEL) {
				/* Return failure if no parameters for HS enable
				 */
				pioctl_req->status_code =
					MLAN_ERROR_INVALID_PARAMETER;
				status = MLAN_STATUS_FAILURE;
				break;
			}
			status = wlan_prepare_cmd(pmpriv,
						  HostCmd_CMD_802_11_HS_CFG_ENH,
						  HostCmd_ACT_GEN_SET, 0,
						  (t_void *)pioctl_req,
						  (t_void *)(&pmadapter->
							     hs_cfg));
			if (status == MLAN_STATUS_SUCCESS)
				status = MLAN_STATUS_PENDING;
			if (pm->param.hs_cfg.conditions ==
			    HOST_SLEEP_CFG_CANCEL) {
				/* Restore previous condition */
				pmadapter->hs_cfg.conditions = prev_cond;
			}
		} else {
			pmadapter->hs_cfg.conditions =
				pm->param.hs_cfg.conditions;
			pmadapter->hs_cfg.gpio = (t_u8)pm->param.hs_cfg.gpio;
			pmadapter->hs_cfg.gap = (t_u8)pm->param.hs_cfg.gap;
			pmadapter->param_type_ind =
				(t_u8)pm->param.hs_cfg.param_type_ind;
			pmadapter->ind_gpio = (t_u8)pm->param.hs_cfg.ind_gpio;
			pmadapter->level = (t_u8)pm->param.hs_cfg.level;
			pmadapter->param_type_ext =
				(t_u8)pm->param.hs_cfg.param_type_ext;
			pmadapter->event_force_ignore =
				pm->param.hs_cfg.event_force_ignore;
			pmadapter->event_use_ext_gap =
				pm->param.hs_cfg.event_use_ext_gap;
			pmadapter->ext_gap = pm->param.hs_cfg.ext_gap;
			pmadapter->gpio_wave = pm->param.hs_cfg.gpio_wave;
			pmadapter->hs_wake_interval =
				pm->param.hs_cfg.hs_wake_interval;
		}
		break;
	case MLAN_ACT_GET:
		pm->param.hs_cfg.conditions = pmadapter->hs_cfg.conditions;
		pm->param.hs_cfg.gpio = pmadapter->hs_cfg.gpio;
		pm->param.hs_cfg.gap = pmadapter->hs_cfg.gap;
		pm->param.hs_cfg.param_type_ind = pmadapter->param_type_ind;
		pm->param.hs_cfg.ind_gpio = pmadapter->ind_gpio;
		pm->param.hs_cfg.level = pmadapter->level;
		pm->param.hs_cfg.param_type_ext = pmadapter->param_type_ext;
		pm->param.hs_cfg.event_force_ignore =
			pmadapter->event_force_ignore;
		pm->param.hs_cfg.event_use_ext_gap =
			pmadapter->event_use_ext_gap;
		pm->param.hs_cfg.ext_gap = pmadapter->ext_gap;
		pm->param.hs_cfg.gpio_wave = pmadapter->gpio_wave;
		pm->param.hs_cfg.hs_wake_interval = pmadapter->hs_wake_interval;
		break;
	default:
		pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID;
		status = MLAN_STATUS_FAILURE;
		break;
	}

	LEAVE();
	return status;
}

/**
 *  @brief Set Robustcoex gpiocfg
 *
 *  @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
 */
mlan_status
wlan_misc_robustcoex(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;
	mlan_ds_misc_cfg *robust_coex_cfg =
		(mlan_ds_misc_cfg *)pioctl_req->pbuf;

	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_802_11_ROBUSTCOEX,
			       cmd_action, 0, (t_void *)pioctl_req,
			       &robust_coex_cfg->param.robustcoexparams);

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

/**
 *  @brief Set/get DMCS config
 *
 *  @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
 */
mlan_status
wlan_misc_dmcs_config(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;
	mlan_ds_misc_cfg *dmcs_cfg = (mlan_ds_misc_cfg *)pioctl_req->pbuf;

	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_DMCS_CONFIG, cmd_action, 0,
			       (t_void *)pioctl_req,
			       &dmcs_cfg->param.dmcs_policy);

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

#if defined(PCIE)
/**
 *  @brief Enable SSU support
 *
 *  @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
 */
mlan_status
wlan_misc_ssu(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 = HostCmd_ACT_GEN_GET;
	mlan_ds_misc_cfg *ssu_cfg = (mlan_ds_misc_cfg *)pioctl_req->pbuf;

	ENTER();

	if (pioctl_req->action == MLAN_ACT_SET)
		cmd_action = HostCmd_ACT_GEN_SET;
	else if (pioctl_req->action == MLAN_ACT_DEFAULT)
		cmd_action = HostCmd_ACT_GEN_SET_DEFAULT;
	else if (pioctl_req->action == MLAN_ACT_GET)
		cmd_action = HostCmd_ACT_GEN_GET;

	ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_SSU, cmd_action, 0,
			       (t_void *)pioctl_req,
			       &ssu_cfg->param.ssu_params);

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

/**
 *  @brief Set the hal/phy cfg params.
 *
 *  @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
 */
mlan_status
wlan_misc_hal_phy_cfg(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 *hal_phy_cfg = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
	t_u16 cmd_act;

	ENTER();

	cmd_act = HostCmd_ACT_GEN_SET;
	ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_HAL_PHY_CFG, cmd_act, 0,
			       (t_void *)pioctl_req,
			       &hal_phy_cfg->param.hal_phy_cfg_params);

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief This function allocates a mlan_buffer.
 *
 *  @param pmadapter Pointer to mlan_adapter
 *  @param data_len   Data length
 *  @param head_room  head_room reserved in mlan_buffer
 *  @param malloc_flag  flag to user moal_malloc
 *  @return           mlan_buffer pointer or MNULL
 */
pmlan_buffer
wlan_alloc_mlan_buffer(mlan_adapter *pmadapter, t_u32 data_len,
		       t_u32 head_room, t_u32 malloc_flag)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	pmlan_buffer pmbuf = MNULL;
	t_u32 buf_size = 0;
	t_u8 *tmp_buf = MNULL;
	pmlan_callbacks pcb = &pmadapter->callbacks;

	ENTER();

#ifdef SDIO
	/* make sure that the data length is at least SDIO block size */
	if (IS_SD(pmadapter->card_type))
		data_len = (data_len + MLAN_SDIO_BLOCK_SIZE - 1) /
			MLAN_SDIO_BLOCK_SIZE * MLAN_SDIO_BLOCK_SIZE;
#endif

	/* head_room is not implemented for malloc mlan buffer */

	switch (malloc_flag) {
	case MOAL_MALLOC_BUFFER:
		buf_size = sizeof(mlan_buffer) + data_len + DMA_ALIGNMENT;
		ret = pcb->moal_malloc(pmadapter->pmoal_handle, buf_size,
				       MLAN_MEM_DEF | MLAN_MEM_DMA,
				       (t_u8 **)&pmbuf);
		if ((ret != MLAN_STATUS_SUCCESS) || !pmbuf) {
			pmbuf = MNULL;
			goto exit;
		}
		memset(pmadapter, pmbuf, 0, sizeof(mlan_buffer));

		pmbuf->pdesc = MNULL;
		/* Align address */
		pmbuf->pbuf = (t_u8 *)ALIGN_ADDR((t_u8 *)pmbuf +
						 sizeof(mlan_buffer),
						 DMA_ALIGNMENT);
		pmbuf->data_offset = 0;
		pmbuf->data_len = data_len;
		pmbuf->flags |= MLAN_BUF_FLAG_MALLOC_BUF;
		break;

	case MOAL_ALLOC_MLAN_BUFFER:
		/* use moal_alloc_mlan_buffer, head_room supported */
		ret = pcb->moal_alloc_mlan_buffer(pmadapter->pmoal_handle,
						  data_len + DMA_ALIGNMENT +
						  head_room, &pmbuf);
		if ((ret != MLAN_STATUS_SUCCESS) || !pmbuf) {
			PRINTM(MERROR, "Failed to allocate 'mlan_buffer'\n");
			goto exit;
		}
		pmbuf->data_offset = head_room;
		tmp_buf = (t_u8 *)ALIGN_ADDR(pmbuf->pbuf + pmbuf->data_offset,
					     DMA_ALIGNMENT);
		pmbuf->data_offset +=
			(t_u32)(tmp_buf - (pmbuf->pbuf + pmbuf->data_offset));
		pmbuf->data_len = data_len;
		pmbuf->flags = 0;
		break;
	}

exit:
	LEAVE();
	return pmbuf;
}

/**
 *  @brief This function frees a mlan_buffer.
 *
 *  @param pmadapter  Pointer to mlan_adapter
 *  @param pmbuf      Pointer to mlan_buffer
 *
 *  @return           N/A
 */
t_void
wlan_free_mlan_buffer(mlan_adapter *pmadapter, pmlan_buffer pmbuf)
{
	pmlan_callbacks pcb = &pmadapter->callbacks;
	ENTER();

	if (pcb && pmbuf) {
		if (pmbuf->flags & MLAN_BUF_FLAG_BRIDGE_BUF)
			util_scalar_decrement(pmadapter->pmoal_handle,
					      &pmadapter->pending_bridge_pkts,
					      pmadapter->callbacks.
					      moal_spin_lock,
					      pmadapter->callbacks.
					      moal_spin_unlock);
		if (pmbuf->flags & MLAN_BUF_FLAG_MALLOC_BUF)
			pcb->moal_mfree(pmadapter->pmoal_handle, (t_u8 *)pmbuf);
		else
			pcb->moal_free_mlan_buffer(pmadapter->pmoal_handle,
						   pmbuf);
	}

	LEAVE();
	return;
}

/**
 *  @brief Delay function implementation
 *
 *  @param pmadapter        A pointer to mlan_adapter structure
 *  @param delay            Delay value
 *  @param u                Units of delay (sec, msec or usec)
 *
 *  @return                 N/A
 */
t_void
wlan_delay_func(mlan_adapter *pmadapter, t_u32 delay, t_delay_unit u)
{
	t_u32 now_tv_sec, now_tv_usec;
	t_u32 upto_tv_sec, upto_tv_usec;
	pmlan_callbacks pcb = &pmadapter->callbacks;

	ENTER();

	if (pcb->moal_udelay) {
		if (u == SEC)
			delay *= 1000000;
		else if (u == MSEC)
			delay *= 1000;
		pcb->moal_udelay(pmadapter->pmoal_handle, delay);
	} else {
		pcb->moal_get_system_time(pmadapter->pmoal_handle, &upto_tv_sec,
					  &upto_tv_usec);

		switch (u) {
		case SEC:
			upto_tv_sec += delay;
			break;
		case MSEC:
			delay *= 1000;
			/* fall through */
		case USEC:
			upto_tv_sec += (delay / 1000000);
			upto_tv_usec += (delay % 1000000);
			break;
		}

		do {
			pcb->moal_get_system_time(pmadapter->pmoal_handle,
						  &now_tv_sec, &now_tv_usec);
			if (now_tv_sec > upto_tv_sec) {
				LEAVE();
				return;
			}

			if ((now_tv_sec == upto_tv_sec) &&
			    (now_tv_usec >= upto_tv_usec)) {
				LEAVE();
				return;
			}
		} while (MTRUE);
	}

	LEAVE();
	return;
}

/**
 *  @brief BSS remove
 *
 *  @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_bss_ioctl_bss_remove(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	ENTER();
	wlan_cancel_bss_pending_cmd(pmadapter, pioctl_req->bss_index);
	LEAVE();
	return MLAN_STATUS_SUCCESS;
}

#if defined(STA_SUPPORT) && defined(UAP_SUPPORT)
/**
 *  @brief Set/Get BSS role
 *
 *  @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_bss_ioctl_bss_role(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;
	HostCmd_DS_VERSION_EXT dummy;
#ifdef USB
	pmlan_callbacks pcb = &pmadapter->callbacks;
	pmlan_buffer pmbuf;
#endif
#if defined(WIFI_DIRECT_SUPPORT)
	t_u8 bss_mode;
#endif
	t_u8 i, global_band = 0;
	int j;

	ENTER();

	bss = (mlan_ds_bss *)pioctl_req->pbuf;
	if (pioctl_req->action == MLAN_ACT_GET) {
		bss->param.bss_role = GET_BSS_ROLE(pmpriv);
	} else {
		if (GET_BSS_ROLE(pmpriv) == bss->param.bss_role) {
			PRINTM(MIOCTL, "BSS ie already in the desired role!\n");
			goto done;
		}
		mlan_block_rx_process(pmadapter, MTRUE);
		/** Switch BSS role */
		wlan_free_priv(pmpriv);

#ifdef USB
		if (IS_USB(pmadapter->card_type)) {
			while ((pmbuf =
				(pmlan_buffer)util_dequeue_list(pmadapter->
								pmoal_handle,
								&pmadapter->
								rx_data_queue,
								pcb->
								moal_spin_lock,
								pcb->
								moal_spin_unlock)))
			{
				pcb->moal_recv_complete(pmadapter->pmoal_handle,
							pmbuf,
							pmadapter->rx_data_ep,
							MLAN_STATUS_FAILURE);
			}
		}
#endif
		pmpriv->bss_role = bss->param.bss_role;
		if (pmpriv->bss_type == MLAN_BSS_TYPE_UAP)
			pmpriv->bss_type = MLAN_BSS_TYPE_STA;
		else if (pmpriv->bss_type == MLAN_BSS_TYPE_STA)
			pmpriv->bss_type = MLAN_BSS_TYPE_UAP;
		/* Initialize private structures */
		wlan_init_priv(pmpriv);
		mlan_block_rx_process(pmadapter, MFALSE);
		/* Initialize function table */
		for (j = 0; mlan_ops[j]; j++) {
			if (mlan_ops[j]->bss_role == GET_BSS_ROLE(pmpriv)) {
				memcpy_ext(pmadapter, &pmpriv->ops, mlan_ops[j],
					   sizeof(mlan_operations),
					   sizeof(mlan_operations));
			}
		}

		for (i = 0; i < pmadapter->priv_num; i++) {
			if (pmadapter->priv[i] &&
			    GET_BSS_ROLE(pmadapter->priv[i]) ==
			    MLAN_BSS_ROLE_STA)
				global_band |= pmadapter->priv[i]->config_bands;
		}

		if (global_band != pmadapter->config_bands) {
			if (wlan_set_regiontable
			    (pmpriv, (t_u8)pmadapter->region_code,
			     global_band | pmadapter->adhoc_start_band)) {
				pioctl_req->status_code = MLAN_ERROR_IOCTL_FAIL;
				LEAVE();
				return MLAN_STATUS_FAILURE;
			}

			if (wlan_11d_set_universaltable(pmpriv,
							global_band |
							pmadapter->
							adhoc_start_band)) {
				pioctl_req->status_code = MLAN_ERROR_IOCTL_FAIL;
				LEAVE();
				return MLAN_STATUS_FAILURE;
			}
			pmadapter->config_bands = global_band;
		}

		/* Issue commands to initialize firmware */
#if defined(WIFI_DIRECT_SUPPORT)
		if (GET_BSS_ROLE(pmpriv) == MLAN_BSS_ROLE_STA)
			bss_mode = BSS_MODE_WIFIDIRECT_CLIENT;
		else
			bss_mode = BSS_MODE_WIFIDIRECT_GO;
		ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_SET_BSS_MODE,
				       HostCmd_ACT_GEN_SET, 0, MNULL,
				       &bss_mode);
		if (ret)
			goto done;
#endif
		ret = pmpriv->ops.init_cmd(pmpriv, MFALSE);
		if (ret == MLAN_STATUS_FAILURE)
			goto done;

		/* Issue dummy Get command to complete the ioctl */
		memset(pmadapter, &dummy, 0, sizeof(HostCmd_DS_VERSION_EXT));
		ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_VERSION_EXT,
				       HostCmd_ACT_GEN_GET, 0,
				       (t_void *)pioctl_req, (t_void *)&dummy);
		if (ret == MLAN_STATUS_SUCCESS)
			ret = MLAN_STATUS_PENDING;
	}

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

/**
 *  @brief Set the custom IE
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *  @param send_ioctl	Flag to indicate if ioctl should be sent with cmd
 *                      (MTRUE if from moal/user, MFALSE if internal)
 *
 *  @return		MLAN_STATUS_PENDING --success, otherwise fail
 */
mlan_status
wlan_misc_ioctl_custom_ie_list(pmlan_adapter pmadapter,
			       pmlan_ioctl_req pioctl_req, t_bool send_ioctl)
{
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_ds_misc_cfg *misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
	custom_ie *ie_data = MNULL;
	t_u16 cmd_action = 0, index, mask, i, len, app_data_len;
	t_s32 ioctl_len;
	t_u8 *tmp_ie;

	ENTER();

	if ((misc->param.cust_ie.len == 0) ||
	    (misc->param.cust_ie.len == sizeof(t_u16))) {
		pioctl_req->action = MLAN_ACT_GET;
		/* Get the IE */
		cmd_action = HostCmd_ACT_GEN_GET;
	} else {
		/* ioctl_len : ioctl length from application, start with
		 * misc->param.cust_ie.len and reach upto 0 */
		ioctl_len = misc->param.cust_ie.len;

		/* app_data_len : length from application, start with 0
		 * and reach upto ioctl_len */
		app_data_len = sizeof(MrvlIEtypesHeader_t);
		misc->param.cust_ie.len = 0;

		while (ioctl_len > 0) {
			ie_data = (custom_ie *)(((t_u8 *)&misc->param.cust_ie) +
						app_data_len);
			ioctl_len -=
				(ie_data->ie_length + MLAN_CUSTOM_IE_HDR_SIZE);
			app_data_len +=
				(ie_data->ie_length + MLAN_CUSTOM_IE_HDR_SIZE);

			index = ie_data->ie_index;
			mask = ie_data->mgmt_subtype_mask;

			/* Need to be Autohandled */
			if (MLAN_CUSTOM_IE_AUTO_IDX_MASK == index) {
				/* Automatic Deletion */
				if (mask == MLAN_CUSTOM_IE_DELETE_MASK) {
					ret = wlan_custom_ioctl_auto_delete
						(pmpriv, pioctl_req, ie_data,
						 index);
					/* if IE to delete is not found, return
					 * error */
					if (ret == MLAN_STATUS_FAILURE)
						goto done;
					index = ie_data->ie_index;
					memset(pmadapter, ie_data, 0,
					       sizeof(custom_ie) *
					       MAX_MGMT_IE_INDEX_TO_FW);
					len = 0;
					for (i = 0;
					     i < pmadapter->max_mgmt_ie_index;
					     i++) {
						/* Check if index is updated
						 * before sending to FW */
						if (index & ((t_u16)1) << i) {
							memcpy_ext(pmadapter,
								   (t_u8 *)
								   ie_data +
								   len, &i,
								   sizeof
								   (ie_data->
								    ie_index),
								   sizeof
								   (ie_data->
								    ie_index));
							len += sizeof(ie_data->
								      ie_index);
							memcpy_ext(pmadapter,
								   (t_u8 *)
								   ie_data +
								   len,
								   &pmpriv->
								   mgmt_ie[i]
								   .
								   mgmt_subtype_mask,
								   sizeof
								   (ie_data->
								    mgmt_subtype_mask),
								   sizeof
								   (ie_data->
								    mgmt_subtype_mask));
							len += sizeof(ie_data->
								      mgmt_subtype_mask);
							memcpy_ext(pmadapter,
								   (t_u8 *)
								   ie_data +
								   len,
								   &pmpriv->
								   mgmt_ie[i]
								   .ie_length,
								   sizeof
								   (ie_data->
								    ie_length),
								   sizeof
								   (ie_data->
								    ie_length));
							len += sizeof(ie_data->
								      ie_length);
							if (pmpriv->mgmt_ie[i]
							    .ie_length) {
								memcpy_ext
									(pmadapter,
									 (t_u8
									  *)
									 ie_data
									 + len,
									 &pmpriv->
									 mgmt_ie
									 [i]
									 .
									 ie_buffer,
									 pmpriv->
									 mgmt_ie
									 [i]
									 .
									 ie_length,
									 pmpriv->
									 mgmt_ie
									 [i]
									 .
									 ie_length);
								len += pmpriv->
									mgmt_ie
									[i]
									.
									ie_length;
							}
						}
					}
					misc->param.cust_ie.len += len;
					pioctl_req->action = MLAN_ACT_SET;
					cmd_action = HostCmd_ACT_GEN_SET;
				} else {	/* Automatic Addition */
					if (MLAN_STATUS_FAILURE ==
					    wlan_custom_ioctl_get_autoidx
					    (pmpriv, pioctl_req, mask, ie_data,
					     &index)) {
						PRINTM(MERROR,
						       "Failed to Set the IE buffer\n");
						ret = MLAN_STATUS_FAILURE;
						goto done;
					}
					mask &= ~MLAN_CUSTOM_IE_NEW_MASK;
					if (MLAN_CUSTOM_IE_AUTO_IDX_MASK ==
					    index ||
					    index >= MAX_MGMT_IE_INDEX) {
						ret = MLAN_STATUS_SUCCESS;
						goto done;
					}
					tmp_ie = (t_u8 *)&pmpriv->mgmt_ie[index]
						.ie_buffer;
					memcpy_ext(pmadapter,
						   tmp_ie +
						   pmpriv->mgmt_ie[index]
						   .ie_length,
						   &ie_data->ie_buffer,
						   ie_data->ie_length,
						   ie_data->ie_length);
					pmpriv->mgmt_ie[index].ie_length +=
						ie_data->ie_length;
					pmpriv->mgmt_ie[index].ie_index = index;
					pmpriv->mgmt_ie[index]
						.mgmt_subtype_mask = mask;

					pioctl_req->action = MLAN_ACT_SET;
					cmd_action = HostCmd_ACT_GEN_SET;
					ie_data->ie_index = index;
					ie_data->ie_length =
						pmpriv->mgmt_ie[index].
						ie_length;
					memcpy_ext(pmadapter,
						   &ie_data->ie_buffer,
						   &pmpriv->mgmt_ie[index]
						   .ie_buffer,
						   pmpriv->mgmt_ie[index].
						   ie_length, MAX_IE_SIZE);
					misc->param.cust_ie.len +=
						pmpriv->mgmt_ie[index]
						.ie_length +
						MLAN_CUSTOM_IE_HDR_SIZE;
				}
			} else {
				if (index >= pmadapter->max_mgmt_ie_index ||
				    index >= MAX_MGMT_IE_INDEX) {
					PRINTM(MERROR,
					       "Invalid custom IE index %d\n",
					       index);
					ret = MLAN_STATUS_FAILURE;
					goto done;
				}
				/* Set/Clear the IE and save it */
				if (ie_data->mgmt_subtype_mask ==
				    MLAN_CUSTOM_IE_DELETE_MASK &&
				    ie_data->ie_length) {
					PRINTM(MINFO, "Clear the IE buffer\n");
					ret = wlan_custom_ioctl_auto_delete
						(pmpriv, pioctl_req, ie_data,
						 index);
					/* if IE to delete is not found, return
					 * error */
					if (ret == MLAN_STATUS_FAILURE)
						goto done;
					memset(pmadapter, ie_data, 0,
					       sizeof(custom_ie) *
					       MAX_MGMT_IE_INDEX_TO_FW);
					memcpy_ext(pmadapter, (t_u8 *)ie_data,
						   &pmpriv->mgmt_ie[index],
						   pmpriv->mgmt_ie[index].
						   ie_length +
						   MLAN_CUSTOM_IE_HDR_SIZE,
						   pmpriv->mgmt_ie[index].
						   ie_length +
						   MLAN_CUSTOM_IE_HDR_SIZE);
				} else {
					/*
					 * Check if this index is being used on
					 * any other interfaces. If yes, then
					 * the request needs to be rejected.
					 */
					ret = wlan_is_custom_ie_index_unused
						(pmpriv, index);
					if (ret == MLAN_STATUS_FAILURE) {
						PRINTM(MERROR,
						       "IE index is used by other interface.\n");
						PRINTM(MERROR,
						       "Set or delete on index %d is not allowed.\n",
						       index);
						pioctl_req->status_code =
							MLAN_ERROR_IOCTL_FAIL;
						goto done;
					}
					PRINTM(MINFO, "Set the IE buffer\n");
					if (ie_data->mgmt_subtype_mask ==
					    MLAN_CUSTOM_IE_DELETE_MASK)
						ie_data->ie_length = 0;
					else {
						if ((pmpriv->mgmt_ie[index]
						     .mgmt_subtype_mask ==
						     ie_data->mgmt_subtype_mask)
						    && (pmpriv->mgmt_ie[index]
							.ie_length ==
							ie_data->ie_length) &&
						    !memcmp(pmpriv->adapter,
							    pmpriv->
							    mgmt_ie[index]
							    .ie_buffer,
							    ie_data->ie_buffer,
							    ie_data->
							    ie_length)) {
							PRINTM(MIOCTL,
							       "same custom ie already configured!\n");
							if (ioctl_len <= 0 &&
							    misc->param.cust_ie.
							    len == 0) {
								goto done;
							} else {
								/* remove
								 * matching IE
								 * from app
								 * buffer */
								app_data_len -=
									ie_data->
									ie_length
									+
									MLAN_CUSTOM_IE_HDR_SIZE;
								memmove(pmadapter, (t_u8 *)ie_data, ie_data->ie_buffer + ie_data->ie_length, ioctl_len);
								continue;
							}
						}
					}
					memset(pmadapter,
					       &pmpriv->mgmt_ie[index], 0,
					       sizeof(custom_ie));
					memcpy_ext(pmadapter,
						   &pmpriv->mgmt_ie[index],
						   ie_data, sizeof(custom_ie),
						   sizeof(custom_ie));
				}

				misc->param.cust_ie.len +=
					pmpriv->mgmt_ie[index].ie_length +
					MLAN_CUSTOM_IE_HDR_SIZE;
				pioctl_req->action = MLAN_ACT_SET;
				cmd_action = HostCmd_ACT_GEN_SET;
			}
		}
	}

	/* Send command to firmware */
	if (GET_BSS_ROLE(pmpriv) == MLAN_BSS_ROLE_STA) {
		ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_MGMT_IE_LIST,
				       cmd_action, 0,
				       (send_ioctl) ? (t_void *)pioctl_req :
				       MNULL, &misc->param.cust_ie);
	}
#ifdef UAP_SUPPORT
	else if (GET_BSS_ROLE(pmpriv) == MLAN_BSS_ROLE_UAP) {
		ret = wlan_prepare_cmd(pmpriv, HOST_CMD_APCMD_SYS_CONFIGURE,
				       cmd_action, 0,
				       (send_ioctl) ? (t_void *)pioctl_req :
				       MNULL,
				       (send_ioctl) ? MNULL : &misc->param.
				       cust_ie);
	}
#endif
	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;
done:
	LEAVE();
	return ret;
}

/**
 *  @brief Read/write adapter register
 *
 *  @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_reg_mem_ioctl_reg_rw(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_reg_mem *reg_mem = MNULL;
	mlan_status ret = MLAN_STATUS_SUCCESS;
	t_u16 cmd_action = 0, cmd_no;

	ENTER();

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

	switch (reg_mem->param.reg_rw.type) {
	case MLAN_REG_MAC:
#if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || defined(PCIE9097) || defined(USB9097) || defined(SD9097)
	case MLAN_REG_MAC2:
#endif
		cmd_no = HostCmd_CMD_MAC_REG_ACCESS;
		break;
	case MLAN_REG_BBP:
#if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || defined(PCIE9097) || defined(USB9097) || defined(SD9097)
	case MLAN_REG_BBP2:
#endif
		cmd_no = HostCmd_CMD_BBP_REG_ACCESS;
		break;
	case MLAN_REG_RF:
#if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || defined(PCIE9097) || defined(USB9097) || defined(SD9097)
	case MLAN_REG_RF2:
#endif
		cmd_no = HostCmd_CMD_RF_REG_ACCESS;
		break;
	case MLAN_REG_CAU:
		cmd_no = HostCmd_CMD_CAU_REG_ACCESS;
		break;
	case MLAN_REG_PSU:
		cmd_no = HostCmd_CMD_TARGET_ACCESS;
		break;
	case MLAN_REG_BCA:
#if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || defined(PCIE9097) || defined(USB9097) || defined(SD9097)
	case MLAN_REG_BCA2:
#endif
		cmd_no = HostCmd_CMD_BCA_REG_ACCESS;
		break;
	default:
		pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID;
		ret = MLAN_STATUS_FAILURE;
		goto exit;
	}

	/* Send request to firmware */
	ret = wlan_prepare_cmd(pmpriv, cmd_no, cmd_action, 0,
			       (t_void *)pioctl_req,
			       (t_void *)&reg_mem->param.reg_rw);

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

exit:
	LEAVE();
	return ret;
}

/**
 *  @brief Read the EEPROM contents of the card
 *
 *  @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_reg_mem_ioctl_read_eeprom(pmlan_adapter pmadapter,
			       pmlan_ioctl_req pioctl_req)
{
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_reg_mem *reg_mem = MNULL;
	mlan_status ret = MLAN_STATUS_SUCCESS;
	t_u16 cmd_action = 0;

	ENTER();

	reg_mem = (mlan_ds_reg_mem *)pioctl_req->pbuf;
	if (pioctl_req->action == MLAN_ACT_GET)
		cmd_action = HostCmd_ACT_GEN_GET;

	/* Send request to firmware */
	ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_EEPROM_ACCESS,
			       cmd_action, 0, (t_void *)pioctl_req,
			       (t_void *)&reg_mem->param.rd_eeprom);

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief Read/write memory of device
 *
 *  @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_reg_mem_ioctl_mem_rw(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_reg_mem *reg_mem = MNULL;
	mlan_status ret = MLAN_STATUS_SUCCESS;
	t_u16 cmd_action = 0;

	ENTER();

	reg_mem = (mlan_ds_reg_mem *)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_MEM_ACCESS, cmd_action, 0,
			       (t_void *)pioctl_req,
			       (t_void *)&reg_mem->param.mem_rw);

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief This function will check if station list is empty
 *
 *  @param priv    A pointer to mlan_private
 *
 *  @return	   MFALSE/MTRUE
 */
t_u8
wlan_is_station_list_empty(mlan_private *priv)
{
	ENTER();
	if (!(util_peek_list(priv->adapter->pmoal_handle, &priv->sta_list,
			     priv->adapter->callbacks.moal_spin_lock,
			     priv->adapter->callbacks.moal_spin_unlock))) {
		LEAVE();
		return MTRUE;
	}
	LEAVE();
	return MFALSE;
}

/**
 *  @brief This function will return the pointer to station entry in station
 * list table which matches the give mac address
 *
 *  @param priv    A pointer to mlan_private
 *  @param mac     mac address to find in station list table
 *
 *  @return	   A pointer to structure sta_node
 */
sta_node *
wlan_get_station_entry(mlan_private *priv, t_u8 *mac)
{
	sta_node *sta_ptr;

	ENTER();

	if (!mac) {
		LEAVE();
		return MNULL;
	}
	sta_ptr =
		(sta_node *)util_peek_list(priv->adapter->pmoal_handle,
					   &priv->sta_list, MNULL, MNULL);

	while (sta_ptr && (sta_ptr != (sta_node *)&priv->sta_list)) {
		if (!memcmp(priv->adapter, sta_ptr->mac_addr, mac,
			    MLAN_MAC_ADDR_LENGTH)) {
			LEAVE();
			return sta_ptr;
		}
		sta_ptr = sta_ptr->pnext;
	}
	LEAVE();
	return MNULL;
}

/**
 *  @brief This function will add a pointer to station entry in station list
 *          table with the give mac address, if it does not exist already
 *
 *  @param priv    A pointer to mlan_private
 *  @param mac     mac address to find in station list table
 *
 *  @return	   A pointer to structure sta_node
 */
sta_node *
wlan_add_station_entry(mlan_private *priv, t_u8 *mac)
{
	sta_node *sta_ptr = MNULL;

	ENTER();

	sta_ptr = wlan_get_station_entry(priv, mac);
	if (sta_ptr)
		goto done;
	if (priv->adapter->callbacks.moal_malloc(priv->adapter->pmoal_handle,
						 sizeof(sta_node), MLAN_MEM_DEF,
						 (t_u8 **)&sta_ptr)) {
		PRINTM(MERROR, "Failed to allocate memory for station node\n");
		LEAVE();
		return MNULL;
	}
	memset(priv->adapter, sta_ptr, 0, sizeof(sta_node));
	memcpy_ext(priv->adapter, sta_ptr->mac_addr, mac, MLAN_MAC_ADDR_LENGTH,
		   MLAN_MAC_ADDR_LENGTH);
	util_enqueue_list_tail(priv->adapter->pmoal_handle, &priv->sta_list,
			       (pmlan_linked_list)sta_ptr,
			       priv->adapter->callbacks.moal_spin_lock,
			       priv->adapter->callbacks.moal_spin_unlock);
#ifdef DRV_EMBEDDED_AUTHENTICATOR
	if ((GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_UAP) &&
	    IsAuthenticatorEnabled(priv->psapriv))
		authenticator_init_client(priv->psapriv,
					  &sta_ptr->cm_connectioninfo, mac);
#endif
done:
	LEAVE();
	return sta_ptr;
}

/**
 *  @brief This function will delete a station entry from station list
 *
 *
 *  @param priv    A pointer to mlan_private
 *  @param mac     station's mac address
 *
 *  @return	   N/A
 */
t_void
wlan_delete_station_entry(mlan_private *priv, t_u8 *mac)
{
	sta_node *sta_ptr = MNULL;
	ENTER();
	sta_ptr = wlan_get_station_entry(priv, mac);
	if (sta_ptr) {
#ifdef DRV_EMBEDDED_AUTHENTICATOR
		if ((GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_UAP) &&
		    IsAuthenticatorEnabled(priv->psapriv))
			authenticator_free_client(priv->psapriv,
						  sta_ptr->cm_connectioninfo);
#endif
		util_unlink_list(priv->adapter->pmoal_handle, &priv->sta_list,
				 (pmlan_linked_list)sta_ptr,
				 priv->adapter->callbacks.moal_spin_lock,
				 priv->adapter->callbacks.moal_spin_unlock);
		priv->adapter->callbacks.moal_mfree(priv->adapter->pmoal_handle,
						    (t_u8 *)sta_ptr);
	}

	LEAVE();
	return;
}

/**
 *  @brief Clean up wapi station list
 *
 *  @param priv  Pointer to the mlan_private driver data struct
 *
 *  @return      N/A
 */
t_void
wlan_delete_station_list(pmlan_private priv)
{
	sta_node *sta_ptr;

	ENTER();
	while ((sta_ptr =
		(sta_node *)util_dequeue_list(priv->adapter->pmoal_handle,
					      &priv->sta_list,
					      priv->adapter->callbacks.
					      moal_spin_lock,
					      priv->adapter->callbacks.
					      moal_spin_unlock))) {
#ifdef DRV_EMBEDDED_AUTHENTICATOR
		if ((GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_UAP) &&
		    IsAuthenticatorEnabled(priv->psapriv))
			authenticator_free_client(priv->psapriv,
						  sta_ptr->cm_connectioninfo);
#endif
		priv->adapter->callbacks.moal_mfree(priv->adapter->pmoal_handle,
						    (t_u8 *)sta_ptr);
	}
	LEAVE();
	return;
}

/**
 *  @brief Get tdls peer list
 *
 *  @param priv         A pointer to mlan_private structure
 *  @param buf          A pointer to tdls_peer_info buf
 *  @return             number of tdls peer
 */
int
wlan_get_tdls_list(mlan_private *priv, tdls_peer_info *buf)
{
	tdls_peer_info *peer_info = buf;
	sta_node *sta_ptr = MNULL;
	int count = 0;
	ENTER();
	if (priv->bss_type != MLAN_BSS_TYPE_STA) {
		LEAVE();
		return count;
	}
	sta_ptr =
		(sta_node *)util_peek_list(priv->adapter->pmoal_handle,
					   &priv->sta_list,
					   priv->adapter->callbacks.
					   moal_spin_lock,
					   priv->adapter->callbacks.
					   moal_spin_unlock);
	if (!sta_ptr) {
		LEAVE();
		return count;
	}
	while (sta_ptr != (sta_node *)&priv->sta_list) {
		if (sta_ptr->status == TDLS_SETUP_COMPLETE) {
			peer_info->snr = sta_ptr->snr;
			peer_info->nf = sta_ptr->nf;
			memcpy_ext(priv->adapter, peer_info->mac_addr,
				   sta_ptr->mac_addr, MLAN_MAC_ADDR_LENGTH,
				   MLAN_MAC_ADDR_LENGTH);
			memcpy_ext(priv->adapter, peer_info->ht_cap,
				   &sta_ptr->HTcap, sizeof(IEEEtypes_HTCap_t),
				   sizeof(peer_info->ht_cap));
			memcpy_ext(priv->adapter, peer_info->ext_cap,
				   &sta_ptr->ExtCap, sizeof(IEEEtypes_ExtCap_t),
				   sizeof(peer_info->ext_cap));
			memcpy_ext(priv->adapter, peer_info->vht_cap,
				   &sta_ptr->vht_cap,
				   sizeof(IEEEtypes_VHTCap_t),
				   sizeof(peer_info->vht_cap));
			peer_info++;
			count++;
		}
		sta_ptr = sta_ptr->pnext;
		if (count >= MLAN_MAX_TDLS_PEER_SUPPORTED)
			break;
	}
	LEAVE();
	return count;
}

/**
 *  @brief Set the TDLS configuration to FW.
 *
 *  @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_tdls_config(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 = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
	tdls_all_config *tdls_all_cfg =
		(tdls_all_config *)misc->param.tdls_config.tdls_data;
	t_u8 event_buf[100];
	mlan_event *pevent = (mlan_event *)event_buf;
	tdls_tear_down_event *tdls_evt =
		(tdls_tear_down_event *)pevent->event_buf;
	sta_node *sta_ptr = MNULL;
	MrvlIEtypes_Data_t *pMrvlTlv = MNULL;
	t_u8 *pos = MNULL;
	t_u16 remain_len = 0;

	ENTER();

	if (misc->param.tdls_config.tdls_action == WLAN_TDLS_TEAR_DOWN_REQ) {
		sta_ptr =
			wlan_get_station_entry(pmpriv,
					       tdls_all_cfg->u.tdls_tear_down.
					       peer_mac_addr);
		if (sta_ptr && sta_ptr->external_tdls) {
			pevent->bss_index = pmpriv->bss_index;
			pevent->event_id = MLAN_EVENT_ID_DRV_TDLS_TEARDOWN_REQ;
			pevent->event_len = sizeof(tdls_tear_down_event);
			memcpy_ext(pmpriv->adapter,
				   (t_u8 *)tdls_evt->peer_mac_addr,
				   tdls_all_cfg->u.tdls_tear_down.peer_mac_addr,
				   MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
			tdls_evt->reason_code =
				tdls_all_cfg->u.tdls_tear_down.reason_code;
			wlan_recv_event(pmpriv,
					MLAN_EVENT_ID_DRV_TDLS_TEARDOWN_REQ,
					pevent);
			LEAVE();
			return ret;
		}
	}
	if (misc->param.tdls_config.tdls_action == WLAN_HOST_TDLS_CONFIG) {
		pmpriv->host_tdls_uapsd_support =
			tdls_all_cfg->u.host_tdls_cfg.uapsd_support;
		pmpriv->host_tdls_cs_support =
			tdls_all_cfg->u.host_tdls_cfg.cs_support;
		pos = tdls_all_cfg->u.host_tdls_cfg.tlv_buffer;
		remain_len = tdls_all_cfg->u.host_tdls_cfg.tlv_len;
		while (remain_len > sizeof(MrvlIEtypesHeader_t)) {
			remain_len -= sizeof(MrvlIEtypesHeader_t);
			pMrvlTlv = (MrvlIEtypes_Data_t *)pos;
			switch (pMrvlTlv->header.type) {
			case SUPPORTED_CHANNELS:
				pmpriv->chan_supp_len =
					(t_u8)MIN(pMrvlTlv->header.len,
						  MAX_IE_SIZE);
				memset(pmadapter, pmpriv->chan_supp, 0,
				       sizeof(pmpriv->chan_supp));
				memcpy_ext(pmadapter, pmpriv->chan_supp,
					   pMrvlTlv->data, pMrvlTlv->header.len,
					   MAX_IE_SIZE);
				DBG_HEXDUMP(MCMD_D, "TDLS supported channel",
					    pmpriv->chan_supp,
					    pmpriv->chan_supp_len);
				break;
			case REGULATORY_CLASS:
				pmpriv->supp_regulatory_class_len =
					(t_u8)MIN(pMrvlTlv->header.len,
						  MAX_IE_SIZE);
				memset(pmadapter, pmpriv->supp_regulatory_class,
				       0,
				       sizeof(pmpriv->supp_regulatory_class));
				memcpy_ext(pmadapter,
					   pmpriv->supp_regulatory_class,
					   pMrvlTlv->data, pMrvlTlv->header.len,
					   MAX_IE_SIZE);
				DBG_HEXDUMP(MCMD_D,
					    "TDLS supported regulatory class",
					    pmpriv->supp_regulatory_class,
					    pmpriv->supp_regulatory_class_len);
				break;
			default:
				break;
			}
			remain_len -= pMrvlTlv->header.len;
			pos += sizeof(MrvlIEtypesHeader_t) +
				pMrvlTlv->header.len;
		}
		LEAVE();
		return ret;
	}
	pioctl_req->action = MLAN_ACT_SET;

	/* Send command to firmware */
	ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_TDLS_CONFIG,
			       HostCmd_ACT_GEN_SET, 0, (t_void *)pioctl_req,
			       &misc->param.tdls_config);

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

/**
 *  @brief enable tdls config for cs and uapsd.
 *
 *  @param pmpriv	A pointer to mlan_private structure
 *  @param enable   	MTRUE/MFALSE
 *
 *  @return
 */
t_void
wlan_tdls_config(pmlan_private pmpriv, t_u8 enable)
{
	mlan_adapter *pmadapter = pmpriv->adapter;
	mlan_callbacks *pcb = (mlan_callbacks *)&pmadapter->callbacks;
	mlan_ds_misc_tdls_config *tdls_config = MNULL;
	tdls_all_config *tdls_all_cfg = MNULL;
	mlan_status ret = MLAN_STATUS_SUCCESS;

	ENTER();

	ret = pcb->moal_malloc(pmadapter->pmoal_handle,
			       sizeof(mlan_ds_misc_tdls_config), MLAN_MEM_DEF,
			       (t_u8 **)&tdls_config);
	if (ret != MLAN_STATUS_SUCCESS || !tdls_config) {
		PRINTM(MERROR, "Memory allocation for tdls_config failed!\n");
		LEAVE();
		return;
	}
	memset(pmadapter, (t_u8 *)tdls_config, 0,
	       sizeof(mlan_ds_misc_tdls_config));
	tdls_all_cfg = (tdls_all_config *)tdls_config->tdls_data;
	tdls_all_cfg->u.tdls_config.enable = enable;
	tdls_config->tdls_action = WLAN_TDLS_CONFIG;
	/* Send command to firmware */
	wlan_prepare_cmd(pmpriv, HostCmd_CMD_TDLS_CONFIG, HostCmd_ACT_GEN_SET,
			 0, MNULL, tdls_config);
	PRINTM(MCMND, "tdls_config: enable=%d\n", enable);

	if (tdls_config)
		pcb->moal_mfree(pmadapter->pmoal_handle, (t_u8 *)tdls_config);

	LEAVE();
}

/**
 *  @brief set tdls channel switch parameters.
 *
 *  @param pmpriv	A pointer to mlan_private structure
 *
 *  @return
 */
static t_void
wlan_tdls_cs_param_config(pmlan_private pmpriv)
{
	mlan_adapter *pmadapter = pmpriv->adapter;
	mlan_callbacks *pcb = (mlan_callbacks *)&pmadapter->callbacks;
	mlan_ds_misc_tdls_config *tdls_config = MNULL;
	tdls_all_config *tdls_all_cfg = MNULL;
	mlan_status ret = MLAN_STATUS_SUCCESS;

	ENTER();

	ret = pcb->moal_malloc(pmadapter->pmoal_handle,
			       sizeof(mlan_ds_misc_tdls_config), MLAN_MEM_DEF,
			       (t_u8 **)&tdls_config);
	if (ret != MLAN_STATUS_SUCCESS || !tdls_config) {
		PRINTM(MERROR, "Memory allocation for tdls_config failed!\n");
		LEAVE();
		return;
	}
	memset(pmadapter, (t_u8 *)tdls_config, 0,
	       sizeof(mlan_ds_misc_tdls_config));

	tdls_all_cfg = (tdls_all_config *)tdls_config->tdls_data;
	tdls_config->tdls_action = WLAN_TDLS_CS_PARAMS;
	tdls_all_cfg->u.tdls_cs_params.unit_time = 2;
	tdls_all_cfg->u.tdls_cs_params.threshold_otherlink = 10;
	tdls_all_cfg->u.tdls_cs_params.threshold_directlink = 0;

	/* Send command to firmware */
	wlan_prepare_cmd(pmpriv, HostCmd_CMD_TDLS_CONFIG, HostCmd_ACT_GEN_SET,
			 0, MNULL, tdls_config);

	if (tdls_config)
		pcb->moal_mfree(pmadapter->pmoal_handle, (t_u8 *)tdls_config);

	LEAVE();
}

/**
 *  @brief start tdls channel switch
 *
 *  @param pmpriv	A pointer to mlan_private structure
 *  @param peer_mac_addr 	A pointer to peer mac address
 *  @param pioctl_buf   A pointer to ioctl request buffer
 *
 *  @return
 */
static t_void
wlan_tdls_cs_start(pmlan_private pmpriv, t_u8 *peer_mac_addr,
		   pmlan_ioctl_req pioctl_buf)
{
	mlan_adapter *pmadapter = pmpriv->adapter;
	mlan_callbacks *pcb = (mlan_callbacks *)&pmadapter->callbacks;
	mlan_ds_misc_tdls_config *tdls_config = MNULL;
	tdls_all_config *tdls_all_cfg = MNULL;
	mlan_ds_misc_cfg *misc = MNULL;
	mlan_status ret = MLAN_STATUS_SUCCESS;

	ENTER();

	ret = pcb->moal_malloc(pmadapter->pmoal_handle,
			       sizeof(mlan_ds_misc_tdls_config), MLAN_MEM_DEF,
			       (t_u8 **)&tdls_config);
	if (ret != MLAN_STATUS_SUCCESS || !tdls_config) {
		PRINTM(MERROR, "Memory allocation for tdls_config failed!\n");
		LEAVE();
		return;
	}
	memset(pmadapter, (t_u8 *)tdls_config, 0,
	       sizeof(mlan_ds_misc_tdls_config));

	if (pioctl_buf) {
		misc = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
		memcpy_ext(pmpriv->adapter, tdls_config,
			   &misc->param.tdls_config,
			   sizeof(mlan_ds_misc_tdls_config),
			   sizeof(mlan_ds_misc_tdls_config));
		tdls_all_cfg = (tdls_all_config *)tdls_config->tdls_data;
		if (tdls_all_cfg->u.tdls_chan_switch.primary_channel > 14) {
			tdls_all_cfg->u.tdls_chan_switch.
				secondary_channel_offset =
				wlan_get_second_channel_offset(pmpriv,
							       tdls_all_cfg->u.
							       tdls_chan_switch.
							       primary_channel);
		}
		PRINTM(MCMND, "Start TDLS CS: channel=%d\n",
		       tdls_all_cfg->u.tdls_chan_switch.primary_channel);
	} else {
		tdls_all_cfg = (tdls_all_config *)tdls_config->tdls_data;
		tdls_config->tdls_action = WLAN_TDLS_INIT_CHAN_SWITCH;
		memcpy_ext(pmpriv->adapter,
			   tdls_all_cfg->u.tdls_chan_switch.peer_mac_addr,
			   peer_mac_addr, MLAN_MAC_ADDR_LENGTH,
			   MLAN_MAC_ADDR_LENGTH);
		tdls_all_cfg->u.tdls_chan_switch.primary_channel =
			pmpriv->tdls_cs_channel;
		if (pmpriv->tdls_cs_channel > 14) {
			tdls_all_cfg->u.tdls_chan_switch.band = BAND_5GHZ;
			tdls_all_cfg->u.tdls_chan_switch.
				secondary_channel_offset =
				wlan_get_second_channel_offset(pmpriv,
							       pmpriv->
							       tdls_cs_channel);
		} else {
			tdls_all_cfg->u.tdls_chan_switch.band = BAND_2GHZ;
		}
		PRINTM(MCMND, "Start TDLS CS: channel=%d\n",
		       pmpriv->tdls_cs_channel);
	}
	tdls_all_cfg->u.tdls_chan_switch.switch_time = 10;
	tdls_all_cfg->u.tdls_chan_switch.switch_timeout = 16;
	tdls_all_cfg->u.tdls_chan_switch.regulatory_class = 12;
	tdls_all_cfg->u.tdls_chan_switch.periodicity = 1;

	/* Send command to firmware */
	wlan_prepare_cmd(pmpriv, HostCmd_CMD_TDLS_CONFIG, HostCmd_ACT_GEN_SET,
			 0, MNULL, tdls_config);

	if (tdls_config)
		pcb->moal_mfree(pmadapter->pmoal_handle, (t_u8 *)tdls_config);

	LEAVE();
}

#if 0
/**
 *  @brief stop tdls channel switch
 *
 *  @param pmpriv	A pointer to mlan_private structure
 *  @param peer_mac_addr 	A pointer to peer mac address
 *  @param pioctl_buf   A pointer to command buffer
 *  @return
 */
static t_void
wlan_tdls_cs_stop(pmlan_private pmpriv, t_u8 *peer_mac_addr)
{
	mlan_adapter *pmadapter = pmpriv->adapter;
	mlan_callbacks *pcb = (mlan_callbacks *)&pmadapter->callbacks;
	mlan_ds_misc_tdls_config *tdls_config = MNULL;
	tdls_all_config *tdls_all_cfg = MNULL;
	mlan_status ret = MLAN_STATUS_SUCCESS;

	ENTER();

	ret = pcb->moal_malloc(pmadapter->pmoal_handle,
			       sizeof(mlan_ds_misc_tdls_config), MLAN_MEM_DEF,
			       (t_u8 **)&tdls_config);
	if (ret != MLAN_STATUS_SUCCESS || !tdls_config) {
		PRINTM(MERROR, "Memory allocation for tdls_config failed!\n");
		LEAVE();
		return;
	}
	memset(pmadapter, (t_u8 *)tdls_config, 0,
	       sizeof(mlan_ds_misc_tdls_config));

	tdls_all_cfg = (tdls_all_config *)tdls_config->tdls_data;
	tdls_config->tdls_action = WLAN_TDLS_STOP_CHAN_SWITCH;

	memcpy_ext(pmpriv->adapter,
		   tdls_all_cfg->u.tdls_stop_chan_switch.peer_mac_addr,
		   peer_mac_addr, MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
	PRINTM(MCMND, "Stop TDLS CS\n");
	/* Send command to firmware */
	wlan_prepare_cmd(pmpriv, HostCmd_CMD_TDLS_CONFIG, HostCmd_ACT_GEN_SET,
			 0, MNULL, tdls_config);

	if (tdls_config)
		pcb->moal_mfree(pmadapter->pmoal_handle, (t_u8 *)tdls_config);

	LEAVE();
}
#endif

/**
 *  @brief Set/Get the TDLS off channel.
 *
 *  @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_tdls_cs_channel(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 = (mlan_ds_misc_cfg *)pioctl_req->pbuf;

	ENTER();

	if (MLAN_ACT_GET == pioctl_req->action)
		misc->param.tdls_cs_channel = pmpriv->tdls_cs_channel;
	else if (MLAN_ACT_SET == pioctl_req->action) {
		pmpriv->tdls_cs_channel = misc->param.tdls_cs_channel;
	}
	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get the TDLS idle time.
 *
 *  @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_tdls_idle_time(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 = (mlan_ds_misc_cfg *)pioctl_req->pbuf;

	ENTER();

	if (MLAN_ACT_GET == pioctl_req->action) {
		misc->param.tdls_idle_time = pmpriv->tdls_idle_time;
	} else if (MLAN_ACT_SET == pioctl_req->action) {
		pmpriv->tdls_idle_time = misc->param.tdls_idle_time;
	}
	LEAVE();
	return ret;
}

/**
 *  @brief Set the TDLS operation to FW.
 *
 *  @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_tdls_oper(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 = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
	mlan_ds_misc_tdls_oper *ptdls_oper = &misc->param.tdls_oper;
	t_u8 event_buf[100];
	mlan_event *ptdls_event = (mlan_event *)event_buf;
	tdls_tear_down_event *tdls_evt =
		(tdls_tear_down_event *)ptdls_event->event_buf;
	sta_node *sta_ptr = MNULL;
	t_u8 i = 0;

	ENTER();
	sta_ptr = wlan_get_station_entry(pmpriv, ptdls_oper->peer_mac);
	switch (ptdls_oper->tdls_action) {
	case WLAN_TDLS_ENABLE_LINK:
		if (sta_ptr && (sta_ptr->status != TDLS_SETUP_FAILURE)) {
			PRINTM(MMSG, "TDLS: Enable link " MACSTR " success\n",
			       MAC2STR(ptdls_oper->peer_mac));
			sta_ptr->status = TDLS_SETUP_COMPLETE;
			pmadapter->tdls_status = TDLS_IN_BASE_CHANNEL;
			if (!pmpriv->txaggrctrl)
				wlan_11n_send_delba_to_peer(pmpriv,
							    pmpriv->
							    curr_bss_params.
							    bss_descriptor.
							    mac_address);
			if (sta_ptr->HTcap.ieee_hdr.element_id == HT_CAPABILITY) {
				sta_ptr->is_11n_enabled = MTRUE;
				if (GETHT_MAXAMSDU
				    (sta_ptr->HTcap.ht_cap.ht_cap_info))
					sta_ptr->max_amsdu =
						MLAN_TX_DATA_BUF_SIZE_8K;
				else
					sta_ptr->max_amsdu =
						MLAN_TX_DATA_BUF_SIZE_4K;
				for (i = 0; i < MAX_NUM_TID; i++) {
					if (sta_ptr->is_11n_enabled)
						sta_ptr->ampdu_sta[i] =
							pmpriv->aggr_prio_tbl[i]
						.ampdu_user;
					else
						sta_ptr->ampdu_sta[i] =
							BA_STREAM_NOT_ALLOWED;
				}
				memset(pmpriv->adapter, sta_ptr->rx_seq, 0xff,
				       sizeof(sta_ptr->rx_seq));
			}
			wlan_restore_tdls_packets(pmpriv, ptdls_oper->peer_mac,
						  TDLS_SETUP_COMPLETE);
			if (ISSUPP_EXTCAP_TDLS_CHAN_SWITCH
			    (sta_ptr->ExtCap.ext_cap)) {
				wlan_tdls_config(pmpriv, MTRUE);
				wlan_tdls_cs_param_config(pmpriv);
				/**tdls cs start*/
				if (pmpriv->tdls_cs_channel &&
				    pmpriv->tdls_cs_channel !=
				    pmpriv->curr_bss_params.bss_descriptor.
				    channel)
					wlan_tdls_cs_start(pmpriv,
							   ptdls_oper->peer_mac,
							   MNULL);
			}
		} else {
			PRINTM(MMSG, "TDLS: Enable link " MACSTR " fail\n",
			       MAC2STR(ptdls_oper->peer_mac));
			/*for supplicant 2.0, we need send event to request
			 *teardown, *for latest supplicant, we only need return
			 *fail, and supplicant will send teardown packet and
			 *disable tdls link*/
			if (sta_ptr) {
				ptdls_event->bss_index = pmpriv->bss_index;
				ptdls_event->event_id =
					MLAN_EVENT_ID_DRV_TDLS_TEARDOWN_REQ;
				ptdls_event->event_len =
					sizeof(tdls_tear_down_event);
				memcpy_ext(pmpriv->adapter,
					   (t_u8 *)tdls_evt->peer_mac_addr,
					   ptdls_oper->peer_mac,
					   MLAN_MAC_ADDR_LENGTH,
					   MLAN_MAC_ADDR_LENGTH);
				tdls_evt->reason_code =
					MLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED;
				wlan_recv_event(pmpriv,
						MLAN_EVENT_ID_DRV_TDLS_TEARDOWN_REQ,
						ptdls_event);
				wlan_restore_tdls_packets(pmpriv,
							  ptdls_oper->peer_mac,
							  TDLS_TEAR_DOWN);
				if (sta_ptr->is_11n_enabled) {
					wlan_cleanup_reorder_tbl(pmpriv,
								 ptdls_oper->
								 peer_mac);
					wlan_11n_cleanup_txbastream_tbl(pmpriv,
									ptdls_oper->
									peer_mac);
				}
				wlan_delete_station_entry(pmpriv,
							  ptdls_oper->peer_mac);
				if (MTRUE == wlan_is_station_list_empty(pmpriv))
					pmadapter->tdls_status = TDLS_NOT_SETUP;
				else
					pmadapter->tdls_status =
						TDLS_IN_BASE_CHANNEL;
			}
			ret = MLAN_STATUS_FAILURE;
		}
		wlan_recv_event(pmpriv, MLAN_EVENT_ID_DRV_DEFER_HANDLING,
				MNULL);
		break;
	case WLAN_TDLS_DISABLE_LINK:
		/* Send command to firmware to delete tdls link */
		ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_TDLS_OPERATION,
				       HostCmd_ACT_GEN_SET, 0,
				       (t_void *)pioctl_req, ptdls_oper);
		if (ret == MLAN_STATUS_SUCCESS)
			ret = MLAN_STATUS_PENDING;
		break;
	case WLAN_TDLS_CREATE_LINK:
		PRINTM(MIOCTL, "CREATE TDLS LINK\n");
		if (sta_ptr && sta_ptr->status == TDLS_SETUP_INPROGRESS) {
			PRINTM(MIOCTL, "We already create the link\n");
			break;
		}
		if (!sta_ptr)
			sta_ptr =
				wlan_add_station_entry(pmpriv,
						       misc->param.tdls_oper.
						       peer_mac);
		if (sta_ptr) {
			sta_ptr->status = TDLS_SETUP_INPROGRESS;
			sta_ptr->external_tdls = MTRUE;
			wlan_hold_tdls_packets(pmpriv,
					       misc->param.tdls_oper.peer_mac);
		}
		ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_TDLS_OPERATION,
				       HostCmd_ACT_GEN_SET, 0,
				       (t_void *)pioctl_req, ptdls_oper);
		if (ret == MLAN_STATUS_SUCCESS)
			ret = MLAN_STATUS_PENDING;
		break;
	case WLAN_TDLS_CONFIG_LINK:
		if (!sta_ptr || sta_ptr->status == TDLS_SETUP_FAILURE) {
			PRINTM(MERROR, "Can not CONFIG TDLS Link\n");
			ret = MLAN_STATUS_FAILURE;
			break;
		}
		ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_TDLS_OPERATION,
				       HostCmd_ACT_GEN_SET, 0,
				       (t_void *)pioctl_req, ptdls_oper);
		if (ret == MLAN_STATUS_SUCCESS)
			ret = MLAN_STATUS_PENDING;
		break;
	case WLAN_TDLS_INIT_CHAN_SWITCH:
		if (sta_ptr &&
		    ISSUPP_EXTCAP_TDLS_CHAN_SWITCH(sta_ptr->ExtCap.ext_cap)) {
			wlan_tdls_config(pmpriv, MTRUE);
			wlan_tdls_cs_param_config(pmpriv);
			/**tdls cs start*/
			wlan_tdls_cs_start(pmpriv, ptdls_oper->peer_mac,
					   pioctl_req);
		}
		wlan_recv_event(pmpriv, MLAN_EVENT_ID_DRV_DEFER_HANDLING,
				MNULL);
		break;
	default:
		break;
	}
	LEAVE();
	return ret;
}

/**
 *  @brief Get AP's ext capability
 *
 *  @param pmpriv	A pointer to mlan_adapter structure
 *  @param ext_cap  A pointer to ExtCap_t structure
 *
 *  @return		MLAN_STATUS_PENDING --success, otherwise fail
 */
static void
wlan_get_ap_ext_cap(mlan_private *pmpriv, ExtCap_t *ext_cap)
{
	pmlan_adapter pmadapter = pmpriv->adapter;
	BSSDescriptor_t *pbss_desc;
	pbss_desc = &pmpriv->curr_bss_params.bss_descriptor;
	memset(pmadapter, ext_cap, 0, sizeof(ExtCap_t));
	if (pbss_desc->pext_cap) {
		memcpy_ext(pmadapter, (t_u8 *)ext_cap,
			   (t_u8 *)pbss_desc->pext_cap +
			   sizeof(IEEEtypes_Header_t),
			   pbss_desc->pext_cap->ieee_hdr.len, sizeof(ExtCap_t));
	}
	return;
}

/**
 *  @brief Set the TDLS operation to FW.
 *
 *  @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_tdls_get_ies(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_ds_misc_tdls_ies *tdls_ies = &misc->param.tdls_ies;
	mlan_status ret = MLAN_STATUS_SUCCESS;
	BSSDescriptor_t *pbss_desc;
	t_u32 usr_dot_11n_dev_cap;
	IEEEtypes_ExtCap_t *ext_cap = MNULL;
	ExtCap_t ap_ext_cap;
	IEEEtypes_HTCap_t *ht_cap = MNULL;
	IEEEtypes_HTInfo_t *ht_info = MNULL;
	IEEEtypes_VHTCap_t *vht_cap = MNULL;
	IEEEtypes_VHTOprat_t *vht_oprat = MNULL;
	IEEEtypes_AssocRsp_t *passoc_rsp = MNULL;
	IEEEtypes_AID_t *aid_info = MNULL;
	t_u8 supp_chan[] = { 1, 11 };
	t_u8 regulatory_class[] = { 1, /**current class*/
		1, 2, 3, 4, 12, 22, 23, 24,
		25, 27, 28, 29, 30, 32, 33
	};							  /**list
								     regulatory
								     class*/
	IEEEtypes_Generic_t *pSupp_chan = MNULL, *pRegulatory_class = MNULL;
	sta_node *sta_ptr = MNULL;
	ENTER();

	/* We don't need peer information for TDLS setup */
	if (!(tdls_ies->flags & TDLS_IE_FLAGS_SETUP))
		sta_ptr = wlan_get_station_entry(pmpriv, tdls_ies->peer_mac);
	pbss_desc = &pmpriv->curr_bss_params.bss_descriptor;
	wlan_get_ap_ext_cap(pmpriv, &ap_ext_cap);
	if (pbss_desc->bss_band & BAND_A)
		usr_dot_11n_dev_cap = pmpriv->usr_dot_11n_dev_cap_a;
	else
		usr_dot_11n_dev_cap = pmpriv->usr_dot_11n_dev_cap_bg;

	/** fill the extcap */
	if (tdls_ies->flags & TDLS_IE_FLAGS_EXTCAP) {
		ext_cap = (IEEEtypes_ExtCap_t *)tdls_ies->ext_cap;
		ext_cap->ieee_hdr.element_id = EXT_CAPABILITY;
		ext_cap->ieee_hdr.len = sizeof(ExtCap_t);
		SET_EXTCAP_TDLS(ext_cap->ext_cap);
		RESET_EXTCAP_TDLS_UAPSD(ext_cap->ext_cap);
		RESET_EXTCAP_TDLS_CHAN_SWITCH(ext_cap->ext_cap);

		if (pmpriv->host_tdls_uapsd_support) {
			/* uapsd in tdls confirm frame */
			if (tdls_ies->flags & TDLS_IE_FLAGS_HTINFO) {
				if (sta_ptr &&
				    ISSUPP_EXTCAP_TDLS_UAPSD(sta_ptr->ExtCap.
							     ext_cap))
					SET_EXTCAP_TDLS_UAPSD(ext_cap->ext_cap);
			} else {
				SET_EXTCAP_TDLS_UAPSD(ext_cap->ext_cap);
			}
		}
		/*  channel switch support */
		if (pmpriv->host_tdls_cs_support &&
		    !IS_EXTCAP_TDLS_CHLSWITCHPROHIB(ap_ext_cap)) {
			/* channel switch in tdls confirm frame */
			if (tdls_ies->flags & TDLS_IE_FLAGS_HTINFO) {
				if (sta_ptr &&
				    ISSUPP_EXTCAP_TDLS_CHAN_SWITCH(sta_ptr->
								   ExtCap.
								   ext_cap))
					SET_EXTCAP_TDLS_CHAN_SWITCH(ext_cap->
								    ext_cap);
			} else {
				SET_EXTCAP_TDLS_CHAN_SWITCH(ext_cap->ext_cap);
			}
		}

		RESET_EXTCAP_TDLS_WIDER_BANDWIDTH(ext_cap->ext_cap);
		if ((pmadapter->fw_bands & BAND_AAC) &&
		    (MFALSE == wlan_is_ap_in_11ac_mode(pmpriv)))
			SET_EXTCAP_TDLS_WIDER_BANDWIDTH(ext_cap->ext_cap);
		/* if peer does not support wider bandwidth, don't set wider
		 * bandwidth*/
		if (sta_ptr && sta_ptr->rate_len &&
		    !ISSUPP_EXTCAP_TDLS_WIDER_BANDWIDTH(sta_ptr->ExtCap.
							ext_cap))
			RESET_EXTCAP_TDLS_WIDER_BANDWIDTH(ext_cap->ext_cap);
		DBG_HEXDUMP(MCMD_D, "TDLS extcap", tdls_ies->ext_cap,
			    sizeof(IEEEtypes_ExtCap_t));
	}

	/** default qos info is 0xf, compare with peer device qos info for tdls
	 * confirm */
	if (tdls_ies->flags & TDLS_IE_FLAGS_QOS_INFO) {
		if (sta_ptr && sta_ptr->rate_len)
			tdls_ies->QosInfo = sta_ptr->qos_info & 0xf;
		PRINTM(MCMND, "TDLS Qos info=0x%x\n", tdls_ies->QosInfo);
	}

	/** fill the htcap based on hwspec */
	if (tdls_ies->flags & TDLS_IE_FLAGS_HTCAP) {
		ht_cap = (IEEEtypes_HTCap_t *)tdls_ies->ht_cap;
		memset(pmadapter, ht_cap, 0, sizeof(IEEEtypes_HTCap_t));
		if ((sta_ptr &&
		     !ISSUPP_EXTCAP_TDLS_CHAN_SWITCH(sta_ptr->ExtCap.ext_cap))
		    || IS_EXTCAP_TDLS_CHLSWITCHPROHIB(ap_ext_cap))
			wlan_fill_ht_cap_ie(pmpriv, ht_cap,
					    pbss_desc->bss_band);
		else if (pmpriv->host_tdls_cs_support &&
			 (pmadapter->fw_bands & BAND_A))
			wlan_fill_ht_cap_ie(pmpriv, ht_cap, BAND_A);
		else
			wlan_fill_ht_cap_ie(pmpriv, ht_cap,
					    pbss_desc->bss_band);
		DBG_HEXDUMP(MCMD_D, "TDLS htcap", tdls_ies->ht_cap,
			    sizeof(IEEEtypes_HTCap_t));
	}
	/** if peer did not support 11AC, do not add vht related ie */
	if (sta_ptr && sta_ptr->rate_len &&
	    (sta_ptr->vht_cap.ieee_hdr.element_id != VHT_CAPABILITY))
		tdls_ies->flags &=
			~(TDLS_IE_FLAGS_VHTCAP | TDLS_IE_FLAGS_VHTOPRAT |
			  TDLS_IE_FLAGS_AID);
	/** fill the vhtcap based on hwspec */
	if (tdls_ies->flags & TDLS_IE_FLAGS_VHTCAP) {
		vht_cap = (IEEEtypes_VHTCap_t *)tdls_ies->vht_cap;
		memset(pmadapter, vht_cap, 0, sizeof(IEEEtypes_VHTCap_t));
		wlan_fill_vht_cap_ie(pmpriv, vht_cap, pbss_desc->bss_band);
		if (ht_cap)
			SETHT_SUPPCHANWIDTH(ht_cap->ht_cap.ht_cap_info);
		DBG_HEXDUMP(MCMD_D, "TDLS vhtcap", tdls_ies->vht_cap,
			    sizeof(IEEEtypes_VHTCap_t));
	}
	/** fill the vhtoperation based on hwspec */
	if (tdls_ies->flags & TDLS_IE_FLAGS_VHTOPRAT) {
		vht_oprat = (IEEEtypes_VHTOprat_t *)tdls_ies->vht_oprat;
		memset(pmadapter, vht_oprat, 0, sizeof(IEEEtypes_VHTOprat_t));
		if (sta_ptr &&
		    (sta_ptr->vht_cap.ieee_hdr.element_id == VHT_CAPABILITY) &&
		    (pbss_desc->bss_band & BAND_A)) {
			wlan_fill_tdls_vht_oprat_ie(pmpriv, vht_oprat, sta_ptr);
		}
		if (sta_ptr)
			memcpy_ext(pmadapter, &sta_ptr->vht_oprat,
				   tdls_ies->vht_oprat,
				   sizeof(IEEEtypes_VHTOprat_t),
				   sizeof(IEEEtypes_VHTOprat_t));
		DBG_HEXDUMP(MCMD_D, "TDLS vht_oprat", tdls_ies->vht_oprat,
			    sizeof(IEEEtypes_VHTOprat_t));
	}
	/** fill the AID info */
	if (tdls_ies->flags & TDLS_IE_FLAGS_AID) {
		if (pmpriv->curr_bss_params.host_mlme)
			passoc_rsp =
				(IEEEtypes_AssocRsp_t *)(pmpriv->assoc_rsp_buf +
							 sizeof
							 (IEEEtypes_MgmtHdr_t));
		else
			passoc_rsp =
				(IEEEtypes_AssocRsp_t *)pmpriv->assoc_rsp_buf;
		aid_info = (IEEEtypes_AID_t *)tdls_ies->aid_info;
		memset(pmadapter, aid_info, 0, sizeof(IEEEtypes_AID_t));
		aid_info->ieee_hdr.element_id = AID_INFO;
		aid_info->ieee_hdr.len = sizeof(t_u16);
		aid_info->AID = wlan_le16_to_cpu(passoc_rsp->a_id);
		PRINTM(MCMND, "TDLS AID=0x%x\n", aid_info->AID);
	}
	/** fill the htinfo */
	if (tdls_ies->flags & TDLS_IE_FLAGS_HTINFO) {
		ht_info = (IEEEtypes_HTInfo_t *)tdls_ies->ht_info;
		pbss_desc = &pmpriv->curr_bss_params.bss_descriptor;
		ht_info->ieee_hdr.element_id = HT_OPERATION;
		ht_info->ieee_hdr.len = sizeof(HTInfo_t);
		ht_info->ht_info.pri_chan = pbss_desc->channel;
		/* follow AP's channel bandwidth */
		if (ISSUPP_CHANWIDTH40(usr_dot_11n_dev_cap) &&
		    pbss_desc->pht_info &&
		    ISALLOWED_CHANWIDTH40(pbss_desc->pht_info->ht_info.
					  field2)) {
			ht_info->ht_info.field2 =
				pbss_desc->pht_info->ht_info.field2;
		} else {
			ht_info->ht_info.field2 =
				wlan_get_second_channel_offset(pmpriv,
							       pbss_desc->
							       channel);
		}
		if (vht_oprat &&
		    vht_oprat->ieee_hdr.element_id == VHT_OPERATION) {
			ht_info->ht_info.field2 =
				wlan_get_second_channel_offset(pmpriv,
							       pbss_desc->
							       channel);
			ht_info->ht_info.field2 |= MBIT(2);
		}
		if (sta_ptr)
			memcpy_ext(pmadapter, &sta_ptr->HTInfo,
				   tdls_ies->ht_info,
				   sizeof(IEEEtypes_HTInfo_t),
				   sizeof(IEEEtypes_HTInfo_t));
		DBG_HEXDUMP(MCMD_D, "TDLS htinfo", tdls_ies->ht_info,
			    sizeof(IEEEtypes_HTInfo_t));
	}

	/** supported channels andl regulatory IE*/
	if (pmpriv->host_tdls_cs_support &&
	    (tdls_ies->flags & TDLS_IE_FLAGS_SUPP_CS_IE) &&
	    !IS_EXTCAP_TDLS_CHLSWITCHPROHIB(ap_ext_cap)) {
		/** supported channels IE*/
		pSupp_chan = (IEEEtypes_Generic_t *)tdls_ies->supp_chan;
		pSupp_chan->ieee_hdr.element_id = SUPPORTED_CHANNELS;
		if (pmpriv->chan_supp_len) {
			pSupp_chan->ieee_hdr.len = pmpriv->chan_supp_len;
			memcpy_ext(pmadapter, pSupp_chan->data,
				   pmpriv->chan_supp, pmpriv->chan_supp_len,
				   sizeof(pSupp_chan->data));
		} else {
			pSupp_chan->ieee_hdr.len = sizeof(supp_chan);
			memcpy_ext(pmadapter, pSupp_chan->data, supp_chan,
				   sizeof(supp_chan), sizeof(pSupp_chan->data));
		}
		DBG_HEXDUMP(MCMD_D, "TDLS supported channel",
			    tdls_ies->supp_chan,
			    pSupp_chan->ieee_hdr.len +
			    sizeof(IEEEtypes_Header_t));

		/**fill supported Regulatory Class IE*/
		pRegulatory_class =
			(IEEEtypes_Generic_t *)tdls_ies->regulatory_class;
		pRegulatory_class->ieee_hdr.element_id = REGULATORY_CLASS;
		if (pmpriv->supp_regulatory_class_len) {
			pRegulatory_class->ieee_hdr.len =
				pmpriv->supp_regulatory_class_len;
			memcpy_ext(pmadapter, pRegulatory_class->data,
				   pmpriv->supp_regulatory_class,
				   pmpriv->supp_regulatory_class_len,
				   sizeof(pRegulatory_class->data));
		} else {
			pRegulatory_class->ieee_hdr.len =
				sizeof(regulatory_class);
			memcpy_ext(pmadapter, pRegulatory_class->data,
				   regulatory_class, sizeof(regulatory_class),
				   sizeof(pRegulatory_class->data));
		}
		DBG_HEXDUMP(MCMD_D, "TDLS supported regulatory class",
			    tdls_ies->regulatory_class,
			    pRegulatory_class->ieee_hdr.len +
			    sizeof(IEEEtypes_Header_t));
	}
	LEAVE();
	return ret;
}

/**
 *  @brief Set mimo switch 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
 */
mlan_status
wlan_radio_ioctl_mimo_switch_cfg(pmlan_adapter pmadapter,
				 pmlan_ioctl_req pioctl_req)
{
	pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_radio_cfg *radio_cfg = (mlan_ds_radio_cfg *)pioctl_req->pbuf;
	mlan_status ret = MLAN_STATUS_SUCCESS;

	ENTER();

	/* Send request to firmware */
	ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_MIMO_SWITCH, 0, 0,
			       (t_void *)pioctl_req,
			       &(radio_cfg->param.mimo_switch_cfg));

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief Get extended version 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
 */
mlan_status
wlan_get_info_ver_ext(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_get_info *pinfo = (mlan_ds_get_info *)pioctl_req->pbuf;
	mlan_status ret = MLAN_STATUS_SUCCESS;

	ENTER();

	/* Send request to firmware */
	ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_VERSION_EXT,
			       HostCmd_ACT_GEN_GET, 0, (t_void *)pioctl_req,
			       &pinfo->param.ver_ext.version_str_sel);

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get link layer statistics
 *
 *  @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_ioctl_link_statistic(mlan_private *pmpriv, pmlan_ioctl_req pioctl_req)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	t_u16 cmd_action = 0;

	ENTER();

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

	switch (pioctl_req->action) {
	case MLAN_ACT_GET:
		cmd_action = HostCmd_ACT_GEN_GET;
		break;
	case MLAN_ACT_SET:
		cmd_action = HostCmd_ACT_GEN_SET;
		break;
	case MLAN_ACT_CLEAR:
		cmd_action = HostCmd_ACT_GEN_REMOVE;
		break;
	default:
		ret = MLAN_STATUS_FAILURE;
		goto exit;
	}

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

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

exit:
	LEAVE();
	return ret;
}

/**
 *  @brief Get TX/RX histogram statistic
 *
 *  @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_get_tx_rx_histogram(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	pmlan_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;

	ENTER();

	/* Send request to firmware */
	ret = wlan_prepare_cmd(pmpriv, HOST_CMD_TX_RX_PKT_STATS,
			       HostCmd_ACT_GEN_GET, 0, (t_void *)pioctl_req,
			       &(pmisc->param.tx_rx_histogram));

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

#ifdef DEBUG_LEVEL1
/**
 *  @brief Set driver debug bit masks in order to enhance performance
 *
 *  @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_set_drvdbg(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_ds_misc_cfg *misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
	mlan_status ret = MLAN_STATUS_SUCCESS;

	ENTER();

	/* Set driver debug bit masks */
	mlan_drvdbg = misc->param.drvdbg;

	LEAVE();
	return ret;
}
#endif

/**
 *  @brief Rx mgmt frame forward register
 *
 *  @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_reg_rx_mgmt_ind(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	pmlan_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;

	ENTER();

	/* Set passthru mask for mgmt frame */
	pmpriv->mgmt_frame_passthru_mask = misc->param.mgmt_subtype_mask;

	/* Send request to firmware */
	ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_RX_MGMT_IND,
			       pioctl_req->action, 0, (t_void *)pioctl_req,
			       &misc->param.mgmt_subtype_mask);

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *   @brief This function processes the 802.11 mgmt Frame
 *
 *   @param priv            A pointer to mlan_private
 *
 *   @param payload         A pointer to the received buffer
 *   @param payload_len     Length of the received buffer
 *   @param prx_pd          A pointer to RxPD
 *
 *   @return                MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
mlan_status
wlan_process_802dot11_mgmt_pkt(mlan_private *priv,
			       t_u8 *payload, t_u32 payload_len, RxPD *prx_pd)
{
	pmlan_adapter pmadapter = priv->adapter;
	pmlan_callbacks pcb = &pmadapter->callbacks;
	mlan_status ret = MLAN_STATUS_SUCCESS;
	wlan_802_11_header *pieee_pkt_hdr = MNULL;
	t_u16 sub_type = 0;
	t_u8 *event_buf = MNULL;
	mlan_event *pevent = MNULL;
	t_u8 unicast = 0;
	t_u8 broadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
	IEEE80211_MGMT *mgmt = MNULL;
	t_u8 category = 0;
	t_u8 action_code = 0;
#ifdef UAP_SUPPORT
	sta_node *sta_ptr = MNULL;
	MrvlIETypes_MgmtFrameSet_t *tlv;
	pmlan_buffer pmbuf;
#endif

	ENTER();
	if (payload_len > (MAX_EVENT_SIZE - sizeof(mlan_event))) {
		PRINTM(MERROR, "Dropping large mgmt frame,len =%d\n",
		       payload_len);
		LEAVE();
		return ret;
	}
	/* Check  packet type-subtype and compare with mgmt_passthru_mask
	 * If event is needed to host, just eventify it */
	pieee_pkt_hdr = (wlan_802_11_header *)payload;
	sub_type = IEEE80211_GET_FC_MGMT_FRAME_SUBTYPE(pieee_pkt_hdr->frm_ctl);
	if (((1 << sub_type) & priv->mgmt_frame_passthru_mask) == 0) {
		PRINTM(MINFO, "Dropping mgmt frame for subtype %d snr=%d.\n",
		       sub_type, prx_pd->snr);
		LEAVE();
		return ret;
	}
	switch (sub_type) {
	case SUBTYPE_ASSOC_REQUEST:
	case SUBTYPE_REASSOC_REQUEST:
#ifdef UAP_SUPPORT
		if (priv->uap_host_based & UAP_FLAG_HOST_MLME) {
			PRINTM_NETINTF(MMSG, priv);
			if (!memcmp(pmadapter, pieee_pkt_hdr->addr3,
				    priv->curr_addr, MLAN_MAC_ADDR_LENGTH)) {
				PRINTM(MMSG,
				       "wlan: HostMlme MICRO_AP_STA_ASSOC "
				       MACSTR "\n",
				       MAC2STR(pieee_pkt_hdr->addr2));
				mgmt = (IEEE80211_MGMT *)payload;
				sta_ptr =
					wlan_add_station_entry(priv,
							       pieee_pkt_hdr->
							       addr2);
				if (sta_ptr) {
					sta_ptr->capability =
						wlan_le16_to_cpu(mgmt->u.
								 assoc_req.
								 capab_info);
					pmbuf = wlan_alloc_mlan_buffer
						(pmadapter, payload_len, 0,
						 MOAL_MALLOC_BUFFER);
					if (pmbuf) {
						PRINTM(MCMND,
						       "check sta capability\n");
						pmbuf->data_len =
							ASSOC_EVENT_FIX_SIZE;
						tlv = (MrvlIETypes_MgmtFrameSet_t *)(pmbuf->pbuf + pmbuf->data_offset + pmbuf->data_len);
						tlv->type =
							wlan_cpu_to_le16
							(TLV_TYPE_MGMT_FRAME);
						tlv->len =
							sizeof
							(IEEEtypes_FrameCtl_t);
						memcpy_ext(pmadapter,
							   (t_u8 *)&tlv->
							   frame_control,
							   &pieee_pkt_hdr->
							   frm_ctl,
							   sizeof
							   (IEEEtypes_FrameCtl_t),
							   sizeof
							   (IEEEtypes_FrameCtl_t));
						pmbuf->data_len +=
							sizeof
							(MrvlIETypes_MgmtFrameSet_t);
						memcpy_ext(pmadapter,
							   pmbuf->pbuf +
							   pmbuf->data_offset +
							   pmbuf->data_len,
							   payload +
							   sizeof
							   (wlan_802_11_header),
							   payload_len -
							   sizeof
							   (wlan_802_11_header),
							   payload_len -
							   sizeof
							   (wlan_802_11_header));
						pmbuf->data_len +=
							payload_len -
							sizeof
							(wlan_802_11_header);
						tlv->len +=
							payload_len -
							sizeof
							(wlan_802_11_header);
						tlv->len =
							wlan_cpu_to_le16(tlv->
									 len);
						DBG_HEXDUMP(MCMD_D, "assoc_req",
							    pmbuf->pbuf +
							    pmbuf->data_offset,
							    pmbuf->data_len);
						wlan_check_sta_capability(priv,
									  pmbuf,
									  sta_ptr);
						wlan_free_mlan_buffer(pmadapter,
								      pmbuf);
					}
				}
			} else {
				PRINTM(MMSG,
				       "wlan: Drop MICRO_AP_STA_ASSOC " MACSTR
				       " from unknown BSSID " MACSTR "\n",
				       MAC2STR(pieee_pkt_hdr->addr2),
				       MAC2STR(pieee_pkt_hdr->addr3));
			}
		}
		unicast = MTRUE;
		break;
#endif
	case SUBTYPE_AUTH:
		unicast = MTRUE;
		PRINTM_NETINTF(MMSG, priv);
		PRINTM(MMSG, "wlan: HostMlme Auth received from " MACSTR "\n",
		       MAC2STR(pieee_pkt_hdr->addr2));
		break;
	case SUBTYPE_PROBE_RESP:
		unicast = MTRUE;
		break;
	case SUBTYPE_DISASSOC:
	case SUBTYPE_DEAUTH:
		if (memcmp(pmadapter, pieee_pkt_hdr->addr1, broadcast,
			   MLAN_MAC_ADDR_LENGTH))
			unicast = MTRUE;
#ifdef UAP_SUPPORT
		if (priv->uap_host_based & UAP_FLAG_HOST_MLME) {
			if (!memcmp(pmadapter, pieee_pkt_hdr->addr3,
				    priv->curr_addr, MLAN_MAC_ADDR_LENGTH)) {
				PRINTM_NETINTF(MMSG, priv);
				PRINTM(MMSG,
				       "wlan: HostMlme Deauth Receive from "
				       MACSTR "\n",
				       MAC2STR(pieee_pkt_hdr->addr2));
			}
		}
#endif
		if (priv->bss_role == MLAN_BSS_ROLE_STA) {
			if (priv->curr_bss_params.host_mlme) {
				if (memcmp(pmadapter, pieee_pkt_hdr->addr3,
					   (t_u8 *)priv->curr_bss_params.
					   bss_descriptor.mac_address,
					   MLAN_MAC_ADDR_LENGTH)) {
					PRINTM(MCMND,
					       "Dropping Deauth frame from other bssid: type=%d "
					       MACSTR "\n", sub_type,
					       MAC2STR(pieee_pkt_hdr->addr3));
					LEAVE();
					return ret;
				}
				PRINTM_NETINTF(MMSG, priv);
				PRINTM(MMSG,
				       "wlan: HostMlme Disconnected: sub_type=%d\n",
				       sub_type);
				pmadapter->pending_disconnect_priv = priv;
				wlan_recv_event(priv,
						MLAN_EVENT_ID_DRV_DEFER_HANDLING,
						MNULL);
			}
		}
		break;
	case SUBTYPE_ACTION:
		category = *(payload + sizeof(wlan_802_11_header));
		action_code = *(payload + sizeof(wlan_802_11_header) + 1);
		if (category == IEEE_MGMT_ACTION_CATEGORY_BLOCK_ACK) {
			PRINTM(MINFO,
			       "Drop BLOCK ACK action frame: action_code=%d\n",
			       action_code);
			LEAVE();
			return ret;
		}
		if ((category == IEEE_MGMT_ACTION_CATEGORY_PUBLIC) &&
		    (action_code == BSS_20_40_COEX)) {
			PRINTM(MINFO,
			       "Drop 20/40 BSS Coexistence Management frame\n");
			LEAVE();
			return ret;
		}
		if ((category == CATEGORY_PUBLIC) &&
		    (action_code == TDLS_DISCOVERY_RESPONSE)) {
			pcb->moal_updata_peer_signal(pmadapter->pmoal_handle,
						     priv->bss_index,
						     pieee_pkt_hdr->addr2,
						     prx_pd->snr, prx_pd->nf);
			PRINTM(MINFO,
			       "Rx: TDLS discovery response, nf=%d, snr=%d\n",
			       prx_pd->nf, prx_pd->snr);
		}
		if (memcmp(pmadapter, pieee_pkt_hdr->addr1, broadcast,
			   MLAN_MAC_ADDR_LENGTH))
			unicast = MTRUE;
		break;
	default:
		break;
	}
	if (unicast == MTRUE) {
		if (memcmp(pmadapter, pieee_pkt_hdr->addr1, priv->curr_addr,
			   MLAN_MAC_ADDR_LENGTH)) {
			PRINTM(MINFO,
			       "Dropping mgmt frame for others: type=%d " MACSTR
			       "\n", sub_type, MAC2STR(pieee_pkt_hdr->addr1));
			LEAVE();
			return ret;
		}
	}
	/* Allocate memory for event buffer */
	ret = pcb->moal_malloc(pmadapter->pmoal_handle, MAX_EVENT_SIZE,
			       MLAN_MEM_DEF, &event_buf);
	if ((ret != MLAN_STATUS_SUCCESS) || !event_buf) {
		PRINTM(MERROR, "Could not allocate buffer for event buf\n");
		LEAVE();
		return MLAN_STATUS_FAILURE;
	}
	pevent = (pmlan_event)event_buf;
	pevent->bss_index = priv->bss_index;
	mgmt = (IEEE80211_MGMT *)payload;
	if (!priv->curr_bss_params.host_mlme &&
	    sub_type == SUBTYPE_ACTION &&
	    mgmt->u.ft_resp.category == FT_CATEGORY &&
	    mgmt->u.ft_resp.action == FT_ACTION_RESPONSE &&
	    mgmt->u.ft_resp.status_code == 0) {
		PRINTM(MCMND, "FT Action response received\n");
#define FT_ACTION_HEAD_LEN (24 + 6 + 16)
		pevent->event_id = MLAN_EVENT_ID_DRV_FT_RESPONSE;
		pevent->event_len =
			payload_len + MLAN_MAC_ADDR_LENGTH - FT_ACTION_HEAD_LEN;
		memcpy_ext(pmadapter, (t_u8 *)pevent->event_buf,
			   &mgmt->u.ft_resp.target_ap_addr,
			   MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
		memcpy_ext(pmadapter,
			   (t_u8 *)(pevent->event_buf + MLAN_MAC_ADDR_LENGTH),
			   payload + FT_ACTION_HEAD_LEN,
			   payload_len - FT_ACTION_HEAD_LEN,
			   pevent->event_len - MLAN_MAC_ADDR_LENGTH);
	} else if (!priv->curr_bss_params.host_mlme &&
		   sub_type == SUBTYPE_AUTH &&
		   mgmt->u.auth.auth_alg == MLAN_AUTH_MODE_FT &&
		   mgmt->u.auth.auth_transaction == 2 &&
		   mgmt->u.auth.status_code == 0) {
		PRINTM(MCMND, "FT auth response received \n");
#define AUTH_PACKET_LEN (24 + 6 + 6)
		pevent->event_id = MLAN_EVENT_ID_DRV_FT_RESPONSE;
		pevent->event_len =
			payload_len + MLAN_MAC_ADDR_LENGTH - AUTH_PACKET_LEN;
		memcpy_ext(pmadapter, (t_u8 *)pevent->event_buf, mgmt->sa,
			   MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
		memcpy_ext(pmadapter,
			   (t_u8 *)(pevent->event_buf + MLAN_MAC_ADDR_LENGTH),
			   payload + AUTH_PACKET_LEN,
			   payload_len - AUTH_PACKET_LEN,
			   pevent->event_len - MLAN_MAC_ADDR_LENGTH);
	} else {
		pevent->event_id = MLAN_EVENT_ID_DRV_MGMT_FRAME;
		pevent->event_len = payload_len + sizeof(pevent->event_id);
		memcpy_ext(pmadapter, (t_u8 *)pevent->event_buf,
			   (t_u8 *)&pevent->event_id, sizeof(pevent->event_id),
			   pevent->event_len);
		memcpy_ext(pmadapter,
			   (t_u8 *)(pevent->event_buf +
				    sizeof(pevent->event_id)), payload,
			   payload_len, payload_len);
	}
	wlan_recv_event(priv, pevent->event_id, pevent);
	if (event_buf)
		pcb->moal_mfree(pmadapter->pmoal_handle, event_buf);
	LEAVE();
	return MLAN_STATUS_SUCCESS;
}

#ifdef STA_SUPPORT
/**
 *  @brief Extended capabilities 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
 */
mlan_status
wlan_misc_ext_capa_cfg(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	pmlan_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;

	ENTER();

	if (MLAN_ACT_GET == pioctl_req->action)
		memcpy_ext(pmpriv->adapter, &misc->param.ext_cap,
			   &pmpriv->def_ext_cap, sizeof(misc->param.ext_cap),
			   sizeof(misc->param.ext_cap));
	else if (MLAN_ACT_SET == pioctl_req->action) {
		memcpy_ext(pmpriv->adapter, &pmpriv->ext_cap,
			   &misc->param.ext_cap, sizeof(misc->param.ext_cap),
			   sizeof(pmpriv->ext_cap));
		/* Save default Extended Capability */
		memcpy_ext(pmpriv->adapter, &pmpriv->def_ext_cap,
			   &pmpriv->ext_cap, sizeof(pmpriv->ext_cap),
			   sizeof(pmpriv->def_ext_cap));
		if (pmpriv->config_bands & BAND_AAC)
			SET_EXTCAP_OPERMODENTF(pmpriv->ext_cap);
	}

	LEAVE();
	return ret;
}

/**
 *  @brief Check whether Extended Capabilities IE support
 *
 *  @param pmpriv             A pointer to mlan_private structure
 *
 *  @return                   MTRUE or MFALSE;
 */
t_u32
wlan_is_ext_capa_support(mlan_private *pmpriv)
{
	ENTER();

	if (ISSUPP_EXTCAP_TDLS(pmpriv->ext_cap) ||
	    ISSUPP_EXTCAP_INTERWORKING(pmpriv->ext_cap) ||
	    ISSUPP_EXTCAP_BSS_TRANSITION(pmpriv->ext_cap)
	    || ISSUPP_EXTCAP_QOS_MAP(pmpriv->ext_cap)
	    || ISSUPP_EXTCAP_OPERMODENTF(pmpriv->ext_cap)
		) {
		LEAVE();
		return MTRUE;
	} else {
		LEAVE();
		return MFALSE;
	}
}
#endif

/**
 *  @brief Set hotspot enable/disable
 *
 *  @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_hotspot_cfg(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	pmlan_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;

	ENTER();

	if (MLAN_ACT_GET == pioctl_req->action)
		misc->param.hotspot_cfg = pmpriv->hotspot_cfg;
	else if (MLAN_ACT_SET == pioctl_req->action)
		pmpriv->hotspot_cfg = misc->param.hotspot_cfg;

	LEAVE();
	return ret;
}

#ifdef STA_SUPPORT
/**
 *  @brief Add Extended Capabilities IE
 *
 *  @param pmpriv             A pointer to mlan_private structure
 *  @param pbss_desc          A pointer to BSSDescriptor_t structure
 *  @param pptlv_out          A pointer to TLV to fill in
 *
 *  @return                   N/A
 */
void
wlan_add_ext_capa_info_ie(mlan_private *pmpriv,
			  BSSDescriptor_t *pbss_desc, t_u8 **pptlv_out)
{
	MrvlIETypes_ExtCap_t *pext_cap = MNULL;

	ENTER();

	pext_cap = (MrvlIETypes_ExtCap_t *)*pptlv_out;
	memset(pmpriv->adapter, pext_cap, 0, sizeof(MrvlIETypes_ExtCap_t));
	pext_cap->header.type = wlan_cpu_to_le16(EXT_CAPABILITY);
	pext_cap->header.len = wlan_cpu_to_le16(sizeof(ExtCap_t));
	if (pmpriv->adapter->ecsa_enable)
		SET_EXTCAP_EXT_CHANNEL_SWITCH(pmpriv->ext_cap);
	else
		RESET_EXTCAP_EXT_CHANNEL_SWITCH(pmpriv->ext_cap);
	if (pbss_desc && pbss_desc->multi_bssid_ap)
		SET_EXTCAP_MULTI_BSSID(pmpriv->ext_cap);
	if (wlan_check_11ax_twt_supported(pmpriv, pbss_desc))
		SET_EXTCAP_TWT_REQ(pmpriv->ext_cap);
	memcpy_ext(pmpriv->adapter, &pext_cap->ext_cap, &pmpriv->ext_cap,
		   sizeof(pmpriv->ext_cap), sizeof(pext_cap->ext_cap));
	*pptlv_out += sizeof(MrvlIETypes_ExtCap_t);

	LEAVE();
}
#endif

/**
 *  @brief Get OTP user data
 *
 *  @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_otp_user_data(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	pmlan_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_FAILURE;

	ENTER();

	if (misc->param.otp_user_data.user_data_length > MAX_OTP_USER_DATA_LEN) {
		PRINTM(MERROR, "Invalid OTP user data length\n");
		pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
		LEAVE();
		return ret;
	}

	ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_OTP_READ_USER_DATA,
			       HostCmd_ACT_GEN_GET, 0, (t_void *)pioctl_req,
			       &misc->param.otp_user_data);

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief This function will search for the specific ie
 *
 *  @param priv    A pointer to mlan_private
 *  @param pevent  A pointer to event buf
 *  @param sta_ptr A pointer to sta_node
 *
 *  @return	       N/A
 */
void
wlan_check_sta_capability(pmlan_private priv, pmlan_buffer pevent,
			  sta_node *sta_ptr)
{
	t_u16 tlv_type, tlv_len;
	t_u16 frame_control, frame_sub_type = 0;
	t_u8 *assoc_req_ie = MNULL;
	t_u8 ie_len = 0, assoc_ie_len = 0;
	IEEEtypes_HTCap_t *pht_cap = MNULL;
	IEEEtypes_VHTCap_t *pvht_cap = MNULL;
	IEEEtypes_Extension_t *phe_cap = MNULL;
#ifdef UAP_SUPPORT
	t_u8 *ext_rate = MNULL, *erp = MNULL;
#endif

	int tlv_buf_left = pevent->data_len - ASSOC_EVENT_FIX_SIZE;
	MrvlIEtypesHeader_t *tlv =
		(MrvlIEtypesHeader_t *)(pevent->pbuf + pevent->data_offset +
					ASSOC_EVENT_FIX_SIZE);
	MrvlIETypes_MgmtFrameSet_t *mgmt_tlv = MNULL;

	ENTER();
	while (tlv_buf_left >= (int)sizeof(MrvlIEtypesHeader_t)) {
		tlv_type = wlan_le16_to_cpu(tlv->type);
		tlv_len = wlan_le16_to_cpu(tlv->len);
		if ((sizeof(MrvlIEtypesHeader_t) + tlv_len) >
		    (unsigned int)tlv_buf_left) {
			PRINTM(MERROR, "wrong tlv: tlvLen=%d, tlvBufLeft=%d\n",
			       tlv_len, tlv_buf_left);
			break;
		}
		if (tlv_type == TLV_TYPE_MGMT_FRAME) {
			mgmt_tlv = (MrvlIETypes_MgmtFrameSet_t *)tlv;
			memcpy_ext(priv->adapter, &frame_control,
				   (t_u8 *)&(mgmt_tlv->frame_control),
				   sizeof(frame_control),
				   sizeof(frame_control));
			frame_sub_type =
				IEEE80211_GET_FC_MGMT_FRAME_SUBTYPE
				(frame_control);
			if ((mgmt_tlv->frame_control.type == 0) &&
			    ((frame_sub_type == SUBTYPE_BEACON)
#ifdef UAP_SUPPORT
			     || (frame_sub_type == SUBTYPE_ASSOC_REQUEST) ||
			     (frame_sub_type == SUBTYPE_REASSOC_REQUEST)
#endif
			    )) {
				if (frame_sub_type == SUBTYPE_BEACON)
					assoc_ie_len =
						sizeof(IEEEtypes_Beacon_t);
#ifdef UAP_SUPPORT
				else if (frame_sub_type ==
					 SUBTYPE_ASSOC_REQUEST)
					assoc_ie_len =
						sizeof(IEEEtypes_AssocRqst_t);
				else if (frame_sub_type ==
					 SUBTYPE_REASSOC_REQUEST)
					assoc_ie_len =
						sizeof(IEEEtypes_ReAssocRqst_t);
#endif
				ie_len = tlv_len -
					sizeof(IEEEtypes_FrameCtl_t) -
					assoc_ie_len;
				assoc_req_ie =
					(t_u8 *)tlv +
					sizeof(MrvlIETypes_MgmtFrameSet_t) +
					assoc_ie_len;
				sta_ptr->is_wmm_enabled =
					wlan_is_wmm_ie_present(priv->adapter,
							       assoc_req_ie,
							       ie_len);
				PRINTM(MCMND, "STA: is_wmm_enabled=%d\n",
				       sta_ptr->is_wmm_enabled);
				pht_cap = (IEEEtypes_HTCap_t *)
					wlan_get_specific_ie(priv, assoc_req_ie,
							     ie_len,
							     HT_CAPABILITY, 0);
				if (pht_cap) {
					PRINTM(MCMND, "STA supports 11n\n");
					sta_ptr->is_11n_enabled = MTRUE;
					memcpy_ext(priv->adapter,
						   (t_u8 *)&sta_ptr->HTcap,
						   pht_cap,
						   sizeof(IEEEtypes_HTCap_t),
						   sizeof(IEEEtypes_HTCap_t));
					if (GETHT_MAXAMSDU
					    (wlan_le16_to_cpu
					     (pht_cap->ht_cap.ht_cap_info)))
						sta_ptr->max_amsdu =
							MLAN_TX_DATA_BUF_SIZE_8K;
					else
						sta_ptr->max_amsdu =
							MLAN_TX_DATA_BUF_SIZE_4K;
				} else {
					PRINTM(MCMND,
					       "STA doesn't support 11n\n");
				}
				pvht_cap = (IEEEtypes_VHTCap_t *)
					wlan_get_specific_ie(priv, assoc_req_ie,
							     ie_len,
							     VHT_CAPABILITY, 0);
				if (pvht_cap &&
				    (priv->is_11ac_enabled == MTRUE)) {
					PRINTM(MCMND, "STA supports 11ac\n");
					sta_ptr->is_11ac_enabled = MTRUE;
					if (GET_VHTCAP_MAXMPDULEN
					    (wlan_le32_to_cpu
					     (pvht_cap->vht_cap.
					      vht_cap_info)) == 2)
						sta_ptr->max_amsdu =
							MLAN_TX_DATA_BUF_SIZE_12K;
					else if (GET_VHTCAP_MAXMPDULEN
						 (wlan_le32_to_cpu
						  (pvht_cap->vht_cap.
						   vht_cap_info)) == 1)
						sta_ptr->max_amsdu =
							MLAN_TX_DATA_BUF_SIZE_8K;
					else
						sta_ptr->max_amsdu =
							MLAN_TX_DATA_BUF_SIZE_4K;
				} else {
					PRINTM(MCMND,
					       "STA doesn't support 11ac\n");
				}
				phe_cap = (IEEEtypes_Extension_t *)
					wlan_get_specific_ie(priv, assoc_req_ie,
							     ie_len, EXTENSION,
							     HE_CAPABILITY);
				if (phe_cap && (priv->is_11ax_enabled == MTRUE)) {
					PRINTM(MCMND, "STA supports 11ax\n");
					sta_ptr->is_11ax_enabled = MTRUE;
					memcpy_ext(priv->adapter,
						   (t_u8 *)&sta_ptr->he_cap,
						   phe_cap,
						   phe_cap->ieee_hdr.len +
						   sizeof(IEEEtypes_Header_t),
						   sizeof(IEEEtypes_HECap_t));
					sta_ptr->he_cap.ieee_hdr.len =
						MIN(phe_cap->ieee_hdr.len,
						    sizeof(IEEEtypes_HECap_t) -
						    sizeof(IEEEtypes_Header_t));
				} else {
					PRINTM(MCMND,
					       "STA doesn't support 11ax\n");
				}
#ifdef UAP_SUPPORT
				/* Note: iphone6 does not have ERP_INFO */
				ext_rate =
					wlan_get_specific_ie(priv, assoc_req_ie,
							     ie_len,
							     EXTENDED_SUPPORTED_RATES,
							     0);
				erp = wlan_get_specific_ie(priv, assoc_req_ie,
							   ie_len, ERP_INFO, 0);
				if (!ext_rate)
					PRINTM(MCMND,
					       "STA doesn't support EXTENDED_SUPPORTED_RATES\n");
				if (!erp)
					PRINTM(MCMND,
					       "STA doesn't support ERP_INFO\n");
				if (sta_ptr->is_11ax_enabled) {
					if (priv->uap_channel <= 14)
						sta_ptr->bandmode = BAND_GAX;
					else
						sta_ptr->bandmode = BAND_AAX;
				} else if (sta_ptr->is_11ac_enabled) {
					if (priv->uap_channel <= 14)
						sta_ptr->bandmode = BAND_GAC;
					else
						sta_ptr->bandmode = BAND_AAC;
				} else if (sta_ptr->is_11n_enabled) {
					if (priv->uap_channel <= 14)
						sta_ptr->bandmode = BAND_GN;
					else
						sta_ptr->bandmode = BAND_AN;
				} else if (ext_rate || erp) {
					if (priv->uap_channel <= 14)
						sta_ptr->bandmode = BAND_G;
					else
						sta_ptr->bandmode = BAND_A;
				} else
					sta_ptr->bandmode = BAND_B;
#endif
#ifdef DRV_EMBEDDED_AUTHENTICATOR
				if (IsAuthenticatorEnabled(priv->psapriv))
					authenticator_get_sta_security_info
						(priv->psapriv,
						 sta_ptr->cm_connectioninfo,
						 assoc_req_ie, ie_len);
#endif
				break;
			}
		}
		tlv_buf_left -= (sizeof(MrvlIEtypesHeader_t) + tlv_len);
		tlv = (MrvlIEtypesHeader_t *)((t_u8 *)tlv + tlv_len +
					      sizeof(MrvlIEtypesHeader_t));
	}
	LEAVE();

	return;
}

/**
 *  @brief check if WMM ie present.
 *
 *  @param pmadapter A pointer to mlan_adapter structure
 *  @param pbuf     A pointer to IE buffer
 *  @param buf_len  IE buffer len
 *
 *  @return         MTRUE/MFALSE
 */
t_u8
wlan_is_wmm_ie_present(pmlan_adapter pmadapter, t_u8 *pbuf, t_u16 buf_len)
{
	t_u16 bytes_left = buf_len;
	IEEEtypes_ElementId_e element_id;
	t_u8 *pcurrent_ptr = pbuf;
	t_u8 element_len;
	t_u16 total_ie_len;
	IEEEtypes_VendorSpecific_t *pvendor_ie;
	const t_u8 wmm_oui[4] = { 0x00, 0x50, 0xf2, 0x02 };
	t_u8 find_wmm_ie = MFALSE;

	ENTER();

	/* Process variable IE */
	while (bytes_left >= 2) {
		element_id = (IEEEtypes_ElementId_e)(*((t_u8 *)pcurrent_ptr));
		element_len = *((t_u8 *)pcurrent_ptr + 1);
		total_ie_len = element_len + sizeof(IEEEtypes_Header_t);

		if (bytes_left < total_ie_len) {
			PRINTM(MERROR, "InterpretIE: Error in processing IE, "
			       "bytes left < IE length\n");
			bytes_left = 0;
			continue;
		}
		switch (element_id) {
		case VENDOR_SPECIFIC_221:
			pvendor_ie = (IEEEtypes_VendorSpecific_t *)pcurrent_ptr;
			if (!memcmp(pmadapter, pvendor_ie->vend_hdr.oui,
				    wmm_oui, sizeof(wmm_oui))) {
				find_wmm_ie = MTRUE;
				PRINTM(MINFO, "find WMM IE\n");
			}
			break;
		default:
			break;
		}
		pcurrent_ptr += element_len + 2;
		/* Need to account for IE ID and IE Len */
		bytes_left -= (element_len + 2);
		if (find_wmm_ie)
			break;
	}

	LEAVE();
	return find_wmm_ie;
}

/**
 *  @brief This function will search for the specific ie
 *
 *
 *  @param priv    A pointer to mlan_private
 *  @param ie_buf  A pointer to ie_buf
 *  @param ie_len  total ie length
 *  @param id      ie's id
 *  @param ext_id  ie's extension id
 *
 *  @return	       ie's poiner or MNULL
 */
t_u8 *
wlan_get_specific_ie(pmlan_private priv, t_u8 *ie_buf, t_u8 ie_len,
		     IEEEtypes_ElementId_e id, t_u8 ext_id)
{
	t_u32 bytes_left = ie_len;
	t_u8 *pcurrent_ptr = ie_buf;
	t_u16 total_ie_len;
	t_u8 *ie_ptr = MNULL;
	IEEEtypes_ElementId_e element_id;
	t_u8 element_len;
	t_u8 element_eid;

	ENTER();

	DBG_HEXDUMP(MDAT_D, "ie", ie_buf, ie_len);
	while (bytes_left >= 2) {
		element_id = (IEEEtypes_ElementId_e)(*((t_u8 *)pcurrent_ptr));
		element_len = *((t_u8 *)pcurrent_ptr + 1);
		element_eid = *((t_u8 *)pcurrent_ptr + 2);
		total_ie_len = element_len + sizeof(IEEEtypes_Header_t);
		if (bytes_left < total_ie_len) {
			PRINTM(MERROR, "InterpretIE: Error in processing IE, "
			       "bytes left < IE length\n");
			break;
		}
		if ((!ext_id && element_id == id) ||
		    (id == EXTENSION && element_id == id &&
		     ext_id == element_eid)) {
			PRINTM(MCMND, "Find IE: id=%d ext_id=%d\n", id, ext_id);
			DBG_HEXDUMP(MCMD_D, "IE", pcurrent_ptr, total_ie_len);
			ie_ptr = pcurrent_ptr;
			break;
		}
		pcurrent_ptr += element_len + 2;
		/* Need to account for IE ID and IE Len */
		bytes_left -= (element_len + 2);
	}

	LEAVE();

	return ie_ptr;
}

/**
 *  @brief Get pm info
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		        MLAN_STATUS_SUCCESS --success
 */
mlan_status
wlan_get_pm_info(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_ds_pm_cfg *pm_cfg = MNULL;

	ENTER();

	pm_cfg = (mlan_ds_pm_cfg *)pioctl_req->pbuf;
	pm_cfg->param.ps_info.is_suspend_allowed = MTRUE;
	wlan_request_cmd_lock(pmadapter);
	if (util_peek_list(pmadapter->pmoal_handle, &pmadapter->cmd_pending_q,
			   MNULL, MNULL) ||
	    pmadapter->curr_cmd || !wlan_bypass_tx_list_empty(pmadapter) ||
	    !wlan_wmm_lists_empty(pmadapter)
#if defined(SDIO) || defined(PCIE)
	    || wlan_pending_interrupt(pmadapter)
#endif
		) {
		pm_cfg->param.ps_info.is_suspend_allowed = MFALSE;
#if defined(SDIO) || defined(PCIE)
		PRINTM(MIOCTL,
		       "PM: cmd_pending_q=%p,curr_cmd=%p,wmm_list_empty=%d, by_pass=%d irq_pending=%d\n",
		       util_peek_list(pmadapter->pmoal_handle,
				      &pmadapter->cmd_pending_q, MNULL, MNULL),
		       pmadapter->curr_cmd, wlan_wmm_lists_empty(pmadapter),
		       wlan_bypass_tx_list_empty(pmadapter),
		       wlan_pending_interrupt(pmadapter));
#else
		PRINTM(MIOCTL,
		       "PM: cmd_pending_q=%p,curr_cmd=%p,wmm_list_empty=%d, by_pass=%d\n",
		       util_peek_list(pmadapter->pmoal_handle,
				      &pmadapter->cmd_pending_q, MNULL, MNULL),
		       pmadapter->curr_cmd, wlan_wmm_lists_empty(pmadapter),
		       wlan_bypass_tx_list_empty(pmadapter));
#endif
	}
	wlan_release_cmd_lock(pmadapter);
	LEAVE();
	return ret;
}

/**
 *  @brief Get hs wakeup reason
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		        MLAN_STATUS_SUCCESS --success
 */
mlan_status
wlan_get_hs_wakeup_reason(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
	pmlan_ds_pm_cfg pm_cfg = MNULL;
	mlan_status ret = MLAN_STATUS_FAILURE;

	ENTER();

	pm_cfg = (mlan_ds_pm_cfg *)pioctl_req->pbuf;

	/* Send command to firmware */
	ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_HS_WAKEUP_REASON,
			       HostCmd_ACT_GEN_GET, 0, (t_void *)pioctl_req,
			       &pm_cfg->param.wakeup_reason);

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get radio 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
 */
mlan_status
wlan_radio_ioctl_radio_ctl(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_ds_radio_cfg *radio_cfg = MNULL;
	t_u16 cmd_action = 0;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];

	ENTER();

	radio_cfg = (mlan_ds_radio_cfg *)pioctl_req->pbuf;
	if (pioctl_req->action == MLAN_ACT_SET) {
		if (pmadapter->radio_on == radio_cfg->param.radio_on_off) {
			ret = MLAN_STATUS_SUCCESS;
			goto exit;
		} else {
			if (pmpriv->media_connected == MTRUE) {
				ret = MLAN_STATUS_FAILURE;
				goto exit;
			}
			cmd_action = HostCmd_ACT_GEN_SET;
		}
	} else
		cmd_action = HostCmd_ACT_GEN_GET;

	/* Send request to firmware */
	ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_RADIO_CONTROL,
			       cmd_action, 0, (t_void *)pioctl_req,
			       &radio_cfg->param.radio_on_off);

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

exit:
	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get antenna 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
 */
mlan_status
wlan_radio_ioctl_ant_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_radio_cfg *radio_cfg = MNULL;
	t_u16 cmd_action = 0;
	mlan_ds_ant_cfg *ant_cfg = MNULL;
	mlan_ds_ant_cfg_1x1 *ant_cfg_1x1 = MNULL;

	ENTER();

	radio_cfg = (mlan_ds_radio_cfg *)pioctl_req->pbuf;
	if (IS_STREAM_2X2(pmadapter->feature_control))
		ant_cfg = &radio_cfg->param.ant_cfg;

	if (pioctl_req->action == MLAN_ACT_SET) {
		/* User input validation */
		if (IS_STREAM_2X2(pmadapter->feature_control)) {
#if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || defined(PCIE9097) || defined(SD9097) || defined(USB9097)
			if (IS_CARD9098(pmadapter->card_type) ||
			    IS_CARD9097(pmadapter->card_type)) {
				ant_cfg->tx_antenna &= 0x0303;
				ant_cfg->rx_antenna &= 0x0303;
				/** 2G antcfg TX */
				if (ant_cfg->tx_antenna & 0x00FF) {
					pmadapter->user_htstream &= ~0xF0;
					pmadapter->user_htstream |=
						(bitcount(ant_cfg->tx_antenna &
							  0x00FF)
						 << 4);
				}
				/* 5G antcfg tx */
				if (ant_cfg->tx_antenna & 0xFF00) {
					pmadapter->user_htstream &= ~0xF000;
					pmadapter->user_htstream |=
						(bitcount(ant_cfg->tx_antenna &
							  0xFF00)
						 << 12);
				}
				/* 2G antcfg RX */
				if (ant_cfg->rx_antenna & 0x00FF) {
					pmadapter->user_htstream &= ~0xF;
					pmadapter->user_htstream |=
						bitcount(ant_cfg->
							 rx_antenna & 0x00FF);
				}
				/* 5G antcfg RX */
				if (ant_cfg->rx_antenna & 0xFF00) {
					pmadapter->user_htstream &= ~0xF00;
					pmadapter->user_htstream |=
						(bitcount(ant_cfg->rx_antenna &
							  0xFF00)
						 << 8);
				}
				PRINTM(MCMND,
				       "user_htstream=0x%x, tx_antenna=0x%x >rx_antenna=0x%x\n",
				       pmadapter->user_htstream,
				       ant_cfg->tx_antenna,
				       ant_cfg->rx_antenna);
			} else {
#endif

				ant_cfg->tx_antenna &= 0x0003;
				ant_cfg->rx_antenna &= 0x0003;
#if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || defined(PCIE9097) || defined(SD9097) || defined(USB9097)
			}
#endif
			if (!ant_cfg->tx_antenna ||
			    bitcount(ant_cfg->tx_antenna & 0x00FF) >
			    pmadapter->number_of_antenna ||
			    bitcount(ant_cfg->tx_antenna & 0xFF00) >
			    pmadapter->number_of_antenna) {
				PRINTM(MERROR,
				       "Invalid TX antenna setting: 0x%x\n",
				       ant_cfg->tx_antenna);
				pioctl_req->status_code =
					MLAN_ERROR_INVALID_PARAMETER;
				ret = MLAN_STATUS_FAILURE;
				goto exit;
			}
			if (ant_cfg->rx_antenna) {
				if (bitcount(ant_cfg->rx_antenna & 0x00FF) >
				    pmadapter->number_of_antenna ||
				    bitcount(ant_cfg->rx_antenna & 0xFF00) >
				    pmadapter->number_of_antenna) {
					PRINTM(MERROR,
					       "Invalid RX antenna setting: 0x%x\n",
					       ant_cfg->rx_antenna);
					pioctl_req->status_code =
						MLAN_ERROR_INVALID_PARAMETER;
					ret = MLAN_STATUS_FAILURE;
					goto exit;
				}
			} else
				ant_cfg->rx_antenna = ant_cfg->tx_antenna;
		} else if (!radio_cfg->param.ant_cfg_1x1.antenna ||
			   ((radio_cfg->param.ant_cfg_1x1.antenna !=
			     RF_ANTENNA_AUTO) &&
			    (radio_cfg->param.ant_cfg_1x1.antenna & 0xFFFC))) {
			PRINTM(MERROR, "Invalid antenna setting\n");
			pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
			ret = MLAN_STATUS_FAILURE;
			goto exit;
		}
		cmd_action = HostCmd_ACT_GEN_SET;
	} else
		cmd_action = HostCmd_ACT_GEN_GET;

	/* Cast it to t_u16, antenna mode for command
	 * HostCmd_CMD_802_11_RF_ANTENNA requires 2 bytes */
	if (!IS_STREAM_2X2(pmadapter->feature_control))
		ant_cfg_1x1 = &radio_cfg->param.ant_cfg_1x1;

	/* Send request to firmware */
	ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_RF_ANTENNA,
			       cmd_action, 0, (t_void *)pioctl_req,
			       (IS_STREAM_2X2(pmadapter->feature_control)) ?
			       (t_void *)ant_cfg : (t_void *)ant_cfg_1x1);

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

exit:
	LEAVE();
	return ret;
}

/**
 *  @brief Get rate bitmap
 *
 *  @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_rate_ioctl_get_rate_bitmap(pmlan_adapter pmadapter,
				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, HostCmd_CMD_TX_RATE_CFG,
			       HostCmd_ACT_GEN_GET, 0, (t_void *)pioctl_req,
			       MNULL);
	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief Set rate bitmap
 *
 *  @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_rate_ioctl_set_rate_bitmap(pmlan_adapter pmadapter,
				pmlan_ioctl_req pioctl_req)
{
	mlan_ds_rate *ds_rate = MNULL;
	mlan_status ret = MLAN_STATUS_FAILURE;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	t_u16 *bitmap_rates = MNULL;

	ENTER();

	ds_rate = (mlan_ds_rate *)pioctl_req->pbuf;
	bitmap_rates = ds_rate->param.rate_cfg.bitmap_rates;

	PRINTM(MINFO,
	       "RateBitmap=%04x%04x%04x%04x%04x%04x%04x%04x"
	       "%04x%04x%04x%04x%04x%04x%04x%04x%04x%04x, "
	       "IsRateAuto=%d, DataRate=%d\n",
	       bitmap_rates[17], bitmap_rates[16], bitmap_rates[15],
	       bitmap_rates[14], bitmap_rates[13], bitmap_rates[12],
	       bitmap_rates[11], bitmap_rates[10], bitmap_rates[9],
	       bitmap_rates[8], bitmap_rates[7], bitmap_rates[6],
	       bitmap_rates[5], bitmap_rates[4], bitmap_rates[3],
	       bitmap_rates[2], bitmap_rates[1], bitmap_rates[0],
	       pmpriv->is_data_rate_auto, pmpriv->data_rate);

	/* Send request to firmware */
	ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_TX_RATE_CFG,
			       HostCmd_ACT_GEN_SET, 0, (t_void *)pioctl_req,
			       (t_void *)bitmap_rates);
	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief Get rate value
 *
 *  @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_get_rate_value(pmlan_adapter pmadapter,
			       pmlan_ioctl_req pioctl_req)
{
	mlan_ds_rate *rate = MNULL;
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];

	ENTER();

	rate = (mlan_ds_rate *)pioctl_req->pbuf;
	rate->param.rate_cfg.is_rate_auto = pmpriv->is_data_rate_auto;
	pioctl_req->data_read_written =
		sizeof(mlan_rate_cfg_t) + MLAN_SUB_COMMAND_SIZE;

	/* If not connected, set rate to the lowest in each band */
	if (pmpriv->media_connected != MTRUE) {
		if (pmpriv->config_bands & (BAND_B | BAND_G)) {
			/* Return the lowest supported rate for BG band */
			rate->param.rate_cfg.rate = SupportedRates_BG[0] & 0x7f;
		} else if (pmpriv->config_bands & (BAND_A | BAND_B)) {
			/* Return the lowest supported rate for A band */
			rate->param.rate_cfg.rate = SupportedRates_BG[0] & 0x7f;
		} else if (pmpriv->config_bands & BAND_A) {
			/* Return the lowest supported rate for A band */
			rate->param.rate_cfg.rate = SupportedRates_A[0] & 0x7f;
		} else if (pmpriv->config_bands & BAND_G) {
			/* Return the lowest supported rate for G band */
			rate->param.rate_cfg.rate = SupportedRates_G[0] & 0x7f;
		} else if (pmpriv->config_bands & BAND_B) {
			/* Return the lowest supported rate for B band */
			rate->param.rate_cfg.rate = SupportedRates_B[0] & 0x7f;
		} else if (pmpriv->config_bands & BAND_GN) {
			/* Return the lowest supported rate for N band */
			rate->param.rate_cfg.rate = SupportedRates_N[0] & 0x7f;
		} else {
			PRINTM(MMSG, "Invalid Band 0x%x\n",
			       pmpriv->config_bands);
		}

	} else {
		/* Send request to firmware */
		ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_TX_RATE_QUERY,
				       HostCmd_ACT_GEN_GET, 0,
				       (t_void *)pioctl_req, MNULL);
		if (ret == MLAN_STATUS_SUCCESS)
			ret = MLAN_STATUS_PENDING;
	}

	LEAVE();
	return ret;
}

/**
 *  @brief Set rate value
 *
 *  @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_rate_ioctl_set_rate_value(pmlan_adapter pmadapter,
			       pmlan_ioctl_req pioctl_req)
{
	mlan_ds_rate *ds_rate = MNULL;
	WLAN_802_11_RATES rates;
	t_u8 *rate = MNULL;
	int rate_index = 0;
	t_u16 bitmap_rates[MAX_BITMAP_RATES_SIZE];
	t_u32 i = 0;
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];

	ENTER();

	ds_rate = (mlan_ds_rate *)pioctl_req->pbuf;

	if (ds_rate->param.rate_cfg.is_rate_auto) {
		memset(pmadapter, bitmap_rates, 0, sizeof(bitmap_rates));
		/* Support all HR/DSSS rates */
		bitmap_rates[0] = 0x000F;
		/* Support all OFDM rates */
		bitmap_rates[1] = 0x00FF;
		/* Rates talbe [0] HR/DSSS,[1] OFDM,[2..9] HT,[10..17] VHT */
		/* Support all HT-MCSs rate */
		for (i = 0; i < NELEMENTS(pmpriv->bitmap_rates) - 3 - 8; i++)
			bitmap_rates[i + 2] = 0xFFFF;
		bitmap_rates[9] = 0x3FFF;
		/* Support all VHT-MCSs rate */
		for (i = 0; i < NELEMENTS(pmpriv->bitmap_rates) - 10; i++)
			bitmap_rates[i + 10] = 0x03FF;	/* 10 Bits valid */
	} else {
		memset(pmadapter, rates, 0, sizeof(rates));
		wlan_get_active_data_rates(pmpriv, pmpriv->bss_mode,
					   (pmpriv->bss_mode ==
					    MLAN_BSS_MODE_INFRA) ?
					   pmpriv->config_bands :
					   pmadapter->adhoc_start_band, rates);
		rate = rates;
		for (i = 0; (rate[i] && i < WLAN_SUPPORTED_RATES); i++) {
			PRINTM(MINFO, "Rate=0x%X  Wanted=0x%X\n", rate[i],
			       ds_rate->param.rate_cfg.rate);
			if ((rate[i] & 0x7f) ==
			    (ds_rate->param.rate_cfg.rate & 0x7f))
				break;
		}
		if ((i < WLAN_SUPPORTED_RATES && !rate[i]) ||
		    (i == WLAN_SUPPORTED_RATES)) {
			PRINTM(MERROR,
			       "The fixed data rate 0x%X is out "
			       "of range\n", ds_rate->param.rate_cfg.rate);
			pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
			ret = MLAN_STATUS_FAILURE;
			goto exit;
		}
		memset(pmadapter, bitmap_rates, 0, sizeof(bitmap_rates));
		rate_index =
			wlan_data_rate_to_index(pmadapter,
						ds_rate->param.rate_cfg.rate);
		/* Only allow b/g rates to be set */
		if (rate_index >= MLAN_RATE_INDEX_HRDSSS0 &&
		    rate_index <= MLAN_RATE_INDEX_HRDSSS3)
			bitmap_rates[0] = 1 << rate_index;
		else {
			rate_index -= 1;	/* There is a 0x00 in the table */
			if (rate_index >= MLAN_RATE_INDEX_OFDM0 &&
			    rate_index <= MLAN_RATE_INDEX_OFDM7)
				bitmap_rates[1] = 1 << (rate_index -
							MLAN_RATE_INDEX_OFDM0);
		}
	}

	/* Send request to firmware */
	ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_TX_RATE_CFG,
			       HostCmd_ACT_GEN_SET, 0, (t_void *)pioctl_req,
			       bitmap_rates);
	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

exit:
	LEAVE();
	return ret;
}

/**
 *  @brief Get rate index
 *
 *  @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_rate_ioctl_get_rate_index(pmlan_adapter pmadapter,
			       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, HostCmd_CMD_TX_RATE_CFG,
			       HostCmd_ACT_GEN_GET, 0, (t_void *)pioctl_req,
			       MNULL);
	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief Set rate index
 *
 *  @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_rate_ioctl_set_rate_index(pmlan_adapter pmadapter,
			       pmlan_ioctl_req pioctl_req)
{
	t_u32 rate_index;
	t_u32 rate_format;
	t_u32 nss;
	t_u32 i;
	mlan_ds_rate *ds_rate = MNULL;
	mlan_status ret = MLAN_STATUS_FAILURE;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	t_u16 bitmap_rates[MAX_BITMAP_RATES_SIZE];
	int tx_mcs_supp = GET_TXMCSSUPP(pmpriv->usr_dev_mcs_support);

	ENTER();

	ds_rate = (mlan_ds_rate *)pioctl_req->pbuf;
	rate_format = ds_rate->param.rate_cfg.rate_format;
	nss = ds_rate->param.rate_cfg.nss;
	rate_index = ds_rate->param.rate_cfg.rate;

	if (ds_rate->param.rate_cfg.is_rate_auto) {
		memset(pmadapter, bitmap_rates, 0, sizeof(bitmap_rates));
		/* Rates talbe [0]: HR/DSSS;[1]: OFDM; [2..9] HT; */
		/* Support all HR/DSSS rates */
		bitmap_rates[0] = 0x000F;
		/* Support all OFDM rates */
		bitmap_rates[1] = 0x00FF;
		/* Support all HT-MCSs rate */
		for (i = 2; i < 9; i++)
			bitmap_rates[i] = 0xFFFF;
		bitmap_rates[9] = 0x3FFF;
		/* [10..17] VHT */
		/* Support all VHT-MCSs rate for NSS 1 and 2 */
		for (i = 10; i < 12; i++)
			bitmap_rates[i] = 0x03FF;	/* 10 Bits valid */
		/* Set to 0 as default value for all other NSSs */
		for (i = 12; i < 17; i++)
			bitmap_rates[i] = 0x0;
		/* [18..25] HE */
		/* Support all HE-MCSs rate for NSS1 and 2 */
		for (i = 18; i < 20; i++)
			bitmap_rates[i] = 0x0FFF;
		for (i = 20; i < NELEMENTS(bitmap_rates); i++)
			bitmap_rates[i] = 0x0;
	} else {
		PRINTM(MINFO, "Rate index is %d\n", rate_index);
		if ((rate_format == MLAN_RATE_FORMAT_HT) &&
		    (rate_index > MLAN_RATE_INDEX_MCS7 &&
		     rate_index <= MLAN_RATE_INDEX_MCS15) &&
		    (tx_mcs_supp < 2)) {
			PRINTM(MERROR,
			       "HW don't support 2x2, rate_index=%d hw_mcs_supp=0x%x\n",
			       rate_index, pmpriv->usr_dev_mcs_support);
			pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
			LEAVE();
			return MLAN_STATUS_FAILURE;
		}
		memset(pmadapter, bitmap_rates, 0, sizeof(bitmap_rates));
		if (rate_format == MLAN_RATE_FORMAT_LG) {
			/* Bitmap of HR/DSSS rates */
			if (rate_index <= MLAN_RATE_INDEX_HRDSSS3) {
				bitmap_rates[0] = 1 << rate_index;
				ret = MLAN_STATUS_SUCCESS;
				/* Bitmap of OFDM rates */
			} else if ((rate_index >= MLAN_RATE_INDEX_OFDM0) &&
				   (rate_index <= MLAN_RATE_INDEX_OFDM7)) {
				bitmap_rates[1] = 1 << (rate_index -
							MLAN_RATE_INDEX_OFDM0);
				ret = MLAN_STATUS_SUCCESS;
			}
		} else if (rate_format == MLAN_RATE_FORMAT_HT) {
			if (rate_index <= MLAN_RATE_INDEX_MCS32) {
				bitmap_rates[2 + (rate_index / 16)] =
					1 << (rate_index % 16);
				ret = MLAN_STATUS_SUCCESS;
			}
		}
		if (rate_format == MLAN_RATE_FORMAT_VHT) {
			if ((rate_index <= MLAN_RATE_INDEX_MCS9) &&
			    (MLAN_RATE_NSS1 <= nss) &&
			    (nss <= MLAN_RATE_NSS2)) {
				bitmap_rates[10 + nss - MLAN_RATE_NSS1] =
					(1 << rate_index);
				ret = MLAN_STATUS_SUCCESS;
			}
		}
		if (rate_format == MLAN_RATE_FORMAT_HE) {
			if (IS_FW_SUPPORT_11AX(pmadapter)) {
				if ((rate_index <= MLAN_RATE_INDEX_MCS11) &&
				    (MLAN_RATE_NSS1 <= nss) &&
				    (nss <= MLAN_RATE_NSS2)) {
					bitmap_rates[18 + nss -
						     MLAN_RATE_NSS1] =
						(1 << rate_index);
					ret = MLAN_STATUS_SUCCESS;
				}
			} else {
				PRINTM(MERROR,
				       "Error! Fw doesn't support 11AX\n");
				LEAVE();
				return MLAN_STATUS_FAILURE;
			}
		}

		if (ret == MLAN_STATUS_FAILURE) {
			PRINTM(MERROR, "Invalid MCS index=%d. \n", rate_index);
			pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
			LEAVE();
			return MLAN_STATUS_FAILURE;
		}
	}

	PRINTM(MINFO,
	       "RateBitmap=%04x%04x%04x%04x%04x%04x%04x%04x"
	       "%04x%04x%04x%04x%04x%04x%04x%04x%04x%04x, "
	       "IsRateAuto=%d, DataRate=%d\n",
	       bitmap_rates[17], bitmap_rates[16], bitmap_rates[15],
	       bitmap_rates[14], bitmap_rates[13], bitmap_rates[12],
	       bitmap_rates[11], bitmap_rates[10], bitmap_rates[9],
	       bitmap_rates[8], bitmap_rates[7], bitmap_rates[6],
	       bitmap_rates[5], bitmap_rates[4], bitmap_rates[3],
	       bitmap_rates[2], bitmap_rates[1], bitmap_rates[0],
	       pmpriv->is_data_rate_auto, pmpriv->data_rate);

	/* Send request to firmware */
	ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_TX_RATE_CFG,
			       HostCmd_ACT_GEN_SET, 0, (t_void *)pioctl_req,
			       (t_void *)bitmap_rates);
	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief Rate configuration 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
 */
mlan_status
wlan_rate_ioctl_cfg(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_ds_rate *rate = MNULL;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	rate = (mlan_ds_rate *)pioctl_req->pbuf;
	if (rate->param.rate_cfg.rate_type == MLAN_RATE_BITMAP) {
		if (pioctl_req->action == MLAN_ACT_GET)
			status = wlan_rate_ioctl_get_rate_bitmap(pmadapter,
								 pioctl_req);
		else
			status = wlan_rate_ioctl_set_rate_bitmap(pmadapter,
								 pioctl_req);
	} else if (rate->param.rate_cfg.rate_type == MLAN_RATE_VALUE) {
		if (pioctl_req->action == MLAN_ACT_GET)
			status = wlan_rate_ioctl_get_rate_value(pmadapter,
								pioctl_req);
		else
			status = wlan_rate_ioctl_set_rate_value(pmadapter,
								pioctl_req);
	} else {
		if (pioctl_req->action == MLAN_ACT_GET)
			status = wlan_rate_ioctl_get_rate_index(pmadapter,
								pioctl_req);
		else
			status = wlan_rate_ioctl_set_rate_index(pmadapter,
								pioctl_req);
	}

	LEAVE();
	return status;
}

/**
 *  @brief Get data rates
 *
 *  @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_rate_ioctl_get_data_rate(pmlan_adapter pmadapter,
			      pmlan_ioctl_req pioctl_req)
{
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_status ret = MLAN_STATUS_SUCCESS;

	ENTER();

	if (pioctl_req->action != MLAN_ACT_GET) {
		ret = MLAN_STATUS_FAILURE;
		goto exit;
	}

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

exit:
	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get remain on channel setting
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
 */
mlan_status
wlan_radio_ioctl_remain_chan_cfg(pmlan_adapter pmadapter,
				 pmlan_ioctl_req pioctl_req)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_ds_radio_cfg *radio_cfg = MNULL;
	t_u16 cmd_action = 0;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];

	ENTER();

	radio_cfg = (mlan_ds_radio_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 request to firmware */
	ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_REMAIN_ON_CHANNEL,
			       cmd_action, 0, (t_void *)pioctl_req,
			       &radio_cfg->param.remain_chan);

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

#ifdef WIFI_DIRECT_SUPPORT
/**
 *  @brief Set/Get wifi_direct_mode
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
 */
mlan_status
wlan_bss_ioctl_wifi_direct_mode(pmlan_adapter pmadapter,
				pmlan_ioctl_req pioctl_req)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_ds_bss *bss = MNULL;

	t_u16 cmd_action = 0;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];

	ENTER();

	bss = (mlan_ds_bss *)pioctl_req->pbuf;

	if (pioctl_req->action == MLAN_ACT_SET)
		cmd_action = HostCmd_ACT_GEN_SET;
	else
		cmd_action = HostCmd_ACT_GEN_GET;

	/* Send request to firmware */
	ret = wlan_prepare_cmd(pmpriv, HOST_CMD_WIFI_DIRECT_MODE_CONFIG,
			       cmd_action, 0, (t_void *)pioctl_req,
			       &bss->param.wfd_mode);

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get p2p config
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
 */
mlan_status
wlan_misc_p2p_config(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
		cmd_action = HostCmd_ACT_GEN_GET;

	/* Send request to firmware */
	ret = wlan_prepare_cmd(pmpriv, HOST_CMD_P2P_PARAMS_CONFIG, cmd_action,
			       0, (t_void *)pioctl_req,
			       &misc_cfg->param.p2p_config);

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}
#endif

/**
 *  @brief Set/Get GPIO TSF Latch config
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
 */
mlan_status
wlan_misc_gpio_tsf_latch_config(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
		cmd_action = HostCmd_ACT_GEN_GET;

	/* Send request to firmware */
	ret = wlan_prepare_cmd(pmpriv, HOST_CMD_GPIO_TSF_LATCH_PARAM_CONFIG,
			       cmd_action, 0, (t_void *)pioctl_req,
			       &misc_cfg->param.gpio_tsf_latch_config);

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief Get TSF info
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
 */
mlan_status
wlan_misc_get_tsf_info(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;
	cmd_action = HostCmd_ACT_GEN_GET;

	/* Send request to firmware */
	ret = wlan_prepare_cmd(pmpriv, HOST_CMD_GPIO_TSF_LATCH_PARAM_CONFIG,
			       cmd_action, 0, (t_void *)pioctl_req,
			       &misc_cfg->param.tsf_info);

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief Set coalesce config
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
 */
mlan_status
wlan_misc_ioctl_coalesce_cfg(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
		cmd_action = HostCmd_ACT_GEN_GET;

	/* Send request to firmware */
	ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_COALESCE_CFG, cmd_action, 0,
			       (t_void *)pioctl_req,
			       &misc_cfg->param.coalesce_cfg);

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief Get/Set USB packet aggregation 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
 */
mlan_status
wlan_misc_ioctl_aggr_ctrl(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_ds_misc_cfg *misc = MNULL;
	t_u16 cmd_action = 0;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];

	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 request to firmware */
	ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_PACKET_AGGR_CTRL, cmd_action,
			       0, (t_void *)pioctl_req,
			       &misc->param.aggr_params);

	if (ret == MLAN_STATUS_SUCCESS) {
		ret = MLAN_STATUS_PENDING;
	}

	LEAVE();
	return ret;
}

#ifdef USB
/**
 *  @brief Get/Set USB packet aggregation 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
 */
mlan_status
wlan_misc_ioctl_usb_aggr_ctrl(pmlan_adapter pmadapter,
			      pmlan_ioctl_req pioctl_req)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_ds_misc_cfg *misc = MNULL;
	t_u16 cmd_action = 0;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];

	ENTER();

	if (pmadapter->pcard_usb->fw_usb_aggr == MFALSE) {
		PRINTM(MERROR, "USB aggregation not supported by FW\n");
		pioctl_req->status_code = MLAN_ERROR_CMD_INVALID;
		LEAVE();
		return MLAN_STATUS_FAILURE;
	}

	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 request to firmware */
	ret = wlan_prepare_cmd(pmpriv,
			       HostCmd_CMD_PACKET_AGGR_OVER_HOST_INTERFACE,
			       cmd_action, 0, (t_void *)pioctl_req,
			       &misc->param.usb_aggr_params);

	if (ret == MLAN_STATUS_SUCCESS) {
		ret = MLAN_STATUS_PENDING;
	}

	LEAVE();
	return ret;
}
#endif

/**
 *  @brief Get/Set Tx control configuration
 *
 *  @param pmadapter    A pointer to mlan_adapter structure
 *  @param pioctl_req   A pointer to ioctl request buffer
 *
 *  @return             MLAN_STATUS_SUCCESS
 */
mlan_status
wlan_misc_ioctl_txcontrol(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_ds_misc_cfg *misc = MNULL;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];

	ENTER();

	misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
	if (pioctl_req->action == MLAN_ACT_SET)
		pmpriv->pkt_tx_ctrl = misc->param.tx_control;
	else
		misc->param.tx_control = pmpriv->pkt_tx_ctrl;

	LEAVE();
	return ret;
}

#ifdef RX_PACKET_COALESCE
/**
 *  @brief Get/Set RX packet coalescing configuration
 *
 *  @param pmadapter    A pointer to mlan_adapter structure
 *  @param pioctl_req   A pointer to ioctl request buffer
 *
 *  @return             MLAN_STATUS_SUCCESS
 */
mlan_status
wlan_misc_ioctl_rx_pkt_coalesce_config(pmlan_adapter pmadapter,
				       pmlan_ioctl_req pioctl_req)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_ds_misc_cfg *misc = MNULL;
	t_u16 cmd_action = 0;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];

	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 request to firmware */
	ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_RX_PKT_COALESCE_CFG,
			       cmd_action, 0, (t_void *)pioctl_req,
			       &misc->param.rx_coalesce);

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}
#endif

/**
 *  @brief Is any uAP started or STA connected?
 *
 *  @param pmadapter    A pointer to mlan_adapter structure
 *
 *  @return             MTRUE/MFALSE
 */
t_bool
wlan_check_interface_active(mlan_adapter *pmadapter)
{
	t_bool ret = MFALSE;
	pmlan_private pmpriv;
	int i;

	if (pmadapter == MNULL)
		return MFALSE;

	for (i = 0; i < pmadapter->priv_num; i++) {
		pmpriv = pmadapter->priv[i];
		if (pmpriv) {
#ifdef UAP_SUPPORT
			if (GET_BSS_ROLE(pmpriv) == MLAN_BSS_ROLE_UAP)
				ret = pmpriv->uap_bss_started;
			else
#endif
			if (GET_BSS_ROLE(pmpriv) == MLAN_BSS_ROLE_STA)
				ret = pmpriv->media_connected;
		}
		if (ret)
			return MTRUE;
	}

	return MFALSE;
}

/**
 *  @brief Get/Set DFS REPEATER mode
 *
 *  @param pmadapter    A pointer to mlan_adapter structure
 *  @param pioctl_req   A pointer to ioctl request buffer
 *
 *  @return             MLAN_STATUS_SUCCESS
 */
mlan_status
wlan_misc_ioctl_dfs_repeater_cfg(pmlan_adapter pmadapter,
				 pmlan_ioctl_req pioctl_req)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_ds_misc_cfg *misc = MNULL;
	t_u16 cmd_action = 0;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];

	ENTER();

	misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;

	if (pioctl_req->action == MLAN_ACT_SET) {
		/* Make sure no interface is active
		 * before setting the dfs repeater mode
		 */
		if (wlan_check_interface_active(pmadapter)) {
			PRINTM(MMSG, "DFS-Repeater active priv found,"
			       " skip enabling the mode.\n");
			ret = MLAN_STATUS_FAILURE;
			goto done;
		}

		cmd_action = HostCmd_ACT_GEN_SET;
	} else {
		cmd_action = HostCmd_ACT_GEN_GET;
	}

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

done:
	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get Low Power Mode
 *
 *  @param pmadapter    A pointer to mlan_adapter structure
 *  @param pioctl_req   A pointer to ioctl request buffer
 *
 *  @return             MLAN_STATUS_SUCCESS
 */
mlan_status
wlan_misc_ioctl_low_pwr_mode(pmlan_adapter pmadapter,
			     pmlan_ioctl_req pioctl_req)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_ds_misc_cfg *misc = MNULL;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];

	ENTER();

	misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;

	/* Send request to firmware */
	ret = wlan_prepare_cmd(pmpriv, HostCMD_CONFIG_LOW_POWER_MODE,
			       HostCmd_ACT_GEN_SET, 0, (t_void *)pioctl_req,
			       &misc->param.low_pwr_mode);

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief Configure PMIC in Firmware
 *
 *  @param pmadapter    A pointer to mlan_adapter structure
 *  @param pioctl_req   A pointer to ioctl request buffer
 *
 *  @return             MLAN_STATUS_SUCCESS
 */
mlan_status
wlan_misc_ioctl_pmic_configure(pmlan_adapter pmadapter,
			       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, HOST_CMD_PMIC_CONFIGURE,
			       HostCmd_ACT_GEN_SET, 0, (t_void *)pioctl_req,
			       MNULL);

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/*  @brief Set/Get CW Mode Level control
 *
 *  @param pmadapter    A pointer to mlan_adapter structure
 *  @param pioctl_req   A pointer to ioctl request buffer
 *
 *  @return             MLAN_STATUS_SUCCESS
 */
mlan_status
wlan_misc_ioctl_cwmode_ctrl(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_ds_misc_cfg *misc = MNULL;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	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 request to firmware */
	ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_CW_MODE_CTRL, cmd_action, 0,
			       (t_void *)pioctl_req, &misc->param.cwmode);

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief push value to stack
 *
 *  @param pmadapter    A pointer to mlan_adapter structure
 *  @param s        A pointer to mef_stack
 *  @param len          Length of value
 *  @param val          A pointer to value
 *
 *  @return             MLAN_STATUS_SUCCESS or FAIL
 */
inline mlan_status
push_n(pmlan_adapter pmadapter, mef_stack *s, t_u8 len, t_u8 *val)
{
	if ((s->sp + len) <= MAX_NUM_STACK_BYTES) {
		memcpy_ext(pmadapter, s->byte + s->sp, val, len,
			   MAX_NUM_STACK_BYTES - s->sp);
		s->sp += len;
		return MLAN_STATUS_SUCCESS;
	} else {
		PRINTM(MERROR, "Stack is full\n");
		return MLAN_STATUS_FAILURE;
	}
}

/**
 *  @brief push value to stack accoring to operand type
 *
 *  @param pmadapter    A pointer to mlan_adapter structure
 *  @param s        A pointer to mef_stack
 *  @param op           A pointer to mef_op
 *
 *  @return             MLAN_STATUS_SUCCESS or FAIL
 */
inline mlan_status
mef_push(pmlan_adapter pmadapter, mef_stack *s, mef_op *op)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	t_u8 nbytes;
	switch (op->operand_type) {
	case OPERAND_DNUM:
		ret = push_n(pmadapter, s, 4, op->val);
		if (ret == MLAN_STATUS_SUCCESS)
			ret = push_n(pmadapter, s, 1, &op->operand_type);
		else
			ret = MLAN_STATUS_FAILURE;
		break;
	case OPERAND_BYTE_SEQ:
		nbytes = op->val[0];
		if (MLAN_STATUS_SUCCESS ==
		    push_n(pmadapter, s, nbytes, op->val + 1) &&
		    MLAN_STATUS_SUCCESS == push_n(pmadapter, s, 1, op->val) &&
		    MLAN_STATUS_SUCCESS ==
		    push_n(pmadapter, s, 1, &op->operand_type))
			ret = MLAN_STATUS_SUCCESS;
		else
			ret = MLAN_STATUS_FAILURE;
		break;
	default:
		ret = push_n(pmadapter, s, 1, &op->operand_type);
		break;
	}
	return ret;
}

/**
 *  @brief push dnum filter to stack
 *
 *  @param pmadapter    A pointer to mlan_adapter structure
 *  @param s        A pointer to mef_stack
 *  @param filter       A pointer to filter item
 *
 *  @return             MLAN_STATUS_SUCCESS or FAIL
 */
static mlan_status
push_filter_dnum_eq(pmlan_adapter pmadapter, mef_stack *s, mef_filter_t *filter)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	t_u32 dnum;
	mef_op op;

	ENTER();

	if (!filter) {
		ret = MLAN_STATUS_FAILURE;
		goto done;
	}
	if (filter->fill_flag != (FILLING_TYPE | FILLING_PATTERN |
				  FILLING_OFFSET | FILLING_NUM_BYTES)) {
		PRINTM(MERROR, "Filter item fill error\n");
		ret = MLAN_STATUS_FAILURE;
		goto done;
	}

	/* Format of decimal num:
	 * |   5 bytes  |    5 bytes    |    5 bytes    |        1 byte | |
	 * pattern  |     offset    |  num of bytes |  type (TYPE_DNUM_EQ)  |
	 */

	/* push pattern */
	memset(pmadapter, &op, 0, sizeof(op));
	op.operand_type = OPERAND_DNUM;
	dnum = filter->pattern;
	memcpy_ext(pmadapter, op.val, &dnum, sizeof(dnum), sizeof(op.val));
	ret = mef_push(pmadapter, s, &op);
	if (ret != MLAN_STATUS_SUCCESS)
		goto done;

	/* push offset */
	memset(pmadapter, &op, 0, sizeof(op));
	op.operand_type = OPERAND_DNUM;
	dnum = filter->offset;
	memcpy_ext(pmadapter, op.val, &dnum, sizeof(dnum), sizeof(op.val));
	ret = mef_push(pmadapter, s, &op);
	if (ret != MLAN_STATUS_SUCCESS)
		goto done;

	/* push num of bytes */
	memset(pmadapter, &op, 0, sizeof(op));
	op.operand_type = OPERAND_DNUM;
	dnum = filter->num_bytes;
	memcpy_ext(pmadapter, op.val, &dnum, sizeof(dnum), sizeof(op.val));
	ret = mef_push(pmadapter, s, &op);
	if (ret != MLAN_STATUS_SUCCESS)
		goto done;

	/* push type */
	memset(pmadapter, &op, 0, sizeof(op));
	op.operand_type = TYPE_DNUM_EQ;
	ret = mef_push(pmadapter, s, &op);

done:
	LEAVE();
	return ret;
}

/**
 *  @brief push byte_eq filter to stack
 *
 *  @param pmadapter    A pointer to mlan_adapter structure
 *  @param s            A pointer to mef_stack
 *  @param filter       A pointer to filter item
 *
 *  @return             MLAN_STATUS_SUCCESS or FAIL
 */
static mlan_status
push_filter_byte_eq(pmlan_adapter pmadapter, mef_stack *s, mef_filter_t *filter)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	t_u32 dnum;
	mef_op op;

	ENTER();

	if (!filter) {
		ret = MLAN_STATUS_FAILURE;
		goto done;
	}
	if (filter->fill_flag != (FILLING_TYPE | FILLING_REPEAT |
				  FILLING_BYTE_SEQ | FILLING_OFFSET)) {
		PRINTM(MERROR, "Filter item fill error\n");
		ret = MLAN_STATUS_FAILURE;
		goto done;
	}

	/* Format of decimal num:
	 * |   5 bytes  |      val      |    5 bytes    |        1 byte | |
	 * repeat   |   bytes seq   |    offset     |  type (TYPE_BYTE_EQ)  |
	 */

	/* push repeat */
	memset(pmadapter, &op, 0, sizeof(op));
	op.operand_type = OPERAND_DNUM;
	dnum = filter->repeat;
	memcpy_ext(pmadapter, op.val, &dnum, sizeof(dnum), sizeof(op.val));
	ret = mef_push(pmadapter, s, &op);
	if (ret != MLAN_STATUS_SUCCESS)
		goto done;

	/* push bytes seq */
	memset(pmadapter, &op, 0, sizeof(op));
	op.operand_type = OPERAND_BYTE_SEQ;
	op.val[0] = filter->num_byte_seq;
	memcpy_ext(pmadapter, &op.val[1], filter->byte_seq,
		   filter->num_byte_seq, MAX_NUM_BYTE_SEQ);
	ret = mef_push(pmadapter, s, &op);
	if (ret != MLAN_STATUS_SUCCESS)
		goto done;

	/* push offset */
	memset(pmadapter, &op, 0, sizeof(op));
	op.operand_type = OPERAND_DNUM;
	dnum = filter->offset;
	memcpy_ext(pmadapter, op.val, &dnum, sizeof(dnum), sizeof(op.val));
	ret = mef_push(pmadapter, s, &op);
	if (ret != MLAN_STATUS_SUCCESS)
		goto done;

	/* push type */
	memset(pmadapter, &op, 0, sizeof(op));
	op.operand_type = TYPE_BYTE_EQ;
	ret = mef_push(pmadapter, s, &op);

done:
	LEAVE();
	return ret;
}

/**
 *  @brief push bite_eq filter to stack
 *
 *  @param pmadapter    A pointer to mlan_adapter structure
 *  @param s            A pointer to mef_stack
 *  @param filter       A pointer to filter item
 *
 *  @return             MLAN_STATUS_SUCCESS or FAIL
 */
static mlan_status
push_filter_bit_eq(pmlan_adapter pmadapter, mef_stack *s, mef_filter_t *filter)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	t_u32 dnum;
	mef_op op;

	ENTER();

	if (!filter) {
		ret = MLAN_STATUS_FAILURE;
		goto done;
	}
	if (filter->fill_flag != (FILLING_TYPE | FILLING_REPEAT |
				  FILLING_BYTE_SEQ | FILLING_OFFSET)) {
		PRINTM(MERROR, "Filter item fill error\n");
		ret = MLAN_STATUS_FAILURE;
		goto done;
	}

	/* Format of decimal num:
	 * |   val      |    5 bytes    |      val      |        1 byte | |
	 * bytes seq  |    offset     |    mask seq   |  type (TYPE_BIT_EQ)   |
	 */

	/* push bytes seq */
	memset(pmadapter, &op, 0, sizeof(op));
	op.operand_type = OPERAND_BYTE_SEQ;
	op.val[0] = filter->num_byte_seq;
	memcpy_ext(pmadapter, &op.val[1], filter->byte_seq,
		   filter->num_byte_seq, MAX_NUM_BYTE_SEQ);
	ret = mef_push(pmadapter, s, &op);
	if (ret != MLAN_STATUS_SUCCESS)
		goto done;

	/* push offset */
	memset(pmadapter, &op, 0, sizeof(op));
	op.operand_type = OPERAND_DNUM;
	dnum = filter->offset;
	memcpy_ext(pmadapter, op.val, &dnum, sizeof(dnum), sizeof(op.val));
	ret = mef_push(pmadapter, s, &op);
	if (ret != MLAN_STATUS_SUCCESS)
		goto done;

	/* push mask seq */
	memset(pmadapter, &op, 0, sizeof(op));
	op.operand_type = OPERAND_BYTE_SEQ;
	op.val[0] = filter->num_mask_seq;
	memcpy_ext(pmadapter, &op.val[1], filter->mask_seq,
		   filter->num_mask_seq, MAX_NUM_BYTE_SEQ);
	ret = mef_push(pmadapter, s, &op);
	if (ret != MLAN_STATUS_SUCCESS)
		goto done;

	/* push type */
	memset(pmadapter, &op, 0, sizeof(op));
	op.operand_type = TYPE_BIT_EQ;
	ret = mef_push(pmadapter, s, &op);

done:
	LEAVE();
	return ret;
}

/**
 *  @brief push filter to stack
 *
 *  @param pmadapter    A pointer to mlan_adapter structure
 *  @param s        A pointer to mef_stack
 *  @param filter       A pointer to filter item
 *
 *  @return             MLAN_STATUS_SUCCESS or FAIL
 */
static mlan_status
wlan_push_filter(pmlan_adapter pmadapter, mef_stack *s, mef_filter_t *filter)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;

	switch (filter->type) {
	case TYPE_DNUM_EQ:
		ret = push_filter_dnum_eq(pmadapter, s, filter);
		break;
	case TYPE_BYTE_EQ:
		ret = push_filter_byte_eq(pmadapter, s, filter);
		break;
	case TYPE_BIT_EQ:
		ret = push_filter_bit_eq(pmadapter, s, filter);
		break;
	default:
		PRINTM(MERROR, "Invalid filter type\n");
		ret = MLAN_STATUS_FAILURE;
		break;
	}
	return ret;
}

/**
 *  @brief generate mef data
 *
 *  @param pmadapter    A pointer to mlan_adapter structure
 *  @param s        A pointer to mef_stack
 *  @param entry        A pointer to mef_entry_t
 *
 *  @return             MLAN_STATUS_SUCCESS or FAIL
 */
static mlan_status
wlan_generate_mef_filter_stack(pmlan_adapter pmadapter,
			       mef_stack *s, mef_entry_t *entry)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mef_op op;
	int i;

	ENTER();

	for (i = 0; i < entry->filter_num; i++) {
		ret = wlan_push_filter(pmadapter, s, &entry->filter_item[i]);
		if (ret != MLAN_STATUS_SUCCESS) {
			PRINTM(MERROR, "push filter to stack error\n");
			goto done;
		}
		if (i != 0) {
			memset(pmadapter, &op, 0, sizeof(op));
			op.operand_type = entry->rpn[i];
			ret = mef_push(pmadapter, s, &op);
			if (ret != MLAN_STATUS_SUCCESS) {
				PRINTM(MERROR, "push filter rpn error\n");
				goto done;
			}
		}
	}
done:
	LEAVE();
	return ret;
}

/**
 *  @brief Set the mef entries to firmware
 *
 *  @param pmpriv        A pointer to mlan_private structure
 *  @param pmadapter    A pointer to mlan_adapter structure
 *  @param pmef      A pointer to mef_cfg structure
 *
 *  @return             MLAN_STATUS_SUCCESS or FAIL
 */
mlan_status
wlan_set_mef_entry(mlan_private *pmpriv,
		   pmlan_adapter pmadapter, mef_cfg_data * pmef)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_ds_misc_cmd *hostcmd;
	HostCmd_DS_GEN *hostcmd_hdr;
	HostCmd_DS_MEF_CFG *mef_hdr;
	mef_entry_header *entry_hdr;
	mef_stack *stack;
	mef_entry_t *pentry;
	t_u8 *buf;
	t_u32 i, buf_len;
	pmlan_callbacks pcb;

	ENTER();

	if (pmef->entry_num > MAX_NUM_ENTRIES) {
		PRINTM(MERROR, "Too many entries\n");
		ret = MLAN_STATUS_FAILURE;
		goto done;
	}
	pcb = &pmadapter->callbacks;
	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 cmd data buffer\n");
		ret = MLAN_STATUS_FAILURE;
		goto err_handle;
	}

	/** Fill the cmd header data*/
	memset(pmadapter, hostcmd, 0, sizeof(mlan_ds_misc_cmd));
	buf = hostcmd->cmd;
	hostcmd_hdr = (HostCmd_DS_GEN *)buf;
	hostcmd_hdr->command = wlan_cpu_to_le16(HostCmd_CMD_MEF_CFG);
	buf_len = S_DS_GEN;

	/** Fill HostCmd_DS_MEF_CFG*/
	mef_hdr = (HostCmd_DS_MEF_CFG *)(buf + buf_len);
	mef_hdr->criteria = wlan_cpu_to_le32(pmef->criteria);
	mef_hdr->nentries = wlan_cpu_to_le16(pmef->entry_num);
	buf_len += sizeof(HostCmd_DS_MEF_CFG);

	/** generate mef entry data*/
	for (i = 0, pentry = pmef->pentry; i < pmef->entry_num; i++, pentry++) {
		/** Fill entry header data*/
		entry_hdr = (mef_entry_header *)(buf + buf_len);
		entry_hdr->mode = pentry->mode;
		entry_hdr->action = pentry->action;
		buf_len += sizeof(mef_entry_header);

		/** Fill Stack data*/
		stack = (mef_stack *)(buf + buf_len);
		ret = wlan_generate_mef_filter_stack(pmadapter, stack, pentry);
		if (ret != MLAN_STATUS_SUCCESS) {
			PRINTM(MERROR, "Generate mef data error\n");
			goto err_handle;
		}
		buf_len += (stack->sp + sizeof(stack->sp));
	}
	hostcmd_hdr->size = wlan_cpu_to_le16(buf_len);
	hostcmd->len = wlan_cpu_to_le32(buf_len);

	DBG_HEXDUMP(MCMD_D, "MEF DATA", (t_u8 *)hostcmd, buf_len + 4);

	/** Send command to firmware*/
	ret = wlan_prepare_cmd(pmpriv, 0, 0, 0, (t_void *)MNULL,
			       (t_void *)hostcmd);

err_handle:
	if (hostcmd)
		pcb->moal_mfree(pmadapter->pmoal_handle, (t_u8 *)hostcmd);
done:
	LEAVE();
	return ret;
}

/*
 *  @brief generate Host_CMD_MEF_CFG cmd data to firmware
 *
 *  @param pmpriv       A pointer to mlan_private structure
 *  @param pmadapter    A pointer to mlan_adapter structure
 *
 *  @return             MLAN_STATUS_SUCCESS or FAIL
 */
mlan_status
wlan_process_mef_cfg_cmd(mlan_private *pmpriv, pmlan_adapter pmadapter)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	pmlan_callbacks pcb;
	mef_cfg_data mef;
	mef_entry_t *pentry;
	mef_entry *pmef;
	t_u16 entry_num = 0;

	ENTER();

	pcb = &pmadapter->callbacks;

	/** check how many entries in adapter*/
	pmef = &pmadapter->entry_cfg;
	entry_num += pmef->enable_autoarp_entry;
	entry_num += pmef->num_wowlan_entry;
	entry_num += pmef->num_ipv6_ns_offload;
	if (!entry_num) {
		PRINTM(MIOCTL, "No filter entries\n");
		goto done;
	}

	ret = pcb->moal_malloc(pmadapter->pmoal_handle,
			       sizeof(mef_entry_t) * entry_num, MLAN_MEM_DEF,
			       (t_u8 **)&mef.pentry);
	if (ret != MLAN_STATUS_SUCCESS || mef.pentry == MNULL) {
		PRINTM(MERROR, "Failed to allocate cmd data buffer\n");
		ret = MLAN_STATUS_FAILURE;
		goto err_handle;
	}
	/** Fill mef_cfg structure*/
	mef.criteria = pmef->criteria;
	mef.entry_num = entry_num;
	memset(pmadapter, mef.pentry, 0, sizeof(mef_entry_t) * entry_num);
	pentry = mef.pentry;
	/** Fill mef_entry_t structure*/
	/** Copy Auto arp response entry*/
	if (pmef->enable_autoarp_entry) {
		memcpy_ext(pmadapter, pentry, &pmef->entry[5],
			   sizeof(mef_entry_t), sizeof(mef_entry_t));
		pentry += pmef->enable_autoarp_entry;
	}
	/** Copy wowlan entry*/
	if (pmef->num_wowlan_entry) {
		memcpy_ext(pmadapter, pentry, &pmef->entry[6],
			   sizeof(mef_entry_t), sizeof(mef_entry_t));
		pentry += pmef->num_wowlan_entry;
	}
	/** Copy IPv6 NS message offload entry */
	if (pmef->num_ipv6_ns_offload)
		memcpy_ext(pmadapter, pentry, &pmef->entry[7],
			   sizeof(mef_entry_t), sizeof(mef_entry_t));

	/** Set Entries to firmware*/
	ret = wlan_set_mef_entry(pmpriv, pmadapter, &mef);
	if (ret != MLAN_STATUS_SUCCESS)
		PRINTM(MERROR, "Set MEF entries error\n");

err_handle:
	if (mef.pentry)
		pcb->moal_mfree(pmadapter->pmoal_handle, (t_u8 *)mef.pentry);
done:
	LEAVE();
	return ret;
}

/*  @brief Get/Set NV-FLT-CONFIG parameters
 *
 *  @param pmadapter    A pointer to mlan_adapter structure
 *  @param pioctl_req   A pointer to ioctl request buffer
 *
 *  @return             MLAN_STATUS_SUCCESS
 */
mlan_status
wlan_misc_ioctl_mef_flt_cfg(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_ds_misc_cfg *misc_cfg = MNULL;
	mlan_ds_misc_mef_flt_cfg *mef_cfg = MNULL;
	mef_entry *pmef = MNULL;

	ENTER();

	misc_cfg = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
	mef_cfg = &misc_cfg->param.mef_flt_cfg;
	pmef = &pmadapter->entry_cfg;
	switch (pioctl_req->action) {
	case MLAN_ACT_SET:
		if (mef_cfg->mef_act_type == MEF_ACT_WOWLAN) {
			pmef->num_wowlan_entry = 1;
			pmef->criteria |= mef_cfg->criteria;
			memcpy_ext(pmadapter, &pmef->entry[6],
				   &mef_cfg->mef_entry, sizeof(mef_entry_t),
				   sizeof(mef_entry_t));
		}
		if (mef_cfg->mef_act_type == MEF_ACT_IPV6_NS) {
			pmef->num_ipv6_ns_offload = 1;
			pmef->criteria |= mef_cfg->criteria;
			memcpy_ext(pmadapter, &pmef->entry[7],
				   &mef_cfg->mef_entry, sizeof(mef_entry_t),
				   sizeof(mef_entry_t));
		}
		/** Set AUTO ARP Entry to adapter*/
		if (mef_cfg->mef_act_type == MEF_ACT_AUTOARP) {
			if (mef_cfg->op_code & MLAN_IPADDR_OP_AUTO_ARP_RESP) {
				pmef->enable_autoarp_entry = 1;
				pmef->criteria |= mef_cfg->criteria;
				memcpy_ext(pmadapter, &pmef->entry[5],
					   &mef_cfg->mef_entry,
					   sizeof(mef_entry_t),
					   sizeof(mef_entry_t));
				if (MLAN_STATUS_SUCCESS !=
				    wlan_process_mef_cfg_cmd(pmadapter->
							     priv[pioctl_req->
								  bss_index],
							     pmadapter))
					PRINTM(MERROR,
					       "Set MEF Entries Error\n");
			} else if (mef_cfg->op_code & MLAN_IPADDR_OP_IP_REMOVE) {
				pmef->enable_autoarp_entry = 0;
				memset(pmadapter, &pmef->entry[5], 0,
				       sizeof(mef_entry_t));
			}
		}
		break;
	case MLAN_ACT_GET:
		if (mef_cfg->mef_act_type == MEF_ACT_WOWLAN)
			memcpy_ext(pmadapter, &mef_cfg->mef_entry,
				   &pmef->entry[6], sizeof(mef_entry_t),
				   sizeof(mef_entry_t));
		break;
	default:
		pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID;
		ret = MLAN_STATUS_FAILURE;
		break;
	}

	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get WPA passphrase for esupplicant
 *
 *  @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_sec_ioctl_passphrase(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;
	t_u16 cmd_action = 0;
#ifdef STA_SUPPORT
	BSSDescriptor_t *pbss_desc;
	int i = 0;
#endif
	ENTER();

	sec = (mlan_ds_sec_cfg *)pioctl_req->pbuf;
#ifdef DRV_EMBEDDED_SUPPLICANT
	if (GET_BSS_ROLE(pmpriv) == MLAN_BSS_ROLE_STA &&
	    !IS_FW_SUPPORT_SUPPLICANT(pmpriv->adapter)) {
		if (sec->param.passphrase.psk_type == MLAN_PSK_QUERY)
			SupplicantQueryPassphrase(pmpriv->psapriv,
						  (void *)&sec->param.
						  passphrase);
		else if (sec->param.passphrase.psk_type == MLAN_PSK_CLEAR)
			SupplicantClearPMK(pmpriv->psapriv,
					   (void *)&sec->param.passphrase);
		else
			SupplicantSetPassphrase(pmpriv->psapriv,
						(void *)&sec->param.passphrase);

		LEAVE();
		return ret;
	}
#endif

	if (!IS_FW_SUPPORT_SUPPLICANT(pmpriv->adapter)) {
		LEAVE();
		return ret;
	}

	if (pioctl_req->action == MLAN_ACT_SET) {
		if (sec->param.passphrase.psk_type == MLAN_PSK_CLEAR)
			cmd_action = HostCmd_ACT_GEN_REMOVE;
		else
			cmd_action = HostCmd_ACT_GEN_SET;
	} else if (pioctl_req->action == MLAN_ACT_CLEAR) {
		cmd_action = HostCmd_ACT_GEN_REMOVE;
	} else {
		if (sec->param.passphrase.psk_type == MLAN_PSK_QUERY) {
#ifdef STA_SUPPORT
			if (GET_BSS_ROLE(pmpriv) == MLAN_BSS_ROLE_STA &&
			    sec->param.passphrase.ssid.ssid_len == 0) {
				i = wlan_find_bssid_in_list(pmpriv,
							    (t_u8 *)&sec->param.
							    passphrase.bssid,
							    MLAN_BSS_MODE_AUTO);
				if (i >= 0) {
					pbss_desc = &pmadapter->pscan_table[i];
					memcpy_ext(pmadapter,
						   &sec->param.passphrase.ssid,
						   &pbss_desc->ssid,
						   sizeof(mlan_802_11_ssid),
						   sizeof(mlan_802_11_ssid));
					memset(pmadapter,
					       &sec->param.passphrase.bssid, 0,
					       MLAN_MAC_ADDR_LENGTH);
					PRINTM(MINFO,
					       "PSK_QUERY: found ssid=%s\n",
					       sec->param.passphrase.ssid.ssid);
				}
			} else
#endif
				memset(pmadapter, &sec->param.passphrase.bssid,
				       0, MLAN_MAC_ADDR_LENGTH);
		}
		cmd_action = HostCmd_ACT_GEN_GET;
	}

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

	LEAVE();
	return ret;
}

/**
 *  @brief Set per packet Txctl and Rxinfo configuration
 *
 *  @param pmadapter    A pointer to mlan_adapter structure
 *  @param pioctl_req   A pointer to ioctl request buffer
 *
 *  @return             MLAN_STATUS_SUCCESS --success, otherwise fail
 */
mlan_status
wlan_misc_per_pkt_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 = MNULL;

	ENTER();

	misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
	pmpriv->rx_pkt_info = MFALSE;
	if (misc->param.txrx_pkt_ctrl & RX_PKT_INFO)
		pmpriv->rx_pkt_info = MTRUE;

	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get region code
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
 */
mlan_status
wlan_misc_ioctl_region(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;
	int i;

	ENTER();

	misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
	if (pioctl_req->action == MLAN_ACT_GET) {
		misc->param.region_code = pmadapter->region_code;
	} else {
		if (pmadapter->otp_region && pmadapter->otp_region->force_reg) {
			PRINTM(MERROR,
			       "ForceRegionRule is set in the on-chip OTP"
			       " memory\n");
			LEAVE();
			return MLAN_STATUS_FAILURE;
		}
		for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) {
			/* Use the region code to search for the index */
			if (misc->param.region_code == region_code_index[i]) {
				pmadapter->region_code =
					(t_u16)misc->param.region_code;
				break;
			}
		}
		/* It's unidentified region code */
		if (i >= MRVDRV_MAX_REGION_CODE) {
			PRINTM(MERROR, "Region Code not identified\n");
			pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
			LEAVE();
			return MLAN_STATUS_FAILURE;
		}
		pmadapter->cfp_code_bg = misc->param.region_code;
		pmadapter->cfp_code_a = misc->param.region_code;
		if (wlan_set_regiontable(pmpriv, (t_u8)pmadapter->region_code,
					 pmadapter->config_bands |
					 pmadapter->adhoc_start_band)) {
			pioctl_req->status_code = MLAN_ERROR_IOCTL_FAIL;
			ret = MLAN_STATUS_FAILURE;
		}
	}
	pioctl_req->data_read_written = sizeof(t_u32) + MLAN_SUB_COMMAND_SIZE;

	LEAVE();
	return ret;
}

/**
 *  @brief Configure GPIO independent reset
 *
 *  @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_ind_rst_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_u16 cmd_action = 0;

	ENTER();

	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_INDEPENDENT_RESET_CFG,
			       cmd_action, 0, (t_void *)pioctl_req,
			       (t_void *)&misc->param.ind_rst_cfg);

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief  Get timestamp from 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
 */
mlan_status
wlan_misc_ioctl_get_tsf(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->action == MLAN_ACT_GET)
		cmd_action = HostCmd_ACT_GEN_GET;
	else {
		PRINTM(MERROR, "No support set tsf!");
		return MLAN_STATUS_FAILURE;
	}

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

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief  Create custom regulatory 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_chan_reg_cfg(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->action == MLAN_ACT_GET)
		cmd_action = HostCmd_ACT_GEN_GET;
	else {
		PRINTM(MERROR, "No support set channel region cfg!");
		return MLAN_STATUS_FAILURE;
	}

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

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief Check operating class validation
 *
 *  @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_operclass_validation(pmlan_adapter pmadapter,
				     mlan_ioctl_req *pioctl_req)
{
	pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_misc_cfg *misc = MNULL;
	t_u8 channel, oper_class;
	mlan_status ret = MLAN_STATUS_SUCCESS;

	ENTER();

	misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
	channel = misc->param.bw_chan_oper.channel;
	oper_class = misc->param.bw_chan_oper.oper_class;
	if (pioctl_req->action == MLAN_ACT_GET) {
		ret = wlan_check_operclass_validation(pmpriv, channel,
						      oper_class);
	} else {
		PRINTM(MERROR, "Unsupported cmd_action\n");
		LEAVE();
		return MLAN_STATUS_FAILURE;
	}

	LEAVE();
	return ret;
}

/**
 *  @brief  Get Region channel power setting
 *
 *  @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_get_rgchnpwr_cfg(pmlan_adapter pmadapter, mlan_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();

	cmd_action = HostCmd_ACT_GEN_GET;

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

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief  Get CHAN_TPRC setting
 *
 *  @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_get_chan_trpc_cfg(pmlan_adapter pmadapter, mlan_ioctl_req *pioctl_req)
{
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_status ret = MLAN_STATUS_SUCCESS;
	t_u16 cmd_action = 0;
	mlan_ds_misc_cfg *misc = MNULL;

	ENTER();

	misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
	cmd_action = HostCmd_ACT_GEN_GET;

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

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief Get non-global operating class
 *
 *  @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_oper_class(pmlan_adapter pmadapter, mlan_ioctl_req *pioctl_req)
{
	pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_misc_cfg *misc = MNULL;
	t_u8 channel, bandwidth, oper_class = 0;
	mlan_status ret = MLAN_STATUS_SUCCESS;

	ENTER();

	misc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;
	channel = misc->param.bw_chan_oper.channel;
	switch (misc->param.bw_chan_oper.bandwidth) {
	case 20:
		bandwidth = BW_20MHZ;
		break;
	case 40:
		bandwidth = BW_40MHZ;
		break;
	case 80:
		bandwidth = BW_80MHZ;
		break;
	default:
		bandwidth = BW_20MHZ;
		break;
	}

	if (pioctl_req->action == MLAN_ACT_GET) {
		ret = wlan_get_curr_oper_class(pmpriv, channel, bandwidth,
					       &oper_class);
		misc->param.bw_chan_oper.oper_class = oper_class;
	} else {
		PRINTM(MERROR, "Unsupported cmd_action\n");
		LEAVE();
		return MLAN_STATUS_FAILURE;
	}

	LEAVE();
	return ret;
}

/**
 *  @brief config dynamic bandwidth
 *
 *  @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_fw_dump_event(pmlan_adapter pmadapter,
			      mlan_ioctl_req *pioctl_req)
{
	pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_index];
	t_u16 cmd_action = 0;
	mlan_status ret = MLAN_STATUS_SUCCESS;

	ENTER();

	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 {
		PRINTM(MERROR, "Unsupported cmd_action\n");
		LEAVE();
		return MLAN_STATUS_FAILURE;
	}

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

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief config boot sleep
 *
 *  @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_bootsleep(pmlan_adapter pmadapter, pmlan_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 {
		PRINTM(MERROR, "Unsupported cmd_action 0x%x\n",
		       pioctl_req->action);
		LEAVE();
		return MLAN_STATUS_FAILURE;
	}

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

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get Infra/Ad-hoc band configuration
 *
 *  @param pmadapter    A pointer to mlan_adapter structure
 *  @param pioctl_req   A pointer to ioctl request buffer
 *
 *  @return     MLAN_STATUS_SUCCESS --success, otherwise fail
 */
mlan_status
wlan_radio_ioctl_band_cfg(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	t_u32 i, global_band = 0;
	t_u32 infra_band = 0;
	t_u32 adhoc_band = 0;
	t_u32 adhoc_channel = 0;
	mlan_ds_radio_cfg *radio_cfg = MNULL;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];

	ENTER();

	radio_cfg = (mlan_ds_radio_cfg *)pioctl_req->pbuf;
	if (pioctl_req->action == MLAN_ACT_SET) {
		infra_band = radio_cfg->param.band_cfg.config_bands;
		adhoc_band = radio_cfg->param.band_cfg.adhoc_start_band;
		adhoc_channel = radio_cfg->param.band_cfg.adhoc_channel;

		/* SET Infra band */
		if ((infra_band | pmadapter->fw_bands) & ~pmadapter->fw_bands) {
			pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
			LEAVE();
			return MLAN_STATUS_FAILURE;
		}

		/* SET Ad-hoc Band */
		if ((adhoc_band | pmadapter->fw_bands) & ~pmadapter->fw_bands) {
			pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
			LEAVE();
			return MLAN_STATUS_FAILURE;
		}
		if (!adhoc_band)
			adhoc_band = pmadapter->adhoc_start_band;

		for (i = 0; i < pmadapter->priv_num; i++) {
			if (pmadapter->priv[i] &&
			    pmadapter->priv[i] != pmpriv &&
			    GET_BSS_ROLE(pmadapter->priv[i]) ==
			    MLAN_BSS_ROLE_STA)
				global_band |=
					(t_u32)pmadapter->priv[i]->config_bands;
		}
		global_band |= infra_band;

		if (wlan_set_regiontable(pmpriv, (t_u8)pmadapter->region_code,
					 global_band | adhoc_band)) {
			pioctl_req->status_code = MLAN_ERROR_IOCTL_FAIL;
			LEAVE();
			return MLAN_STATUS_FAILURE;
		}
#ifdef STA_SUPPORT
		if (wlan_11d_set_universaltable(pmpriv,
						global_band | adhoc_band)) {
			pioctl_req->status_code = MLAN_ERROR_IOCTL_FAIL;
			LEAVE();
			return MLAN_STATUS_FAILURE;
		}
#endif
		pmpriv->config_bands = infra_band;
		pmadapter->config_bands = global_band;

		pmadapter->adhoc_start_band = adhoc_band;
		pmpriv->intf_state_11h.adhoc_auto_sel_chan = MFALSE;

#ifdef STA_SUPPORT
		/*
		 * If no adhoc_channel is supplied verify if the existing
		 * adhoc channel compiles with new adhoc_band
		 */
		if (!adhoc_channel) {
			if (!wlan_find_cfp_by_band_and_channel
			    (pmadapter, pmadapter->adhoc_start_band,
			     pmpriv->adhoc_channel)) {
				/* Pass back the default channel */
				radio_cfg->param.band_cfg.adhoc_channel =
					DEFAULT_AD_HOC_CHANNEL;
				if ((pmadapter->adhoc_start_band & BAND_A)
					) {
					radio_cfg->param.band_cfg.
						adhoc_channel =
						DEFAULT_AD_HOC_CHANNEL_A;
				}
			}
		} else {
			/* Return error if adhoc_band and adhoc_channel
			 * combination is invalid
			 */
			if (!wlan_find_cfp_by_band_and_channel
			    (pmadapter, pmadapter->adhoc_start_band,
			     (t_u16)adhoc_channel)) {
				pioctl_req->status_code =
					MLAN_ERROR_INVALID_PARAMETER;
				LEAVE();
				return MLAN_STATUS_FAILURE;
			}
			pmpriv->adhoc_channel = (t_u8)adhoc_channel;
		}

#endif

	} else {
		/* Infra Bands   */
		radio_cfg->param.band_cfg.config_bands = pmpriv->config_bands;
		/* Adhoc Band    */
		radio_cfg->param.band_cfg.adhoc_start_band =
			pmadapter->adhoc_start_band;
		/* Adhoc Channel */
		radio_cfg->param.band_cfg.adhoc_channel = pmpriv->adhoc_channel;
		/* FW support Bands */
		radio_cfg->param.band_cfg.fw_bands = pmadapter->fw_bands;
		PRINTM(MINFO, "Global config band = %d\n",
		       pmadapter->config_bands);
#ifdef STA_SUPPORT
#endif
	}

	LEAVE();
	return MLAN_STATUS_SUCCESS;
}

/**
 *  @brief Rx Abort 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_rxabortcfg(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_RX_ABORT_CFG, cmd_action, 0,
			       (t_void *)pioctl_req,
			       &(pmisc->param.rx_abort_cfg));
	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief Rx Abort Cfg ext
 *
 *  @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_rxabortcfg_ext(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_RX_ABORT_CFG_EXT, cmd_action,
			       0, (t_void *)pioctl_req,
			       &(pmisc->param.rx_abort_cfg_ext));
	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief Dot11mc unassociated FTM 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_dot11mc_unassoc_ftm_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_DOT11MC_UNASSOC_FTM_CFG,
			       cmd_action, 0, (t_void *)pioctl_req,
			       &(pmisc->param.dot11mc_unassoc_ftm_cfg));
	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief Tx ampdu protection 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
 */
mlan_status
wlan_misc_ioctl_tx_ampdu_prot_mode(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_TX_AMPDU_PROT_MODE,
			       cmd_action, 0, (t_void *)pioctl_req,
			       &(pmisc->param.tx_ampdu_prot_mode));
	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief Rate adapt config
 *
 *  @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_rate_adapt_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_RATE_ADAPT_CFG, cmd_action,
			       0, (t_void *)pioctl_req,
			       &(pmisc->param.rate_adapt_cfg));
	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief CCK Desense config
 *
 *  @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_cck_desense_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_CCK_DESENSE_CFG, cmd_action,
			       0, (t_void *)pioctl_req,
			       &(pmisc->param.cck_desense_cfg));
	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief config dynamic bandwidth
 *
 *  @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_dyn_bw(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 {
		PRINTM(MERROR, "Unsupported cmd_action\n");
		LEAVE();
		return MLAN_STATUS_FAILURE;
	}

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

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get low power mode configuration parameter
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS --success
 */
mlan_status
wlan_power_ioctl_set_get_lpm(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 *pm_cfg = MNULL;
	t_u16 cmd_action = 0, lpm = 0;

	ENTER();

	pm_cfg = (mlan_ds_power_cfg *)pioctl_req->pbuf;
	cmd_action = HostCmd_ACT_GEN_GET;
	if (pioctl_req->action == MLAN_ACT_SET) {
		cmd_action = HostCmd_ACT_GEN_SET;
		lpm = pm_cfg->param.lpm;
	}

	ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_LOW_POWER_MODE_CFG,
			       cmd_action, 0, (t_void *)pioctl_req, &lpm);

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief RF Test Mode config
 *
 *  @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_rf_test_cfg(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_private *pmpriv = MNULL;
	mlan_ds_misc_cfg *pmisc = MNULL;
	mlan_status ret = MLAN_STATUS_FAILURE;
	t_u16 cmd_action = 0;

	ENTER();

	if (!pioctl_req)
		goto done;

	pmpriv = pmadapter->priv[pioctl_req->bss_index];
	pmisc = (mlan_ds_misc_cfg *)pioctl_req->pbuf;

	switch (pmisc->sub_command) {
	case MLAN_OID_MISC_RF_TEST_GENERIC:
		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_MFG_COMMAND,
				       cmd_action, 0, (t_void *)pioctl_req,
				       &(pmisc->param.mfg_generic_cfg));
		break;
	case MLAN_OID_MISC_RF_TEST_TX_CONT:
		if (pioctl_req->action == MLAN_ACT_SET)
			cmd_action = HostCmd_ACT_GEN_SET;
		else {
			PRINTM(MERROR, "Unsupported cmd_action\n");
			ret = MLAN_STATUS_FAILURE;
			goto done;
		}
		ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_MFG_COMMAND,
				       cmd_action, 0, (t_void *)pioctl_req,
				       &(pmisc->param.mfg_tx_cont));
		break;
	case MLAN_OID_MISC_RF_TEST_TX_FRAME:
		if (pioctl_req->action == MLAN_ACT_SET)
			cmd_action = HostCmd_ACT_GEN_SET;
		else {
			PRINTM(MERROR, "Unsupported cmd_action\n");
			ret = MLAN_STATUS_FAILURE;
			goto done;
		}
		ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_MFG_COMMAND,
				       cmd_action, 0, (t_void *)pioctl_req,
				       &(pmisc->param.mfg_tx_frame2));
		break;
	case MLAN_OID_MISC_RF_TEST_HE_POWER:
		if (pioctl_req->action == MLAN_ACT_SET)
			cmd_action = HostCmd_ACT_GEN_SET;
		else {
			PRINTM(MERROR, "Unsupported cmd_action\n");
			ret = MLAN_STATUS_FAILURE;
			goto done;
		}
		ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_MFG_COMMAND,
				       cmd_action, 0, (t_void *)pioctl_req,
				       &(pmisc->param.mfg_he_power));
		break;
	}

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

/**
 *  @brief Range ext mode config
 *
 *  @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_range_ext(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_RANGE_EXT, cmd_action, 0,
			       (t_void *)pioctl_req,
			       &(pmisc->param.range_ext_mode));
	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;

}

#ifdef UAP_SUPPORT
/**
 *  @brief set wacp 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
 */
mlan_status
wlan_misc_ioctl_wacp_mode(IN pmlan_adapter pmadapter,
			  IN 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;
	t_u16 cmd_action;

	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;

	ret = wlan_prepare_cmd(pmpriv,
			       HOST_CMD_APCMD_SYS_CONFIGURE,
			       cmd_action,
			       0,
			       (t_void *)pioctl_req,
			       (t_void *)&misc->param.wacp_mode);

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}
#endif
