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

/********************************************************
Change log:
    11/10/2008: initial version
********************************************************/

#include "mlan.h"
#include "mlan_join.h"
#include "mlan_util.h"
#include "mlan_fw.h"
#include "mlan_main.h"
#include "mlan_wmm.h"
#include "mlan_11n.h"
#include "mlan_11ac.h"

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

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

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

/**
 *
 *  @brief set/get max tx buf size
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return				MLAN_STATUS_SUCCESS --success, otherwise
 * fail
 */
static mlan_status
wlan_11n_ioctl_max_tx_buf_size(pmlan_adapter pmadapter,
			       pmlan_ioctl_req pioctl_req)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_ds_11n_cfg *cfg = MNULL;

	ENTER();
	cfg = (mlan_ds_11n_cfg *)pioctl_req->pbuf;
	cfg->param.tx_buf_size = (t_u32)pmadapter->max_tx_buf_size;
	pioctl_req->data_read_written = sizeof(t_u32) + MLAN_SUB_COMMAND_SIZE;

	LEAVE();
	return ret;
}

/**
 *  @brief Set/get htcapinfo 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
 */
static mlan_status
wlan_11n_ioctl_htusrcfg(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_11n_cfg *cfg = MNULL;

	ENTER();

	cfg = (mlan_ds_11n_cfg *)pioctl_req->pbuf;

	if (pioctl_req->action == MLAN_ACT_SET) {
		if (((cfg->param.htcap_cfg.htcap & ~IGN_HW_DEV_CAP) &
		     pmpriv->adapter->hw_dot_11n_dev_cap) !=
		    (cfg->param.htcap_cfg.htcap & ~IGN_HW_DEV_CAP)) {
			pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
			ret = MLAN_STATUS_FAILURE;
		} else {
			if (cfg->param.htcap_cfg.misc_cfg == BAND_SELECT_BG) {
				pmpriv->usr_dot_11n_dev_cap_bg =
					cfg->param.htcap_cfg.htcap;
				PRINTM(MINFO,
				       "Set: UsrDot11nCap for 2.4GHz 0x%x\n",
				       pmpriv->usr_dot_11n_dev_cap_bg);
			}
			if (cfg->param.htcap_cfg.misc_cfg == BAND_SELECT_A) {
				pmpriv->usr_dot_11n_dev_cap_a =
					cfg->param.htcap_cfg.htcap;
				PRINTM(MINFO,
				       "Set: UsrDot11nCap for 5GHz 0x%x\n",
				       pmpriv->usr_dot_11n_dev_cap_a);
			}
			if (cfg->param.htcap_cfg.misc_cfg == BAND_SELECT_BOTH) {
				pmpriv->usr_dot_11n_dev_cap_bg =
					cfg->param.htcap_cfg.htcap;
				pmpriv->usr_dot_11n_dev_cap_a =
					cfg->param.htcap_cfg.htcap;
				PRINTM(MINFO,
				       "Set: UsrDot11nCap for 2.4GHz and 5GHz 0x%x\n",
				       cfg->param.htcap_cfg.htcap);
			}
		}
	} else {
		/* Hardware 11N device capability required */
		if (cfg->param.htcap_cfg.hw_cap_req)
			cfg->param.htcap_cfg.htcap =
				pmadapter->hw_dot_11n_dev_cap;
		else {
			if (cfg->param.htcap_cfg.misc_cfg == BAND_SELECT_BG) {
				cfg->param.htcap_cfg.htcap =
					pmpriv->usr_dot_11n_dev_cap_bg;
				PRINTM(MINFO,
				       "Get: UsrDot11nCap for 2.4GHz 0x%x\n",
				       cfg->param.htcap_cfg.htcap);
			}
			if (cfg->param.htcap_cfg.misc_cfg == BAND_SELECT_A) {
				cfg->param.htcap_cfg.htcap =
					pmpriv->usr_dot_11n_dev_cap_a;
				PRINTM(MINFO,
				       "Get: UsrDot11nCap for 5GHz 0x%x\n",
				       cfg->param.htcap_cfg.htcap);
			}
		}
	}

	LEAVE();
	return ret;
}

/**
 *  @brief Enable/Disable AMSDU AGGR CTRL
 *
 *  @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_11n_ioctl_amsdu_aggr_ctrl(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_11n_cfg *cfg = MNULL;
	t_u16 cmd_action = 0;

	ENTER();

	cfg = (mlan_ds_11n_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_AMSDU_AGGR_CTRL, cmd_action,
			       0, (t_void *)pioctl_req,
			       (t_void *)&cfg->param.amsdu_aggr_ctrl);
	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief Set/get 11n configuration
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_PENDING --success, otherwise fail
 */
static mlan_status
wlan_11n_ioctl_httxcfg(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_11n_cfg *cfg = MNULL;
	t_u16 cmd_action = 0;

	ENTER();

	cfg = (mlan_ds_11n_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_11N_CFG, cmd_action, 0,
			       (t_void *)pioctl_req,
			       (t_void *)&cfg->param.tx_cfg);
	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief Set/get TX beamforming capabilities
 *
 *  @param pmadapter    A pointer to mlan_adapter structure
 *  @param pioctl_req   A pointer to ioctl request buffer
 *
 *  @return             MLAN_STATUS_SUCCESS --success
 */
static mlan_status
wlan_11n_ioctl_tx_bf_cap(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_11n_cfg *cfg = MNULL;

	ENTER();

	cfg = (mlan_ds_11n_cfg *)pioctl_req->pbuf;
	if (pioctl_req->action == MLAN_ACT_SET)
		pmpriv->tx_bf_cap = cfg->param.tx_bf_cap;
	else
		cfg->param.tx_bf_cap = pmpriv->tx_bf_cap;

	LEAVE();
	return ret;
}

/**
 *  @brief Set/get TX beamforming configurations
 *
 *  @param pmadapter    A pointer to mlan_adapter structure
 *  @param pioctl_req   A pointer to ioctl request buffer
 *
 *  @return             MLAN_STATUS_PENDING --success, otherwise fail
 */
static mlan_status
wlan_11n_ioctl_tx_bf_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_11n_cfg *cfg = MNULL;
	t_u16 cmd_action = 0;

	ENTER();

	cfg = (mlan_ds_11n_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_TX_BF_CFG, cmd_action, 0,
			       (t_void *)pioctl_req,
			       (t_void *)&cfg->param.tx_bf);
	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief Set/get HT stream configurations
 *
 *  @param pmadapter    A pointer to mlan_adapter structure
 *  @param pioctl_req   A pointer to ioctl request buffer
 *
 *  @return             MLAN_STATUS_SUCCESS --success, otherwise fail
 */
static mlan_status
wlan_11n_ioctl_stream_cfg(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_ds_11n_cfg *cfg = MNULL;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];

	ENTER();

	cfg = (mlan_ds_11n_cfg *)pioctl_req->pbuf;
	if (pioctl_req->action == MLAN_ACT_GET) {
		cfg->param.stream_cfg = pmpriv->usr_dev_mcs_support;
	} else if (pioctl_req->action == MLAN_ACT_SET) {
		switch (cfg->param.stream_cfg) {
		case HT_STREAM_MODE_2X2:
			if (pmadapter->hw_dev_mcs_support == HT_STREAM_MODE_1X1) {
				PRINTM(MERROR,
				       "HW does not support this mode\n");
				ret = MLAN_STATUS_FAILURE;
			} else
				pmpriv->usr_dev_mcs_support =
					cfg->param.stream_cfg;
			break;
		case HT_STREAM_MODE_1X1:
			pmpriv->usr_dev_mcs_support = cfg->param.stream_cfg;
			break;
		default:
			PRINTM(MERROR, "Invalid stream mode\n");
			pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
			ret = MLAN_STATUS_FAILURE;
			break;
		}
	}

	LEAVE();
	return ret;
}

/**
 *  @brief Set/get control to coex RX window size 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
 */
static mlan_status
wlan_11n_ioctl_coex_rx_winsize(pmlan_adapter pmadapter,
			       pmlan_ioctl_req pioctl_req)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_ds_11n_cfg *cfg = MNULL;

	ENTER();

	cfg = (mlan_ds_11n_cfg *)pioctl_req->pbuf;
	if (pioctl_req->action == MLAN_ACT_GET)
		cfg->param.coex_rx_winsize = pmadapter->coex_rx_winsize;
	else if (pioctl_req->action == MLAN_ACT_SET)
		pmadapter->coex_rx_winsize = (t_u8)cfg->param.coex_rx_winsize;

	LEAVE();
	return ret;
}

/**
 *  @brief This function will send delba request to
 *          the peer in the TxBAStreamTbl
 *
 *  @param priv     A pointer to mlan_private
 *  @param ra       MAC Address to send DELBA
 *
 *  @return         N/A
 */
void
wlan_11n_send_delba_to_peer(mlan_private *priv, t_u8 *ra)
{
	TxBAStreamTbl *ptx_tbl;

	ENTER();
	wlan_request_ralist_lock(priv);
	ptx_tbl = (TxBAStreamTbl *)util_peek_list(priv->adapter->pmoal_handle,
						  &priv->tx_ba_stream_tbl_ptr,
						  MNULL, MNULL);
	if (!ptx_tbl) {
		wlan_release_ralist_lock(priv);
		LEAVE();
		return;
	}

	while (ptx_tbl != (TxBAStreamTbl *)&priv->tx_ba_stream_tbl_ptr) {
		if (!memcmp(priv->adapter, ptx_tbl->ra, ra,
			    MLAN_MAC_ADDR_LENGTH)) {
			PRINTM(MIOCTL, "Tx:Send delba to tid=%d, " MACSTR "\n",
			       ptx_tbl->tid, MAC2STR(ptx_tbl->ra));
			wlan_send_delba(priv, MNULL, ptx_tbl->tid, ptx_tbl->ra,
					1);
		}
		ptx_tbl = ptx_tbl->pnext;
	}
	wlan_release_ralist_lock(priv);
	/* Signal MOAL to trigger mlan_main_process */
	wlan_recv_event(priv, MLAN_EVENT_ID_DRV_DEFER_HANDLING, MNULL);
	LEAVE();
	return;
}

/**
 *  @brief Set/Get control to TX AMPDU configuration on infra link
 *
 *  @param pmadapter    A pointer to mlan_adapter structure
 *  @param pioctl_req   A pointer to ioctl request buffer
 *
 *  @return             MLAN_STATUS_SUCCESS --success, otherwise fail
 */
static mlan_status
wlan_11n_ioctl_txaggrctrl(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_ds_11n_cfg *cfg = MNULL;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];

	ENTER();

	cfg = (mlan_ds_11n_cfg *)pioctl_req->pbuf;
	if (pioctl_req->action == MLAN_ACT_GET)
		cfg->param.txaggrctrl = pmpriv->txaggrctrl;
	else if (pioctl_req->action == MLAN_ACT_SET)
		pmpriv->txaggrctrl = (t_u8)cfg->param.txaggrctrl;

	if (pmpriv->media_connected == MTRUE) {
		if (pioctl_req->action == MLAN_ACT_SET && !pmpriv->txaggrctrl &&
		    pmpriv->adapter->tdls_status != TDLS_NOT_SETUP)
			wlan_11n_send_delba_to_peer(pmpriv,
						    pmpriv->curr_bss_params.
						    bss_descriptor.mac_address);
	}
	LEAVE();
	return ret;
}

/**
 *  @brief This function will resend addba request to all
 *          the peer in the TxBAStreamTbl
 *
 *  @param priv     A pointer to mlan_private
 *
 *  @return         N/A
 */
static void
wlan_11n_update_addba_request(mlan_private *priv)
{
	TxBAStreamTbl *ptx_tbl;

	ENTER();

	wlan_request_ralist_lock(priv);
	ptx_tbl = (TxBAStreamTbl *)util_peek_list(priv->adapter->pmoal_handle,
						  &priv->tx_ba_stream_tbl_ptr,
						  MNULL, MNULL);
	if (!ptx_tbl) {
		wlan_release_ralist_lock(priv);
		LEAVE();
		return;
	}

	while (ptx_tbl != (TxBAStreamTbl *)&priv->tx_ba_stream_tbl_ptr) {
		wlan_send_addba(priv, ptx_tbl->tid, ptx_tbl->ra);
		ptx_tbl = ptx_tbl->pnext;
	}
	wlan_release_ralist_lock(priv);
	/* Signal MOAL to trigger mlan_main_process */
	wlan_recv_event(priv, MLAN_EVENT_ID_DRV_DEFER_HANDLING, MNULL);
	LEAVE();
	return;
}

/**
 *  @brief Set/get addba parameter
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return				MLAN_STATUS_SUCCESS --success
 */
static mlan_status
wlan_11n_ioctl_addba_param(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_11n_cfg *cfg = MNULL;
	t_u32 timeout;

	ENTER();

	cfg = (mlan_ds_11n_cfg *)pioctl_req->pbuf;
	if (pioctl_req->action == MLAN_ACT_GET) {
		cfg->param.addba_param.timeout = pmpriv->add_ba_param.timeout;
		cfg->param.addba_param.txwinsize =
			pmpriv->add_ba_param.tx_win_size;
		cfg->param.addba_param.rxwinsize =
			pmpriv->add_ba_param.rx_win_size;
		cfg->param.addba_param.txamsdu = pmpriv->add_ba_param.tx_amsdu;
		cfg->param.addba_param.rxamsdu = pmpriv->add_ba_param.rx_amsdu;
	} else {
		timeout = pmpriv->add_ba_param.timeout;
		pmpriv->add_ba_param.timeout = cfg->param.addba_param.timeout;
		pmpriv->add_ba_param.tx_win_size =
			cfg->param.addba_param.txwinsize;

		pmpriv->add_ba_param.rx_win_size =
			cfg->param.addba_param.rxwinsize;
		pmpriv->user_rxwinsize = pmpriv->add_ba_param.rx_win_size;
		pmpriv->add_ba_param.tx_amsdu = cfg->param.addba_param.txamsdu;
		pmpriv->add_ba_param.rx_amsdu = cfg->param.addba_param.rxamsdu;
		if (timeout != pmpriv->add_ba_param.timeout)
			wlan_11n_update_addba_request(pmpriv);
	}

	LEAVE();
	return ret;
}

/**
 *  @brief This function send delba to specific tid
 *
 *  @param priv         A pointer to mlan_priv
 *  @param tid          tid
 *  @return             N/A
 */
void
wlan_11n_delba(mlan_private *priv, int tid)
{
	RxReorderTbl *rx_reor_tbl_ptr;

	ENTER();

	rx_reor_tbl_ptr =
		(RxReorderTbl *)util_peek_list(priv->adapter->pmoal_handle,
					       &priv->rx_reorder_tbl_ptr,
					       priv->adapter->callbacks.
					       moal_spin_lock,
					       priv->adapter->callbacks.
					       moal_spin_unlock);
	if (!rx_reor_tbl_ptr) {
		LEAVE();
		return;
	}

	while (rx_reor_tbl_ptr != (RxReorderTbl *)&priv->rx_reorder_tbl_ptr) {
		if (rx_reor_tbl_ptr->tid == tid) {
			PRINTM(MIOCTL, "Send delba to tid=%d, " MACSTR "\n",
			       tid, MAC2STR(rx_reor_tbl_ptr->ta));
			wlan_send_delba(priv, MNULL, tid, rx_reor_tbl_ptr->ta,
					0);
			LEAVE();
			return;
		}
		rx_reor_tbl_ptr = rx_reor_tbl_ptr->pnext;
	}

	LEAVE();
	return;
}

/**
 *  @brief Set/get addba reject set
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
 */
static mlan_status
wlan_11n_ioctl_addba_reject(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	int i = 0;
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_11n_cfg *cfg = MNULL;

	ENTER();

	cfg = (mlan_ds_11n_cfg *)pioctl_req->pbuf;

	if (pioctl_req->action == MLAN_ACT_GET) {
		PRINTM(MINFO, "Get Addba reject\n");
		memcpy_ext(pmadapter, cfg->param.addba_reject,
			   pmpriv->addba_reject, MAX_NUM_TID, MAX_NUM_TID);
	} else {
		for (i = 0; i < MAX_NUM_TID; i++) {
			/* For AMPDU */
			if (cfg->param.addba_reject[i] >
			    ADDBA_RSP_STATUS_REJECT) {
				pioctl_req->status_code =
					MLAN_ERROR_INVALID_PARAMETER;
				ret = MLAN_STATUS_FAILURE;
				break;
			}

			pmpriv->addba_reject[i] = cfg->param.addba_reject[i];
		}
		if (pmpriv->media_connected == MTRUE) {
			for (i = 0; i < MAX_NUM_TID; i++) {
				if (cfg->param.addba_reject[i] ==
				    ADDBA_RSP_STATUS_REJECT) {
					PRINTM(MIOCTL,
					       "Receive addba reject: tid=%d\n",
					       i);
					wlan_11n_delba(pmpriv, i);
				}
			}
			wlan_recv_event(pmpriv,
					MLAN_EVENT_ID_DRV_DEFER_HANDLING,
					MNULL);
		}
	}

	LEAVE();
	return ret;
}

/**
 *  @brief Set/get ibss ampdu param
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
 */
static mlan_status
wlan_11n_ioctl_ibss_ampdu_param(pmlan_adapter pmadapter,
				pmlan_ioctl_req pioctl_req)
{
	int i = 0;
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_11n_cfg *cfg = MNULL;

	ENTER();

	cfg = (mlan_ds_11n_cfg *)pioctl_req->pbuf;

	if (pioctl_req->action == MLAN_ACT_GET) {
		PRINTM(MINFO, "Get IBSS AMPDU param\n");
		for (i = 0; i < MAX_NUM_TID; i++) {
			cfg->param.ibss_ampdu.ampdu[i] = pmpriv->ibss_ampdu[i];
			cfg->param.ibss_ampdu.addba_reject[i] =
				pmpriv->ibss_addba_reject[i];
		}
	} else {
		for (i = 0; i < MAX_NUM_TID; i++) {
			/* For AMPDU  RX */
			if (cfg->param.ibss_ampdu.addba_reject[i] >
			    ADDBA_RSP_STATUS_REJECT) {
				pioctl_req->status_code =
					MLAN_ERROR_INVALID_PARAMETER;
				ret = MLAN_STATUS_FAILURE;
				break;
			}
			pmpriv->ibss_addba_reject[i] =
				cfg->param.ibss_ampdu.addba_reject[i];
			/* For AMPDU TX */
			if ((cfg->param.ibss_ampdu.ampdu[i] > HIGH_PRIO_TID) &&
			    (cfg->param.ibss_ampdu.ampdu[i] !=
			     BA_STREAM_NOT_ALLOWED)) {
				pioctl_req->status_code =
					MLAN_ERROR_INVALID_PARAMETER;
				ret = MLAN_STATUS_FAILURE;
				break;
			}
			pmpriv->ibss_ampdu[i] = cfg->param.ibss_ampdu.ampdu[i];
		}
		PRINTM(MMSG, "IBSS addba reject: %d %d %d %d %d %d %d %d\n",
		       pmpriv->ibss_addba_reject[0],
		       pmpriv->ibss_addba_reject[1],
		       pmpriv->ibss_addba_reject[2],
		       pmpriv->ibss_addba_reject[3],
		       pmpriv->ibss_addba_reject[4],
		       pmpriv->ibss_addba_reject[5],
		       pmpriv->ibss_addba_reject[6],
		       pmpriv->ibss_addba_reject[7]);
		PRINTM(MMSG, "IBSS ampdu %d %d %d %d %d %d %d %d\n",
		       pmpriv->ibss_ampdu[0], pmpriv->ibss_ampdu[1],
		       pmpriv->ibss_ampdu[2], pmpriv->ibss_ampdu[3],
		       pmpriv->ibss_ampdu[4], pmpriv->ibss_ampdu[5],
		       pmpriv->ibss_ampdu[6], pmpriv->ibss_ampdu[7]);
	}
	LEAVE();
	return ret;
}

/**
 *  @brief Set/Get Minimum BA Threshold
 *
 *  @param pmadapter   A pointer to mlan_adapter structure
 *  @param pioctl_req A pointer to ioctl request buffer
 *
 *  @return     MLAN_STATUS_SUCCESS --success
 */
static mlan_status
wlan_11n_ioctl_min_ba_threshold_cfg(pmlan_adapter pmadapter,
				    pmlan_ioctl_req pioctl_req)
{
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_ds_11n_cfg *cfg = MNULL;
	ENTER();
	cfg = (mlan_ds_11n_cfg *)pioctl_req->pbuf;
	if (pioctl_req->action == MLAN_ACT_GET)
		cfg->param.min_ba_threshold = pmadapter->min_ba_threshold;
	else
		pmadapter->min_ba_threshold = cfg->param.min_ba_threshold;
	pioctl_req->data_read_written = sizeof(t_u8) + MLAN_SUB_COMMAND_SIZE;
	LEAVE();
	return ret;
}

/**
 *  @brief This function will send DELBA to entries in the priv's
 *          Tx BA stream table
 *
 *  @param priv                 A pointer to mlan_private
 *  @param pioctl_req	        A pointer to ioctl request buffer
 *  @param tid                  TID
 *  @param peer_address         A pointer to peer address
 *  @param last_tx_ba_to_delete A pointer to the last entry in TxBAStreamTbl
 *
 *  @return		MLAN_STATUS_SUCCESS or MLAN_STATUS_PENDING
 */
static mlan_status
wlan_send_delba_to_entry_in_txbastream_tbl(pmlan_private priv,
					   pmlan_ioctl_req pioctl_req, t_u8 tid,
					   t_u8 *peer_address,
					   TxBAStreamTbl *last_tx_ba_to_delete)
{
	pmlan_adapter pmadapter = priv->adapter;
	TxBAStreamTbl *tx_ba_stream_tbl_ptr;
	t_u8 zero_mac[MLAN_MAC_ADDR_LENGTH] = { 0 };
	mlan_status ret = MLAN_STATUS_SUCCESS;

	ENTER();

	wlan_request_ralist_lock(priv);
	tx_ba_stream_tbl_ptr =
		(TxBAStreamTbl *)util_peek_list(pmadapter->pmoal_handle,
						&priv->tx_ba_stream_tbl_ptr,
						MNULL, MNULL);
	if (!tx_ba_stream_tbl_ptr) {
		wlan_release_ralist_lock(priv);
		LEAVE();
		return ret;
	}

	while (tx_ba_stream_tbl_ptr !=
	       (TxBAStreamTbl *)&priv->tx_ba_stream_tbl_ptr) {
		if (tx_ba_stream_tbl_ptr->ba_status == BA_STREAM_SETUP_COMPLETE) {
			if (((tid == DELBA_ALL_TIDS) ||
			     (tid == tx_ba_stream_tbl_ptr->tid)) &&
			    (!memcmp(pmadapter, peer_address, zero_mac,
				     MLAN_MAC_ADDR_LENGTH) ||
			     !memcmp(pmadapter, peer_address,
				     tx_ba_stream_tbl_ptr->ra,
				     MLAN_MAC_ADDR_LENGTH))) {
				if (last_tx_ba_to_delete &&
				    (tx_ba_stream_tbl_ptr ==
				     last_tx_ba_to_delete))
					ret = wlan_send_delba(priv, pioctl_req,
							      tx_ba_stream_tbl_ptr->
							      tid,
							      tx_ba_stream_tbl_ptr->
							      ra, 1);
				else
					ret = wlan_send_delba(priv, MNULL,
							      tx_ba_stream_tbl_ptr->
							      tid,
							      tx_ba_stream_tbl_ptr->
							      ra, 1);
			}
		}
		tx_ba_stream_tbl_ptr = tx_ba_stream_tbl_ptr->pnext;
	}
	wlan_release_ralist_lock(priv);

	LEAVE();
	return ret;
}

/**
 *  @brief This function will send DELBA to entries in the priv's
 *          rx reordering table
 *
 *  @param priv                 A pointer to mlan_private
 *  @param pioctl_req	        A pointer to ioctl request buffer
 *  @param tid                  TID
 *  @param peer_address         A pointer to peer address
 *  @param last_rx_ba_to_delete A pointer to the last entry in RxReorderTbl
 *
 *  @return		MLAN_STATUS_SUCCESS or MLAN_STATUS_PENDING
 */
static mlan_status
wlan_send_delba_to_entry_in_reorder_tbl(pmlan_private priv,
					pmlan_ioctl_req pioctl_req, t_u8 tid,
					t_u8 *peer_address,
					RxReorderTbl *last_rx_ba_to_delete)
{
	pmlan_adapter pmadapter = priv->adapter;
	RxReorderTbl *rx_reor_tbl_ptr;
	t_u8 zero_mac[MLAN_MAC_ADDR_LENGTH] = { 0 };
	mlan_status ret = MLAN_STATUS_SUCCESS;

	ENTER();

	rx_reor_tbl_ptr =
		(RxReorderTbl *)util_peek_list(pmadapter->pmoal_handle,
					       &priv->rx_reorder_tbl_ptr,
					       pmadapter->callbacks.
					       moal_spin_lock,
					       pmadapter->callbacks.
					       moal_spin_unlock);
	if (!rx_reor_tbl_ptr) {
		LEAVE();
		return ret;
	}

	while (rx_reor_tbl_ptr != (RxReorderTbl *)&priv->rx_reorder_tbl_ptr) {
		if (rx_reor_tbl_ptr->ba_status == BA_STREAM_SETUP_COMPLETE) {
			if (((tid == DELBA_ALL_TIDS) ||
			     (tid == rx_reor_tbl_ptr->tid)) &&
			    (!memcmp(pmadapter, peer_address, zero_mac,
				     MLAN_MAC_ADDR_LENGTH) ||
			     !memcmp(pmadapter, peer_address,
				     rx_reor_tbl_ptr->ta,
				     MLAN_MAC_ADDR_LENGTH))) {
				if (last_rx_ba_to_delete &&
				    (rx_reor_tbl_ptr == last_rx_ba_to_delete))
					ret = wlan_send_delba(priv, pioctl_req,
							      rx_reor_tbl_ptr->
							      tid,
							      rx_reor_tbl_ptr->
							      ta, 0);
				else
					ret = wlan_send_delba(priv, MNULL,
							      rx_reor_tbl_ptr->
							      tid,
							      rx_reor_tbl_ptr->
							      ta, 0);
			}
		}
		rx_reor_tbl_ptr = rx_reor_tbl_ptr->pnext;
	}

	LEAVE();
	return ret;
}

/**
 *  @brief IOCTL to delete BA
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
 */
static mlan_status
wlan_11n_ioctl_delba(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_11n_cfg *cfg = MNULL;
	TxBAStreamTbl *tx_ba_stream_tbl_ptr, *last_tx_ba_to_delete = MNULL;
	RxReorderTbl *rx_reor_tbl_ptr, *last_rx_ba_to_delete = MNULL;
	t_u8 zero_mac[MLAN_MAC_ADDR_LENGTH] = { 0 };
	t_u8 tid, *peer_address;

	ENTER();

	cfg = (mlan_ds_11n_cfg *)pioctl_req->pbuf;
	tid = cfg->param.del_ba.tid;
	peer_address = cfg->param.del_ba.peer_mac_addr;

	PRINTM(MINFO, "DelBA: direction %d, TID %d, peer address " MACSTR "\n",
	       cfg->param.del_ba.direction, tid, MAC2STR(peer_address));

	if (cfg->param.del_ba.direction & DELBA_RX) {
		rx_reor_tbl_ptr =
			(RxReorderTbl *)util_peek_list(pmadapter->pmoal_handle,
						       &pmpriv->
						       rx_reorder_tbl_ptr,
						       pmadapter->callbacks.
						       moal_spin_lock,
						       pmadapter->callbacks.
						       moal_spin_unlock);

		if (rx_reor_tbl_ptr) {
			while (rx_reor_tbl_ptr !=
			       (RxReorderTbl *)&pmpriv->rx_reorder_tbl_ptr) {
				if (rx_reor_tbl_ptr->ba_status ==
				    BA_STREAM_SETUP_COMPLETE) {
					if (((tid == DELBA_ALL_TIDS) ||
					     (tid == rx_reor_tbl_ptr->tid)) &&
					    (!memcmp(pmadapter, peer_address,
						     zero_mac,
						     MLAN_MAC_ADDR_LENGTH) ||
					     !memcmp(pmadapter, peer_address,
						     rx_reor_tbl_ptr->ta,
						     MLAN_MAC_ADDR_LENGTH))) {
						/* Found RX BA to delete */
						last_rx_ba_to_delete =
							rx_reor_tbl_ptr;
					}
				}
				rx_reor_tbl_ptr = rx_reor_tbl_ptr->pnext;
			}
		}
	}

	if ((last_rx_ba_to_delete == MNULL) &&
	    (cfg->param.del_ba.direction & DELBA_TX)) {
		wlan_request_ralist_lock(pmpriv);
		tx_ba_stream_tbl_ptr =
			(TxBAStreamTbl *)util_peek_list(pmadapter->pmoal_handle,
							&pmpriv->
							tx_ba_stream_tbl_ptr,
							MNULL, MNULL);

		if (tx_ba_stream_tbl_ptr) {
			while (tx_ba_stream_tbl_ptr !=
			       (TxBAStreamTbl *)&pmpriv->tx_ba_stream_tbl_ptr) {
				if (tx_ba_stream_tbl_ptr->ba_status ==
				    BA_STREAM_SETUP_COMPLETE) {
					if (((tid == DELBA_ALL_TIDS) ||
					     (tid ==
					      tx_ba_stream_tbl_ptr->tid)) &&
					    (!memcmp(pmadapter, peer_address,
						     zero_mac,
						     MLAN_MAC_ADDR_LENGTH) ||
					     !memcmp(pmadapter, peer_address,
						     tx_ba_stream_tbl_ptr->ra,
						     MLAN_MAC_ADDR_LENGTH))) {
						/* Found TX BA to delete */
						last_tx_ba_to_delete =
							tx_ba_stream_tbl_ptr;
					}
				}
				tx_ba_stream_tbl_ptr =
					tx_ba_stream_tbl_ptr->pnext;
			}
		}
		wlan_release_ralist_lock(pmpriv);
	}

	if (cfg->param.del_ba.direction & DELBA_TX) {
		if (last_rx_ba_to_delete)
			ret = wlan_send_delba_to_entry_in_txbastream_tbl(pmpriv,
									 MNULL,
									 tid,
									 peer_address,
									 MNULL);
		else
			ret = wlan_send_delba_to_entry_in_txbastream_tbl(pmpriv,
									 pioctl_req,
									 tid,
									 peer_address,
									 last_tx_ba_to_delete);
	}
	if (last_rx_ba_to_delete) {
		ret = wlan_send_delba_to_entry_in_reorder_tbl(pmpriv,
							      pioctl_req, tid,
							      peer_address,
							      last_rx_ba_to_delete);
	}

	LEAVE();
	return ret;
}

/**
 *  @brief IOCTL to reject addba req
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
 */
static mlan_status
wlan_11n_ioctl_rejectaddbareq(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_11n_cfg *cfg = MNULL;
	t_u16 cmd_action = 0;

	ENTER();

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

	/* Send command to firmware */
	ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_REJECT_ADDBA_REQ, cmd_action,
			       0, (t_void *)pioctl_req,
			       &cfg->param.reject_addba_req);

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief This function will send DELBA to entries in the priv's
 *          Tx BA stream table
 *
 *  @param priv                 A pointer to mlan_private
 *  @param tid                  TID
 *
 *  @return		 N/A
 */
static void
wlan_send_delba_txbastream_tbl(pmlan_private priv, t_u8 tid)
{
	pmlan_adapter pmadapter = priv->adapter;
	TxBAStreamTbl *tx_ba_stream_tbl_ptr;

	ENTER();

	wlan_request_ralist_lock(priv);
	tx_ba_stream_tbl_ptr =
		(TxBAStreamTbl *)util_peek_list(pmadapter->pmoal_handle,
						&priv->tx_ba_stream_tbl_ptr,
						MNULL, MNULL);
	if (!tx_ba_stream_tbl_ptr) {
		wlan_release_ralist_lock(priv);
		LEAVE();
		return;
	}

	while (tx_ba_stream_tbl_ptr !=
	       (TxBAStreamTbl *)&priv->tx_ba_stream_tbl_ptr) {
		if (tx_ba_stream_tbl_ptr->ba_status == BA_STREAM_SETUP_COMPLETE) {
			if (tid == tx_ba_stream_tbl_ptr->tid) {
				PRINTM(MIOCTL,
				       "Tx:Send delba to tid=%d, " MACSTR "\n",
				       tid, MAC2STR(tx_ba_stream_tbl_ptr->ra));
				wlan_release_ralist_lock(priv);
				wlan_send_delba(priv, MNULL,
						tx_ba_stream_tbl_ptr->tid,
						tx_ba_stream_tbl_ptr->ra, 1);
				LEAVE();
				return;
			}
		}
		tx_ba_stream_tbl_ptr = tx_ba_stream_tbl_ptr->pnext;
	}
	wlan_release_ralist_lock(priv);

	LEAVE();
	return;
}

/**
 *  @brief update station list for the new aggr_prio_tbl setting
 *
 *  @param priv 	A pointer to mlan_private structure
 *
 *
 *  @return		N/A
 */
static void
wlan_update_all_stations_ampdu(mlan_private *priv)
{
	sta_node *sta_ptr;
	mlan_adapter *pmadapter = priv->adapter;
	int i = 0;

	ENTER();
	pmadapter->callbacks.moal_spin_lock(pmadapter->pmoal_handle,
					    priv->wmm.ra_list_spinlock);
	sta_ptr = (sta_node *)util_peek_list(pmadapter->pmoal_handle,
					     &priv->sta_list, MNULL, MNULL);
	if (!sta_ptr) {
		pmadapter->callbacks.moal_spin_unlock(pmadapter->pmoal_handle,
						      priv->wmm.
						      ra_list_spinlock);
		LEAVE();
		return;
	}
	while (sta_ptr != (sta_node *)&priv->sta_list) {
		for (i = 0; i < MAX_NUM_TID; i++) {
			if (sta_ptr->is_11n_enabled)
				sta_ptr->ampdu_sta[i] =
					priv->aggr_prio_tbl[i].ampdu_user;
		}
		sta_ptr = sta_ptr->pnext;
	}
	pmadapter->callbacks.moal_spin_unlock(pmadapter->pmoal_handle,
					      priv->wmm.ra_list_spinlock);
	LEAVE();
	return;
}

/**
 *  @brief Set/get aggr_prio_tbl
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
 */
static mlan_status
wlan_11n_ioctl_aggr_prio_tbl(pmlan_adapter pmadapter,
			     pmlan_ioctl_req pioctl_req)
{
	int i = 0;
	mlan_status ret = MLAN_STATUS_SUCCESS;
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];
	mlan_ds_11n_cfg *cfg = MNULL;

	ENTER();

	cfg = (mlan_ds_11n_cfg *)pioctl_req->pbuf;

	if (pioctl_req->action == MLAN_ACT_GET) {
		for (i = 0; i < MAX_NUM_TID; i++) {
			cfg->param.aggr_prio_tbl.ampdu[i] =
				pmpriv->aggr_prio_tbl[i].ampdu_user;
			cfg->param.aggr_prio_tbl.amsdu[i] =
				pmpriv->aggr_prio_tbl[i].amsdu;
		}
	} else {
		for (i = 0; i < MAX_NUM_TID; i++) {
			/* For AMPDU */
			if ((cfg->param.aggr_prio_tbl.ampdu[i] >
			     HIGH_PRIO_TID)&&
			    (cfg->param.aggr_prio_tbl.ampdu[i] !=
			     BA_STREAM_NOT_ALLOWED)) {
				pioctl_req->status_code =
					MLAN_ERROR_INVALID_PARAMETER;
				ret = MLAN_STATUS_FAILURE;
				break;
			}

			pmpriv->aggr_prio_tbl[i].ampdu_ap =
				pmpriv->aggr_prio_tbl[i].ampdu_user =
				cfg->param.aggr_prio_tbl.ampdu[i];

			/* For AMSDU */
			if ((cfg->param.aggr_prio_tbl.amsdu[i] >
			     HIGH_PRIO_TID &&
			     cfg->param.aggr_prio_tbl.amsdu[i] !=
			     BA_STREAM_NOT_ALLOWED)) {
				pioctl_req->status_code =
					MLAN_ERROR_INVALID_PARAMETER;
				ret = MLAN_STATUS_FAILURE;
				break;
			} else {
				pmpriv->aggr_prio_tbl[i].amsdu =
					cfg->param.aggr_prio_tbl.amsdu[i];
			}
		}
		if (pmpriv->media_connected == MTRUE) {
			for (i = 0; i < MAX_NUM_TID; i++) {
				if (cfg->param.aggr_prio_tbl.ampdu[i] ==
				    BA_STREAM_NOT_ALLOWED) {
					PRINTM(MIOCTL,
					       "Receive aggrpriotbl: BA not allowed tid=%d\n",
					       i);
					wlan_send_delba_txbastream_tbl(pmpriv,
								       i);
				}
			}
			wlan_update_all_stations_ampdu(pmpriv);
			wlan_recv_event(pmpriv,
					MLAN_EVENT_ID_DRV_DEFER_HANDLING,
					MNULL);
		}
	}

	LEAVE();
	return ret;
}

/**
 *  @brief This function update all the tx_win_size
 *
 *  @param pmadapter    A pointer to mlan_adapter
 *
 *
 *  @return             N/A
 */
void
wlan_update_ampdu_txwinsize(pmlan_adapter pmadapter)
{
	t_u8 i;
	t_u32 tx_win_size = 0;
	pmlan_private priv = MNULL;

	ENTER();

	for (i = 0; i < pmadapter->priv_num; i++) {
		if (pmadapter->priv[i]) {
			priv = pmadapter->priv[i];
			tx_win_size = priv->add_ba_param.tx_win_size;
#ifdef STA_SUPPORT
			if (priv->bss_type == MLAN_BSS_TYPE_STA)
				priv->add_ba_param.tx_win_size =
					MLAN_STA_AMPDU_DEF_TXWINSIZE;
#endif
#ifdef WIFI_DIRECT_SUPPORT
			if (priv->bss_type == MLAN_BSS_TYPE_WIFIDIRECT)
				priv->add_ba_param.tx_win_size =
					MLAN_WFD_AMPDU_DEF_TXRXWINSIZE;
#endif
#ifdef UAP_SUPPORT
			if (priv->bss_type == MLAN_BSS_TYPE_UAP)
				priv->add_ba_param.tx_win_size =
					MLAN_UAP_AMPDU_DEF_TXWINSIZE;
#endif
			if (pmadapter->coex_win_size &&
			    pmadapter->coex_tx_win_size)
				priv->add_ba_param.tx_win_size =
					pmadapter->coex_tx_win_size;

			if (tx_win_size != priv->add_ba_param.tx_win_size) {
				if (priv->media_connected == MTRUE) {
					for (i = 0; i < MAX_NUM_TID; i++)
						wlan_send_delba_txbastream_tbl
							(priv, i);
					wlan_recv_event(priv,
							MLAN_EVENT_ID_DRV_DEFER_HANDLING,
							MNULL);
				}
			}
		}
	}
	LEAVE();
	return;
}

/**
 *  @brief Get supported MCS set
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
 */
static mlan_status
wlan_11n_ioctl_supported_mcs_set(pmlan_adapter pmadapter,
				 pmlan_ioctl_req pioctl_req)
{
	mlan_ds_11n_cfg *cfg = MNULL;
	int rx_mcs_supp;
	t_u8 mcs_set[NUM_MCS_FIELD];
	mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index];

	ENTER();

	if (pioctl_req->action == MLAN_ACT_SET) {
		PRINTM(MERROR, "Set operation is not supported\n");
		pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID;
		LEAVE();
		return MLAN_STATUS_FAILURE;
	}
	rx_mcs_supp = GET_RXMCSSUPP(pmpriv->usr_dev_mcs_support);
	/* Set MCS for 1x1/2x2 */
	memset(pmadapter, (t_u8 *)mcs_set, 0xff, rx_mcs_supp);
	/* Clear all the other values */
	memset(pmadapter, (t_u8 *)&mcs_set[rx_mcs_supp], 0,
	       NUM_MCS_FIELD - rx_mcs_supp);
	/* Set MCS32 with 40MHz support */
	if ((ISSUPP_CHANWIDTH40(pmpriv->usr_dot_11n_dev_cap_bg)
	     || ISSUPP_CHANWIDTH40(pmpriv->usr_dot_11n_dev_cap_a)
	    ) &&
	    !(pmpriv->curr_chan_flags & CHAN_FLAGS_NO_HT40PLUS &&
	      pmpriv->curr_chan_flags & CHAN_FLAGS_NO_HT40MINUS))
		SETHT_MCS32(mcs_set);

	cfg = (mlan_ds_11n_cfg *)pioctl_req->pbuf;
	memcpy_ext(pmadapter, cfg->param.supported_mcs_set, mcs_set,
		   NUM_MCS_FIELD, NUM_MCS_FIELD);

	LEAVE();
	return MLAN_STATUS_SUCCESS;
}

/**
 *  @brief This function checks if the given pointer is valid entry of
 *         Tx BA Stream table
 *
 *  @param priv         Pointer to mlan_private
 *  @param ptxtblptr    Pointer to tx ba stream entry
 *
 *  @return             MTRUE or MFALSE
 */
static int
wlan_is_txbastreamptr_valid(mlan_private *priv, TxBAStreamTbl *ptxtblptr)
{
	TxBAStreamTbl *ptx_tbl;

	ENTER();

	ptx_tbl = (TxBAStreamTbl *)util_peek_list(priv->adapter->pmoal_handle,
						  &priv->tx_ba_stream_tbl_ptr,
						  MNULL, MNULL);
	if (!ptx_tbl) {
		LEAVE();
		return MFALSE;
	}

	while (ptx_tbl != (TxBAStreamTbl *)&priv->tx_ba_stream_tbl_ptr) {
		if (ptx_tbl == ptxtblptr) {
			LEAVE();
			return MTRUE;
		}
		ptx_tbl = ptx_tbl->pnext;
	}
	LEAVE();
	return MFALSE;
}

/**
 *  @brief This function will return the pointer to a entry in BA Stream
 *          table which matches the ba_status requested
 *
 *  @param priv         A pointer to mlan_private
 *  @param ba_status    Current status of the BA stream
 *
 *  @return             A pointer to first entry matching status in BA stream
 *                      NULL if not found
 */
static TxBAStreamTbl *
wlan_11n_get_txbastream_status(mlan_private *priv, baStatus_e ba_status)
{
	TxBAStreamTbl *ptx_tbl;

	ENTER();

	ptx_tbl = (TxBAStreamTbl *)util_peek_list(priv->adapter->pmoal_handle,
						  &priv->tx_ba_stream_tbl_ptr,
						  MNULL, MNULL);
	if (!ptx_tbl) {
		LEAVE();
		return MNULL;
	}

	while (ptx_tbl != (TxBAStreamTbl *)&priv->tx_ba_stream_tbl_ptr) {
		if (ptx_tbl->ba_status == ba_status) {
			LEAVE();
			return ptx_tbl;
		}
		ptx_tbl = ptx_tbl->pnext;
	}

	LEAVE();
	return MNULL;
}

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

#ifdef STA_SUPPORT
/**
 *  @brief This function fills the cap info
 *
 *  @param priv         A pointer to mlan_private structure
 *  @param pht_cap      A pointer to MrvlIETypes_HTCap_t structure
 *  @param bands        Band configuration
 *
 *  @return             N/A
 */
static void
wlan_fill_cap_info(mlan_private *priv, HTCap_t *ht_cap, t_u8 bands)
{
	t_u32 usr_dot_11n_dev_cap;

	ENTER();

	if (bands & BAND_A)
		usr_dot_11n_dev_cap = priv->usr_dot_11n_dev_cap_a;
	else
		usr_dot_11n_dev_cap = priv->usr_dot_11n_dev_cap_bg;

	if (ISSUPP_CHANWIDTH40(usr_dot_11n_dev_cap))
		SETHT_SUPPCHANWIDTH(ht_cap->ht_cap_info);
	else
		RESETHT_SUPPCHANWIDTH(ht_cap->ht_cap_info);

	if (ISSUPP_GREENFIELD(usr_dot_11n_dev_cap))
		SETHT_GREENFIELD(ht_cap->ht_cap_info);
	else
		RESETHT_GREENFIELD(ht_cap->ht_cap_info);

	if (ISSUPP_SHORTGI20(usr_dot_11n_dev_cap))
		SETHT_SHORTGI20(ht_cap->ht_cap_info);
	else
		RESETHT_SHORTGI20(ht_cap->ht_cap_info);

	if (ISSUPP_SHORTGI40(usr_dot_11n_dev_cap))
		SETHT_SHORTGI40(ht_cap->ht_cap_info);
	else
		RESETHT_SHORTGI40(ht_cap->ht_cap_info);
	if (ISSUPP_RXSTBC(usr_dot_11n_dev_cap))
		SETHT_RXSTBC(ht_cap->ht_cap_info, 1);
	else
		RESETHT_RXSTBC(ht_cap->ht_cap_info);

	if (ISENABLED_40MHZ_INTOLARENT(usr_dot_11n_dev_cap))
		SETHT_40MHZ_INTOLARANT(ht_cap->ht_cap_info);
	else
		RESETHT_40MHZ_INTOLARANT(ht_cap->ht_cap_info);

	/** if current channel only allow 20Mhz, we should cler 40Mhz support */
	if (priv->curr_chan_flags & CHAN_FLAGS_NO_HT40PLUS &&
	    priv->curr_chan_flags & CHAN_FLAGS_NO_HT40MINUS) {
		RESETHT_SUPPCHANWIDTH(ht_cap->ht_cap_info);
		RESETHT_SHORTGI40(ht_cap->ht_cap_info);
		RESETHT_40MHZ_INTOLARANT(ht_cap->ht_cap_info);
	}
	/* No user config for LDPC coding capability yet */
	if (ISSUPP_RXLDPC(usr_dot_11n_dev_cap))
		SETHT_LDPCCODINGCAP(ht_cap->ht_cap_info);
	else
		RESETHT_LDPCCODINGCAP(ht_cap->ht_cap_info);

	/* No user config for TX STBC yet */
	if (ISSUPP_TXSTBC(usr_dot_11n_dev_cap))
		SETHT_TXSTBC(ht_cap->ht_cap_info);
	else
		RESETHT_TXSTBC(ht_cap->ht_cap_info);

	/* No user config for Delayed BACK yet */
	RESETHT_DELAYEDBACK(ht_cap->ht_cap_info);

	/* Need change to support 8k AMSDU receive */
	RESETHT_MAXAMSDU(ht_cap->ht_cap_info);

	/* SM power save */
	RESETHT_SM_POWERSAVE(ht_cap->ht_cap_info);	/* Clear to HT SMPS static mode */
	if (ISSUPP_MIMOPS(usr_dot_11n_dev_cap)) {
		if (ISSUPP_SMPS_DYNAMIC_MODE(usr_dot_11n_dev_cap))
			SETHT_SMPS_DYNAMIC(ht_cap->ht_cap_info);	/* Set to HT SMPS dynamic mode */
	} else {
		SETHT_SMPS_DISABLE(ht_cap->ht_cap_info);	/* Disable HT SMPS */
	}

	LEAVE();
}

/**
 *  @brief This function clear the bit in cap info which we don't support
 *
 *  @param priv         A pointer to mlan_private structure
 *  @param pht_cap      A pointer to MrvlIETypes_HTCap_t structure
 *  @param bands        Band configuration
 *
 *  @return             N/A
 */
static void
wlan_reset_cap_info(mlan_private *priv, HTCap_t *ht_cap, t_u8 bands)
{
	t_u32 usr_dot_11n_dev_cap;

	ENTER();

	if (bands & BAND_A)
		usr_dot_11n_dev_cap = priv->usr_dot_11n_dev_cap_a;
	else
		usr_dot_11n_dev_cap = priv->usr_dot_11n_dev_cap_bg;

	if (!ISSUPP_CHANWIDTH40(usr_dot_11n_dev_cap))
		RESETHT_SUPPCHANWIDTH(ht_cap->ht_cap_info);

	if (!ISSUPP_GREENFIELD(usr_dot_11n_dev_cap))
		RESETHT_GREENFIELD(ht_cap->ht_cap_info);

	if (!ISSUPP_SHORTGI20(usr_dot_11n_dev_cap))
		RESETHT_SHORTGI20(ht_cap->ht_cap_info);

	if (!ISSUPP_SHORTGI40(usr_dot_11n_dev_cap))
		RESETHT_SHORTGI40(ht_cap->ht_cap_info);
	if (!ISSUPP_RXSTBC(usr_dot_11n_dev_cap))
		RESETHT_RXSTBC(ht_cap->ht_cap_info);

	if (!ISENABLED_40MHZ_INTOLARENT(usr_dot_11n_dev_cap))
		RESETHT_40MHZ_INTOLARANT(ht_cap->ht_cap_info);

	/** if current channel only allow 20Mhz, we should cler 40Mhz support */
	if (priv->curr_chan_flags & CHAN_FLAGS_NO_HT40PLUS &&
	    priv->curr_chan_flags & CHAN_FLAGS_NO_HT40MINUS) {
		RESETHT_SUPPCHANWIDTH(ht_cap->ht_cap_info);
		RESETHT_SHORTGI40(ht_cap->ht_cap_info);
		RESETHT_40MHZ_INTOLARANT(ht_cap->ht_cap_info);
	}
	/* No user config for LDPC coding capability yet */
	if (!ISSUPP_RXLDPC(usr_dot_11n_dev_cap))
		RESETHT_LDPCCODINGCAP(ht_cap->ht_cap_info);

	/* No user config for TX STBC yet */
	if (!ISSUPP_TXSTBC(usr_dot_11n_dev_cap))
		RESETHT_TXSTBC(ht_cap->ht_cap_info);

	/* No user config for Delayed BACK yet */
	RESETHT_DELAYEDBACK(ht_cap->ht_cap_info);

	/* Need change to support 8k AMSDU receive */
	RESETHT_MAXAMSDU(ht_cap->ht_cap_info);
	/* SM power save */
	if (!ISSUPP_MIMOPS(usr_dot_11n_dev_cap))
		SETHT_SMPS_DISABLE(ht_cap->ht_cap_info);	/* Disable HT SMPS */

	LEAVE();
}

/**
 *  @brief This function fills the HT cap tlv
 *
 *  @param priv         A pointer to mlan_private structure
 *  @param pht_cap      A pointer to MrvlIETypes_HTCap_t structure
 *  @param bands        Band configuration
 *  @param fill         A flag for fill the htcap info
 *
 *  @return             N/A
 */
void
wlan_fill_ht_cap_tlv(mlan_private *priv, MrvlIETypes_HTCap_t *pht_cap,
		     t_u16 bands, t_u8 fill)
{
	mlan_adapter *pmadapter = priv->adapter;
	int rx_mcs_supp;
	t_u32 usr_dot_11n_dev_cap;

	ENTER();

	if (bands & BAND_A)
		usr_dot_11n_dev_cap = priv->usr_dot_11n_dev_cap_a;
	else
		usr_dot_11n_dev_cap = priv->usr_dot_11n_dev_cap_bg;

	/* Fill HT cap info */
	if (fill)
		wlan_fill_cap_info(priv, &pht_cap->ht_cap, bands);
	else
		wlan_reset_cap_info(priv, &pht_cap->ht_cap, bands);

	pht_cap->ht_cap.ht_cap_info =
		wlan_cpu_to_le16(pht_cap->ht_cap.ht_cap_info);

	/* Set ampdu param */
	SETAMPDU_SIZE(pht_cap->ht_cap.ampdu_param, AMPDU_FACTOR_64K);
	SETAMPDU_SPACING(pht_cap->ht_cap.ampdu_param, 0);

	rx_mcs_supp = GET_RXMCSSUPP(priv->usr_dev_mcs_support);
#if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || defined(PCIE9097) || defined(SD9097) || defined(USB9097)
	if (IS_CARD9098(pmadapter->card_type) ||
	    IS_CARD9097(pmadapter->card_type)) {
		if (bands & BAND_A)
			rx_mcs_supp = MIN(rx_mcs_supp,
					  GET_RXMCSSUPP(pmadapter->
							user_htstream >> 8));
		else
			rx_mcs_supp =
				MIN(rx_mcs_supp,
				    GET_RXMCSSUPP(pmadapter->user_htstream));
	}
#endif
	memset(pmadapter, (t_u8 *)pht_cap->ht_cap.supported_mcs_set, 0xff,
	       rx_mcs_supp);
	/* Clear all the other values to get the minimum mcs set btw STA and AP
	 */
	memset(pmadapter,
	       (t_u8 *)&pht_cap->ht_cap.supported_mcs_set[rx_mcs_supp], 0,
	       NUM_MCS_FIELD - rx_mcs_supp);
	/* Set MCS32 with 40MHz support */
	/* if current channel only support 20MHz, we should not set 40Mz
	 * supprot*/
	if (ISSUPP_CHANWIDTH40(usr_dot_11n_dev_cap) &&
	    !(priv->curr_chan_flags & CHAN_FLAGS_NO_HT40PLUS &&
	      priv->curr_chan_flags & CHAN_FLAGS_NO_HT40MINUS))
		SETHT_MCS32(pht_cap->ht_cap.supported_mcs_set);

	/* Clear RD responder bit */
	RESETHT_EXTCAP_RDG(pht_cap->ht_cap.ht_ext_cap);
	pht_cap->ht_cap.ht_ext_cap =
		wlan_cpu_to_le16(pht_cap->ht_cap.ht_ext_cap);

	/* Set Tx BF cap */
	pht_cap->ht_cap.tx_bf_cap = wlan_cpu_to_le32(priv->tx_bf_cap);

	LEAVE();
	return;
}

/**
 *  @brief This function fills the HT cap ie
 *
 *  @param priv         A pointer to mlan_private structure
 *  @param pht_cap      A pointer to IEEEtypes_HTCap_t structure
 *  @param bands        Band configuration
 *
 *  @return             N/A
 */
void
wlan_fill_ht_cap_ie(mlan_private *priv, IEEEtypes_HTCap_t *pht_cap, t_u16 bands)
{
	mlan_adapter *pmadapter = priv->adapter;
	int rx_mcs_supp;
	t_u32 usr_dot_11n_dev_cap;

	ENTER();

	pht_cap->ieee_hdr.element_id = HT_CAPABILITY;
	pht_cap->ieee_hdr.len = sizeof(HTCap_t);
	if (bands & BAND_A)
		usr_dot_11n_dev_cap = priv->usr_dot_11n_dev_cap_a;
	else
		usr_dot_11n_dev_cap = priv->usr_dot_11n_dev_cap_bg;

	/* Fill HT cap info */
	wlan_fill_cap_info(priv, &pht_cap->ht_cap, bands);

	/* Set ampdu param */
	SETAMPDU_SIZE(pht_cap->ht_cap.ampdu_param, AMPDU_FACTOR_64K);
	SETAMPDU_SPACING(pht_cap->ht_cap.ampdu_param, 0);

	rx_mcs_supp = GET_RXMCSSUPP(priv->usr_dev_mcs_support);
#if defined(PCIE9098) || defined(SD9098) || defined(USB9098) || defined(PCIE9097) || defined(SD9097) || defined(USB9097)
	if (IS_CARD9098(pmadapter->card_type) ||
	    IS_CARD9097(pmadapter->card_type)) {
		if (bands & BAND_A)
			rx_mcs_supp = MIN(rx_mcs_supp,
					  GET_RXMCSSUPP(pmadapter->
							user_htstream >> 8));
		else
			rx_mcs_supp =
				MIN(rx_mcs_supp,
				    GET_RXMCSSUPP(pmadapter->user_htstream));
	}
#endif
	memset(pmadapter, (t_u8 *)pht_cap->ht_cap.supported_mcs_set, 0xff,
	       rx_mcs_supp);
	/* Clear all the other values to get the minimum mcs set btw STA and AP
	 */
	memset(pmadapter,
	       (t_u8 *)&pht_cap->ht_cap.supported_mcs_set[rx_mcs_supp], 0,
	       NUM_MCS_FIELD - rx_mcs_supp);
	/* Set MCS32 with 40MHz support */
	/* if current channel only support 20MHz, we should not set 40Mz
	 * supprot*/
	if (ISSUPP_CHANWIDTH40(usr_dot_11n_dev_cap) &&
	    !(priv->curr_chan_flags & CHAN_FLAGS_NO_HT40PLUS &&
	      priv->curr_chan_flags & CHAN_FLAGS_NO_HT40MINUS))
		SETHT_MCS32(pht_cap->ht_cap.supported_mcs_set);

	/* Clear RD responder bit */
	RESETHT_EXTCAP_RDG(pht_cap->ht_cap.ht_ext_cap);

	/* Set Tx BF cap */
	pht_cap->ht_cap.tx_bf_cap = priv->tx_bf_cap;

	LEAVE();
	return;
}
#endif /* STA_SUPPORT */

/**
 *  @brief This function prints the 802.11n device capability
 *
 *  @param pmadapter     A pointer to mlan_adapter structure
 *  @param cap           Capability value
 *
 *  @return        N/A
 */
void
wlan_show_dot11ndevcap(pmlan_adapter pmadapter, t_u32 cap)
{
	ENTER();

	PRINTM(MINFO, "GET_HW_SPEC: Maximum MSDU length = %s octets\n",
	       (ISSUPP_MAXAMSDU(cap) ? "7935" : "3839"));
	PRINTM(MINFO, "GET_HW_SPEC: Beam forming %s\n",
	       (ISSUPP_BEAMFORMING(cap) ? "supported" : "not supported"));
	PRINTM(MINFO, "GET_HW_SPEC: Greenfield preamble %s\n",
	       (ISSUPP_GREENFIELD(cap) ? "supported" : "not supported"));
	PRINTM(MINFO, "GET_HW_SPEC: AMPDU %s\n",
	       (ISSUPP_AMPDU(cap) ? "supported" : "not supported"));
	PRINTM(MINFO, "GET_HW_SPEC: MIMO Power Save %s\n",
	       (ISSUPP_MIMOPS(cap) ? "supported" : "not supported"));
	PRINTM(MINFO, "GET_HW_SPEC: Rx STBC %s\n",
	       (ISSUPP_RXSTBC(cap) ? "supported" : "not supported"));
	PRINTM(MINFO, "GET_HW_SPEC: Tx STBC %s\n",
	       (ISSUPP_TXSTBC(cap) ? "supported" : "not supported"));
	PRINTM(MINFO, "GET_HW_SPEC: Short GI for 40 Mhz %s\n",
	       (ISSUPP_SHORTGI40(cap) ? "supported" : "not supported"));
	PRINTM(MINFO, "GET_HW_SPEC: Short GI for 20 Mhz %s\n",
	       (ISSUPP_SHORTGI20(cap) ? "supported" : "not supported"));
	PRINTM(MINFO, "GET_HW_SPEC: LDPC coded packet receive %s\n",
	       (ISSUPP_RXLDPC(cap) ? "supported" : "not supported"));

	PRINTM(MINFO, "GET_HW_SPEC: Number of Tx BA streams supported = %d\n",
	       ISSUPP_GETTXBASTREAM(cap));
	PRINTM(MINFO, "GET_HW_SPEC: 40 Mhz channel width %s\n",
	       (ISSUPP_CHANWIDTH40(cap) ? "supported" : "not supported"));
	PRINTM(MINFO, "GET_HW_SPEC: 20 Mhz channel width %s\n",
	       (ISSUPP_CHANWIDTH20(cap) ? "supported" : "not supported"));
	PRINTM(MINFO, "GET_HW_SPEC: 10 Mhz channel width %s\n",
	       (ISSUPP_CHANWIDTH10(cap) ? "supported" : "not supported"));

	if (ISSUPP_RXANTENNAA(cap))
		PRINTM(MINFO, "GET_HW_SPEC: Presence of Rx antenna A\n");
	if (ISSUPP_RXANTENNAB(cap))
		PRINTM(MINFO, "GET_HW_SPEC: Presence of Rx antenna B\n");
	if (ISSUPP_RXANTENNAC(cap))
		PRINTM(MINFO, "GET_HW_SPEC: Presence of Rx antenna C\n");
	if (ISSUPP_RXANTENNAD(cap))
		PRINTM(MINFO, "GET_HW_SPEC: Presence of Rx antenna D\n");
	if (ISSUPP_TXANTENNAA(cap))
		PRINTM(MINFO, "GET_HW_SPEC: Presence of Tx antenna A\n");
	if (ISSUPP_TXANTENNAB(cap))
		PRINTM(MINFO, "GET_HW_SPEC: Presence of Tx antenna B\n");
	if (ISSUPP_TXANTENNAC(cap))
		PRINTM(MINFO, "GET_HW_SPEC: Presence of Tx antenna C\n");
	if (ISSUPP_TXANTENNAD(cap))
		PRINTM(MINFO, "GET_HW_SPEC: Presence of Tx antenna D\n");

	LEAVE();
	return;
}

/**
 *  @brief This function prints the 802.11n device MCS
 *
 *  @param pmadapter A pointer to mlan_adapter structure
 *  @param support   Support value
 *
 *  @return        N/A
 */
void
wlan_show_devmcssupport(pmlan_adapter pmadapter, t_u8 support)
{
	ENTER();

	PRINTM(MINFO, "GET_HW_SPEC: MCSs for %dx%d MIMO\n",
	       GET_RXMCSSUPP(support), GET_TXMCSSUPP(support));

	LEAVE();
	return;
}

/**
 *  @brief This function handles the command response of
 *              delete a block ack request
 *
 *  @param priv    A pointer to mlan_private structure
 *  @param resp    A pointer to HostCmd_DS_COMMAND
 *
 *  @return        MLAN_STATUS_SUCCESS
 */
mlan_status
wlan_ret_11n_delba(mlan_private *priv, HostCmd_DS_COMMAND *resp)
{
	int tid;
	TxBAStreamTbl *ptx_ba_tbl;
	HostCmd_DS_11N_DELBA *pdel_ba =
		(HostCmd_DS_11N_DELBA *)&resp->params.del_ba;

	ENTER();

	pdel_ba->del_ba_param_set = wlan_le16_to_cpu(pdel_ba->del_ba_param_set);
	pdel_ba->reason_code = wlan_le16_to_cpu(pdel_ba->reason_code);

	tid = pdel_ba->del_ba_param_set >> DELBA_TID_POS;
	if (pdel_ba->del_result == BA_RESULT_SUCCESS) {
		mlan_11n_delete_bastream_tbl(priv, tid, pdel_ba->peer_mac_addr,
					     TYPE_DELBA_SENT,
					     INITIATOR_BIT(pdel_ba->
							   del_ba_param_set),
					     0);
		wlan_request_ralist_lock(priv);
		ptx_ba_tbl =
			wlan_11n_get_txbastream_status(priv,
						       BA_STREAM_SETUP_INPROGRESS);
		wlan_release_ralist_lock(priv);
		if (ptx_ba_tbl)
			wlan_send_addba(priv, ptx_ba_tbl->tid, ptx_ba_tbl->ra);
	} else {		/*
				 * In case of failure, recreate
				 * the deleted stream in case
				 * we initiated the ADDBA
				 */
		if (INITIATOR_BIT(pdel_ba->del_ba_param_set)) {
			wlan_request_ralist_lock(priv);
			if (!wlan_11n_get_txbastream_tbl
			    (priv, tid, pdel_ba->peer_mac_addr, MFALSE))
				wlan_11n_create_txbastream_tbl(priv,
							       pdel_ba->
							       peer_mac_addr,
							       tid,
							       BA_STREAM_SETUP_INPROGRESS);
			ptx_ba_tbl =
				wlan_11n_get_txbastream_status(priv,
							       BA_STREAM_SETUP_INPROGRESS);
			wlan_release_ralist_lock(priv);
			if (ptx_ba_tbl) {
				mlan_11n_delete_bastream_tbl(priv,
							     ptx_ba_tbl->tid,
							     ptx_ba_tbl->ra,
							     TYPE_DELBA_SENT,
							     MTRUE, 0);
			}
		}
	}

	LEAVE();
	return MLAN_STATUS_SUCCESS;
}

/**
 *  @brief This function handles the command response of
 *              add a block ack request
 *
 *  @param priv    A pointer to mlan_private structure
 *  @param resp    A pointer to HostCmd_DS_COMMAND
 *
 *  @return        MLAN_STATUS_SUCCESS
 */
mlan_status
wlan_ret_11n_addba_req(mlan_private *priv, HostCmd_DS_COMMAND *resp)
{
	t_u8 tid;
	HostCmd_DS_11N_ADDBA_RSP *padd_ba_rsp =
		(HostCmd_DS_11N_ADDBA_RSP *)&resp->params.add_ba_rsp;
	TxBAStreamTbl *ptx_ba_tbl;
	raListTbl *ra_list = MNULL;
	int tid_down;

	ENTER();

	padd_ba_rsp->block_ack_param_set =
		wlan_le16_to_cpu(padd_ba_rsp->block_ack_param_set);
	padd_ba_rsp->block_ack_tmo =
		wlan_le16_to_cpu(padd_ba_rsp->block_ack_tmo);
	padd_ba_rsp->ssn = (wlan_le16_to_cpu(padd_ba_rsp->ssn)) & SSN_MASK;
	padd_ba_rsp->status_code = wlan_le16_to_cpu(padd_ba_rsp->status_code);

	tid = (padd_ba_rsp->block_ack_param_set & BLOCKACKPARAM_TID_MASK) >>
		BLOCKACKPARAM_TID_POS;
	tid_down = wlan_get_wmm_tid_down(priv, tid);
	ra_list = wlan_wmm_get_ralist_node(priv, tid_down,
					   padd_ba_rsp->peer_mac_addr);
	if (padd_ba_rsp->status_code == BA_RESULT_SUCCESS) {
		ptx_ba_tbl =
			wlan_11n_get_txbastream_tbl(priv, tid,
						    padd_ba_rsp->peer_mac_addr,
						    MTRUE);
		if (ptx_ba_tbl) {
			PRINTM(MCMND,
			       "ADDBA REQ: " MACSTR
			       " tid=%d ssn=%d win_size=%d,amsdu=%d\n",
			       MAC2STR(padd_ba_rsp->peer_mac_addr), tid,
			       padd_ba_rsp->ssn,
			       ((padd_ba_rsp->block_ack_param_set &
				 BLOCKACKPARAM_WINSIZE_MASK) >>
				BLOCKACKPARAM_WINSIZE_POS),
			       padd_ba_rsp->block_ack_param_set &
			       BLOCKACKPARAM_AMSDU_SUPP_MASK);
			ptx_ba_tbl->ba_status = BA_STREAM_SETUP_COMPLETE;
			if ((padd_ba_rsp->block_ack_param_set &
			     BLOCKACKPARAM_AMSDU_SUPP_MASK) &&
			    priv->add_ba_param.tx_amsdu &&
			    (priv->aggr_prio_tbl[tid].amsdu !=
			     BA_STREAM_NOT_ALLOWED))
				ptx_ba_tbl->amsdu = MTRUE;
			else
				ptx_ba_tbl->amsdu = MFALSE;
			if (ra_list) {
				ra_list->amsdu_in_ampdu = ptx_ba_tbl->amsdu;
				ra_list->ba_status = BA_STREAM_SETUP_COMPLETE;
			}
		} else {
			PRINTM(MERROR, "BA stream not created\n");
		}
	} else {
		if (ra_list) {
			ra_list->amsdu_in_ampdu = MFALSE;
			ra_list->ba_status = BA_STREAM_NOT_SETUP;
		}
		mlan_11n_delete_bastream_tbl(priv, tid,
					     padd_ba_rsp->peer_mac_addr,
					     TYPE_DELBA_SENT, MTRUE, 0);
		if (padd_ba_rsp->add_rsp_result != BA_RESULT_TIMEOUT) {
#ifdef UAP_SUPPORT
			if (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_UAP)
				disable_station_ampdu(priv, tid,
						      padd_ba_rsp->
						      peer_mac_addr);
#endif /* UAP_SUPPORT */
			if (ra_list && ra_list->is_tdls_link)
				disable_station_ampdu(priv, tid,
						      padd_ba_rsp->
						      peer_mac_addr);
			priv->aggr_prio_tbl[tid].ampdu_ap =
				BA_STREAM_NOT_ALLOWED;

		} else {
			if (ra_list) {
				ra_list->packet_count = 0;
				ra_list->ba_packet_threshold =
					wlan_get_random_ba_threshold(priv->
								     adapter);
			}
		}
	}

	LEAVE();
	return MLAN_STATUS_SUCCESS;
}

/**
 *  @brief This function restore tx_pause flag
 *
 *  @param priv         A pointer to mlan_private structure
 *  @param flag         MTRUE/MFALSE;
 *
 *  @return             N/A
 */
void
wlan_set_tx_pause_flag(mlan_private *priv, t_u8 flag)
{
	mlan_private *pmpriv = MNULL;
	t_u8 i;
	for (i = 0; i < priv->adapter->priv_num; i++) {
		pmpriv = priv->adapter->priv[i];
		if (pmpriv)
			pmpriv->tx_pause = flag;
	}
}

/**
 *  @brief This function prepares command of reconfigure tx buf
 *
 *  @param priv         A pointer to mlan_private structure
 *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
 *  @param cmd_action   The action: GET or SET
 *  @param pdata_buf    A pointer to data buffer
 *
 *  @return             MLAN_STATUS_SUCCESS
 */
mlan_status
wlan_cmd_recfg_tx_buf(mlan_private *priv, HostCmd_DS_COMMAND *cmd,
		      int cmd_action, void *pdata_buf)
{
	HostCmd_DS_TXBUF_CFG *ptx_buf = &cmd->params.tx_buf;
	t_u16 action = (t_u16)cmd_action;
	t_u16 buf_size = *((t_u16 *)pdata_buf);

	ENTER();
	cmd->command = wlan_cpu_to_le16(HostCmd_CMD_RECONFIGURE_TX_BUFF);
	cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_TXBUF_CFG) + S_DS_GEN);
	ptx_buf->action = wlan_cpu_to_le16(action);
	switch (action) {
	case HostCmd_ACT_GEN_SET:
		PRINTM(MCMND, "set tx_buf = %d\n", buf_size);
		ptx_buf->buff_size = wlan_cpu_to_le16(buf_size);
		/** stop tx traffic */
		wlan_set_tx_pause_flag(priv, MTRUE);
		break;
	case HostCmd_ACT_GEN_GET:
	default:
		ptx_buf->buff_size = 0;
		break;
	}
	LEAVE();
	return MLAN_STATUS_SUCCESS;
}

/**
 *  @brief This function prepares command of amsdu aggr control
 *
 *  @param priv         A pointer to mlan_private structure
 *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
 *  @param cmd_action   The action: GET or SET
 *  @param pdata_buf    A pointer to data buffer
 *
 *  @return             MLAN_STATUS_SUCCESS
 */
mlan_status
wlan_cmd_amsdu_aggr_ctrl(mlan_private *priv,
			 HostCmd_DS_COMMAND *cmd, int cmd_action,
			 void *pdata_buf)
{
	HostCmd_DS_AMSDU_AGGR_CTRL *pamsdu_ctrl = &cmd->params.amsdu_aggr_ctrl;
	t_u16 action = (t_u16)cmd_action;
	mlan_ds_11n_amsdu_aggr_ctrl *aa_ctrl =
		(mlan_ds_11n_amsdu_aggr_ctrl *)pdata_buf;

	ENTER();

	cmd->command = wlan_cpu_to_le16(HostCmd_CMD_AMSDU_AGGR_CTRL);
	cmd->size =
		wlan_cpu_to_le16(sizeof(HostCmd_DS_AMSDU_AGGR_CTRL) + S_DS_GEN);
	pamsdu_ctrl->action = wlan_cpu_to_le16(action);
	switch (action) {
	case HostCmd_ACT_GEN_SET:
		pamsdu_ctrl->enable = wlan_cpu_to_le16(aa_ctrl->enable);
		pamsdu_ctrl->curr_buf_size = 0;
		break;
	case HostCmd_ACT_GEN_GET:
	default:
		pamsdu_ctrl->curr_buf_size = 0;
		break;
	}
	LEAVE();
	return MLAN_STATUS_SUCCESS;
}

/**
 *  @brief This function handles the command response of amsdu aggr ctrl
 *
 *  @param pmpriv       A pointer to mlan_private structure
 *  @param resp         A pointer to HostCmd_DS_COMMAND
 *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
 *
 *  @return        MLAN_STATUS_SUCCESS
 */
mlan_status
wlan_ret_amsdu_aggr_ctrl(pmlan_private pmpriv,
			 HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf)
{
	mlan_ds_11n_cfg *cfg = MNULL;
	HostCmd_DS_AMSDU_AGGR_CTRL *amsdu_ctrl = &resp->params.amsdu_aggr_ctrl;

	ENTER();

	if (pioctl_buf) {
		cfg = (mlan_ds_11n_cfg *)pioctl_buf->pbuf;
		cfg->param.amsdu_aggr_ctrl.enable =
			wlan_le16_to_cpu(amsdu_ctrl->enable);
		cfg->param.amsdu_aggr_ctrl.curr_buf_size =
			wlan_le16_to_cpu(amsdu_ctrl->curr_buf_size);
	}
	LEAVE();
	return MLAN_STATUS_SUCCESS;
}

/**
 *  @brief This function prepares 11n cfg command
 *
 *  @param pmpriv       A pointer to mlan_private structure
 *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
 *  @param cmd_action   the action: GET or SET
 *  @param pdata_buf    A pointer to data buffer
 *  @return             MLAN_STATUS_SUCCESS
 */
mlan_status
wlan_cmd_11n_cfg(pmlan_private pmpriv,
		 HostCmd_DS_COMMAND *cmd, t_u16 cmd_action, t_void *pdata_buf)
{
	HostCmd_DS_11N_CFG *htcfg = &cmd->params.htcfg;
	mlan_ds_11n_tx_cfg *txcfg = (mlan_ds_11n_tx_cfg *)pdata_buf;

	ENTER();
	cmd->command = wlan_cpu_to_le16(HostCmd_CMD_11N_CFG);
	cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_11N_CFG) + S_DS_GEN);
	htcfg->action = wlan_cpu_to_le16(cmd_action);
	htcfg->ht_tx_cap = wlan_cpu_to_le16(txcfg->httxcap);
	htcfg->ht_tx_info = wlan_cpu_to_le16(txcfg->httxinfo);
	htcfg->misc_config = wlan_cpu_to_le16(txcfg->misc_cfg);
	LEAVE();
	return MLAN_STATUS_SUCCESS;
}

/**
 *  @brief This function handles the command response of 11ncfg
 *
 *  @param pmpriv       A pointer to mlan_private structure
 *  @param resp         A pointer to HostCmd_DS_COMMAND
 *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
 *
 *  @return        MLAN_STATUS_SUCCESS
 */
mlan_status
wlan_ret_11n_cfg(pmlan_private pmpriv,
		 HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf)
{
	mlan_ds_11n_cfg *cfg = MNULL;
	HostCmd_DS_11N_CFG *htcfg = &resp->params.htcfg;

	ENTER();
	if (pioctl_buf &&
	    (wlan_le16_to_cpu(htcfg->action) == HostCmd_ACT_GEN_GET)) {
		cfg = (mlan_ds_11n_cfg *)pioctl_buf->pbuf;
		cfg->param.tx_cfg.httxcap = wlan_le16_to_cpu(htcfg->ht_tx_cap);
		cfg->param.tx_cfg.httxinfo =
			wlan_le16_to_cpu(htcfg->ht_tx_info);
		cfg->param.tx_cfg.misc_cfg =
			wlan_le16_to_cpu(htcfg->misc_config);
	}
	LEAVE();
	return MLAN_STATUS_SUCCESS;
}

/**
 *  @brief This function prepares reject addba req command
 *
 *  @param pmpriv       A pointer to mlan_private structure
 *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
 *  @param cmd_action   the action: GET or SET
 *  @param pdata_buf    A pointer to data buffer
 *  @return             MLAN_STATUS_SUCCESS
 */
mlan_status
wlan_cmd_reject_addba_req(pmlan_private pmpriv,
			  HostCmd_DS_COMMAND *cmd,
			  t_u16 cmd_action, t_void *pdata_buf)
{
	HostCmd_DS_REJECT_ADDBA_REQ *preject_addba_req =
		&cmd->params.rejectaddbareq;
	mlan_ds_reject_addba_req *prejaddbareq =
		(mlan_ds_reject_addba_req *)pdata_buf;

	ENTER();
	cmd->command = wlan_cpu_to_le16(HostCmd_CMD_REJECT_ADDBA_REQ);
	cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_REJECT_ADDBA_REQ) +
				     S_DS_GEN);
	preject_addba_req->action = wlan_cpu_to_le16(cmd_action);
	preject_addba_req->conditions =
		wlan_cpu_to_le32(prejaddbareq->conditions);
	LEAVE();
	return MLAN_STATUS_SUCCESS;
}

/**
 *  @brief This function handles the command response of reject addba req
 *
 *  @param pmpriv       A pointer to mlan_private structure
 *  @param resp         A pointer to HostCmd_DS_COMMAND
 *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
 *
 *  @return        MLAN_STATUS_SUCCESS
 */
mlan_status
wlan_ret_reject_addba_req(pmlan_private pmpriv,
			  HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf)
{
	mlan_ds_11n_cfg *cfg = MNULL;
	HostCmd_DS_REJECT_ADDBA_REQ *preject_addba_req =
		&resp->params.rejectaddbareq;

	ENTER();
	if (pioctl_buf && (wlan_le16_to_cpu(preject_addba_req->action) ==
			   HostCmd_ACT_GEN_GET)) {
		cfg = (mlan_ds_11n_cfg *)pioctl_buf->pbuf;
		cfg->param.reject_addba_req.conditions =
			wlan_le32_to_cpu(preject_addba_req->conditions);
	}
	LEAVE();
	return MLAN_STATUS_SUCCESS;
}

/**
 *  @brief This function prepares TX BF configuration command
 *
 *  @param pmpriv       A pointer to mlan_private structure
 *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
 *  @param cmd_action   The action: GET or SET
 *  @param pdata_buf    A pointer to data buffer
 *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
mlan_status
wlan_cmd_tx_bf_cfg(pmlan_private pmpriv,
		   HostCmd_DS_COMMAND *cmd, t_u16 cmd_action, t_void *pdata_buf)
{
	pmlan_adapter pmadapter = pmpriv->adapter;
	HostCmd_DS_TX_BF_CFG *txbfcfg = &cmd->params.tx_bf_cfg;
	mlan_ds_11n_tx_bf_cfg *txbf = (mlan_ds_11n_tx_bf_cfg *)pdata_buf;

	ENTER();

	cmd->command = wlan_cpu_to_le16(HostCmd_CMD_TX_BF_CFG);
	cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_TX_BF_CFG) + S_DS_GEN);

	if (txbf->bf_action == SET_GET_BF_PERIODICITY) {
		memcpy_ext(pmadapter, txbfcfg->body.bf_periodicity.peer_mac,
			   txbf->body.bf_periodicity[0].peer_mac,
			   MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
	}
	txbfcfg->action = wlan_cpu_to_le16(txbf->action);
	txbfcfg->bf_action = wlan_cpu_to_le16(txbf->bf_action);
	if (cmd_action == HostCmd_ACT_GEN_SET) {
		switch (txbf->bf_action) {
		case BF_GLOBAL_CONFIGURATION:
			txbfcfg->body.bf_global_cfg.bf_enbl =
				txbf->body.bf_global_cfg.bf_enbl;
			txbfcfg->body.bf_global_cfg.sounding_enbl =
				txbf->body.bf_global_cfg.sounding_enbl;
			txbfcfg->body.bf_global_cfg.fb_type =
				txbf->body.bf_global_cfg.fb_type;
			txbfcfg->body.bf_global_cfg.snr_threshold =
				txbf->body.bf_global_cfg.snr_threshold;
			txbfcfg->body.bf_global_cfg.sounding_interval =
				wlan_cpu_to_le16(txbf->body.bf_global_cfg.
						 sounding_interval);
			txbfcfg->body.bf_global_cfg.bf_mode =
				txbf->body.bf_global_cfg.bf_mode;
			break;
		case TRIGGER_SOUNDING_FOR_PEER:
			memcpy_ext(pmadapter,
				   txbfcfg->body.bf_sound_args.peer_mac,
				   txbf->body.bf_sound[0].peer_mac,
				   MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
			break;
		case SET_GET_BF_PERIODICITY:
			txbfcfg->body.bf_periodicity.interval =
				wlan_cpu_to_le16(txbf->body.bf_periodicity->
						 interval);
			break;
		case TX_BF_FOR_PEER_ENBL:
			memcpy_ext(pmadapter, txbfcfg->body.tx_bf_peer.peer_mac,
				   txbf->body.tx_bf_peer[0].peer_mac,
				   MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
			txbfcfg->body.tx_bf_peer.bf_enbl =
				txbf->body.tx_bf_peer[0].bf_enbl;
			txbfcfg->body.tx_bf_peer.sounding_enbl =
				txbf->body.tx_bf_peer[0].sounding_enbl;
			txbfcfg->body.tx_bf_peer.fb_type =
				txbf->body.tx_bf_peer[0].fb_type;
			break;
		case SET_SNR_THR_PEER:
			memcpy_ext(pmadapter, txbfcfg->body.bf_snr.peer_mac,
				   txbf->body.bf_snr[0].peer_mac,
				   MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
			txbfcfg->body.bf_snr.snr = txbf->body.bf_snr[0].snr;
			break;
		default:
			LEAVE();
			return MLAN_STATUS_FAILURE;
		}
	}

	LEAVE();
	return MLAN_STATUS_SUCCESS;
}

/**
 *  @brief This function handles the command response
 *  of TX BF configuration
 *
 *  @param pmpriv       A pointer to mlan_private structure
 *  @param resp         A pointer to HostCmd_DS_COMMAND
 *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
 *
 *  @return        MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
mlan_status
wlan_ret_tx_bf_cfg(pmlan_private pmpriv,
		   HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf)
{
	pmlan_adapter pmadapter = pmpriv->adapter;
	HostCmd_DS_TX_BF_CFG *txbfcfg = &resp->params.tx_bf_cfg;
	mlan_ds_11n_cfg *cfg_11n = MNULL;
	mlan_ds_11n_tx_bf_cfg *txbf = MNULL;
	bf_peer_args *tx_bf_peer;
	bf_snr_thr_t *bf_snr;
	int i;

	ENTER();

	if (pioctl_buf) {
		cfg_11n = (mlan_ds_11n_cfg *)pioctl_buf->pbuf;
		txbf = (mlan_ds_11n_tx_bf_cfg *)&cfg_11n->param.tx_bf;
		txbf->bf_action = wlan_le16_to_cpu(txbfcfg->bf_action);
		switch (txbf->bf_action) {
		case BF_GLOBAL_CONFIGURATION:
			txbf->body.bf_global_cfg.bf_enbl =
				txbfcfg->body.bf_global_cfg.bf_enbl;
			txbf->body.bf_global_cfg.sounding_enbl =
				txbfcfg->body.bf_global_cfg.sounding_enbl;
			txbf->body.bf_global_cfg.fb_type =
				txbfcfg->body.bf_global_cfg.fb_type;
			txbf->body.bf_global_cfg.snr_threshold =
				txbfcfg->body.bf_global_cfg.snr_threshold;
			txbf->body.bf_global_cfg.sounding_interval =
				wlan_le16_to_cpu(txbfcfg->body.bf_global_cfg.
						 sounding_interval);
			txbf->body.bf_global_cfg.bf_mode =
				txbfcfg->body.bf_global_cfg.bf_mode;
			break;
		case TRIGGER_SOUNDING_FOR_PEER:
			memcpy_ext(pmadapter, txbf->body.bf_sound[0].peer_mac,
				   txbfcfg->body.bf_sound_args.peer_mac,
				   MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
			txbf->body.bf_sound[0].status =
				txbfcfg->body.bf_sound_args.status;
			break;
		case SET_GET_BF_PERIODICITY:
			memcpy_ext(pmadapter,
				   txbf->body.bf_periodicity->peer_mac,
				   txbfcfg->body.bf_periodicity.peer_mac,
				   MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
			txbf->body.bf_periodicity->interval =
				wlan_le16_to_cpu(txbfcfg->body.bf_periodicity.
						 interval);
			break;
		case TX_BF_FOR_PEER_ENBL:
			txbf->no_of_peers = *(t_u8 *)&txbfcfg->body;
			tx_bf_peer = (bf_peer_args *)((t_u8 *)&txbfcfg->body +
						      sizeof(t_u8));
			for (i = 0; i < (int)txbf->no_of_peers; i++) {
				memcpy_ext(pmadapter,
					   txbf->body.tx_bf_peer[i].peer_mac,
					   (t_u8 *)tx_bf_peer->peer_mac,
					   MLAN_MAC_ADDR_LENGTH,
					   MLAN_MAC_ADDR_LENGTH);
				txbf->body.tx_bf_peer[i].bf_enbl =
					tx_bf_peer->bf_enbl;
				txbf->body.tx_bf_peer[i].sounding_enbl =
					tx_bf_peer->sounding_enbl;
				txbf->body.tx_bf_peer[i].fb_type =
					tx_bf_peer->fb_type;
				tx_bf_peer++;
			}
			break;
		case SET_SNR_THR_PEER:
			txbf->no_of_peers = *(t_u8 *)&txbfcfg->body;
			bf_snr = (bf_snr_thr_t *)((t_u8 *)&txbfcfg->body +
						  sizeof(t_u8));
			for (i = 0; i < (int)txbf->no_of_peers; i++) {
				memcpy_ext(pmadapter,
					   txbf->body.bf_snr[i].peer_mac,
					   (t_u8 *)bf_snr->peer_mac,
					   MLAN_MAC_ADDR_LENGTH,
					   MLAN_MAC_ADDR_LENGTH);
				txbf->body.bf_snr[i].snr = bf_snr->snr;
				bf_snr++;
			}
			break;
		default:
			LEAVE();
			return MLAN_STATUS_FAILURE;
		}
	}

	LEAVE();
	return MLAN_STATUS_SUCCESS;
}

/**
 * @brief Get second channel offset
 *
 * @param chan            channel num
 * @return                second channel offset
 */
t_u8
wlan_get_second_channel_offset(mlan_private *priv, int chan)
{
	t_u8 chan2Offset = SEC_CHAN_NONE;

	/* Special Case: 20Mhz-only Channel */
	if (chan == 165)
		return chan2Offset;

	switch (chan) {
	case 36:
	case 44:
	case 52:
	case 60:
	case 100:
	case 108:
	case 116:
	case 124:
	case 132:
	case 140:
	case 149:
	case 157:
		chan2Offset = SEC_CHAN_ABOVE;
		break;
	case 40:
	case 48:
	case 56:
	case 64:
	case 104:
	case 112:
	case 120:
	case 128:
	case 136:
	case 144:
	case 153:
	case 161:
		chan2Offset = SEC_CHAN_BELOW;
		break;
	}
	return chan2Offset;
}

#ifdef STA_SUPPORT
/**
 *  @brief validate the channel offset for Infra/Ad-hoc band configuration
 *
 *  @param pmpriv       A pointer to mlan_private structure
 *  @param band         band
 *  @param chan         primary channel
 *  @param chan_bw      channel bandwidth
 *
 *  @return             channel offset (NO_SEC_CHANNEL, SEC_CHANNEL_ABOVE,
 *                                      SEC_CHANNEL_BELOW)
 */
t_u8
wlan_validate_chan_offset(mlan_private *pmpriv, t_u16 band,
			  t_u32 chan, t_u8 chan_bw)
{
	t_u8 chan_offset;
	pmlan_adapter pmadapter = pmpriv->adapter;

	if (chan_bw == CHANNEL_BW_40MHZ_ABOVE)
		chan_offset = SEC_CHAN_ABOVE;
	else if (chan_bw == CHANNEL_BW_40MHZ_BELOW)
		chan_offset = SEC_CHAN_BELOW;
	else
		chan_offset = SEC_CHAN_NONE;

	/* validation */
	if (chan_offset != SEC_CHAN_NONE) {
		if (band & BAND_GN) {
			if ((chan == 1) || (chan == 2) || (chan == 3) ||
			    (chan == 4))
				chan_offset = SEC_CHAN_ABOVE;
			else if ((chan == 10) || (chan == 11) || (chan == 12) ||
				 (chan == 13))
				chan_offset = SEC_CHAN_BELOW;

			/* check if channel 12 is supported in the region */
			if (!wlan_find_cfp_by_band_and_channel(pmadapter, band,
							       12))
				if ((chan == 8) || (chan == 9))
					chan_offset = SEC_CHAN_BELOW;
		} else if (band & BAND_AN)
			chan_offset =
				wlan_get_second_channel_offset(pmpriv, chan);
	}
	return chan_offset;
}

/**
 *  @brief This function check if ht40 is allowed in current region
 *
 *  @param pmpriv       A pointer to mlan_private structure
 *  @param pbss_desc    A pointer to BSSDescriptor_t structure
 *
 *  @return MTRUE/MFALSE
 */
static int
wlan_check_chan_width_ht40_by_region(mlan_private *pmpriv,
				     BSSDescriptor_t *pbss_desc)
{
	pmlan_adapter pmadapter = pmpriv->adapter;
	int i = 0;
	int cover_pri_chan = MFALSE;
	t_u8 pri_chan;
	t_u8 chan_offset;
	t_u8 num_cfp;

	ENTER();

	if (pbss_desc->pht_info == MNULL) {
		PRINTM(MERROR, "ht_info pointer NULL, force use HT20\n");
		LEAVE();
		return MFALSE;
	}
	if (pmpriv->curr_chan_flags & CHAN_FLAGS_NO_HT40PLUS &&
	    pmpriv->curr_chan_flags & CHAN_FLAGS_NO_HT40MINUS) {
		LEAVE();
		return MFALSE;
	}

	pri_chan = pbss_desc->pht_info->ht_info.pri_chan;
	chan_offset = GET_SECONDARYCHAN(pbss_desc->pht_info->ht_info.field2);
	if ((chan_offset == SEC_CHAN_ABOVE) &&
	    (pmpriv->curr_chan_flags & CHAN_FLAGS_NO_HT40PLUS)) {
		pmpriv->curr_chan_flags |=
			CHAN_FLAGS_NO_HT40MINUS | CHAN_FLAGS_NO_80MHZ;
		return MFALSE;
	}
	if ((chan_offset == SEC_CHAN_BELOW) &&
	    (pmpriv->curr_chan_flags & CHAN_FLAGS_NO_HT40MINUS)) {
		pmpriv->curr_chan_flags |=
			CHAN_FLAGS_NO_HT40PLUS | CHAN_FLAGS_NO_80MHZ;
		return MFALSE;
	}
	if (pmpriv->curr_chan_flags & CHAN_FLAGS_MAX)
		return MTRUE;

	num_cfp = pmadapter->region_channel[0].num_cfp;

	if ((pbss_desc->bss_band & (BAND_B | BAND_G)) &&
	    pmadapter->region_channel[0].valid) {
		for (i = 0; i < num_cfp; i++) {
			if (pri_chan ==
			    pmadapter->region_channel[0].pcfp[i].channel) {
				cover_pri_chan = MTRUE;
				break;
			}
		}
		if (!cover_pri_chan) {
			PRINTM(MERROR, "Invalid channel, force use HT20\n");
			LEAVE();
			return MFALSE;
		}

		if (chan_offset == SEC_CHAN_ABOVE) {
			if (pri_chan > num_cfp - 4) {
				PRINTM(MERROR,
				       "Invalid second channel offset, force use HT20\n");
				LEAVE();
				return MFALSE;
			}
		}
	}
	LEAVE();
	return MTRUE;
}

/**
 *  @brief This function append the 802_11N tlv
 *
 *  @param pmpriv       A pointer to mlan_private structure
 *  @param pbss_desc    A pointer to BSSDescriptor_t structure
 *  @param ppbuffer     A Pointer to command buffer pointer
 *
 *  @return bytes added to the buffer
 */
int
wlan_cmd_append_11n_tlv(mlan_private *pmpriv,
			BSSDescriptor_t *pbss_desc, t_u8 **ppbuffer)
{
	pmlan_adapter pmadapter = pmpriv->adapter;
	MrvlIETypes_HTCap_t *pht_cap;
	MrvlIEtypes_ChanListParamSet_t *pchan_list;
	MrvlIETypes_2040BSSCo_t *p2040_bss_co;
	MrvlIETypes_ExtCap_t *pext_cap;
	t_u32 usr_dot_11n_dev_cap, orig_usr_dot_11n_dev_cap = 0;
	t_u8 usr_dot_11ac_bw;
	int ret_len = 0;

	ENTER();

	/* Null Checks */
	if (ppbuffer == MNULL) {
		LEAVE();
		return 0;
	}
	if (*ppbuffer == MNULL) {
		LEAVE();
		return 0;
	}
	if (pbss_desc == MNULL) {
		LEAVE();
		return 0;
	}

	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;

	if (pmpriv->bss_mode == MLAN_BSS_MODE_IBSS)
		usr_dot_11ac_bw = BW_FOLLOW_VHTCAP;
	else
		usr_dot_11ac_bw = pmpriv->usr_dot_11ac_bw;
	if ((pbss_desc->bss_band & (BAND_B | BAND_G | BAND_A)) &&
	    ISSUPP_CHANWIDTH40(usr_dot_11n_dev_cap) &&
	    !wlan_check_chan_width_ht40_by_region(pmpriv, pbss_desc)) {
		orig_usr_dot_11n_dev_cap = usr_dot_11n_dev_cap;
		RESETSUPP_CHANWIDTH40(usr_dot_11n_dev_cap);
		RESET_40MHZ_INTOLARENT(usr_dot_11n_dev_cap);
		RESETSUPP_SHORTGI40(usr_dot_11n_dev_cap);
		pmpriv->usr_dot_11n_dev_cap_bg = usr_dot_11n_dev_cap;
		pbss_desc->curr_bandwidth = BW_20MHZ;
	}
	if (pbss_desc->pht_cap) {
		pht_cap = (MrvlIETypes_HTCap_t *)*ppbuffer;
		memset(pmadapter, pht_cap, 0, sizeof(MrvlIETypes_HTCap_t));
		pht_cap->header.type = wlan_cpu_to_le16(HT_CAPABILITY);
		pht_cap->header.len = sizeof(HTCap_t);
		memcpy_ext(pmadapter,
			   (t_u8 *)pht_cap + sizeof(MrvlIEtypesHeader_t),
			   (t_u8 *)pbss_desc->pht_cap +
			   sizeof(IEEEtypes_Header_t),
			   pht_cap->header.len, pht_cap->header.len);

		pht_cap->ht_cap.ht_cap_info =
			wlan_le16_to_cpu(pht_cap->ht_cap.ht_cap_info);
		pht_cap->ht_cap.ht_ext_cap =
			wlan_le16_to_cpu(pht_cap->ht_cap.ht_ext_cap);
		wlan_fill_ht_cap_tlv(pmpriv, pht_cap, pbss_desc->bss_band,
				     MTRUE);

		/** check if need support 80+80MHZ */
		/** reset the 2 spatial stream rate for 80 + 80 Mhz */
		if (wlan_is_80_80_support(pmpriv, pbss_desc))
			pht_cap->ht_cap.supported_mcs_set[1] = 0;
		HEXDUMP("HT_CAPABILITIES IE", (t_u8 *)pht_cap,
			sizeof(MrvlIETypes_HTCap_t));
		*ppbuffer += sizeof(MrvlIETypes_HTCap_t);
		ret_len += sizeof(MrvlIETypes_HTCap_t);
		pht_cap->header.len = wlan_cpu_to_le16(pht_cap->header.len);
	} else {
		// AP don't support 11N
		LEAVE();
		return 0;
	}

	if (pbss_desc->pht_info) {

		pchan_list = (MrvlIEtypes_ChanListParamSet_t *)*ppbuffer;
		memset(pmadapter, pchan_list, 0,
		       sizeof(MrvlIEtypes_ChanListParamSet_t));
		pchan_list->header.type = wlan_cpu_to_le16(TLV_TYPE_CHANLIST);
		pchan_list->header.len =
			sizeof(MrvlIEtypes_ChanListParamSet_t) -
			sizeof(MrvlIEtypesHeader_t);
		pchan_list->chan_scan_param[0].chan_number =
			pbss_desc->pht_info->ht_info.pri_chan;
		pchan_list->chan_scan_param[0].bandcfg.chanBand =
			wlan_band_to_radio_type((t_u8)pbss_desc->bss_band);
		/* support the VHT if the network to be join has the VHT
		 * operation */
		if (ISSUPP_11ACENABLED(pmadapter->fw_cap_info) &&
		    (usr_dot_11ac_bw == BW_FOLLOW_VHTCAP) &&
		    (!(pmpriv->curr_chan_flags & CHAN_FLAGS_NO_80MHZ)) &&
		    wlan_11ac_bandconfig_allowed(pmpriv, pbss_desc->bss_band) &&
		    pbss_desc->pvht_oprat &&
		    pbss_desc->pvht_oprat->chan_width == VHT_OPER_CHWD_80MHZ) {
			pchan_list->chan_scan_param[0].bandcfg.chanWidth =
				CHAN_BW_80MHZ;
			pchan_list->chan_scan_param[0].bandcfg.chan2Offset =
				GET_SECONDARYCHAN(pbss_desc->pht_info->ht_info.
						  field2);
			pbss_desc->curr_bandwidth = BW_80MHZ;
		} else if (ISSUPP_CHANWIDTH40(usr_dot_11n_dev_cap) &&
			   ISALLOWED_CHANWIDTH40(pbss_desc->pht_info->ht_info.
						 field2) &&
			   wlan_check_chan_width_ht40_by_region(pmpriv,
								pbss_desc)) {
			pchan_list->chan_scan_param[0].bandcfg.chan2Offset =
				GET_SECONDARYCHAN(pbss_desc->pht_info->ht_info.
						  field2);
			pbss_desc->curr_bandwidth = BW_40MHZ;
			pchan_list->chan_scan_param[0].bandcfg.chanWidth =
				CHAN_BW_40MHZ;
		}
		pchan_list->chan_scan_param[0].bandcfg.scanMode =
			SCAN_MODE_USER;
		HEXDUMP("ChanList", (t_u8 *)pchan_list,
			sizeof(MrvlIEtypes_ChanListParamSet_t));
		HEXDUMP("pht_info", (t_u8 *)pbss_desc->pht_info,
			sizeof(MrvlIETypes_HTInfo_t) - 2);
		*ppbuffer += sizeof(MrvlIEtypes_ChanListParamSet_t);
		ret_len += sizeof(MrvlIEtypes_ChanListParamSet_t);
		pchan_list->header.len =
			wlan_cpu_to_le16(pchan_list->header.len);
	}

	if (pbss_desc->pbss_co_2040) {
		p2040_bss_co = (MrvlIETypes_2040BSSCo_t *)*ppbuffer;
		memset(pmadapter, p2040_bss_co, 0,
		       sizeof(MrvlIETypes_2040BSSCo_t));
		p2040_bss_co->header.type = wlan_cpu_to_le16(BSSCO_2040);
		p2040_bss_co->header.len = sizeof(BSSCo2040_t);

		memcpy_ext(pmadapter,
			   (t_u8 *)p2040_bss_co + sizeof(MrvlIEtypesHeader_t),
			   (t_u8 *)pbss_desc->pbss_co_2040 +
			   sizeof(IEEEtypes_Header_t),
			   p2040_bss_co->header.len, p2040_bss_co->header.len);

		HEXDUMP("20/40 BSS Coexistence IE", (t_u8 *)p2040_bss_co,
			sizeof(MrvlIETypes_2040BSSCo_t));
		*ppbuffer += sizeof(MrvlIETypes_2040BSSCo_t);
		ret_len += sizeof(MrvlIETypes_2040BSSCo_t);
		p2040_bss_co->header.len =
			wlan_cpu_to_le16(p2040_bss_co->header.len);
	}

	if (pbss_desc->pext_cap) {
		pext_cap = (MrvlIETypes_ExtCap_t *)*ppbuffer;
		memset(pmadapter, pext_cap, 0, sizeof(MrvlIETypes_ExtCap_t));
		pext_cap->header.type = wlan_cpu_to_le16(EXT_CAPABILITY);
		pext_cap->header.len = sizeof(ExtCap_t);

		memcpy_ext(pmadapter,
			   (t_u8 *)pext_cap + sizeof(MrvlIEtypesHeader_t),
			   (t_u8 *)&pmpriv->ext_cap, sizeof(ExtCap_t),
			   pext_cap->header.len);
		if (pbss_desc && pbss_desc->multi_bssid_ap)
			SET_EXTCAP_MULTI_BSSID(pext_cap->ext_cap);
		if (!pmadapter->ecsa_enable)
			RESET_EXTCAP_EXT_CHANNEL_SWITCH(pext_cap->ext_cap);
		else
			SET_EXTCAP_EXT_CHANNEL_SWITCH(pext_cap->ext_cap);

		HEXDUMP("Extended Capabilities IE", (t_u8 *)pext_cap,
			sizeof(MrvlIETypes_ExtCap_t));
		*ppbuffer += sizeof(MrvlIETypes_ExtCap_t);
		ret_len += sizeof(MrvlIETypes_ExtCap_t);
		pext_cap->header.len = wlan_cpu_to_le16(pext_cap->header.len);
	} else if (wlan_is_ext_capa_support(pmpriv) ||
		   (pmpriv->config_bands & BAND_AAC)
		) {
		wlan_add_ext_capa_info_ie(pmpriv, pbss_desc, ppbuffer);
		ret_len += sizeof(MrvlIETypes_ExtCap_t);
	}
	PRINTM(MCMND, "curr_bandwidth=%d\n", pbss_desc->curr_bandwidth);
	if (orig_usr_dot_11n_dev_cap)
		pmpriv->usr_dot_11n_dev_cap_bg = orig_usr_dot_11n_dev_cap;

	LEAVE();
	return ret_len;
}

#endif /* STA_SUPPORT */

/**
 *  @brief 11n configuration handler
 *
 *  @param pmadapter	A pointer to mlan_adapter structure
 *  @param pioctl_req	A pointer to ioctl request buffer
 *
 *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
 */
mlan_status
wlan_11n_cfg_ioctl(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
{
	mlan_status status = MLAN_STATUS_SUCCESS;
	mlan_ds_11n_cfg *cfg = MNULL;

	ENTER();

	if (pioctl_req->buf_len < sizeof(mlan_ds_11n_cfg)) {
		PRINTM(MINFO, "MLAN bss IOCTL length is too short.\n");
		pioctl_req->data_read_written = 0;
		pioctl_req->buf_len_needed = sizeof(mlan_ds_11n_cfg);
		pioctl_req->status_code = MLAN_ERROR_INVALID_PARAMETER;
		LEAVE();
		return MLAN_STATUS_RESOURCE;
	}
	cfg = (mlan_ds_11n_cfg *)pioctl_req->pbuf;
	switch (cfg->sub_command) {
	case MLAN_OID_11N_CFG_TX:
		status = wlan_11n_ioctl_httxcfg(pmadapter, pioctl_req);
		break;
	case MLAN_OID_11N_HTCAP_CFG:
		status = wlan_11n_ioctl_htusrcfg(pmadapter, pioctl_req);
		break;
	case MLAN_OID_11N_CFG_AGGR_PRIO_TBL:
		status = wlan_11n_ioctl_aggr_prio_tbl(pmadapter, pioctl_req);
		break;
	case MLAN_OID_11N_CFG_ADDBA_REJECT:
		status = wlan_11n_ioctl_addba_reject(pmadapter, pioctl_req);
		break;
	case MLAN_OID_11N_CFG_ADDBA_PARAM:
		status = wlan_11n_ioctl_addba_param(pmadapter, pioctl_req);
		break;
	case MLAN_OID_11N_CFG_DELBA:
		status = wlan_11n_ioctl_delba(pmadapter, pioctl_req);
		break;
	case MLAN_OID_11N_CFG_REJECT_ADDBA_REQ:
		status = wlan_11n_ioctl_rejectaddbareq(pmadapter, pioctl_req);
		break;
	case MLAN_OID_11N_CFG_MAX_TX_BUF_SIZE:
		status = wlan_11n_ioctl_max_tx_buf_size(pmadapter, pioctl_req);
		break;
	case MLAN_OID_11N_CFG_AMSDU_AGGR_CTRL:
		status = wlan_11n_ioctl_amsdu_aggr_ctrl(pmadapter, pioctl_req);
		break;
	case MLAN_OID_11N_CFG_SUPPORTED_MCS_SET:
		status = wlan_11n_ioctl_supported_mcs_set(pmadapter,
							  pioctl_req);
		break;
	case MLAN_OID_11N_CFG_TX_BF_CAP:
		status = wlan_11n_ioctl_tx_bf_cap(pmadapter, pioctl_req);
		break;
	case MLAN_OID_11N_CFG_TX_BF_CFG:
		status = wlan_11n_ioctl_tx_bf_cfg(pmadapter, pioctl_req);
		break;
	case MLAN_OID_11N_CFG_STREAM_CFG:
		status = wlan_11n_ioctl_stream_cfg(pmadapter, pioctl_req);
		break;
	case MLAN_OID_11N_CFG_COEX_RX_WINSIZE:
		status = wlan_11n_ioctl_coex_rx_winsize(pmadapter, pioctl_req);
		break;
	case MLAN_OID_11N_CFG_TX_AGGR_CTRL:
		status = wlan_11n_ioctl_txaggrctrl(pmadapter, pioctl_req);
		break;
	case MLAN_OID_11N_CFG_IBSS_AMPDU_PARAM:
		status = wlan_11n_ioctl_ibss_ampdu_param(pmadapter, pioctl_req);
		break;
	case MLAN_OID_11N_CFG_MIN_BA_THRESHOLD:
		status = wlan_11n_ioctl_min_ba_threshold_cfg(pmadapter,
							     pioctl_req);
		break;
	default:
		pioctl_req->status_code = MLAN_ERROR_IOCTL_INVALID;
		status = MLAN_STATUS_FAILURE;
		break;
	}
	LEAVE();
	return status;
}

/**
 *  @brief This function will delete the given entry in Tx BA Stream table
 *
 *  @param priv     Pointer to mlan_private
 *  @param ptx_tbl  Pointer to tx ba stream entry to delete
 *
 *  @return         N/A
 */
void
wlan_11n_delete_txbastream_tbl_entry(mlan_private *priv, TxBAStreamTbl *ptx_tbl)
{
	pmlan_adapter pmadapter = priv->adapter;

	ENTER();

	if (!ptx_tbl || !wlan_is_txbastreamptr_valid(priv, ptx_tbl))
		goto exit;
	PRINTM(MINFO, "Delete BA stream table entry: %p\n", ptx_tbl);
	util_unlink_list(pmadapter->pmoal_handle, &priv->tx_ba_stream_tbl_ptr,
			 (pmlan_linked_list)ptx_tbl, MNULL, MNULL);
	pmadapter->callbacks.moal_mfree(pmadapter->pmoal_handle,
					(t_u8 *)ptx_tbl);
exit:
	LEAVE();
}

/**
 *  @brief This function will delete all the entries in Tx BA Stream table
 *
 *  @param priv         A pointer to mlan_private
 *
 *  @return             N/A
 */
void
wlan_11n_deleteall_txbastream_tbl(mlan_private *priv)
{
	int i;
	TxBAStreamTbl *del_tbl_ptr = MNULL;

	ENTER();

	wlan_request_ralist_lock(priv);
	while ((del_tbl_ptr =
		(TxBAStreamTbl *)util_peek_list(priv->adapter->pmoal_handle,
						&priv->tx_ba_stream_tbl_ptr,
						MNULL, MNULL))) {
		wlan_11n_delete_txbastream_tbl_entry(priv, del_tbl_ptr);
	}

	util_init_list((pmlan_linked_list)&priv->tx_ba_stream_tbl_ptr);
	wlan_release_ralist_lock(priv);
	for (i = 0; i < MAX_NUM_TID; ++i) {
		priv->aggr_prio_tbl[i].ampdu_ap =
			priv->aggr_prio_tbl[i].ampdu_user;
	}

	LEAVE();
}

/**
 *  @brief This function will return the pointer to an entry in BA Stream
 *          table which matches the give RA/TID pair
 *
 *  @param priv    A pointer to mlan_private
 *  @param tid     TID to find in reordering table
 *  @param ra      RA to find in reordering table
 *  @param lock    flag for request the spin_lock
 *
 *  @return        A pointer to first entry matching RA/TID in BA stream
 *                 NULL if not found
 */
TxBAStreamTbl *
wlan_11n_get_txbastream_tbl(mlan_private *priv, int tid, t_u8 *ra, int lock)
{
	TxBAStreamTbl *ptx_tbl;
	pmlan_adapter pmadapter = priv->adapter;

	ENTER();

	if (lock)
		wlan_request_ralist_lock(priv);
	ptx_tbl = (TxBAStreamTbl *)util_peek_list(pmadapter->pmoal_handle,
						  &priv->tx_ba_stream_tbl_ptr,
						  MNULL, MNULL);
	if (!ptx_tbl) {
		if (lock)
			wlan_release_ralist_lock(priv);
		LEAVE();
		return MNULL;
	}

	while (ptx_tbl != (TxBAStreamTbl *)&priv->tx_ba_stream_tbl_ptr) {
		PRINTM(MDAT_D, "get_txbastream_tbl TID %d\n", ptx_tbl->tid);
		DBG_HEXDUMP(MDAT_D, "RA", ptx_tbl->ra, MLAN_MAC_ADDR_LENGTH);

		if ((!memcmp(pmadapter, ptx_tbl->ra, ra,
			     MLAN_MAC_ADDR_LENGTH)) && (ptx_tbl->tid == tid)) {
			if (lock)
				wlan_release_ralist_lock(priv);
			LEAVE();
			return ptx_tbl;
		}

		ptx_tbl = ptx_tbl->pnext;
	}
	if (lock)
		wlan_release_ralist_lock(priv);
	LEAVE();
	return MNULL;
}

/**
 *  @brief This function will create a entry in tx ba stream table for the
 *          given RA/TID.
 *
 *  @param priv      A pointer to mlan_private
 *  @param ra        RA to find in reordering table
 *  @param tid       TID to find in reordering table
 *  @param ba_status BA stream status to create the stream with
 *
 *  @return          N/A
 */
void
wlan_11n_create_txbastream_tbl(mlan_private *priv, t_u8 *ra, int tid,
			       baStatus_e ba_status)
{
	TxBAStreamTbl *new_node = MNULL;
	pmlan_adapter pmadapter = priv->adapter;
	raListTbl *ra_list = MNULL;
	int tid_down;

	ENTER();

	PRINTM(MDAT_D, "create_txbastream_tbl TID %d\n", tid);
	DBG_HEXDUMP(MDAT_D, "RA", ra, MLAN_MAC_ADDR_LENGTH);

	if (pmadapter->callbacks.
	    moal_malloc(pmadapter->pmoal_handle, sizeof(TxBAStreamTbl),
			MLAN_MEM_DEF, (t_u8 **)&new_node)) {
		PRINTM(MERROR,
		       "wlan_11n_create_txbastream_tbl Failed to allocate new_node\n");
		LEAVE();
		return;
	}
	tid_down = wlan_get_wmm_tid_down(priv, tid);
	ra_list = wlan_wmm_get_ralist_node(priv, tid_down, ra);
	if (ra_list) {
		ra_list->amsdu_in_ampdu = MFALSE;
		ra_list->ba_status = ba_status;
	}
	util_init_list((pmlan_linked_list)new_node);

	new_node->tid = tid;
	new_node->ba_status = ba_status;
	memcpy_ext(pmadapter, new_node->ra, ra, MLAN_MAC_ADDR_LENGTH,
		   MLAN_MAC_ADDR_LENGTH);

	util_enqueue_list_tail(pmadapter->pmoal_handle,
			       &priv->tx_ba_stream_tbl_ptr,
			       (pmlan_linked_list)new_node, MNULL, MNULL);

	LEAVE();
}

/**
 *  @brief This function will send a block ack to given tid/ra
 *
 *  @param priv     A pointer to mlan_private
 *  @param tid      TID to send the ADDBA
 *  @param peer_mac MAC address to send the ADDBA
 *
 *  @return         MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
int
wlan_send_addba(mlan_private *priv, int tid, t_u8 *peer_mac)
{
	HostCmd_DS_11N_ADDBA_REQ add_ba_req;
	static t_u8 dialog_tok;
	mlan_status ret;

	ENTER();

	PRINTM(MCMND, "Send addba: TID %d\n", tid);
	DBG_HEXDUMP(MCMD_D, "Send addba RA", peer_mac, MLAN_MAC_ADDR_LENGTH);

	add_ba_req.block_ack_param_set = (t_u16)((tid << BLOCKACKPARAM_TID_POS)
						 | (priv->add_ba_param.
						    tx_win_size <<
						    BLOCKACKPARAM_WINSIZE_POS) |
						 IMMEDIATE_BLOCK_ACK);
	/** enable AMSDU inside AMPDU */
	if (priv->add_ba_param.tx_amsdu &&
	    (priv->aggr_prio_tbl[tid].amsdu != BA_STREAM_NOT_ALLOWED))
		add_ba_req.block_ack_param_set |= BLOCKACKPARAM_AMSDU_SUPP_MASK;
	add_ba_req.block_ack_tmo = (t_u16)priv->add_ba_param.timeout;

	++dialog_tok;

	if (dialog_tok == 0)
		dialog_tok = 1;

	add_ba_req.dialog_token = dialog_tok;
	memcpy_ext(priv->adapter, &add_ba_req.peer_mac_addr, peer_mac,
		   MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);

	/* We don't wait for the response of this command */
	ret = wlan_prepare_cmd(priv, HostCmd_CMD_11N_ADDBA_REQ, 0, 0, MNULL,
			       &add_ba_req);

	LEAVE();
	return ret;
}

/**
 *  @brief This function will delete a block ack to given tid/ra
 *
 *  @param priv         A pointer to mlan_private
 *  @param pioctl_req   A pointer to ioctl request buffer
 *  @param tid          TID to send the ADDBA
 *  @param peer_mac     MAC address to send the ADDBA
 *  @param initiator    MTRUE if we have initiated ADDBA, MFALSE otherwise
 *
 *  @return             MLAN_STATUS_PENDING --success, otherwise fail
 */
int
wlan_send_delba(mlan_private *priv, pmlan_ioctl_req pioctl_req, int tid,
		t_u8 *peer_mac, int initiator)
{
	HostCmd_DS_11N_DELBA delba;
	mlan_status ret;

	ENTER();

	memset(priv->adapter, &delba, 0, sizeof(delba));
	delba.del_ba_param_set = (tid << DELBA_TID_POS);

	if (initiator)
		DELBA_INITIATOR(delba.del_ba_param_set);
	else
		DELBA_RECIPIENT(delba.del_ba_param_set);

	memcpy_ext(priv->adapter, &delba.peer_mac_addr, peer_mac,
		   MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);

	ret = wlan_prepare_cmd(priv, HostCmd_CMD_11N_DELBA, HostCmd_ACT_GEN_SET,
			       0, (t_void *)pioctl_req, (t_void *)&delba);

	if (ret == MLAN_STATUS_SUCCESS)
		ret = MLAN_STATUS_PENDING;

	LEAVE();
	return ret;
}

/**
 *  @brief This function handles the command response of
 *          delete a block ack request
 *
 *  @param priv		A pointer to mlan_private structure
 *  @param del_ba	A pointer to command response buffer
 *
 *  @return        N/A
 */
void
wlan_11n_delete_bastream(mlan_private *priv, t_u8 *del_ba)
{
	HostCmd_DS_11N_DELBA *pdel_ba = (HostCmd_DS_11N_DELBA *)del_ba;
	int tid;

	ENTER();

	DBG_HEXDUMP(MCMD_D, "Delba:", (t_u8 *)pdel_ba, 20);
	pdel_ba->del_ba_param_set = wlan_le16_to_cpu(pdel_ba->del_ba_param_set);
	pdel_ba->reason_code = wlan_le16_to_cpu(pdel_ba->reason_code);

	tid = pdel_ba->del_ba_param_set >> DELBA_TID_POS;

	mlan_11n_delete_bastream_tbl(priv, tid, pdel_ba->peer_mac_addr,
				     TYPE_DELBA_RECEIVE,
				     INITIATOR_BIT(pdel_ba->del_ba_param_set),
				     pdel_ba->reason_code);

	LEAVE();
}

/**
 *  @brief Get Rx reordering table
 *
 *  @param priv         A pointer to mlan_private structure
 *  @param buf          A pointer to rx_reorder_tbl structure
 *  @return             number of rx reorder table entry
 */
int
wlan_get_rxreorder_tbl(mlan_private *priv, rx_reorder_tbl *buf)
{
	int i;
	rx_reorder_tbl *ptbl = buf;
	RxReorderTbl *rx_reorder_tbl_ptr;
	int count = 0;
	ENTER();
	priv->adapter->callbacks.moal_spin_lock(priv->adapter->pmoal_handle,
						priv->rx_reorder_tbl_ptr.plock);
	rx_reorder_tbl_ptr =
		(RxReorderTbl *)util_peek_list(priv->adapter->pmoal_handle,
					       &priv->rx_reorder_tbl_ptr, MNULL,
					       MNULL);
	if (!rx_reorder_tbl_ptr) {
		priv->adapter->callbacks.moal_spin_unlock(priv->adapter->
							  pmoal_handle,
							  priv->
							  rx_reorder_tbl_ptr.
							  plock);
		LEAVE();
		return count;
	}
	while (rx_reorder_tbl_ptr != (RxReorderTbl *)&priv->rx_reorder_tbl_ptr) {
		ptbl->tid = (t_u16)rx_reorder_tbl_ptr->tid;
		memcpy_ext(priv->adapter, ptbl->ta, rx_reorder_tbl_ptr->ta,
			   MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
		ptbl->start_win = rx_reorder_tbl_ptr->start_win;
		ptbl->win_size = rx_reorder_tbl_ptr->win_size;

		ptbl->amsdu = rx_reorder_tbl_ptr->amsdu;
		for (i = 0; i < rx_reorder_tbl_ptr->win_size; ++i) {
			if (rx_reorder_tbl_ptr->rx_reorder_ptr[i])
				ptbl->buffer[i] = MTRUE;
			else
				ptbl->buffer[i] = MFALSE;
		}
		rx_reorder_tbl_ptr = rx_reorder_tbl_ptr->pnext;
		ptbl++;
		count++;
		if (count >= MLAN_MAX_RX_BASTREAM_SUPPORTED)
			break;
	}
	priv->adapter->callbacks.moal_spin_unlock(priv->adapter->pmoal_handle,
						  priv->rx_reorder_tbl_ptr.
						  plock);
	LEAVE();
	return count;
}

/**
 *  @brief Get transmit BA stream table
 *
 *  @param priv         A pointer to mlan_private structure
 *  @param buf          A pointer to tx_ba_stream_tbl structure
 *  @return             number of ba stream table entry
 */
int
wlan_get_txbastream_tbl(mlan_private *priv, tx_ba_stream_tbl *buf)
{
	TxBAStreamTbl *ptxtbl;
	tx_ba_stream_tbl *ptbl = buf;
	int count = 0;
	t_u32 bastream_max = 0;

	ENTER();

	wlan_request_ralist_lock(priv);
	ptxtbl = (TxBAStreamTbl *)util_peek_list(priv->adapter->pmoal_handle,
						 &priv->tx_ba_stream_tbl_ptr,
						 MNULL, MNULL);
	if (!ptxtbl) {
		wlan_release_ralist_lock(priv);
		LEAVE();
		return count;
	}
	bastream_max = ISSUPP_GETTXBASTREAM(priv->adapter->hw_dot_11n_dev_cap);
	if (bastream_max == 0)
		bastream_max = MLAN_MAX_TX_BASTREAM_DEFAULT;

	while (ptxtbl != (TxBAStreamTbl *)&priv->tx_ba_stream_tbl_ptr) {
		ptbl->tid = (t_u16)ptxtbl->tid;
		PRINTM(MINFO, "tid=%d\n", ptbl->tid);
		memcpy_ext(priv->adapter, ptbl->ra, ptxtbl->ra,
			   MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
		ptbl->amsdu = ptxtbl->amsdu;
		ptxtbl = ptxtbl->pnext;
		ptbl++;
		count++;
		if (count >= (int)bastream_max)
			break;
	}
	wlan_release_ralist_lock(priv);
	LEAVE();
	return count;
}

/**
 *  @brief This function check if 11AC is allowed in bandcfg
 *
 *  @param pmpriv       A pointer to mlan_private structure
 *  @param bss_band     bss band
 *
 *  @return 0--not allowed, other value allowed
 */
t_u8
wlan_11n_bandconfig_allowed(mlan_private *pmpriv, t_u8 bss_band)
{
	if (pmpriv->bss_mode == MLAN_BSS_MODE_IBSS) {
		if (bss_band & BAND_G)
			return (pmpriv->adapter->adhoc_start_band & BAND_GN);
		else if (bss_band & BAND_A)
			return (pmpriv->adapter->adhoc_start_band & BAND_AN);
	} else {
		if (bss_band & BAND_G)
			return (pmpriv->config_bands & BAND_GN);
		else if (bss_band & BAND_A)
			return (pmpriv->config_bands & BAND_AN);
	}
	return 0;
}

/**
 *  @brief This function cleans up txbastream_tbl for specific station
 *
 *  @param priv     A pointer to mlan_private
 *  @param ra       RA to find in txbastream_tbl
 *  @return         N/A
 */
void
wlan_11n_cleanup_txbastream_tbl(mlan_private *priv, t_u8 *ra)
{
	TxBAStreamTbl *ptx_tbl = MNULL;
	t_u8 i;
	ENTER();

	wlan_request_ralist_lock(priv);
	for (i = 0; i < MAX_NUM_TID; ++i) {
		ptx_tbl = wlan_11n_get_txbastream_tbl(priv, i, ra, MFALSE);
		if (ptx_tbl)
			wlan_11n_delete_txbastream_tbl_entry(priv, ptx_tbl);
	}
	wlan_release_ralist_lock(priv);
	LEAVE();
	return;
}

void
wlan_update_11n_cap(mlan_private *pmpriv)
{
	mlan_adapter *pmadapter = pmpriv->adapter;

	pmpriv->usr_dev_mcs_support = pmadapter->hw_dev_mcs_support;
	pmpriv->usr_dot_11n_dev_cap_bg =
		pmadapter->hw_dot_11n_dev_cap & DEFAULT_11N_CAP_MASK_BG;
	pmpriv->usr_dot_11n_dev_cap_a =
		pmadapter->hw_dot_11n_dev_cap & DEFAULT_11N_CAP_MASK_A;
}
