/*
 * Copyright (c) 2011-2014, 2016, 2017 The Linux Foundation. All rights reserved.
 *
 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
 *
 *
 * Permission to use, copy, modify, and/or distribute this software for
 * any purpose with or without fee is hereby granted, provided that the
 * above copyright notice and this permission notice appear in all
 * copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

/*
 * This file was originally distributed by Qualcomm Atheros, Inc.
 * under proprietary terms before Copyright ownership was assigned
 * to the Linux Foundation.
 */

/*
 *
 * limSendMessages.c: Provides functions to send messages or Indications to HAL.
 * Author:    Sunit Bhatia
 * Date:       09/21/2006
 * History:-
 * Date        Modified by            Modification Information
 *
 * --------------------------------------------------------------------------
 *
 */
#include "limSendMessages.h"
#include "cfgApi.h"
#include "limTrace.h"
#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
#include "vos_diag_core_log.h"
#endif //FEATURE_WLAN_DIAG_SUPPORT
/* When beacon filtering is enabled, firmware will
 * analyze the selected beacons received during BMPS,
 * and monitor any changes in the IEs as listed below.
 * The format of the table is:
 *    - EID
 *    - Check for IE presence
 *    - Byte offset
 *    - Byte value
 *    - Bit Mask
 *    - Byte refrence
 */
static tBeaconFilterIe beaconFilterTable[] = {
   {SIR_MAC_DS_PARAM_SET_EID,    0, {0, 0, DS_PARAM_CHANNEL_MASK, 0}},
   {SIR_MAC_ERP_INFO_EID,        0, {0, 0, ERP_FILTER_MASK,       0}},
   {SIR_MAC_EDCA_PARAM_SET_EID,  0, {0, 0, EDCA_FILTER_MASK,      0}},
   {SIR_MAC_QOS_CAPABILITY_EID,  0, {0, 0, QOS_FILTER_MASK,       0}},
   {SIR_MAC_CHNL_SWITCH_ANN_EID, 1, {0, 0, 0,                     0}},
   {SIR_MAC_HT_INFO_EID,         0, {0, 0, HT_BYTE0_FILTER_MASK,  0}},
   {SIR_MAC_HT_INFO_EID,         0, {2, 0, HT_BYTE2_FILTER_MASK,  0}},
   {SIR_MAC_HT_INFO_EID,         0, {5, 0, HT_BYTE5_FILTER_MASK,  0}}
#if defined WLAN_FEATURE_VOWIFI
   ,{SIR_MAC_PWR_CONSTRAINT_EID,  0, {0, 0, 0, 0}}
#endif
#ifdef WLAN_FEATURE_11AC
   ,{SIR_MAC_VHT_OPMODE_EID,     0,  {0, 0, 0, 0}}
   ,{SIR_MAC_VHT_OPERATION_EID,  0,  {0, 0, VHTOP_CHWIDTH_MASK, 0}}
#endif
};

/**
 * limSendCFParams()
 *
 *FUNCTION:
 * This function is called to send CFP Parameters to WDA, when they are changed.
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 * NA
 *
 *NOTE:
 * NA
 *
 * @param pMac  pointer to Global Mac structure.
 * @param bssIdx Bss Index of the BSS to which STA is associated.
 * @param cfpCount CFP Count, if that is changed.
 * @param cfpPeriod CFP Period if that is changed.
 *
 * @return success if message send is ok, else false.
 */
tSirRetStatus limSendCFParams(tpAniSirGlobal pMac, tANI_U8 bssIdx, tANI_U8 cfpCount, tANI_U8 cfpPeriod)
{
    tpUpdateCFParams pCFParams = NULL;
    tSirRetStatus   retCode = eSIR_SUCCESS;
    tSirMsgQ msgQ;

    pCFParams = vos_mem_malloc(sizeof( tUpdateCFParams ));
    if ( NULL == pCFParams )
      {
        limLog( pMac, LOGP,
            FL( "Unable to allocate memory during Update CF Params" ));
        retCode = eSIR_MEM_ALLOC_FAILED;
        goto returnFailure;
      }
    vos_mem_set( (tANI_U8 *) pCFParams, sizeof(tUpdateCFParams), 0);
    pCFParams->cfpCount = cfpCount;
    pCFParams->cfpPeriod = cfpPeriod;
    pCFParams->bssIdx     = bssIdx;

    msgQ.type = WDA_UPDATE_CF_IND;
    msgQ.reserved = 0;
    msgQ.bodyptr = pCFParams;
    msgQ.bodyval = 0;
    limLog( pMac, LOG3,
                FL( "Sending WDA_UPDATE_CF_IND..." ));
    MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type));
    if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ )))
    {
        vos_mem_free(pCFParams);
        limLog( pMac, LOGP,
                    FL("Posting  WDA_UPDATE_CF_IND to WDA failed, reason=%X"),
                    retCode );
    }
returnFailure:
    return retCode;
}

/**
 * limSendBeaconParams()
 *
 *FUNCTION:
 * This function is called to send beacnon interval, short preamble or other
 * parameters to WDA, which are changed and indication is received in beacon.
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 * NA
 *
 *NOTE:
 * NA
 *
 * @param pMac  pointer to Global Mac structure.
 * @param tpUpdateBeaconParams pointer to the structure,
                which contains the beacon parameters which are changed.
 *
 * @return success if message send is ok, else false.
 */
tSirRetStatus limSendBeaconParams(tpAniSirGlobal pMac,
                                  tpUpdateBeaconParams pUpdatedBcnParams,
                                  tpPESession  psessionEntry )
{
    tpUpdateBeaconParams pBcnParams = NULL;
    tSirRetStatus   retCode = eSIR_SUCCESS;
    tSirMsgQ msgQ;

    pBcnParams = vos_mem_malloc(sizeof(*pBcnParams));
    if ( NULL == pBcnParams )
    {
        limLog( pMac, LOGP,
            FL( "Unable to allocate memory during Update Beacon Params" ));
        return eSIR_MEM_ALLOC_FAILED;
    }
    vos_mem_copy((tANI_U8 *) pBcnParams,  pUpdatedBcnParams, sizeof(*pBcnParams));
    msgQ.type = WDA_UPDATE_BEACON_IND;
    msgQ.reserved = 0;
    msgQ.bodyptr = pBcnParams;
    msgQ.bodyval = 0;
    PELOG3(limLog( pMac, LOG3,
                FL( "Sending WDA_UPDATE_BEACON_IND, paramChangeBitmap in hex = %x" ),
                    pUpdatedBcnParams->paramChangeBitmap);)
    if(NULL == psessionEntry)
    {
        vos_mem_free(pBcnParams);
        MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type));
        return eSIR_FAILURE;
    }
    else
    {
        MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type));
    }
    pBcnParams->smeSessionId = psessionEntry->smeSessionId;
    if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ )))
    {
        vos_mem_free(pBcnParams);
        limLog( pMac, LOGP,
                    FL("Posting  WDA_UPDATE_BEACON_IND to WDA failed, reason=%X"),
                    retCode );
    }
    limSendBeaconInd(pMac, psessionEntry);
    return retCode;
}

/**
 * limSendSwitchChnlParams()
 *
 *FUNCTION:
 * This function is called to send Channel Switch Indication to WDA
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 * NA
 *
 *NOTE:
 * NA
 *
 * @param pMac  pointer to Global Mac structure.
 * @param chnlNumber New Channel Number to be switched to.
 * @param secondaryChnlOffset  an enum for secondary channel offset.
 * @param localPowerConstraint 11h local power constraint value
 *
 * @return success if message send is ok, else false.
 */
#if !defined WLAN_FEATURE_VOWIFI
tSirRetStatus limSendSwitchChnlParams(tpAniSirGlobal pMac,
                                      tANI_U8 chnlNumber,
                                      ePhyChanBondState secondaryChnlOffset,
                                      tANI_U8 localPwrConstraint,
                                      tANI_U8 peSessionId,
                                      uint8_t is_restart)
#else
tSirRetStatus limSendSwitchChnlParams(tpAniSirGlobal pMac,
                                      tANI_U8 chnlNumber,
                                      ePhyChanBondState secondaryChnlOffset,
                                      tPowerdBm maxTxPower, tANI_U8 peSessionId,
                                      uint8_t is_restart)
#endif
{
    tpSwitchChannelParams pChnlParams = NULL;
    tSirRetStatus   retCode = eSIR_SUCCESS;
    tSirMsgQ msgQ;
    tpPESession pSessionEntry;

    if((pSessionEntry = peFindSessionBySessionId(pMac, peSessionId)) == NULL)
    {
       limLog( pMac, LOGP,
             FL( "Unable to get Session for session Id %d" ), peSessionId);
       return eSIR_FAILURE;
    }
    pChnlParams = vos_mem_malloc(sizeof( tSwitchChannelParams ));
    if ( NULL == pChnlParams )
    {
        limLog( pMac, LOGP,
            FL( "Unable to allocate memory during Switch Channel Params" ));
        retCode = eSIR_MEM_ALLOC_FAILED;
        goto returnFailure;
    }
    vos_mem_set((tANI_U8 *) pChnlParams, sizeof(tSwitchChannelParams), 0);
    pChnlParams->secondaryChannelOffset = secondaryChnlOffset;
    pChnlParams->channelNumber= chnlNumber;
    vos_mem_copy( pChnlParams->selfStaMacAddr, pSessionEntry->selfMacAddr, sizeof(tSirMacAddr) );
#if defined WLAN_FEATURE_VOWIFI
    pChnlParams->maxTxPower = maxTxPower;
#else
    pChnlParams->localPowerConstraint = localPwrConstraint;
#endif
    vos_mem_copy(  pChnlParams->bssId, pSessionEntry->bssId, sizeof(tSirMacAddr) );
    pChnlParams->peSessionId = peSessionId;
    pChnlParams->vhtCapable = pSessionEntry->vhtCapability;
    pChnlParams->dot11_mode = pSessionEntry->dot11mode;

    /*Set DFS flag for DFS channel*/
    if (vos_nv_getChannelEnabledState(chnlNumber) == NV_CHANNEL_DFS)
       pChnlParams->isDfsChannel= VOS_TRUE;
    else
       pChnlParams->isDfsChannel = VOS_FALSE;

    pChnlParams->restart_on_chan_switch = is_restart;
    pChnlParams->reduced_beacon_interval =
       pMac->sap.SapDfsInfo.reduced_beacon_interval;

    if (pSessionEntry->sub20_channelwidth == SUB20_MODE_5MHZ)
            pChnlParams->channelwidth = CH_WIDTH_5MHZ;
    else if (pSessionEntry->sub20_channelwidth == SUB20_MODE_10MHZ)
            pChnlParams->channelwidth = CH_WIDTH_10MHZ;

    if (pSessionEntry->bssType == eSIR_INFRASTRUCTURE_MODE &&
        pSessionEntry->sub20_channelwidth !=
        pMac->sta_sub20_current_channelwidth)
        sme_set_sta_chanlist_with_sub20(pMac,
                                        pSessionEntry->sub20_channelwidth);

    limLog(pMac, LOG1, FL("Set sub20 channel width %d"),
           pSessionEntry->sub20_channelwidth);

    //we need to defer the message until we get the response back from WDA.
    SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
    msgQ.type = WDA_CHNL_SWITCH_REQ;
    msgQ.reserved = 0;
    msgQ.bodyptr = pChnlParams;
    msgQ.bodyval = 0;
#if defined WLAN_FEATURE_VOWIFI
    PELOG3(limLog( pMac, LOG3,
        FL( "Sending WDA_CHNL_SWITCH_REQ with SecondaryChnOffset - %d, ChannelNumber - %d, maxTxPower - %d"),
        pChnlParams->secondaryChannelOffset, pChnlParams->channelNumber, pChnlParams->maxTxPower);)
#else
    PELOG3(limLog( pMac, LOG3,
        FL( "Sending WDA_CHNL_SWITCH_REQ with SecondaryChnOffset - %d, ChannelNumber - %d, LocalPowerConstraint - %d"),
        pChnlParams->secondaryChannelOffset, pChnlParams->channelNumber, pChnlParams->localPowerConstraint);)
#endif
    MTRACE(macTraceMsgTx(pMac, peSessionId, msgQ.type));
    limLog(pMac,LOG1,"SessionId:%d WDA_CHNL_SWITCH_REQ for SSID:%s",peSessionId,
           pSessionEntry->ssId.ssId);
    if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ )))
    {
        vos_mem_free(pChnlParams);
        limLog(pMac, LOGP,
               FL("Posting  WDA_CHNL_SWITCH_REQ to WDA failed, reason=%X"),
               retCode );
    }
returnFailure:
    return retCode;
}

/**
 * limSendEdcaParams()
 *
 *FUNCTION:
 * This function is called to send dynamically changing EDCA Parameters to WDA.
 *
 *LOGIC:
 *
 *ASSUMPTIONS:
 * NA
 *
 *NOTE:
 * NA
 *
 * @param pMac  pointer to Global Mac structure.
 * @param tpUpdatedEdcaParams pointer to the structure which contains
 *                                       dynamically changing EDCA parameters.
 * @return success if message send is ok, else false.
 */
tSirRetStatus limSendEdcaParams(tpAniSirGlobal pMac,
                                tSirMacEdcaParamRecord *pUpdatedEdcaParams,
                                tANI_U16 bssIdx)
{
    tEdcaParams *pEdcaParams = NULL;
    tSirRetStatus   retCode = eSIR_SUCCESS;
    tSirMsgQ msgQ;

    pEdcaParams = vos_mem_malloc(sizeof(tEdcaParams));
    if ( NULL == pEdcaParams )
    {
        limLog( pMac, LOGP,
            FL( "Unable to allocate memory during Update EDCA Params" ));
        retCode = eSIR_MEM_ALLOC_FAILED;
        return retCode;
    }
    pEdcaParams->bssIdx = bssIdx;
    pEdcaParams->acbe = pUpdatedEdcaParams[EDCA_AC_BE];
    pEdcaParams->acbk = pUpdatedEdcaParams[EDCA_AC_BK];
    pEdcaParams->acvi = pUpdatedEdcaParams[EDCA_AC_VI];
    pEdcaParams->acvo = pUpdatedEdcaParams[EDCA_AC_VO];
    msgQ.type = WDA_UPDATE_EDCA_PROFILE_IND;
    msgQ.reserved = 0;
    msgQ.bodyptr = pEdcaParams;
    msgQ.bodyval = 0;
    {
        tANI_U8 i;
        PELOG1(limLog( pMac, LOG1,FL("Sending WDA_UPDATE_EDCA_PROFILE_IND with EDCA Parameters:" ));)
        for(i=0; i<MAX_NUM_AC; i++)
        {
            PELOG1(limLog(pMac, LOG1, FL("AC[%d]:  AIFSN %d, ACM %d, CWmin %d, CWmax %d, TxOp %d "),
                   i, pUpdatedEdcaParams[i].aci.aifsn, pUpdatedEdcaParams[i].aci.acm,
                   pUpdatedEdcaParams[i].cw.min, pUpdatedEdcaParams[i].cw.max, pUpdatedEdcaParams[i].txoplimit);)
        }
    }
    MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type));
    if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ )))
    {
        vos_mem_free(pEdcaParams);
        limLog( pMac, LOGP,
                    FL("Posting  WDA_UPDATE_EDCA_PROFILE_IND to WDA failed, reason=%X"),
                    retCode );
    }
    return retCode;
}

/**
 * limSetActiveEdcaParams()
 *
 * FUNCTION:
 *  This function is called to set the most up-to-date EDCA parameters
 *  given the default local EDCA parameters.  The rules are as following:
 *  - If ACM bit is set for all ACs, then downgrade everything to Best Effort.
 *  - If ACM is not set for any AC, then PE will use the default EDCA
 *    parameters as advertised by AP.
 *  - If ACM is set in any of the ACs, PE will use the EDCA parameters
 *    from the next best AC for which ACM is not enabled.
 *
 * @param pMac  pointer to Global Mac structure.
 * @param plocalEdcaParams pointer to the local EDCA parameters
 * @ param psessionEntry point to the session entry
 * @return none
 */
 void limSetActiveEdcaParams(tpAniSirGlobal pMac, tSirMacEdcaParamRecord *plocalEdcaParams, tpPESession psessionEntry)
{
    tANI_U8   ac, newAc, i;
    tANI_U8   acAdmitted;
#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
    vos_log_qos_edca_pkt_type *log_ptr = NULL;
#endif //FEATURE_WLAN_DIAG_SUPPORT
    // Initialize gLimEdcaParamsActive[] to be same as localEdcaParams
    psessionEntry->gLimEdcaParamsActive[EDCA_AC_BE] = plocalEdcaParams[EDCA_AC_BE];
    psessionEntry->gLimEdcaParamsActive[EDCA_AC_BK] = plocalEdcaParams[EDCA_AC_BK];
    psessionEntry->gLimEdcaParamsActive[EDCA_AC_VI] = plocalEdcaParams[EDCA_AC_VI];
    psessionEntry->gLimEdcaParamsActive[EDCA_AC_VO] = plocalEdcaParams[EDCA_AC_VO];
    /* An AC requires downgrade if the ACM bit is set, and the AC has not
     * yet been admitted in uplink or bi-directions.
     * If an AC requires downgrade, it will downgrade to the next beset AC
     * for which ACM is not enabled.
     *
     * - There's no need to downgrade AC_BE since it IS the lowest AC. Hence
     *   start the for loop with AC_BK.
     * - If ACM bit is set for an AC, initially downgrade it to AC_BE. Then
     *   traverse thru the AC list. If we do find the next best AC which is
     *   better than AC_BE, then use that one. For example, if ACM bits are set
     *   such that: BE_ACM=1, BK_ACM=1, VI_ACM=1, VO_ACM=0
     *   then all AC will be downgraded to AC_BE.
     */
    if(!pMac->psOffloadEnabled)
    {
        limLog(pMac, LOG1, FL("adAdmitMask[UPLINK] = 0x%x "),
                           pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] );
        limLog(pMac, LOG1, FL("adAdmitMask[DOWNLINK] = 0x%x "),
                           pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] );
    }
    else
    {
        limLog(pMac, LOG1, FL("adAdmitMask[UPLINK] = 0x%x "),
                           psessionEntry->gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] );
        limLog(pMac, LOG1, FL("adAdmitMask[DOWNLINK] = 0x%x "),
                           psessionEntry->gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] );
    }
    for (ac = EDCA_AC_BK; ac <= EDCA_AC_VO; ac++)
    {
        if(!pMac->psOffloadEnabled)
        {
            acAdmitted = ( (pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] &
                           (1 << ac)) >> ac );
        }
        else
        {
            acAdmitted =
                ((psessionEntry->gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] &
                 (1 << ac)) >> ac );
        }

        limLog(pMac, LOG1, FL("For AC[%d]: acm=%d,  acAdmit=%d "), ac, plocalEdcaParams[ac].aci.acm, acAdmitted);
        if ( (plocalEdcaParams[ac].aci.acm == 1) && (acAdmitted == 0) )
        {
            limLog(pMac, LOG1, FL("We need to downgrade AC %d!! "), ac);
            newAc = EDCA_AC_BE;
            for (i=ac-1; i>0; i--)
            {
                if (plocalEdcaParams[i].aci.acm == 0)
                {
                    newAc = i;
                    break;
                }
            }
            limLog(pMac, LOGW, FL("Downgrading AC %d ---> AC %d "), ac, newAc);
            psessionEntry->gLimEdcaParamsActive[ac] = plocalEdcaParams[newAc];
        }
    }
//log: LOG_WLAN_QOS_EDCA_C
#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
    WLAN_VOS_DIAG_LOG_ALLOC(log_ptr, vos_log_qos_edca_pkt_type, LOG_WLAN_QOS_EDCA_C);
    if(log_ptr)
    {
       log_ptr->aci_be = psessionEntry->gLimEdcaParamsActive[EDCA_AC_BE].aci.aci;
       log_ptr->cw_be  = psessionEntry->gLimEdcaParamsActive[EDCA_AC_BE].cw.max << 4 |
          psessionEntry->gLimEdcaParamsActive[EDCA_AC_BE].cw.min;
       log_ptr->txoplimit_be = psessionEntry->gLimEdcaParamsActive[EDCA_AC_BE].txoplimit;
       log_ptr->aci_bk = psessionEntry->gLimEdcaParamsActive[EDCA_AC_BK].aci.aci;
       log_ptr->cw_bk  = psessionEntry->gLimEdcaParamsActive[EDCA_AC_BK].cw.max << 4 |
          psessionEntry->gLimEdcaParamsActive[EDCA_AC_BK].cw.min;
       log_ptr->txoplimit_bk = psessionEntry->gLimEdcaParamsActive[EDCA_AC_BK].txoplimit;
       log_ptr->aci_vi = psessionEntry->gLimEdcaParamsActive[EDCA_AC_VI].aci.aci;
       log_ptr->cw_vi  = psessionEntry->gLimEdcaParamsActive[EDCA_AC_VI].cw.max << 4 |
          psessionEntry->gLimEdcaParamsActive[EDCA_AC_VI].cw.min;
       log_ptr->txoplimit_vi = psessionEntry->gLimEdcaParamsActive[EDCA_AC_VI].txoplimit;
       log_ptr->aci_vo = psessionEntry->gLimEdcaParamsActive[EDCA_AC_VO].aci.aci;
       log_ptr->cw_vo  = psessionEntry->gLimEdcaParamsActive[EDCA_AC_VO].cw.max << 4 |
          psessionEntry->gLimEdcaParamsActive[EDCA_AC_VO].cw.min;
       log_ptr->txoplimit_vo = psessionEntry->gLimEdcaParamsActive[EDCA_AC_VO].txoplimit;
    }
    WLAN_VOS_DIAG_LOG_REPORT(log_ptr);
#endif //FEATURE_WLAN_DIAG_SUPPORT

    return;
 }

/** ---------------------------------------------------------
\fn      limSetLinkState
\brief   LIM sends a message to WDA to set the link state
\param   tpAniSirGlobal  pMac
\param   tSirLinkState      state
\return  None
  -----------------------------------------------------------*/
tSirRetStatus limSetLinkState(tpAniSirGlobal pMac, tSirLinkState state,tSirMacAddr bssId,
                              tSirMacAddr selfMacAddr, tpSetLinkStateCallback callback,
                              void *callbackArg)
{
    tSirMsgQ msgQ;
    tSirRetStatus retCode;
    tpLinkStateParams pLinkStateParams = NULL;
    // Allocate memory.
    pLinkStateParams = vos_mem_malloc(sizeof(tLinkStateParams));
    if ( NULL == pLinkStateParams )
    {
        limLog( pMac, LOGP,
        FL( "Unable to allocate memory while sending Set Link State" ));
        retCode = eSIR_SME_RESOURCES_UNAVAILABLE;
        return retCode;
    }
    vos_mem_set((tANI_U8 *) pLinkStateParams, sizeof(tLinkStateParams), 0);
    pLinkStateParams->state        = state;
    pLinkStateParams->callback     = callback;
    pLinkStateParams->callbackArg  = callbackArg;

    /* Copy Mac address */
    sirCopyMacAddr(pLinkStateParams->bssid,bssId);
    sirCopyMacAddr(pLinkStateParams->selfMacAddr, selfMacAddr);

    msgQ.type = WDA_SET_LINK_STATE;
    msgQ.reserved = 0;
    msgQ.bodyptr = pLinkStateParams;
    msgQ.bodyval = 0;

    MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type));

    retCode = (tANI_U32)wdaPostCtrlMsg(pMac, &msgQ);
    if (retCode != eSIR_SUCCESS)
    {
        vos_mem_free(pLinkStateParams);
        limLog(pMac, LOGP, FL("Posting link state %d failed, reason = %x "),
               state, retCode);
    }
    return retCode;
}
#ifdef WLAN_FEATURE_VOWIFI_11R
extern tSirRetStatus limSetLinkStateFT(tpAniSirGlobal pMac, tSirLinkState
state,tSirMacAddr bssId, tSirMacAddr selfMacAddr, int ft, tpPESession psessionEntry)
{
    tSirMsgQ msgQ;
    tSirRetStatus retCode;
    tpLinkStateParams pLinkStateParams = NULL;
    // Allocate memory.
    pLinkStateParams = vos_mem_malloc(sizeof(tLinkStateParams));
    if ( NULL == pLinkStateParams )
    {
        limLog( pMac, LOGP,
        FL( "Unable to allocate memory while sending Set Link State" ));
        retCode = eSIR_SME_RESOURCES_UNAVAILABLE;
        return retCode;
    }
    vos_mem_set((tANI_U8 *) pLinkStateParams, sizeof(tLinkStateParams), 0);
    pLinkStateParams->state = state;
    /* Copy Mac address */
    sirCopyMacAddr(pLinkStateParams->bssid,bssId);
    sirCopyMacAddr(pLinkStateParams->selfMacAddr, selfMacAddr);
    pLinkStateParams->ft = 1;
    pLinkStateParams->session = psessionEntry;

    msgQ.type = WDA_SET_LINK_STATE;
    msgQ.reserved = 0;
    msgQ.bodyptr = pLinkStateParams;
    msgQ.bodyval = 0;
    if(NULL == psessionEntry)
    {
        MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type));
    }
    else
    {
        MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type));
    }

    retCode = (tANI_U32)wdaPostCtrlMsg(pMac, &msgQ);
    if (retCode != eSIR_SUCCESS)
    {
        vos_mem_free(pLinkStateParams);
        limLog(pMac, LOGP, FL("Posting link state %d failed, reason = %x "),
               state, retCode);
    }
    return retCode;
}
#endif

/** ---------------------------------------------------------
\fn      limSendSetTxPowerReq
\brief   LIM sends a WDA_SET_TX_POWER_REQ message to WDA
\param   tpAniSirGlobal      pMac
\param   tpSirSetTxPowerReq  request message
\return  None
  -----------------------------------------------------------*/
tSirRetStatus limSendSetTxPowerReq(tpAniSirGlobal pMac,  tANI_U32 *pMsgBuf)
{
    tSirSetTxPowerReq   *txPowerReq;
    tSirRetStatus        retCode = eSIR_SUCCESS;
    tSirMsgQ             msgQ;
    tpPESession          psessionEntry;
    tANI_U8              sessionId = 0;

    if (NULL == pMsgBuf)
        return eSIR_FAILURE;

    txPowerReq = vos_mem_malloc(sizeof(tSirSetTxPowerReq));
    if ( NULL == txPowerReq )
    {
        return eSIR_FAILURE;
    }
    vos_mem_copy(txPowerReq, (tSirSetTxPowerReq *)pMsgBuf, sizeof(tSirSetTxPowerReq));

    /* Found corresponding seesion to find BSS IDX */
    psessionEntry = peFindSessionByBssid(pMac, txPowerReq->bssId, &sessionId);
    if (NULL == psessionEntry)
    {
        vos_mem_free(txPowerReq);
        limLog(pMac, LOGE, FL("Session does not exist for given BSSID"));
        return eSIR_FAILURE;
    }

    /* FW API requests BSS IDX */
    txPowerReq->bssIdx = psessionEntry->bssIdx;

    msgQ.type = WDA_SET_TX_POWER_REQ;
    msgQ.reserved = 0;
    msgQ.bodyptr = txPowerReq;
    msgQ.bodyval = 0;
    PELOGW(limLog(pMac, LOGW, FL("Sending WDA_SET_TX_POWER_REQ to WDA"));)
    MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type));
    retCode = wdaPostCtrlMsg(pMac, &msgQ);
    if (eSIR_SUCCESS != retCode)
    {
        limLog(pMac, LOGP, FL("Posting WDA_SET_TX_POWER_REQ to WDA failed, reason=%X"), retCode);
        vos_mem_free(txPowerReq);
        return retCode;
    }

    return retCode;
}
/** ---------------------------------------------------------
\fn      limSendGetTxPowerReq
\brief   LIM sends a WDA_GET_TX_POWER_REQ message to WDA
\param   tpAniSirGlobal      pMac
\param   tpSirGetTxPowerReq  request message
\return  None
  -----------------------------------------------------------*/
tSirRetStatus limSendGetTxPowerReq(tpAniSirGlobal pMac,  tpSirGetTxPowerReq pTxPowerReq)
{
    tSirRetStatus  retCode = eSIR_SUCCESS;
    tSirMsgQ       msgQ;
    if (NULL == pTxPowerReq)
        return retCode;
    msgQ.type = WDA_GET_TX_POWER_REQ;
    msgQ.reserved = 0;
    msgQ.bodyptr = pTxPowerReq;
    msgQ.bodyval = 0;
    PELOGW(limLog(pMac, LOGW, FL( "Sending WDA_GET_TX_POWER_REQ to WDA"));)
    MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type));
    if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ )))
    {
        limLog( pMac, LOGP, FL("Posting WDA_GET_TX_POWER_REQ to WDA failed, reason=%X"), retCode );
        if (NULL != pTxPowerReq)
        {
            vos_mem_free(pTxPowerReq);
        }
        return retCode;
    }
    return retCode;
}
/** ---------------------------------------------------------
\fn      limSendBeaconFilterInfo
\brief   LIM sends beacon filtering info to WDA
\param   tpAniSirGlobal  pMac
\return  None
  -----------------------------------------------------------*/
tSirRetStatus limSendBeaconFilterInfo(tpAniSirGlobal pMac,tpPESession psessionEntry)
{
    tpBeaconFilterMsg  pBeaconFilterMsg = NULL;
    tSirRetStatus      retCode = eSIR_SUCCESS;
    tSirMsgQ           msgQ;
    tANI_U8            *ptr;
    tANI_U32           i;
    tANI_U32           msgSize;
    tpBeaconFilterIe   pIe;

    if( psessionEntry == NULL )
    {
        limLog( pMac, LOGE, FL("Fail to find the right session "));
        retCode = eSIR_FAILURE;
        return retCode;
    }
    msgSize = sizeof(tBeaconFilterMsg) + sizeof(beaconFilterTable);
    pBeaconFilterMsg = vos_mem_malloc(msgSize);
    if ( NULL == pBeaconFilterMsg )
    {
        limLog( pMac, LOGP, FL("Fail to allocate memory for beaconFiilterMsg "));
        retCode = eSIR_MEM_ALLOC_FAILED;
        return retCode;
    }
    vos_mem_set((tANI_U8 *) pBeaconFilterMsg, msgSize, 0);
    // Fill in capability Info and mask
    //Don't send this message if no active Infra session is found.
    pBeaconFilterMsg->capabilityInfo = psessionEntry->limCurrentBssCaps;
    pBeaconFilterMsg->capabilityMask = CAPABILITY_FILTER_MASK;
    pBeaconFilterMsg->beaconInterval = (tANI_U16) psessionEntry->beaconParams.beaconInterval;
    // Fill in number of IEs in beaconFilterTable
    pBeaconFilterMsg->ieNum = (tANI_U16) (sizeof(beaconFilterTable) / sizeof(tBeaconFilterIe));
    //Fill the BSSIDX
    pBeaconFilterMsg->bssIdx = psessionEntry->bssIdx;

    //Fill message with info contained in the beaconFilterTable
    ptr = (tANI_U8 *)pBeaconFilterMsg + sizeof(tBeaconFilterMsg);
    for(i=0; i < (pBeaconFilterMsg->ieNum); i++)
    {
        pIe = (tpBeaconFilterIe) ptr;
        pIe->elementId = beaconFilterTable[i].elementId;
        pIe->checkIePresence = beaconFilterTable[i].checkIePresence;
        pIe->byte.offset = beaconFilterTable[i].byte.offset;
        pIe->byte.value =  beaconFilterTable[i].byte.value;
        pIe->byte.bitMask =  beaconFilterTable[i].byte.bitMask;
        pIe->byte.ref =  beaconFilterTable[i].byte.ref;
        ptr += sizeof(tBeaconFilterIe);
    }
    msgQ.type = WDA_BEACON_FILTER_IND;
    msgQ.reserved = 0;
    msgQ.bodyptr = pBeaconFilterMsg;
    msgQ.bodyval = 0;
    limLog( pMac, LOG3, FL( "Sending WDA_BEACON_FILTER_IND..." ));
    MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type));
    if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ )))
    {
        vos_mem_free(pBeaconFilterMsg);
        limLog( pMac, LOGP,
            FL("Posting  WDA_BEACON_FILTER_IND to WDA failed, reason=%X"),
            retCode );
        return retCode;
    }
    return retCode;
}

#ifdef WLAN_FEATURE_11AC
tSirRetStatus limSendModeUpdate(tpAniSirGlobal pMac,
                                tUpdateVHTOpMode *pTempParam,
                                tpPESession  psessionEntry )
{
    tUpdateVHTOpMode *pVhtOpMode = NULL;
    tSirRetStatus   retCode = eSIR_SUCCESS;
    tSirMsgQ msgQ;

    pVhtOpMode = vos_mem_malloc(sizeof(tUpdateVHTOpMode));
    if ( NULL == pVhtOpMode )
    {
        limLog( pMac, LOGP,
            FL( "Unable to allocate memory during Update Op Mode" ));
        return eSIR_MEM_ALLOC_FAILED;
    }
    vos_mem_copy((tANI_U8 *)pVhtOpMode, pTempParam, sizeof(tUpdateVHTOpMode));
    msgQ.type =  WDA_UPDATE_OP_MODE;
    msgQ.reserved = 0;
    msgQ.bodyptr = pVhtOpMode;
    msgQ.bodyval = 0;
    limLog(pMac, LOG3, FL(
                "Sending WDA_UPDATE_OP_MODE, opMode - %d, staId - %d"),
                    pVhtOpMode->opMode, pVhtOpMode->staId);
    if(NULL == psessionEntry)
    {
        MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type));
    }
    else
    {
        MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type));
    }
    if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ )))
    {
        vos_mem_free(pVhtOpMode);
        limLog( pMac, LOGP,
                    FL("Posting  WDA_UPDATE_OP_MODE to WDA failed, reason=%X"),
                    retCode );
    }

    return retCode;
}

tSirRetStatus limSendRxNssUpdate(tpAniSirGlobal pMac,
                                tUpdateRxNss *pTempParam,
                                tpPESession  psessionEntry )
{
    tUpdateRxNss *pRxNss = NULL;
    tSirRetStatus   retCode = eSIR_SUCCESS;
    tSirMsgQ msgQ;

    pRxNss = vos_mem_malloc(sizeof(tUpdateRxNss));
    if ( NULL == pRxNss )
    {
        limLog( pMac, LOGP,
            FL( "Unable to allocate memory during Update Rx Nss" ));
        return eSIR_MEM_ALLOC_FAILED;
    }
    vos_mem_copy((tANI_U8 *)pRxNss, pTempParam, sizeof(tUpdateRxNss));
    msgQ.type =  WDA_UPDATE_RX_NSS;
    msgQ.reserved = 0;
    msgQ.bodyptr = pRxNss;
    msgQ.bodyval = 0;
    PELOG3(limLog( pMac, LOG3,
                FL( "Sending WDA_UPDATE_RX_NSS" ));)
    if(NULL == psessionEntry)
    {
        MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type));
    }
    else
    {
        MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type));
    }
    if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ )))
    {
        vos_mem_free(pRxNss);
        limLog( pMac, LOGP,
                    FL("Posting WDA_UPDATE_RX_NSS to WDA failed, reason=%X"),
                    retCode );
    }

    return retCode;
}

tSirRetStatus limSetMembership(tpAniSirGlobal pMac,
                                tUpdateMembership *pTempParam,
                                tpPESession  psessionEntry )
{
    tUpdateMembership *pMembership = NULL;
    tSirRetStatus   retCode = eSIR_SUCCESS;
    tSirMsgQ msgQ;

    pMembership = vos_mem_malloc(sizeof(tUpdateMembership));
    if ( NULL == pMembership )
    {
        limLog( pMac, LOGP,
            FL( "Unable to allocate memory during Update Membership Mode" ));
        return eSIR_MEM_ALLOC_FAILED;
    }
    vos_mem_copy((tANI_U8 *)pMembership, pTempParam, sizeof(tUpdateMembership));

    msgQ.type =  WDA_UPDATE_MEMBERSHIP;
    msgQ.reserved = 0;
    msgQ.bodyptr = pMembership;
    msgQ.bodyval = 0;
    PELOG3(limLog( pMac, LOG3,
                FL( "Sending WDA_UPDATE_MEMBERSHIP" ));)
    if(NULL == psessionEntry)
    {
        MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type));
    }
    else
    {
        MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type));
    }
    if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ )))
    {
        vos_mem_free(pMembership);
        limLog( pMac, LOGP,
                    FL("Posting  WDA_UPDATE_MEMBERSHIP to WDA failed, reason=%X"),
                    retCode );
    }

    return retCode;
}

tSirRetStatus limSetUserPos(tpAniSirGlobal pMac,
                                tUpdateUserPos *pTempParam,
                                tpPESession  psessionEntry )
{
    tUpdateUserPos *pUserPos = NULL;
    tSirRetStatus   retCode = eSIR_SUCCESS;
    tSirMsgQ msgQ;

    pUserPos = vos_mem_malloc(sizeof(tUpdateUserPos));
    if ( NULL == pUserPos )
    {
        limLog( pMac, LOGP,
            FL( "Unable to allocate memory during Update User Position" ));
        return eSIR_MEM_ALLOC_FAILED;
    }
    vos_mem_copy((tANI_U8 *)pUserPos, pTempParam, sizeof(tUpdateUserPos));

    msgQ.type =  WDA_UPDATE_USERPOS;
    msgQ.reserved = 0;
    msgQ.bodyptr = pUserPos;
    msgQ.bodyval = 0;
    PELOG3(limLog( pMac, LOG3,
                FL( "Sending WDA_UPDATE_USERPOS" ));)
    if(NULL == psessionEntry)
    {
        MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type));
    }
    else
    {
        MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type));
    }
    if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ )))
    {
        vos_mem_free(pUserPos);
        limLog( pMac, LOGP,
                    FL("Posting  WDA_UPDATE_USERPOS to WDA failed, reason=%X"),
                    retCode );
    }

    return retCode;
}

#endif


#ifdef WLAN_FEATURE_11W
/** ---------------------------------------------------------
\fn      limSendExcludeUnencryptInd
\brief   LIM sends a message to HAL to indicate whether to
         ignore or indicate the unprotected packet error
\param   tpAniSirGlobal  pMac
\param   tANI_BOOLEAN excludeUnenc - true: ignore, false:
         indicate
\param   tpPESession  psessionEntry - session context
\return  status
  -----------------------------------------------------------*/
tSirRetStatus limSendExcludeUnencryptInd(tpAniSirGlobal pMac,
                                         tANI_BOOLEAN excludeUnenc,
                                         tpPESession  psessionEntry)
{
    tSirRetStatus   retCode = eSIR_SUCCESS;
    tSirMsgQ msgQ;
    tSirWlanExcludeUnencryptParam * pExcludeUnencryptParam;

    pExcludeUnencryptParam = vos_mem_malloc(sizeof(tSirWlanExcludeUnencryptParam));
    if ( NULL == pExcludeUnencryptParam )
    {
        limLog(pMac, LOGP,
            FL( "Unable to allocate memory during limSendExcludeUnencryptInd"));
        return eSIR_MEM_ALLOC_FAILED;
    }

    pExcludeUnencryptParam->excludeUnencrypt = excludeUnenc;
    sirCopyMacAddr(pExcludeUnencryptParam->bssId, psessionEntry->bssId);

    msgQ.type =  WDA_EXCLUDE_UNENCRYPTED_IND;
    msgQ.reserved = 0;
    msgQ.bodyptr = pExcludeUnencryptParam;
    msgQ.bodyval = 0;
    PELOG3(limLog(pMac, LOG3,
                FL("Sending WDA_EXCLUDE_UNENCRYPTED_IND"));)
    MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type));
    retCode = wdaPostCtrlMsg(pMac, &msgQ);
    if (eSIR_SUCCESS != retCode)
    {
        vos_mem_free(pExcludeUnencryptParam);
        limLog(pMac, LOGP,
               FL("Posting  WDA_EXCLUDE_UNENCRYPTED_IND to WDA failed, reason=%X"),
               retCode);
    }

    return retCode;
}
#endif
