/** @file mlan_11n.c
 *
 *  @brief This file contains functions for 11n handling.
 *
 *  Copyright (C) 2008-2009, Marvell International Ltd. 
 *  All Rights Reserved
 */

/********************************************************
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"

/********************************************************
    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(IN pmlan_adapter pmadapter,
                               IN 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_SET) {
        if ((cfg->param.tx_buf_size == MLAN_TX_DATA_BUF_SIZE_2K) ||
            (cfg->param.tx_buf_size == MLAN_TX_DATA_BUF_SIZE_4K) ||
            (cfg->param.tx_buf_size == MLAN_TX_DATA_BUF_SIZE_8K)) {
            pmadapter->max_tx_buf_size = (t_u16) cfg->param.tx_buf_size;
        } else
            ret = MLAN_STATUS_FAILURE;
    } else
        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(IN pmlan_adapter pmadapter,
                        IN pmlan_ioctl_req pioctl_req)
{
    mlan_status ret = MLAN_STATUS_SUCCESS;
    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
    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 & ~IGN_HW_DEV_CAP) &
             pmpriv->adapter->hw_dot_11n_dev_cap)
            != (cfg->param.htcap_cfg & ~IGN_HW_DEV_CAP))
            ret = MLAN_STATUS_FAILURE;
        else
            pmadapter->usr_dot_11n_dev_cap = cfg->param.htcap_cfg;
        PRINTM(MINFO, "UsrDot11nCap 0x%x\n", pmadapter->usr_dot_11n_dev_cap);
    } else {
        cfg->param.htcap_cfg = pmadapter->usr_dot_11n_dev_cap;
        PRINTM(MINFO, "UsrDot11nCap 0x%x\n", cfg->param.htcap_cfg);
    }

    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_SUCCESS --success, otherwise fail
 */
static mlan_status
wlan_11n_ioctl_amsdu_aggr_ctrl(IN pmlan_adapter pmadapter,
                               IN pmlan_ioctl_req pioctl_req)
{
    mlan_status ret = MLAN_STATUS_SUCCESS;
    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
    mlan_ds_11n_cfg *cfg = MNULL;
    t_u16 cmd_action = 0;

    ENTER();

    PRINTM(MERROR, "Prepare the command\n");
    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_SUCCESS --success, otherwise fail
 */
static mlan_status
wlan_11n_ioctl_httxcfg(IN pmlan_adapter pmadapter,
                       IN pmlan_ioctl_req pioctl_req)
{
    mlan_status ret = MLAN_STATUS_SUCCESS;
    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
    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 addba parameter 
 *
 *  @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_param(IN pmlan_adapter pmadapter,
                           IN pmlan_ioctl_req pioctl_req)
{
    mlan_status ret = MLAN_STATUS_SUCCESS;
    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
    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;
    } 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;
        if (timeout != pmpriv->add_ba_param.timeout) {
            wlan_11n_update_addba_request(pmpriv);
        }
    }

    LEAVE();
    return ret;
}

/** 
 *  @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(IN pmlan_adapter pmadapter,
                            IN pmlan_ioctl_req pioctl_req)
{
    int i = 0;
    mlan_status ret = MLAN_STATUS_SUCCESS;
    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
    mlan_ds_11n_cfg *cfg = MNULL;

    ENTER();

    cfg = (mlan_ds_11n_cfg *) pioctl_req->pbuf;

    if (pioctl_req->action == MLAN_ACT_GET) {
        PRINTM(MERROR, "Addba reject MLAN\n");
        memcpy(cfg->param.addba_reject, pmpriv->addba_reject, MAX_NUM_TID);
    } else {
        if (pmpriv->media_connected == MTRUE) {
            PRINTM(MERROR, "Can not set aggr priority table in connected"
                   " state\n");
            LEAVE();
            return MLAN_STATUS_FAILURE;
        }

        for (i = 0; i < MAX_NUM_TID; i++) {
            /* For AMPDU */
            if (cfg->param.addba_reject[i] > ADDBA_RSP_STATUS_REJECT) {
                ret = MLAN_STATUS_FAILURE;
                break;
            }

            pmpriv->addba_reject[i] = cfg->param.addba_reject[i];
        }
    }

    LEAVE();
    return ret;
}

/** 
 *  @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(IN pmlan_adapter pmadapter,
                             IN pmlan_ioctl_req pioctl_req)
{
    int i = 0;
    mlan_status ret = MLAN_STATUS_SUCCESS;
    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
    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 {
        if (pmpriv->media_connected == MTRUE) {
            PRINTM(MERROR, "Can not set aggr priority table in connected"
                   " state\n");
            LEAVE();
            return MLAN_STATUS_FAILURE;
        }

        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)) {
                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)) {
                ret = MLAN_STATUS_FAILURE;
                break;
            } else {
                pmpriv->aggr_prio_tbl[i].amsdu =
                    cfg->param.aggr_prio_tbl.amsdu[i];
            }
        }
    }

    LEAVE();
    return ret;
}

/**
 *  @brief This function fills the cap info
 *
 *  @param pmadapter    A pointer to mlan_adapter structure
 *  @param pht_cap      A pointer to MrvlIETypes_HTCap_t structure
 *
 *  @return             N/A
 */
void
wlan_fill_cap_info(mlan_adapter * pmadapter, MrvlIETypes_HTCap_t * pht_cap)
{
    int rx_mcs_supp;

    ENTER();

    if (ISSUPP_CHANWIDTH40(pmadapter->hw_dot_11n_dev_cap) &&
        ISSUPP_CHANWIDTH40(pmadapter->usr_dot_11n_dev_cap))
        SETHT_SUPPCHANWIDTH(pht_cap->ht_cap.ht_cap_info);
    else
        RESETHT_SUPPCHANWIDTH(pht_cap->ht_cap.ht_cap_info);

    if (ISSUPP_GREENFIELD(pmadapter->hw_dot_11n_dev_cap) &&
        ISSUPP_GREENFIELD(pmadapter->usr_dot_11n_dev_cap))
        SETHT_GREENFIELD(pht_cap->ht_cap.ht_cap_info);
    else
        RESETHT_GREENFIELD(pht_cap->ht_cap.ht_cap_info);

    if (ISSUPP_SHORTGI20(pmadapter->hw_dot_11n_dev_cap) &&
        ISSUPP_SHORTGI20(pmadapter->usr_dot_11n_dev_cap))
        SETHT_SHORTGI20(pht_cap->ht_cap.ht_cap_info);
    else
        RESETHT_SHORTGI20(pht_cap->ht_cap.ht_cap_info);

    if (ISSUPP_SHORTGI40(pmadapter->hw_dot_11n_dev_cap) &&
        ISSUPP_SHORTGI40(pmadapter->usr_dot_11n_dev_cap))
        SETHT_SHORTGI40(pht_cap->ht_cap.ht_cap_info);
    else
        RESETHT_SHORTGI40(pht_cap->ht_cap.ht_cap_info);

    /* No user config for RX STBC yet */
    if (ISSUPP_RXSTBC(pmadapter->hw_dot_11n_dev_cap)
        && ISSUPP_RXSTBC(pmadapter->usr_dot_11n_dev_cap))
        SETHT_RXSTBC(pht_cap->ht_cap.ht_cap_info, 1);
    else
        RESETHT_RXSTBC(pht_cap->ht_cap.ht_cap_info);

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

    /* No user config for Delayed BACK yet */
    if (GET_DELAYEDBACK(pmadapter->hw_dot_11n_dev_cap))
        SETHT_DELAYEDBACK(pht_cap->ht_cap.ht_cap_info);
    else
        RESETHT_DELAYEDBACK(pht_cap->ht_cap.ht_cap_info);

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

    SETAMPDU_SIZE(pht_cap->ht_cap.ampdu_param, AMPDU_FACTOR_64K);
    SETAMPDU_SPACING(pht_cap->ht_cap.ampdu_param, 0);

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

    rx_mcs_supp = GET_RXMCSSUPP(pmadapter->hw_dev_mcs_support);
/** Maximum MCS */
#define NUM_MCS_FIELD      16

    /* Set MCS for 1x1 */
    memset((t_u8 *) pht_cap->ht_cap.supported_mcs_set, 0xff, rx_mcs_supp);
    /* Clear all the other values */
    memset((t_u8 *) & pht_cap->ht_cap.supported_mcs_set[rx_mcs_supp], 0,
           NUM_MCS_FIELD - rx_mcs_supp);
    /* Set MCS32, this is mandatory for any 11n device */
    SETHT_MCS32(pht_cap->ht_cap.supported_mcs_set);

    LEAVE();
}

/********************************************************
    Global Functions
********************************************************/
/** 
 *  @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 Delayed Block Ack streams = %d\n",
           GET_DELAYEDBACK(cap));
    PRINTM(MINFO, "GET_HW_SPEC: Number of Immediate Block Ack streams = %d\n",
           GET_IMMEDIATEBACK(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: Prescence of Rx antennea A\n");
    }
    if (ISSUPP_RXANTENNAB(cap)) {
        PRINTM(MINFO, "GET_HW_SPEC: Prescence of Rx antennea B\n");
    }
    if (ISSUPP_RXANTENNAC(cap)) {
        PRINTM(MINFO, "GET_HW_SPEC: Prescence of Rx antennea C\n");
    }
    if (ISSUPP_RXANTENNAD(cap)) {
        PRINTM(MINFO, "GET_HW_SPEC: Prescence of Rx antennea D\n");
    }
    if (ISSUPP_TXANTENNAA(cap)) {
        PRINTM(MINFO, "GET_HW_SPEC: Prescence of Tx antennea A\n");
    }
    if (ISSUPP_TXANTENNAB(cap)) {
        PRINTM(MINFO, "GET_HW_SPEC: Prescence of Tx antennea B\n");
    }
    if (ISSUPP_TXANTENNAC(cap)) {
        PRINTM(MINFO, "GET_HW_SPEC: Prescence of Tx antennea C\n");
    }
    if (ISSUPP_TXANTENNAD(cap)) {
        PRINTM(MINFO, "GET_HW_SPEC: Prescence of Tx antennea 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));

        if ((ptx_ba_tbl = wlan_11n_get_txbastream_status(priv,
                                                         BA_STREAM_SETUP_INPROGRESS)))
        {
            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_11n_create_txbastream_tbl(priv, pdel_ba->peer_mac_addr, tid,
                                           BA_STREAM_SETUP_INPROGRESS);
            if ((ptx_ba_tbl = wlan_11n_get_txbastream_status(priv,
                                                             BA_STREAM_SETUP_INPROGRESS)))
            {
                mlan_11n_delete_bastream_tbl(priv, ptx_ba_tbl->tid,
                                             ptx_ba_tbl->ra, TYPE_DELBA_SENT,
                                             MTRUE);
            }
        }
    }

    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)
{
    int tid;
    HostCmd_DS_11N_ADDBA_RSP *padd_ba_rsp =
        (HostCmd_DS_11N_ADDBA_RSP *) & resp->params.add_ba_rsp;
    TxBAStreamTbl *ptx_ba_tbl;

    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;
    if (padd_ba_rsp->status_code == BA_RESULT_SUCCESS) {
        if ((ptx_ba_tbl = wlan_11n_get_txbastream_tbl(priv, tid,
                                                      padd_ba_rsp->
                                                      peer_mac_addr))) {
            PRINTM(MINFO, "BA stream complete\n");
            ptx_ba_tbl->ba_status = BA_STREAM_SETUP_COMPLETE;
        } else {
            PRINTM(MERROR, "Stream not created!!!\n");
        }
    } else {
        mlan_11n_delete_bastream_tbl(priv, tid, padd_ba_rsp->peer_mac_addr,
                                     TYPE_DELBA_SENT, MTRUE);
        if (padd_ba_rsp->add_rsp_result != BA_RESULT_TIMEOUT) {
            priv->aggr_prio_tbl[tid].ampdu_ap = BA_STREAM_NOT_ALLOWED;
        }
    }

    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(IN pmlan_private pmpriv,
                 IN HostCmd_DS_COMMAND * resp, IN mlan_ioctl_req * pioctl_buf)
{
    mlan_ds_11n_cfg *cfg = MNULL;
    HostCmd_DS_11N_CFG *htcfg = &resp->params.htcfg;

    ENTER();
    if (pioctl_buf) {
        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);
    }
    LEAVE();
    return MLAN_STATUS_SUCCESS;
}

/** 
 *  @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);
        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(IN pmlan_private pmpriv,
                         IN HostCmd_DS_COMMAND * resp,
                         IN 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 or MLAN_STATUS_FAILURE
 */
mlan_status
wlan_cmd_11n_cfg(IN pmlan_private pmpriv,
                 IN HostCmd_DS_COMMAND * cmd,
                 IN t_u16 cmd_action, IN 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;

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

/**
 *  @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(IN mlan_private * pmpriv,
                        IN BSSDescriptor_t * pbss_desc, OUT t_u8 ** ppbuffer)
{
    MrvlIETypes_HTCap_t *pht_cap;
    MrvlIETypes_HTInfo_t *pht_info;
    MrvlIEtypes_ChanListParamSet_t *pchan_list;
    MrvlIETypes_2040BSSCo_t *p2040_bss_co;
    MrvlIETypes_ExtCap_t *pext_cap;
    int ret_len = 0;

    ENTER();

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

    if (pbss_desc->pht_cap) {
        pht_cap = (MrvlIETypes_HTCap_t *) * ppbuffer;
        memset(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((t_u8 *) pht_cap + sizeof(MrvlIEtypesHeader_t),
               (t_u8 *) pbss_desc->pht_cap + sizeof(IEEEtypes_Header_t),
               pht_cap->header.len);

        pht_cap->ht_cap.ht_cap_info =
            wlan_le16_to_cpu(pht_cap->ht_cap.ht_cap_info);
        wlan_fill_cap_info(pmpriv->adapter, pht_cap);
        pht_cap->ht_cap.ht_cap_info =
            wlan_cpu_to_le16(pht_cap->ht_cap.ht_cap_info);

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

    if (pbss_desc->pht_info) {
        pht_info = (MrvlIETypes_HTInfo_t *) * ppbuffer;
        memset(pht_info, 0, sizeof(MrvlIETypes_HTInfo_t));
        pht_info->header.type = wlan_cpu_to_le16(HT_OPERATION);
        pht_info->header.len = sizeof(HTInfo_t);

        memcpy((t_u8 *) pht_info + sizeof(MrvlIEtypesHeader_t),
               (t_u8 *) pbss_desc->pht_info + sizeof(IEEEtypes_Header_t),
               pht_info->header.len);

        if (!ISSUPP_CHANWIDTH40(pmpriv->adapter->hw_dot_11n_dev_cap) ||
            !ISSUPP_CHANWIDTH40(pmpriv->adapter->usr_dot_11n_dev_cap)) {
            RESET_CHANWIDTH40(pht_info->ht_info.field2);
        }

        *ppbuffer += sizeof(MrvlIETypes_HTInfo_t);
        ret_len += sizeof(MrvlIETypes_HTInfo_t);
        pht_info->header.len = wlan_cpu_to_le16(pht_info->header.len);

        pchan_list = (MrvlIEtypes_ChanListParamSet_t *) * ppbuffer;
        memset(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].radio_type =
            wlan_band_to_radio_type((t_u8) pbss_desc->bss_band);

        if ((ISSUPP_CHANWIDTH40(pmpriv->adapter->hw_dot_11n_dev_cap) &&
             ISSUPP_CHANWIDTH40(pmpriv->adapter->usr_dot_11n_dev_cap)) &&
            ISALLOWED_CHANWIDTH40(pbss_desc->pht_info->ht_info.field2))
            SET_SECONDARYCHAN(pchan_list->chan_scan_param[0].radio_type,
                              GET_SECONDARYCHAN(pbss_desc->pht_info->ht_info.
                                                field2));

        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(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((t_u8 *) p2040_bss_co + sizeof(MrvlIEtypesHeader_t),
               (t_u8 *) pbss_desc->pbss_co_2040 + sizeof(IEEEtypes_Header_t),
               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(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((t_u8 *) pext_cap + sizeof(MrvlIEtypesHeader_t),
               (t_u8 *) pbss_desc->pext_cap + sizeof(IEEEtypes_Header_t),
               pext_cap->header.len);

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

    LEAVE();
    return ret_len;
}

/**
 *  @brief This function reconfigure the tx buf size in firmware.
 *
 *  @param pmpriv    A pointer to mlan_private structure
 *  @param pbss_desc  BSSDescriptor_t from the scan table to assoc
 *
 *  @return          N/A
 */
void
wlan_cfg_tx_buf(mlan_private * pmpriv, BSSDescriptor_t * pbss_desc)
{
    t_u16 max_amsdu = MLAN_TX_DATA_BUF_SIZE_2K;
    t_u16 tx_buf = 0;

    ENTER();

    if (pbss_desc->pht_cap) {
        if (GETHT_MAXAMSDU(pbss_desc->pht_cap->ht_cap.ht_cap_info))
            max_amsdu = MLAN_TX_DATA_BUF_SIZE_8K;
        else
            max_amsdu = MLAN_TX_DATA_BUF_SIZE_4K;
    }

    tx_buf = MIN(pmpriv->adapter->max_tx_buf_size, max_amsdu);

    PRINTM(MINFO, "max_amsdu=%d, maxTxBuf=%d\n", max_amsdu,
           pmpriv->adapter->max_tx_buf_size);

    if (pmpriv->adapter->tx_buf_size != tx_buf) {
        wlan_prepare_cmd(pmpriv, HostCmd_CMD_RECONFIGURE_TX_BUFF,
                         HostCmd_ACT_GEN_SET, 0, MNULL, &tx_buf);
    }
    LEAVE();
    return;
}

/** 
 *  @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(IN pmlan_adapter pmadapter, IN 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);
        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_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;
    default:
        status = MLAN_STATUS_FAILURE;
        break;
    }
    LEAVE();
    return status;
}

/**
 *  @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
 */
int
wlan_is_txbastreamptr_valid(mlan_private * priv, TxBAStreamTbl * ptxtblptr)
{
    TxBAStreamTbl *ptx_tbl;

    ENTER();

    if (!
        (ptx_tbl =
         (TxBAStreamTbl *) util_peek_list(&priv->tx_ba_stream_tbl_ptr, MNULL,
                                          MNULL))) {
        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 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();

    pmadapter->callbacks.moal_spin_lock(priv->tx_ba_stream_tbl_ptr.plock);

    if (!ptx_tbl && wlan_is_txbastreamptr_valid(priv, ptx_tbl)) {
        goto exit;
    }

    PRINTM(MINFO, "tx_ba_stream_tbl_ptr %p\n", ptx_tbl);

    util_unlink_list(&priv->tx_ba_stream_tbl_ptr,
                     (pmlan_linked_list) ptx_tbl, MNULL, MNULL);

    pmadapter->callbacks.moal_mfree((t_u8 *) ptx_tbl);

  exit:
    pmadapter->callbacks.moal_spin_unlock(priv->tx_ba_stream_tbl_ptr.plock);
    LEAVE();
}

/**
 *  @brief This function will delete all the entires 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;

    ENTER();

    while ((del_tbl_ptr = (TxBAStreamTbl *)
            util_peek_list(&priv->tx_ba_stream_tbl_ptr,
                           priv->adapter->callbacks.moal_spin_lock,
                           priv->adapter->callbacks.moal_spin_unlock))) {
        wlan_11n_delete_txbastream_tbl_entry(priv, del_tbl_ptr);
    }

    util_init_list((pmlan_linked_list) & priv->tx_ba_stream_tbl_ptr);

    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 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
 */
TxBAStreamTbl *
wlan_11n_get_txbastream_status(mlan_private * priv, baStatus_e ba_status)
{
    TxBAStreamTbl *ptx_tbl;

    ENTER();

    if (!
        (ptx_tbl =
         (TxBAStreamTbl *) util_peek_list(&priv->tx_ba_stream_tbl_ptr,
                                          priv->adapter->callbacks.
                                          moal_spin_lock,
                                          priv->adapter->callbacks.
                                          moal_spin_unlock))) {
        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;
}

/**
 *  @brief This function will return the pointer to a 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
 *
 *  @return 	   A pointer to first entry matching RA/TID in BA stream
 */
TxBAStreamTbl *
wlan_11n_get_txbastream_tbl(mlan_private * priv, int tid, t_u8 * ra)
{
    TxBAStreamTbl *ptx_tbl;
    pmlan_adapter pmadapter = priv->adapter;

    ENTER();

    if (!
        (ptx_tbl =
         (TxBAStreamTbl *) util_peek_list(&priv->tx_ba_stream_tbl_ptr,
                                          pmadapter->callbacks.moal_spin_lock,
                                          pmadapter->callbacks.
                                          moal_spin_unlock))) {
        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(ptx_tbl->ra, ra, MLAN_MAC_ADDR_LENGTH))
            && (ptx_tbl->tid == tid)) {
            LEAVE();
            return ptx_tbl;
        }

        ptx_tbl = ptx_tbl->pnext;
    }

    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 *newNode;
    pmlan_adapter pmadapter = priv->adapter;

    ENTER();

    if (!wlan_11n_get_txbastream_tbl(priv, tid, ra)) {
        PRINTM(MDAT_D, "get_txbastream_tbl TID %d", tid);
        DBG_HEXDUMP(MDAT_D, "RA", ra, MLAN_MAC_ADDR_LENGTH);

        pmadapter->callbacks.moal_malloc(sizeof(TxBAStreamTbl),
                                         (t_u8 **) & newNode);
        util_init_list((pmlan_linked_list) newNode);

        newNode->tid = tid;
        newNode->ba_status = ba_status;
        memcpy(newNode->ra, ra, MLAN_MAC_ADDR_LENGTH);

        util_enqueue_list_tail(&priv->tx_ba_stream_tbl_ptr,
                               (pmlan_linked_list) newNode,
                               pmadapter->callbacks.moal_spin_lock,
                               pmadapter->callbacks.moal_spin_unlock);
    }

    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);
    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(&add_ba_req.peer_mac_addr, peer_mac, 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 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_SUCCESS or MLAN_STATUS_FAILURE
 */
int
wlan_send_delba(mlan_private * priv, int tid, t_u8 * peer_mac, int initiator)
{
    HostCmd_DS_11N_DELBA delba;
    mlan_status ret;

    ENTER();

    memset(&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(&delba.peer_mac_addr, peer_mac, MLAN_MAC_ADDR_LENGTH);

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

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

    LEAVE();
}

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

    TxBAStreamTbl *ptx_tbl;

    ENTER();

    if (!
        (ptx_tbl =
         (TxBAStreamTbl *) util_peek_list(&priv->tx_ba_stream_tbl_ptr,
                                          priv->adapter->callbacks.
                                          moal_spin_lock,
                                          priv->adapter->callbacks.
                                          moal_spin_unlock))) {
        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;
    }

    mlan_main_process(priv->adapter);
    LEAVE();
    return;
}

/** 
 *  @brief Get Rx reordering table
 *   
 *  @param priv         A pointer to mlan_private structure
 *  @param buf          A pointer to rx_reorder_tbl structure
 *  @return             num 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 *rxReorderTblPtr;
    int count = 0;
    ENTER();
    if (!
        (rxReorderTblPtr =
         (RxReorderTbl *) util_peek_list(&priv->rx_reorder_tbl_ptr,
                                         priv->adapter->callbacks.
                                         moal_spin_lock,
                                         priv->adapter->callbacks.
                                         moal_spin_unlock))) {
        LEAVE();
        return count;
    }
    while (rxReorderTblPtr != (RxReorderTbl *) & priv->rx_reorder_tbl_ptr) {
        ptbl->tid = (t_u16) rxReorderTblPtr->tid;
        memcpy(ptbl->ta, rxReorderTblPtr->ta, MLAN_MAC_ADDR_LENGTH);
        ptbl->start_win = rxReorderTblPtr->start_win;
        ptbl->win_size = rxReorderTblPtr->win_size;
        for (i = 0; i < rxReorderTblPtr->win_size; ++i) {
            if (rxReorderTblPtr->rx_reorder_ptr[i])
                ptbl->buffer[i] = MTRUE;
            else
                ptbl->buffer[i] = MFALSE;
        }
        rxReorderTblPtr = rxReorderTblPtr->pnext;
        ptbl++;
        count++;
    }
    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;

    ENTER();

    if (!(ptxtbl = (TxBAStreamTbl *) util_peek_list(&priv->tx_ba_stream_tbl_ptr,
                                                    priv->adapter->callbacks.
                                                    moal_spin_lock,
                                                    priv->adapter->callbacks.
                                                    moal_spin_unlock))) {
        LEAVE();
        return count;
    }

    while (ptxtbl != (TxBAStreamTbl *) & priv->tx_ba_stream_tbl_ptr) {
        ptbl->tid = (t_u16) ptxtbl->tid;
        PRINTM(MMSG, "tid=%d\n", ptbl->tid);
        memcpy(ptbl->ra, ptxtbl->ra, MLAN_MAC_ADDR_LENGTH);
        ptxtbl = ptxtbl->pnext;
        ptbl++;
        count++;
    }

    LEAVE();
    return count;
}
