/*
 * Copyright (c) 2011-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}}, //primary channel
   {SIR_MAC_HT_INFO_EID,         0, {1, 0, HT_BYTE1_FILTER_MASK,  0}}, //Secondary Channel
   {SIR_MAC_HT_INFO_EID,         0, {2, 0, HT_BYTE2_FILTER_MASK,  0}}, //HT  protection
   {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
   ,{SIR_MAC_RSN_EID,             1, {0, 0, 0,                    0}}
   ,{SIR_MAC_WPA_EID,             1, {0, 0, 0,                    0}}
};

/**
 * 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)
    {
        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(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)
#else
tSirRetStatus limSendSwitchChnlParams(tpAniSirGlobal pMac,
                                      tANI_U8 chnlNumber,
                                      ePhyChanBondState secondaryChnlOffset,
                                      tPowerdBm maxTxPower, tANI_U8 peSessionId)
#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;
#if defined WLAN_FEATURE_VOWIFI  
    pChnlParams->maxTxPower = maxTxPower;
    vos_mem_copy( pChnlParams->selfStaMacAddr, pSessionEntry->selfMacAddr, sizeof(tSirMacAddr) );
#else
    pChnlParams->localPowerConstraint = localPwrConstraint;
#endif
    vos_mem_copy(  pChnlParams->bssId, pSessionEntry->bssId, sizeof(tSirMacAddr) );
    pChnlParams->peSessionId = peSessionId;

    if (LIM_SWITCH_CHANNEL_CSA == pSessionEntry->channelChangeCSA )
    {
        pChnlParams->channelSwitchSrc =  eHAL_CHANNEL_SWITCH_SOURCE_CSA;
        pSessionEntry->channelChangeCSA = 0;
    }
    //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  
    limLog( pMac, LOG1,
        FL( "Sending WDA_CHNL_SWITCH_REQ with SecondaryChnOffset - %d,"
        " ChannelNumber - %d, maxTxPower - %d"),
        pChnlParams->secondaryChannelOffset, pChnlParams->channelNumber,
                                                pChnlParams->maxTxPower);
#else
    limLog( pMac, LOG1,
        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.
 * @param highPerformance  If the peer is Airgo (taurus) then switch to highPerformance is true.
 *
 * @return success if message send is ok, else false.
 */
tSirRetStatus limSendEdcaParams(tpAniSirGlobal pMac, tSirMacEdcaParamRecord *pUpdatedEdcaParams, tANI_U16 bssIdx, tANI_BOOLEAN highPerformance)
{
    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];
    pEdcaParams->highPerformance = highPerformance;
    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.
     */
    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] );
    for (ac = EDCA_AC_BK; ac <= EDCA_AC_VO; ac++)
    {
        acAdmitted = ( (pMac->lim.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
  -----------------------------------------------------------*/
 //Original code with out anu's change
#if 0
tSirRetStatus limSetLinkState(tpAniSirGlobal pMac, tSirLinkState state,tSirMacAddr bssId)
{
    tSirMsgQ msg;
    tSirRetStatus retCode;
    msg.type = WDA_SET_LINK_STATE;
    msg.bodyval = (tANI_U32) state;
    msg.bodyptr = NULL;
    MTRACE(macTraceMsgTx(pMac, 0, msg.type));
    retCode = wdaPostCtrlMsg(pMac, &msg);
    if (retCode != eSIR_SUCCESS)
        limLog(pMac, LOGP, FL("Posting link state %d failed, reason = %x "), retCode);
    return retCode;
}
#endif //0
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      limSendHT40OBSSScanInd
\brief   LIM sends a WDA_HT40_OBSS_SCAN_IND message to WDA
\param   tpAniSirGlobal      pMac
\param   psessionEntry  session Entry
\return  None
  -----------------------------------------------------------*/
tSirRetStatus limSendHT40OBSSScanInd(tpAniSirGlobal pMac,
                                               tpPESession psessionEntry)
{
    tSirRetStatus           retCode = eSIR_SUCCESS;
    tSirHT40OBSSScanInd    *ht40OBSSScanInd;
    tANI_U32                validChannelNum;
    tSirMsgQ             msgQ;
    tANI_U8              validChanList[WNI_CFG_VALID_CHANNEL_LIST_LEN];
    tANI_U8              channel24GNum, count;

    ht40OBSSScanInd = vos_mem_malloc(sizeof(tSirHT40OBSSScanInd));
    if ( NULL == ht40OBSSScanInd)
    {
        return eSIR_FAILURE;
    }

    VOS_TRACE(VOS_MODULE_ID_PE,VOS_TRACE_LEVEL_INFO,
             "OBSS Scan Indication bssIdx- %d staId %d",
             psessionEntry->bssIdx, psessionEntry->staId);

    ht40OBSSScanInd->cmdType = HT40_OBSS_SCAN_PARAM_START;
    ht40OBSSScanInd->scanType = eSIR_ACTIVE_SCAN;
    ht40OBSSScanInd->OBSSScanPassiveDwellTime =
           psessionEntry->obssHT40ScanParam.OBSSScanPassiveDwellTime;
    ht40OBSSScanInd->OBSSScanActiveDwellTime =
           psessionEntry->obssHT40ScanParam.OBSSScanActiveDwellTime;
    ht40OBSSScanInd->BSSChannelWidthTriggerScanInterval =
           psessionEntry->obssHT40ScanParam.BSSChannelWidthTriggerScanInterval;
    ht40OBSSScanInd->OBSSScanPassiveTotalPerChannel =
           psessionEntry->obssHT40ScanParam.OBSSScanPassiveTotalPerChannel;
    ht40OBSSScanInd->OBSSScanActiveTotalPerChannel =
           psessionEntry->obssHT40ScanParam.OBSSScanActiveTotalPerChannel;
    ht40OBSSScanInd->BSSWidthChannelTransitionDelayFactor =
           psessionEntry->obssHT40ScanParam.BSSWidthChannelTransitionDelayFactor;
    ht40OBSSScanInd->OBSSScanActivityThreshold =
           psessionEntry->obssHT40ScanParam.OBSSScanActivityThreshold;
    /* TODO update it from the associated BSS*/
    ht40OBSSScanInd->currentOperatingClass = 81;

    validChannelNum = WNI_CFG_VALID_CHANNEL_LIST_LEN;
    if (wlan_cfgGetStr(pMac, WNI_CFG_VALID_CHANNEL_LIST,
                          validChanList,
                          &validChannelNum) != eSIR_SUCCESS)
    {
        limLog(pMac, LOGE,
                   FL("could not retrieve Valid channel list"));
        vos_mem_free(ht40OBSSScanInd);
        return eSIR_FAILURE;
    }
    /* Extract 24G channel list */
    channel24GNum = 0;
    for( count =0 ;count < validChannelNum &&
                   (channel24GNum < SIR_ROAM_MAX_CHANNELS);count++)
    {
       if ((validChanList[count]> RF_CHAN_1) &&
           (validChanList[count] < RF_CHAN_14))
       {
          ht40OBSSScanInd->channels[channel24GNum] = validChanList[count];
          channel24GNum++;
       }
    }
    ht40OBSSScanInd->channelCount = channel24GNum;
    /* FW API requests BSS IDX */
    ht40OBSSScanInd->selfStaIdx = psessionEntry->staId;
    ht40OBSSScanInd->bssIdx = psessionEntry->bssIdx;
    ht40OBSSScanInd->fortyMHZIntolerent = 0;
    ht40OBSSScanInd->ieFieldLen = 0;

    msgQ.type = WDA_HT40_OBSS_SCAN_IND;
    msgQ.reserved = 0;
    msgQ.bodyptr = (void *)ht40OBSSScanInd;
    msgQ.bodyval = 0;
    limLog(pMac, LOG1, FL("Sending WDA_HT40_OBSS_SCAN_IND to WDA"
           "Obss Scan trigger width = %d, delay factor = %d"),
           ht40OBSSScanInd->BSSChannelWidthTriggerScanInterval,
            ht40OBSSScanInd->BSSWidthChannelTransitionDelayFactor);
    MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type));
    retCode = wdaPostCtrlMsg(pMac, &msgQ);
    if (eSIR_SUCCESS != retCode)
    {
        limLog(pMac, LOGP, FL("Posting WDA_HT40_OBSS_SCAN_IND "
                              "to WDA failed, reason=%X"), retCode);
        vos_mem_free(ht40OBSSScanInd);
        return retCode;
    }
    return retCode;
}
/** ---------------------------------------------------------
\fn      limSendHT40OBSSScanInd
\brief   LIM sends a WDA_HT40_OBSS_SCAN_IND message to WDA
\         Stop command support is only for debugging
\         As per 802.11 spec OBSS scan is mandatory while
\         operating in HT40 on 2.4GHz band
\param   tpAniSirGlobal      pMac
\param   psessionEntry  Session entry
\return  None
  -----------------------------------------------------------*/
tSirRetStatus limSendHT40OBSSStopScanInd(tpAniSirGlobal pMac,
                                               tpPESession psessionEntry)
{
    tSirRetStatus        retCode = eSIR_SUCCESS;
    tSirMsgQ             msgQ;
    tANI_U8              bssIdx;

    bssIdx = psessionEntry->bssIdx;

    VOS_TRACE (VOS_MODULE_ID_PE,VOS_TRACE_LEVEL_INFO,
               " Sending STOP OBSS cmd, bssid %d staid %d ",
               psessionEntry->bssIdx, psessionEntry->staId);

    msgQ.type = WDA_HT40_OBSS_STOP_SCAN_IND;
    msgQ.reserved = 0;
    msgQ.bodyptr = (void *)&bssIdx;
    msgQ.bodyval = 0;
    PELOGW(limLog(pMac, LOGW,
         FL("Sending WDA_HT40_OBSS_STOP_SCAN_IND to WDA"));)
    MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type));
    retCode = wdaPostCtrlMsg(pMac, &msgQ);
    if (eSIR_SUCCESS != retCode)
    {
        limLog(pMac, LOGE, FL("Posting WDA_HT40_OBSS_SCAN_IND "
                              "to WDA failed, reason=%X"), retCode);
        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;
    tANI_BOOLEAN       ignore_secchannel_bcn_filter = false;
    bool filter_skipped = false;
    tpBeaconFilterIe   pIe;
    tpDphHashNode      pStaDs;

    if( psessionEntry == NULL )
    {
        limLog( pMac, LOGE, FL("Fail to find the right session "));
        retCode = eSIR_FAILURE;
        return retCode;
    }
    /*
     * Dont send the WPA and RSN iE in filter if FW doesnt support
     * IS_FEATURE_BCN_FLT_DELTA_ENABLE,
     * else host will get all beacons which have RSN IE or WPA IE
     */
    if(IS_FEATURE_BCN_FLT_DELTA_ENABLE)
        msgSize = sizeof(tBeaconFilterMsg) + sizeof(beaconFilterTable);
    else
        msgSize = sizeof(tBeaconFilterMsg) + sizeof(beaconFilterTable) - (2 * sizeof(tBeaconFilterIe));

    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
    //TBD-RAJESH get the BSS capability from session.
    //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
    /*
     * Dont send the WPA and RSN iE in filter if FW doesnt support
     * IS_FEATURE_BCN_FLT_DELTA_ENABLE,
     * else host will get all beacons which have RSN IE or WPA IE
     */
    if(IS_FEATURE_BCN_FLT_DELTA_ENABLE)
        pBeaconFilterMsg->ieNum = (tANI_U16) (sizeof(beaconFilterTable) / sizeof(tBeaconFilterIe));
    else
        pBeaconFilterMsg->ieNum = (tANI_U16) ((sizeof(beaconFilterTable) / sizeof(tBeaconFilterIe)) - 2);

    //Fill the BSSIDX
    pBeaconFilterMsg->bssIdx = psessionEntry->bssIdx;

    pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER,
                            &psessionEntry->dph.dphHashTable);
    if((psessionEntry->currentOperChannel <= RF_CHAN_14) &&
       ((psessionEntry->htSupportedChannelWidthSet ==
                                eHT_CHANNEL_WIDTH_20MHZ) ||
        (pStaDs != NULL && (pStaDs->htSupportedChannelWidthSet ==
                                eHT_CHANNEL_WIDTH_20MHZ))))
    {
        ignore_secchannel_bcn_filter = true;
    }

    //Fill message with info contained in the beaconFilterTable
    ptr = (tANI_U8 *)pBeaconFilterMsg + sizeof(tBeaconFilterMsg);
    for(i=0; i < (pBeaconFilterMsg->ieNum); i++)
    {
        /*
        *Interoperability workaround:  TP-LINK TL-WDR6300
        *The value of Secondary Channel Offset in HT Operation element
        *of beacon frame switching between 1 and 0, which causes dut(sta)
        *to wake up frequently.
        */
        if((ignore_secchannel_bcn_filter == true) &&
           (beaconFilterTable[i].elementId == SIR_MAC_HT_INFO_EID) &&
           (beaconFilterTable[i].byte.offset == 1) &&
           (beaconFilterTable[i].byte.bitMask == HT_BYTE1_FILTER_MASK))
        {
            limLog( pMac, LOGW,
                FL("Skip Secondary Channel bcn filter when channel is 20Mhz"));
            filter_skipped = true;
            continue;
        }
        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);
    }
    if (filter_skipped)
       pBeaconFilterMsg->ieNum--;

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

/**
 * \brief Send CB mode update to WDA
 *
 * \param pMac Pointer to the global MAC structure
 *
 * \param psessionEntry          session entry
 *          pTempParam            CB mode
 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
 */
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, LOG1,
                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;
}

#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;
    limLog(pMac, LOG1,
                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

