/*
 * Copyright (c) 2011-2015, 2017-2018 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.
 */

/*
 * This file limProcessAuthFrame.cc contains the code
 * for processing received Authentication Frame.
 * Author:        Chandra Modumudi
 * Date:          03/11/02
 * History:-
 * Date           Modified by    Modification Information
 * --------------------------------------------------------------------
 * 05/12/2010     js             To support Shared key authentication at AP side
 *
 */

#include "wniApi.h"
#include "wniCfg.h"
#include "aniGlobal.h"
#include "cfgApi.h"

#include "utilsApi.h"
#include "limUtils.h"
#include "limAssocUtils.h"
#include "limSecurityUtils.h"
#include "limSerDesUtils.h"
#ifdef WLAN_FEATURE_VOWIFI_11R
#include "limFT.h"
#endif
#include "vos_utils.h"
#ifdef WLAN_FEATURE_LFR_MBB
#include "lim_mbb.h"
#endif


/**
 * isAuthValid
 *
 *FUNCTION:
 * This function is called by limProcessAuthFrame() upon Authentication
 * frame reception.
 *
 *LOGIC:
 * This function is used to test validity of auth frame:
 * - AUTH1 and AUTH3 must be received in AP mode
 * - AUTH2 and AUTH4 must be received in STA mode
 * - AUTH3 and AUTH4 must have challenge text IE, that is,'type' field has been set to
 *                 SIR_MAC_CHALLENGE_TEXT_EID by parser
 * -
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 *
 * @param  *auth - Pointer to extracted auth frame body
 *
 * @return 0 or 1 (Valid)
 */


static inline unsigned int isAuthValid(tpAniSirGlobal pMac, tpSirMacAuthFrameBody auth,tpPESession sessionEntry) {
    unsigned int valid;
    valid=1;

    if (  ((auth->authTransactionSeqNumber==SIR_MAC_AUTH_FRAME_1)||
           (auth->authTransactionSeqNumber==SIR_MAC_AUTH_FRAME_3)) &&
          ((sessionEntry->limSystemRole == eLIM_STA_ROLE)||(sessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)))
        valid=0;

    if ( ((auth->authTransactionSeqNumber==SIR_MAC_AUTH_FRAME_2)||(auth->authTransactionSeqNumber==SIR_MAC_AUTH_FRAME_4))&&
         ((sessionEntry->limSystemRole == eLIM_AP_ROLE)||(sessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE)))
        valid=0;

    if ( ((auth->authTransactionSeqNumber==SIR_MAC_AUTH_FRAME_3)||(auth->authTransactionSeqNumber==SIR_MAC_AUTH_FRAME_4))&&
         (auth->type!=SIR_MAC_CHALLENGE_TEXT_EID)&&(auth->authAlgoNumber != eSIR_SHARED_KEY))
        valid=0;

    return valid;
}

#ifdef WLAN_FEATURE_SAE
/**
 * lim_process_sae_auth_frame()-Process SAE authentication frame
 * @mac_ctx: MAC context
 * @rx_pkt_info: Rx packet
 * @pe_session: PE session
 *
 * Return: None
 */
static void lim_process_sae_auth_frame(tpAniSirGlobal mac_ctx,
                                       uint8_t *rx_pkt_info,
                                       tpPESession pe_session)
{
    tpSirMacMgmtHdr mac_hdr;

    mac_hdr = WDA_GET_RX_MAC_HEADER(rx_pkt_info);

    limLog(mac_ctx, LOG1, FL("Received SAE Auth frame type %d subtype %d"),
           mac_hdr->fc.type, mac_hdr->fc.subType);

    if (pe_session->limMlmState != eLIM_MLM_WT_SAE_AUTH_STATE)
        limLog(mac_ctx, LOGE,
               FL("received SAE auth response in unexpected state %x"),
               pe_session->limMlmState);

    limSendSmeMgmtFrameInd(mac_ctx, pe_session->peSessionId,
                           rx_pkt_info, pe_session,
                           WDA_GET_RX_RSSI_DB(rx_pkt_info));
}
#else
static void lim_process_sae_auth_frame(tpAniSirGlobal mac_ctx,
                                       uint8_t *rx_pkt_info,
                                       tpPESession pe_session)
{}
#endif

/**
 * limProcessAuthFrame
 *
 *FUNCTION:
 * This function is called by limProcessMessageQueue() upon Authentication
 * frame reception.
 *
 *LOGIC:
 * This function processes received Authentication frame and responds
 * with either next Authentication frame in sequence to peer MAC entity
 * or LIM_MLM_AUTH_IND on AP or LIM_MLM_AUTH_CNF on STA.
 *
 *ASSUMPTIONS:
 *
 *NOTE:
 * 1. Authentication failures are reported to SME with same status code
 *    received from the peer MAC entity.
 * 2. Authentication frame2/4 received with alogirthm number other than
 *    one requested in frame1/3 are logged with an error and auth confirm
 *    will be sent to SME only after auth failure timeout.
 * 3. Inconsistency in the spec:
 *    On receiving Auth frame2, specs says that if WEP key mapping key
 *    or default key is NULL, Auth frame3 with a status code 15 (challenge
 *    failure to be returned to peer entity. However, section 7.2.3.10,
 *    table 14 says that status code field is 'reserved' for frame3 !
 *    In the current implementation, Auth frame3 is returned with status
 *    code 15 overriding section 7.2.3.10.
 * 4. If number pre-authentications reach configrable max limit,
 *    Authentication frame with 'unspecified failure' status code is
 *    returned to requesting entity.
 *
 * @param  pMac - Pointer to Global MAC structure
 * @param  *pRxPacketInfo - A pointer to Rx packet info structure
 * @return None
 */

void
limProcessAuthFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tpPESession psessionEntry)
{
    tANI_U8                 *pBody, keyId, cfgPrivacyOptImp,
                            defaultKey[SIR_MAC_KEY_LENGTH],
                            *encrAuthFrame = NULL,
                            *plainBody = NULL;
    tANI_U16                frameLen;
    //tANI_U32                authRspTimeout, maxNumPreAuth, val;
    tANI_U32                maxNumPreAuth, val;
    tSirMacAuthFrameBody    *pRxAuthFrameBody,
                            *rxAuthFrame = NULL,
                            *authFrame = NULL;
    tpSirMacMgmtHdr         pHdr;
    tCfgWepKeyEntry         *pKeyMapEntry = NULL;
    struct tLimPreAuthNode  *pAuthNode;
    tLimMlmAuthInd          mlmAuthInd;
    tANI_U8                 decryptResult;
    tANI_U8                 *pChallenge;
    tANI_U32                key_length=8;
    tANI_U8                 *challengeTextArray = NULL;
    tpDphHashNode           pStaDs = NULL;
    tANI_U16                assocId = 0;
    tANI_U16                currSeqNo = 0;
    tANI_U16                auth_alg = 0;
    /* Added For BT -AMP support */
    // Get pointer to Authentication frame header and body
 

    pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
    frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);

    if (!frameLen)
    {
        // Log error
        limLog(pMac, LOGE,
               FL("received Authentication frame with no body from "));
        limPrintMacAddr(pMac, pHdr->sa, LOGE);

        return;
    }

    if (limIsGroupAddr(pHdr->sa))
    {
        // Received Auth frame from a BC/MC address
        // Log error and ignore it
       limLog(pMac, LOGE,
               FL("received Auth frame from a BC/MC address - "));
       limPrintMacAddr(pMac, pHdr->sa, LOGE);

        return;
    }
    currSeqNo = (pHdr->seqControl.seqNumHi << 4) | (pHdr->seqControl.seqNumLo);
    limLog(pMac, LOG1,
               FL("Sessionid: %d System role : %d limMlmState: %d :Auth "
               "Frame Received: BSSID: "MAC_ADDRESS_STR " (RSSI %d)"),
               psessionEntry->peSessionId, psessionEntry->limSystemRole,
               psessionEntry->limMlmState, MAC_ADDR_ARRAY(pHdr->bssId),
               (uint)abs((tANI_S8)WDA_GET_RX_RSSI_DB(pRxPacketInfo)));

    pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);

    auth_alg = *(uint16_t *)pBody;
    limLog(pMac, LOG1, FL("auth_alg %d "), auth_alg);

    //PELOG3(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG3, (tANI_U8*)pBd, ((tpHalBufDesc) pBd)->mpduDataOffset + frameLen);)

    //Restore default failure timeout
    if (VOS_P2P_CLIENT_MODE == psessionEntry->pePersona && psessionEntry->defaultAuthFailureTimeout)
    {
        limLog(pMac, LOG1, FL("Restore default failure timeout"));
        ccmCfgSetInt(pMac,WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT ,
                          psessionEntry->defaultAuthFailureTimeout, NULL, eANI_BOOLEAN_FALSE);
    }

    rxAuthFrame = vos_mem_malloc(sizeof(tSirMacAuthFrameBody));
    if (!rxAuthFrame) {
        limLog(pMac, LOGE, FL("Failed to allocate memory"));
        return;
    }

    authFrame = vos_mem_malloc(sizeof(tSirMacAuthFrameBody));
    if (!authFrame) {
        limLog(pMac, LOGE, FL("failed to allocate memory"));
        goto free;
    }

    plainBody = vos_mem_malloc(LIM_ENCR_AUTH_BODY_LEN);
    if (!plainBody) {
        limLog(pMac, LOGE, FL("failed to allocate memory"));
        goto free;
    }

    challengeTextArray = vos_mem_malloc(SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH);
    if(!challengeTextArray) {
        limLog(pMac, LOGE, FL("failed to allocate memory"));
        goto free;
    }

    vos_mem_set(rxAuthFrame, sizeof(tSirMacAuthFrameBody), 0);
    vos_mem_set(authFrame, sizeof(tSirMacAuthFrameBody), 0);
    vos_mem_set(plainBody, LIM_ENCR_AUTH_BODY_LEN, 0);
    vos_mem_set(challengeTextArray, SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH, 0);
   
    /// Determine if WEP bit is set in the FC or received MAC header
    if (pHdr->fc.wep)
    {
        /**
         * WEP bit is set in FC of MAC header.
         */

        // If TKIP counter measures enabled issue Deauth frame to station
        if ((psessionEntry->bTkipCntrMeasActive) && (psessionEntry->limSystemRole == eLIM_AP_ROLE))
        {
            PELOGE( limLog(pMac, LOGE,
               FL("Tkip counter measures Enabled, sending Deauth frame to")); )
            limPrintMacAddr(pMac, pHdr->sa, LOGE);

            limSendDeauthMgmtFrame( pMac, eSIR_MAC_MIC_FAILURE_REASON,
                                    pHdr->sa, psessionEntry, FALSE );
            goto free;
        }

        // Extract key ID from IV (most 2 bits of 4th byte of IV)

        keyId = (*(pBody + 3)) >> 6;

        /**
         * On STA in infrastructure BSS, Authentication frames received
         * with WEP bit set in the FC must be rejected with challenge
         * failure status code (wierd thing in the spec - this should have
         * been rejected with unspecified failure or unexpected assertion
         * of wep bit (this status code does not exist though) or
         * Out-of-sequence-Authentication-Frame status code.
         */

        if (psessionEntry->limSystemRole == eLIM_STA_ROLE || psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)
        {
            authFrame->authAlgoNumber = eSIR_SHARED_KEY;
            authFrame->authTransactionSeqNumber = SIR_MAC_AUTH_FRAME_4;
            authFrame->authStatusCode = eSIR_MAC_CHALLENGE_FAILURE_STATUS;
            // Log error
            PELOGE(limLog(pMac, LOGE,
                   FL("received Authentication frame with wep bit set on "
                   "role=%d "MAC_ADDRESS_STR),
                   psessionEntry->limSystemRole, MAC_ADDR_ARRAY(pHdr->sa) );)
            limSendAuthMgmtFrame(pMac, authFrame,
                                 pHdr->sa,
                                 LIM_NO_WEP_IN_FC,
                                 psessionEntry, eSIR_FALSE);
            goto free;
        }

        if ((frameLen < LIM_ENCR_AUTH_BODY_LEN_SAP) ||
            (frameLen > LIM_ENCR_AUTH_BODY_LEN))
        {
            // Log error
            limLog(pMac, LOGE,
                   FL("Not enough size [%d] to decrypt received Auth frame"),
                   frameLen);
            limPrintMacAddr(pMac, pHdr->sa, LOGE);

            goto free;
        }
        if(psessionEntry->limSystemRole == eLIM_AP_ROLE)
        {
            val = psessionEntry->privacy; 
        } 
        else 
        // Accept Authentication frame only if Privacy is implemented
        if (wlan_cfgGetInt(pMac, WNI_CFG_PRIVACY_ENABLED,
                      &val) != eSIR_SUCCESS)
        {
            /**
             * Could not get Privacy option
             * from CFG. Log error.
             */
            limLog(pMac, LOGP, FL("could not retrieve Privacy option"));
        }

        cfgPrivacyOptImp = (tANI_U8)val;
        if (cfgPrivacyOptImp)
        {
            /**
             * Privacy option is implemented.
             * Check if the received frame is Authentication
             * frame3 and there is a context for requesting STA.
             * If not, reject with unspecified failure status code
             */
            pAuthNode = limSearchPreAuthList(pMac, pHdr->sa);

            if (pAuthNode == NULL)
            {
                // Log error
                PELOGE(limLog(pMac, LOGE,
                       FL("received Authentication frame from peer that has "
                       "no preauth context with WEP bit set "MAC_ADDRESS_STR),
                       MAC_ADDR_ARRAY(pHdr->sa));)

                /**
                 * No 'pre-auth' context exists for this STA that sent
                 * an Authentication frame with FC bit set.
                 * Send Auth frame4 with 'out of sequence' status code.
                 */
                authFrame->authAlgoNumber = eSIR_SHARED_KEY;
                authFrame->authTransactionSeqNumber =
                SIR_MAC_AUTH_FRAME_4;
                authFrame->authStatusCode =
                eSIR_MAC_AUTH_FRAME_OUT_OF_SEQ_STATUS;

                limSendAuthMgmtFrame(pMac, authFrame,
                                     pHdr->sa,
                                     LIM_NO_WEP_IN_FC,
                                     psessionEntry, eSIR_FALSE);

                goto free;
            }
            else
            {
                /// Change the auth-response timeout
                limDeactivateAndChangePerStaIdTimer(pMac,
                                                    eLIM_AUTH_RSP_TIMER,
                                                    pAuthNode->authNodeIdx);

                /// 'Pre-auth' status exists for STA
                if ((pAuthNode->mlmState !=
                     eLIM_MLM_WT_AUTH_FRAME3_STATE) &&
                    (pAuthNode->mlmState !=
                     eLIM_MLM_AUTH_RSP_TIMEOUT_STATE))
                {
                    // Log error
                    PELOGE(limLog(pMac, LOGE,
                           FL("received Authentication frame from peer that is "
                           "in state %d "MAC_ADDRESS_STR),
                            pAuthNode->mlmState, MAC_ADDR_ARRAY(pHdr->sa));)

                    /**
                     * Should not have received Authentication frame
                     * with WEP bit set in FC in other states.
                     * Reject by sending Authenticaton frame with
                     * out of sequence Auth frame status code.
                     */

                    authFrame->authAlgoNumber = eSIR_SHARED_KEY;
                    authFrame->authTransactionSeqNumber =
                    SIR_MAC_AUTH_FRAME_4;
                    authFrame->authStatusCode =
                    eSIR_MAC_AUTH_FRAME_OUT_OF_SEQ_STATUS;

                    limSendAuthMgmtFrame(pMac, authFrame,
                                         pHdr->sa,
                                         LIM_NO_WEP_IN_FC,
                                         psessionEntry, eSIR_FALSE);

                    goto free;
                }
            }

            /**
             * Check if there exists a key mappping key
             * for the STA that sent Authentication frame
             */
            pKeyMapEntry = limLookUpKeyMappings(pHdr->sa);

            if (pKeyMapEntry)
            {
                if (!pKeyMapEntry->wepOn)
                {
                    // Log error
                    PELOGE(limLog(pMac, LOGE,
                           FL("received Auth frame3 from peer that has NULL "
                           "key map entry "
                           MAC_ADDRESS_STR),MAC_ADDR_ARRAY(pHdr->sa));)

                    /**
                     * Key Mapping entry has null key.
                     * Send Authentication frame
                     * with challenge failure status code
                     */
                    authFrame->authAlgoNumber = eSIR_SHARED_KEY;
                    authFrame->authTransactionSeqNumber =
                    SIR_MAC_AUTH_FRAME_4;
                    authFrame->authStatusCode =
                    eSIR_MAC_CHALLENGE_FAILURE_STATUS;

                    limSendAuthMgmtFrame(pMac, authFrame,
                                         pHdr->sa,
                                         LIM_NO_WEP_IN_FC,
                                         psessionEntry, eSIR_FALSE);

                    goto free;
                } // if (!pKeyMapEntry->wepOn)
                else
                {
                    decryptResult = limDecryptAuthFrame(pMac, pKeyMapEntry->key,
                                                        pBody,
                                                        plainBody,
                                                        key_length,
                                                        (tANI_U16) (frameLen-SIR_MAC_WEP_IV_LENGTH));
                    if (decryptResult == LIM_DECRYPT_ICV_FAIL)
                    {
                        /// ICV failure
                        PELOGW(limLog(pMac, LOGW, FL("=====> decryptResult == "
                        "LIM_DECRYPT_ICV_FAIL ..."));)
                        // Log error
                        PELOGE(limLog(pMac, LOGE,
                               FL("received Authentication frame from peer "
                               "that failed decryption, Addr "
                               MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pHdr->sa));)

                        limDeletePreAuthNode(pMac,
                                             pHdr->sa);
                        authFrame->authAlgoNumber = eSIR_SHARED_KEY;
                        authFrame->authTransactionSeqNumber =
                        SIR_MAC_AUTH_FRAME_4;
                        authFrame->authStatusCode =
                        eSIR_MAC_CHALLENGE_FAILURE_STATUS;

                        limSendAuthMgmtFrame(
                                            pMac, authFrame,
                                            pHdr->sa,
                                            LIM_NO_WEP_IN_FC,
                                            psessionEntry, eSIR_FALSE);


                        goto free;
                    }

                    if ( ( sirConvertAuthFrame2Struct(pMac, plainBody, frameLen-8,
                         rxAuthFrame)!=eSIR_SUCCESS ) ||
                         ( !isAuthValid(pMac, rxAuthFrame,psessionEntry) ) )
                    {
                        PELOGE(limLog(pMac, LOGE,
                               FL("failed to convert Auth Frame to structure "
                               "or Auth is not valid "));)
                        goto free;
                    }


                } // end if (pKeyMapEntry->key == NULL)
            } // if keyMappings has entry
            else
            {

                val = SIR_MAC_KEY_LENGTH;

                if(psessionEntry->limSystemRole == eLIM_AP_ROLE)
                {   
                    tpSirKeys pKey;
                    pKey =  &psessionEntry->WEPKeyMaterial[keyId].key[0];              
                    vos_mem_copy(defaultKey, pKey->key, pKey->keyLength);
                    val = pKey->keyLength;
                }                   
                else                              
                if (wlan_cfgGetStr(pMac, (tANI_U16) (WNI_CFG_WEP_DEFAULT_KEY_1 + keyId),
                              defaultKey, &val) != eSIR_SUCCESS)
                {
                    /// Could not get Default key from CFG.
                    //Log error.
                    limLog(pMac, LOGP,
                           FL("could not retrieve Default key"));

                    /**
                     * Send Authentication frame
                     * with challenge failure status code
                     */

                    authFrame->authAlgoNumber = eSIR_SHARED_KEY;
                    authFrame->authTransactionSeqNumber =
                    SIR_MAC_AUTH_FRAME_4;
                    authFrame->authStatusCode =
                    eSIR_MAC_CHALLENGE_FAILURE_STATUS;

                    limSendAuthMgmtFrame(pMac, authFrame,
                                         pHdr->sa,
                                         LIM_NO_WEP_IN_FC,
                                         psessionEntry, eSIR_FALSE);

                    goto free;
                }

                    key_length=val;

                    decryptResult = limDecryptAuthFrame(pMac, defaultKey,
                                                        pBody,
                                                        plainBody,
                                                        key_length,
                                                        (tANI_U16) (frameLen-SIR_MAC_WEP_IV_LENGTH));
                    if (decryptResult == LIM_DECRYPT_ICV_FAIL)
                    {
                        PELOGW(limLog(pMac, LOGW, FL("=====> decryptResult == "
                        "LIM_DECRYPT_ICV_FAIL ..."));)
                        // Log error
                        PELOGE(limLog(pMac, LOGE,
                               FL("received Authentication frame from peer that "
                               "failed decryption: "
                               MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pHdr->sa));)
                        /// ICV failure
                        limDeletePreAuthNode(pMac,
                                             pHdr->sa);
                        authFrame->authAlgoNumber = eSIR_SHARED_KEY;
                        authFrame->authTransactionSeqNumber =
                        SIR_MAC_AUTH_FRAME_4;
                        authFrame->authStatusCode =
                        eSIR_MAC_CHALLENGE_FAILURE_STATUS;

                        limSendAuthMgmtFrame(
                                            pMac, authFrame,
                                            pHdr->sa,
                                            LIM_NO_WEP_IN_FC,
                                            psessionEntry, eSIR_FALSE);

                        goto free;
                    }
                    if ( ( sirConvertAuthFrame2Struct(pMac, plainBody, frameLen-8,
                           rxAuthFrame)!=eSIR_SUCCESS ) ||
                        ( !isAuthValid(pMac, rxAuthFrame, psessionEntry) ) )
                    {
                        limLog(pMac, LOGE,
                               FL("failed to convert Auth Frame to structure "
                               "or Auth is not valid "));
                        goto free;
                    }
            } // End of check for Key Mapping/Default key presence
        }
        else
        {
            // Log error
            PELOGE(limLog(pMac, LOGE,
                   FL("received Authentication frame3 from peer that while "
                   "privacy option is turned OFF "
                   MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pHdr->sa));)
            /**
             * Privacy option is not implemented.
             * So reject Authentication frame received with
             * WEP bit set by sending Authentication frame
             * with 'challenge failure' status code. This is
             * another strange thing in the spec. Status code
             * should have been 'unsupported algorithm' status code.
             */

            authFrame->authAlgoNumber = eSIR_SHARED_KEY;
            authFrame->authTransactionSeqNumber =
            SIR_MAC_AUTH_FRAME_4;
            authFrame->authStatusCode =
            eSIR_MAC_CHALLENGE_FAILURE_STATUS;

            limSendAuthMgmtFrame(pMac, authFrame,
                                 pHdr->sa,
                                 LIM_NO_WEP_IN_FC,
                                 psessionEntry, eSIR_FALSE);

            goto free;
        } // else if (wlan_cfgGetInt(CFG_PRIVACY_OPTION_IMPLEMENTED))
    } else if ((auth_alg ==
        eSIR_AUTH_TYPE_SAE) && (LIM_IS_STA_ROLE(psessionEntry))) {
        lim_process_sae_auth_frame(pMac, pRxPacketInfo, psessionEntry);
        goto free;
    } // if (fc.wep)
    else
    {


        if ( ( sirConvertAuthFrame2Struct(pMac, pBody,
            frameLen, rxAuthFrame)!=eSIR_SUCCESS ) ||
            ( !isAuthValid(pMac, rxAuthFrame,psessionEntry) ) )
        {
            PELOGE(limLog(pMac, LOGE,
                   FL("failed to convert Auth Frame to structure or Auth is "
                   "not valid "));)
            goto free;
        }
    }


    pRxAuthFrameBody = rxAuthFrame;

   PELOGW(limLog(pMac, LOGW,
           FL("Received Auth frame with type=%d seqnum=%d, status=%d (%d)"),
           (tANI_U32) pRxAuthFrameBody->authAlgoNumber,
           (tANI_U32) pRxAuthFrameBody->authTransactionSeqNumber,
           (tANI_U32) pRxAuthFrameBody->authStatusCode,(tANI_U32)pMac->lim.gLimNumPreAuthContexts);)

    // IOT Workaround: with invalid WEP password, some APs reply AUTH frame 4
    // with invalid seqNumber. This AUTH frame will be dropped by driver,
    // thus driver sends the generic status code instead of protocol status code.
    // As a workaround, assign the correct seqNumber for the AUTH frame 4.
    if (psessionEntry->limMlmState == eLIM_MLM_WT_AUTH_FRAME4_STATE &&
        pRxAuthFrameBody->authTransactionSeqNumber != SIR_MAC_AUTH_FRAME_1 &&
        pRxAuthFrameBody->authTransactionSeqNumber != SIR_MAC_AUTH_FRAME_2 &&
        pRxAuthFrameBody->authTransactionSeqNumber != SIR_MAC_AUTH_FRAME_3) {
        PELOGE(limLog(pMac, LOGE, FL("Workaround: Assign a correct seqNumber=4 "
                "for AUTH frame 4"));)
        pRxAuthFrameBody->authTransactionSeqNumber = SIR_MAC_AUTH_FRAME_4;
    }

    switch (pRxAuthFrameBody->authTransactionSeqNumber)
    {
        case SIR_MAC_AUTH_FRAME_1:
            // AuthFrame 1
            
            pStaDs = dphLookupHashEntry(pMac, pHdr->sa,
                    &assocId, &psessionEntry->dph.dphHashTable);
            if (pStaDs)
            {
                tLimMlmDisassocReq      *pMlmDisassocReq = NULL;
                tLimMlmDeauthReq        *pMlmDeauthReq = NULL;
                tAniBool                 isConnected = eSIR_TRUE;

                pMlmDisassocReq = pMac->lim.limDisassocDeauthCnfReq.pMlmDisassocReq;
                if (pMlmDisassocReq &&
                        (vos_mem_compare((tANI_U8 *) pHdr->sa,
                                         (tANI_U8 *) &pMlmDisassocReq->peerMacAddr,
                                          sizeof(tSirMacAddr))))
                {
                    PELOGE(limLog(pMac, LOGE, FL("TODO:Ack for disassoc "
                                "frame is pending Issue delsta for "
                                MAC_ADDRESS_STR),
                                MAC_ADDR_ARRAY(pMlmDisassocReq->peerMacAddr));)
                    limProcessDisassocAckTimeout(pMac);
                    isConnected = eSIR_FALSE;
                }
                pMlmDeauthReq = pMac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq;
                if (pMlmDeauthReq &&
                        (vos_mem_compare((tANI_U8 *) pHdr->sa,
                                         (tANI_U8 *) &pMlmDeauthReq->peerMacAddr,
                                         sizeof(tSirMacAddr))))
                {
                    PELOGE(limLog(pMac, LOGE, FL("TODO:Ack for deauth frame "
                                "is pending Issue delsta for "
                                MAC_ADDRESS_STR),
                                MAC_ADDR_ARRAY(pMlmDeauthReq->peerMacAddr));)
                    limProcessDeauthAckTimeout(pMac);
                    isConnected = eSIR_FALSE;
                }

                /* pStaDS != NULL and isConnected = 1 means the STA is already
                 * connected, But SAP received the Auth from that station.
                 * For non PMF connection send Deauth frame as STA will retry
                 * to connect back.
                 *
                 * For PMF connection the AP should not tear down or otherwise
                 * modify the state of the existing association until the
                 * SA-Query procedure determines that the original SA is
                 * invalid.
                 */
                if (isConnected && pStaDs->PrevAuthSeqno != currSeqNo
#ifdef WLAN_FEATURE_11W
                    && !pStaDs->rmfEnabled
#endif
                   )
                {
                    limLog(pMac, LOGE,
                            FL("STA is already connected but received auth frame"
                                "Send the Deauth and lim Delete Station Context"
                                "(staId: %d, assocId: %d) "),
                            pStaDs->staIndex, assocId);
                    limSendDeauthMgmtFrame(pMac, eSIR_MAC_UNSPEC_FAILURE_REASON,
                            (tANI_U8 *) pHdr->sa, psessionEntry, FALSE);
                    limTriggerSTAdeletion(pMac, pStaDs, psessionEntry);
                    goto free;
                }
            }

            /// Check if there exists pre-auth context for this STA
            pAuthNode = limSearchPreAuthList(pMac, pHdr->sa);
            if (pAuthNode)
            {
                /// Pre-auth context exists for the STA
                if (pAuthNode->seqNo != currSeqNo)
                {
                    /**
                     * STA is initiating brand-new Authentication
                     * sequence after local Auth Response timeout.
                     * Or STA retrying to transmit First Auth frame due to packet drop OTA
                     * Delete Pre-auth node and fall through.
                     */
                    if(pAuthNode->fTimerStarted)
                    {
                        limDeactivateAndChangePerStaIdTimer(pMac,
                                                    eLIM_AUTH_RSP_TIMER,
                                                    pAuthNode->authNodeIdx);
                    }
                    PELOGE(limLog(pMac, LOGE, FL("STA is initiating brand-new "
                    "Authentication ..."));)
                    limDeletePreAuthNode(pMac,
                                         pHdr->sa);
                    /**
                     *  SAP Mode:Disassociate the station and 
                     *  delete its entry if we have its entry 
                     *  already and received "auth" from the 
                     *  same station.
                     */  

                    for (assocId = 0; assocId < psessionEntry->dph.dphHashTable.size; assocId++)// Softap dphHashTable.size = 8
                    {
                        pStaDs = dphGetHashEntry(pMac, assocId, &psessionEntry->dph.dphHashTable);

                        if (NULL == pStaDs)
                             continue;

                        if (pStaDs->valid)
                        {
                             if (vos_mem_compare((tANI_U8 *) &pStaDs->staAddr,
                                      (tANI_U8 *) &(pHdr->sa), (tANI_U8) (sizeof(tSirMacAddr))) )
                                  break;
                        }

                        pStaDs = NULL;
                    }

                    if (NULL != pStaDs
#ifdef WLAN_FEATURE_11W
                        && !pStaDs->rmfEnabled
#endif
                       )
                    {
                        PELOGE(limLog(pMac, LOGE, FL("lim Delete Station "
                        "Context (staId: %d, assocId: %d) "),pStaDs->staIndex,
                        assocId);)
                        limSendDeauthMgmtFrame(pMac,
                               eSIR_MAC_UNSPEC_FAILURE_REASON, (tANI_U8 *) pAuthNode->peerMacAddr, psessionEntry, FALSE);
                        limTriggerSTAdeletion(pMac, pStaDs, psessionEntry);
                        goto free;
                    }
                }
                else
                {
                    /* 
                     * This can happen when first authentication frame is received
                     * but ACK lost at STA side, in this case 2nd auth frame is already 
                     * in transmission queue
                     * */
                    PELOGE(limLog(pMac, LOGE, FL("STA is initiating "
                    "Authentication after ACK lost..."));)
                    goto free;
                }
            }
            if (wlan_cfgGetInt(pMac, WNI_CFG_MAX_NUM_PRE_AUTH,
                          (tANI_U32 *) &maxNumPreAuth) != eSIR_SUCCESS)
            {
                /**
                 * Could not get MaxNumPreAuth
                 * from CFG. Log error.
                 */
                limLog(pMac, LOGP,
                       FL("could not retrieve MaxNumPreAuth"));
            }

            if (pMac->lim.gLimNumPreAuthContexts == maxNumPreAuth &&
                !limDeleteOpenAuthPreAuthNode(pMac))
            {
                PELOGE(limLog(pMac, LOGE, FL("Max number of "
                    "preauth context reached"));)
                /**
                 * Maximum number of pre-auth contexts
                 * reached. Send Authentication frame
                 * with unspecified failure
                 */
                authFrame->authAlgoNumber =
                pRxAuthFrameBody->authAlgoNumber;
                authFrame->authTransactionSeqNumber =
                pRxAuthFrameBody->authTransactionSeqNumber + 1;
                authFrame->authStatusCode =
                eSIR_MAC_UNSPEC_FAILURE_STATUS;

                limSendAuthMgmtFrame(pMac, authFrame,
                                     pHdr->sa,
                                     LIM_NO_WEP_IN_FC,
                                     psessionEntry, eSIR_FALSE);

                goto free;
            }
            /// No Pre-auth context exists for the STA.
            if (limIsAuthAlgoSupported(
                                      pMac,
                                      (tAniAuthType)
                                      pRxAuthFrameBody->authAlgoNumber, psessionEntry))
            {
                switch (pRxAuthFrameBody->authAlgoNumber)
                {
                    case eSIR_OPEN_SYSTEM:
                        PELOGW(limLog(pMac, LOGW, FL("=======> eSIR_OPEN_SYSTEM  ..."));)
                        /// Create entry for this STA in pre-auth list
                        pAuthNode = limAcquireFreePreAuthNode(pMac, &pMac->lim.gLimPreAuthTimerTable);
                        if (pAuthNode == NULL)
                        {
                            // Log error
                            limLog(pMac, LOGW,
                                   FL("Max pre-auth nodes reached "));
                            limPrintMacAddr(pMac, pHdr->sa, LOGW);
                            goto free;
                        }

                        limLog(pMac, LOG1,
                               FL("Alloc new data: peer "MAC_ADDRESS_STR),
                                                 MAC_ADDR_ARRAY(pHdr->sa));

                        vos_mem_copy((tANI_U8 *) pAuthNode->peerMacAddr,
                                      pHdr->sa,
                                      sizeof(tSirMacAddr));

                        pAuthNode->mlmState =
                        eLIM_MLM_AUTHENTICATED_STATE;
                        pAuthNode->authType = (tAniAuthType)
                                              pRxAuthFrameBody->authAlgoNumber;
                        pAuthNode->fSeen = 0;
                        pAuthNode->fTimerStarted = 0;
                        pAuthNode->seqNo = ((pHdr->seqControl.seqNumHi << 4) |
                                            (pHdr->seqControl.seqNumLo));
                        pAuthNode->timestamp = vos_timer_get_system_ticks();
                        limAddPreAuthNode(pMac, pAuthNode);

                        /**
                         * Send Authenticaton frame with Success
                         * status code.
                         */

                        authFrame->authAlgoNumber =
                        pRxAuthFrameBody->authAlgoNumber;
                        authFrame->authTransactionSeqNumber =
                        pRxAuthFrameBody->authTransactionSeqNumber + 1;
                        authFrame->authStatusCode = eSIR_MAC_SUCCESS_STATUS;
                        limSendAuthMgmtFrame(
                                            pMac, authFrame,
                                            pHdr->sa,
                                            LIM_NO_WEP_IN_FC,
                                            psessionEntry, eSIR_FALSE);

                        /// Send Auth indication to SME

                        vos_mem_copy((tANI_U8 *) mlmAuthInd.peerMacAddr,
                                     (tANI_U8 *) pHdr->sa,
                                     sizeof(tSirMacAddr));
                        mlmAuthInd.authType = (tAniAuthType)
                                              pRxAuthFrameBody->authAlgoNumber;
                        mlmAuthInd.sessionId = psessionEntry->smeSessionId;

                        limPostSmeMessage(pMac,
                                          LIM_MLM_AUTH_IND,
                                          (tANI_U32 *) &mlmAuthInd);
                        break;

                    case eSIR_SHARED_KEY:
                        PELOGW(limLog(pMac, LOGW, FL("=======> eSIR_SHARED_KEY  ..."));)
                        if(psessionEntry->limSystemRole == eLIM_AP_ROLE)
                        {
                            val = psessionEntry->privacy;
                        }
                        else   
                        if (wlan_cfgGetInt(pMac, WNI_CFG_PRIVACY_ENABLED,
                                      &val) != eSIR_SUCCESS)
                        {
                            /**
                             * Could not get Privacy option
                             * from CFG. Log error.
                             */
                            limLog(pMac, LOGP,
                                   FL("could not retrieve Privacy option"));
                        }
                        cfgPrivacyOptImp = (tANI_U8)val;
                        if (!cfgPrivacyOptImp)
                        {
                            // Log error
                            PELOGE(limLog(pMac, LOGE,
                                   FL("received Auth frame for unsupported auth algorithm %d "
                                   MAC_ADDRESS_STR), pRxAuthFrameBody->authAlgoNumber,
                                   MAC_ADDR_ARRAY(pHdr->sa));)

                            /**
                             * Authenticator does not have WEP
                             * implemented.
                             * Reject by sending Authentication frame
                             * with Auth algorithm not supported status
                             * code.
                             */

                            authFrame->authAlgoNumber =
                            pRxAuthFrameBody->authAlgoNumber;
                            authFrame->authTransactionSeqNumber =
                            pRxAuthFrameBody->authTransactionSeqNumber + 1;
                            authFrame->authStatusCode =
                            eSIR_MAC_AUTH_ALGO_NOT_SUPPORTED_STATUS;

                            limSendAuthMgmtFrame(
                                                pMac, authFrame,
                                                pHdr->sa,
                                                LIM_NO_WEP_IN_FC,
                                                psessionEntry, eSIR_FALSE);

                            goto free;
                        }
                        else
                        {
                            // Create entry for this STA
                            //in pre-auth list
                            pAuthNode = limAcquireFreePreAuthNode(pMac, &pMac->lim.gLimPreAuthTimerTable);
                            if (pAuthNode == NULL)
                            {
                                // Log error
                                limLog(pMac, LOGW,
                                       FL("Max pre-auth nodes reached "));
                                limPrintMacAddr(pMac, pHdr->sa, LOGW);

                                goto free;
                            }

                            vos_mem_copy((tANI_U8 *) pAuthNode->peerMacAddr,
                                          pHdr->sa,
                                          sizeof(tSirMacAddr));

                            pAuthNode->mlmState =
                            eLIM_MLM_WT_AUTH_FRAME3_STATE;
                            pAuthNode->authType =
                            (tAniAuthType)
                            pRxAuthFrameBody->authAlgoNumber;
                            pAuthNode->fSeen = 0;
                            pAuthNode->fTimerStarted = 0;
                            pAuthNode->seqNo = ((pHdr->seqControl.seqNumHi << 4) |
                                                (pHdr->seqControl.seqNumLo));
                            pAuthNode->timestamp = vos_timer_get_system_ticks();
                            limAddPreAuthNode(pMac, pAuthNode);

                            limLog(pMac, LOG1,
                                   FL("Alloc new data: id %d peer "MAC_ADDRESS_STR),
                                    pAuthNode->authNodeIdx, MAC_ADDR_ARRAY(pHdr->sa));

                            /// Create and activate Auth Response timer
                            if (tx_timer_change_context(&pAuthNode->timer, pAuthNode->authNodeIdx) != TX_SUCCESS)
                            {
                                /// Could not start Auth response timer.
                                // Log error
                                limLog(pMac, LOGP,
                                   FL("Unable to chg context auth response timer for peer "));
                                limPrintMacAddr(pMac, pHdr->sa, LOGP);

                                /**
                                 * Send Authenticaton frame with
                                 * unspecified failure status code.
                                 */

                                authFrame->authAlgoNumber =
                                        pRxAuthFrameBody->authAlgoNumber;
                                authFrame->authTransactionSeqNumber =
                                        pRxAuthFrameBody->authTransactionSeqNumber + 1;
                                authFrame->authStatusCode =
                                        eSIR_MAC_UNSPEC_FAILURE_STATUS;

                                limSendAuthMgmtFrame(pMac, authFrame,
                                                     pHdr->sa,
                                                     LIM_NO_WEP_IN_FC,
                                                     psessionEntry, eSIR_FALSE);

                                limDeletePreAuthNode(pMac, pHdr->sa);
                                goto free;
                            }

                            limActivateAuthRspTimer(pMac, pAuthNode);

                            pAuthNode->fTimerStarted = 1;

                            /*
                             * get random bytes and use as challenge text
                             */
                            if( !VOS_IS_STATUS_SUCCESS( vos_rand_get_bytes( 0, (tANI_U8 *)challengeTextArray, SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH ) ) )
                            {
                               limLog(pMac, LOGE,FL("Challenge text "
                               "preparation failed in limProcessAuthFrame"));
                               goto free;
                            }
                            
                            pChallenge = pAuthNode->challengeText;

                            vos_mem_copy(pChallenge,
                                        (tANI_U8 *) challengeTextArray,
                                         sizeof(challengeTextArray));

                            /**
                             * Sending Authenticaton frame with challenge.
                             */

                            authFrame->authAlgoNumber =
                            pRxAuthFrameBody->authAlgoNumber;
                            authFrame->authTransactionSeqNumber =
                            pRxAuthFrameBody->authTransactionSeqNumber + 1;
                            authFrame->authStatusCode =
                            eSIR_MAC_SUCCESS_STATUS;
                            authFrame->type   = SIR_MAC_CHALLENGE_TEXT_EID;
                            authFrame->length = SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH;
                            vos_mem_copy(authFrame->challengeText,
                                         pAuthNode->challengeText,
                                         SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH);

                            limSendAuthMgmtFrame(
                                                pMac, authFrame,
                                                pHdr->sa,
                                                LIM_NO_WEP_IN_FC,
                                                psessionEntry, eSIR_FALSE);
                        } // if (wlan_cfgGetInt(CFG_PRIVACY_OPTION_IMPLEMENTED))

                        break;

                    default:
                         // Log error
                       PELOGE( limLog(pMac, LOGE,
                               FL("received Auth frame for unsupported auth "
                               "algorithm %d "MAC_ADDRESS_STR),
                               pRxAuthFrameBody->authAlgoNumber,
                               MAC_ADDR_ARRAY(pHdr->sa));)

                        /**
                         * Responding party does not support the
                         * authentication algorithm requested by
                         * sending party.
                         * Reject by sending Authentication frame
                         * with auth algorithm not supported status code
                         */

                        authFrame->authAlgoNumber =
                        pRxAuthFrameBody->authAlgoNumber;
                        authFrame->authTransactionSeqNumber =
                        pRxAuthFrameBody->authTransactionSeqNumber + 1;
                        authFrame->authStatusCode =
                        eSIR_MAC_AUTH_ALGO_NOT_SUPPORTED_STATUS;

                        limSendAuthMgmtFrame(
                                            pMac, authFrame,
                                            pHdr->sa,
                                            LIM_NO_WEP_IN_FC,
                                            psessionEntry, eSIR_FALSE);

                        goto free;
                } // end switch(pRxAuthFrameBody->authAlgoNumber)
            } // if (limIsAuthAlgoSupported(pRxAuthFrameBody->authAlgoNumber))
            else
            {
                // Log error
                PELOGE(limLog(pMac, LOGE,
                       FL("received Authentication frame for unsupported auth "
                       "algorithm %d "MAC_ADDRESS_STR),
                       pRxAuthFrameBody->authAlgoNumber,
                       MAC_ADDR_ARRAY(pHdr->sa));)

                /**
                 * Responding party does not support the
                 * authentication algorithm requested by sending party.
                 * Reject Authentication with StatusCode=13.
                 */
                authFrame->authAlgoNumber =
                pRxAuthFrameBody->authAlgoNumber;
                authFrame->authTransactionSeqNumber =
                pRxAuthFrameBody->authTransactionSeqNumber + 1;
                authFrame->authStatusCode =
                eSIR_MAC_AUTH_ALGO_NOT_SUPPORTED_STATUS;

                limSendAuthMgmtFrame(pMac, authFrame,
                                     pHdr->sa,
                                     LIM_NO_WEP_IN_FC,
                                     psessionEntry, eSIR_FALSE);

                goto free;
            } //end if (limIsAuthAlgoSupported(pRxAuthFrameBody->authAlgoNumber))
            break;

        case SIR_MAC_AUTH_FRAME_2:
            // AuthFrame 2

            if (psessionEntry->limMlmState != eLIM_MLM_WT_AUTH_FRAME2_STATE)
            {
                /**
                 * Received Authentication frame2 in an unexpected state.
                 * Log error and ignore the frame.
                 */

                // Log error
                limLog(pMac, LOG1,
                       FL("received Auth frame2 from peer in state %d, addr "),
                       psessionEntry->limMlmState);
                limPrintMacAddr(pMac, pHdr->sa, LOG1);

                goto free;
            }

            if ( !vos_mem_compare((tANI_U8 *) pHdr->sa,
                                  (tANI_U8 *) &pMac->lim.gpLimMlmAuthReq->peerMacAddr,
                                  sizeof(tSirMacAddr)) )
            {
                /**
                 * Received Authentication frame from an entity
                 * other than one request was initiated.
                 * Wait until Authentication Failure Timeout.
                 */

                // Log error
                PELOGW(limLog(pMac, LOGW,
                       FL("received Auth frame2 from unexpected peer "
                       MAC_ADDRESS_STR),
                       MAC_ADDR_ARRAY(pHdr->sa));)

                break;
            }

            if (pRxAuthFrameBody->authStatusCode ==
                eSIR_MAC_AUTH_ALGO_NOT_SUPPORTED_STATUS)
            {
                /**
                 * Interoperability workaround: Linksys WAP4400N is returning
                 * wrong authType in OpenAuth response in case of 
                 * SharedKey AP configuration. Pretend we don't see that,
                 * so upper layer can fallback to SharedKey authType,
                 * and successfully connect to the AP.
                 */
                if (pRxAuthFrameBody->authAlgoNumber !=
                    pMac->lim.gpLimMlmAuthReq->authType)
                {
                    pRxAuthFrameBody->authAlgoNumber =
                    pMac->lim.gpLimMlmAuthReq->authType;
                }
            }

            if (pRxAuthFrameBody->authAlgoNumber !=
                pMac->lim.gpLimMlmAuthReq->authType)
            {
                /*
                 * Auth algo is open in rx auth frame when auth type is SAE and
                 * PMK is cached as driver sent auth algo as open in tx frame
                 * as well.
                 */
                if ((pMac->lim.gpLimMlmAuthReq->authType ==
                     eSIR_AUTH_TYPE_SAE) && psessionEntry->sae_pmk_cached) {
                     limLog(pMac, LOGW,
                            FL("rx Auth frame2 auth algo %d in SAE PMK case"),
                            pRxAuthFrameBody->authAlgoNumber);
                } else {
                    /**
                     * Received Authentication frame with an auth
                     * algorithm other than one requested.
                     * Wait until Authentication Failure Timeout.
                     */
                    // Log error
                    PELOGW(limLog(pMac, LOGW,
                           FL("received Auth frame2 for unexpected auth algo num %d "
                           MAC_ADDRESS_STR), pRxAuthFrameBody->authAlgoNumber,
                           MAC_ADDR_ARRAY(pHdr->sa));)
                    break;
                }
            }

            if (pRxAuthFrameBody->authStatusCode ==
                eSIR_MAC_SUCCESS_STATUS)
            {
                if (pRxAuthFrameBody->authAlgoNumber ==
                    eSIR_OPEN_SYSTEM)
                {
                    psessionEntry->limCurrentAuthType = eSIR_OPEN_SYSTEM;

                    pAuthNode = limAcquireFreePreAuthNode(pMac, &pMac->lim.gLimPreAuthTimerTable);

                    if (pAuthNode == NULL)
                    {
                        // Log error
                        limLog(pMac, LOGW,
                               FL("Max pre-auth nodes reached "));
                        limPrintMacAddr(pMac, pHdr->sa, LOGW);

                        goto free;
                    }

                    limLog(pMac, LOG1,
                              FL("Alloc new data: peer "MAC_ADDRESS_STR),
                                                 MAC_ADDR_ARRAY(pHdr->sa));

                    vos_mem_copy((tANI_U8 *) pAuthNode->peerMacAddr,
                                 pMac->lim.gpLimMlmAuthReq->peerMacAddr,
                                 sizeof(tSirMacAddr));
                    pAuthNode->fTimerStarted = 0;
                    pAuthNode->authType = pMac->lim.gpLimMlmAuthReq->authType;
                    pAuthNode->seqNo = ((pHdr->seqControl.seqNumHi << 4) |
                                        (pHdr->seqControl.seqNumLo));
                    pAuthNode->timestamp = vos_timer_get_system_ticks();
                    limAddPreAuthNode(pMac, pAuthNode);

                    limRestoreFromAuthState(pMac, eSIR_SME_SUCCESS,
                                            pRxAuthFrameBody->authStatusCode,psessionEntry);
                } // if (pRxAuthFrameBody->authAlgoNumber == eSIR_OPEN_SYSTEM)
                else
                {
                    // Shared key authentication

                    if(psessionEntry->limSystemRole == eLIM_AP_ROLE)
                    {
                        val = psessionEntry->privacy;
                    }
                    else   
                    if (wlan_cfgGetInt(pMac, WNI_CFG_PRIVACY_ENABLED,
                                  &val) != eSIR_SUCCESS)
                    {
                        /**
                         * Could not get Privacy option
                         * from CFG. Log error.
                         */
                        limLog(pMac, LOGP,
                               FL("could not retrieve Privacy option"));
                    }
                    cfgPrivacyOptImp = (tANI_U8)val;
                    if (!cfgPrivacyOptImp)
                    {
                        /**
                         * Requesting STA does not have WEP implemented.
                         * Reject with unsupported authentication algorithm
                         * Status code and wait until auth failure timeout
                         */

                        // Log error
                       PELOGE( limLog(pMac, LOGE,
                               FL("received Auth frame from peer for "
                               "unsupported auth algo %d "
                               MAC_ADDRESS_STR), pRxAuthFrameBody->authAlgoNumber,
                               MAC_ADDR_ARRAY(pHdr->sa));)

                        authFrame->authAlgoNumber =
                        pRxAuthFrameBody->authAlgoNumber;
                        authFrame->authTransactionSeqNumber =
                        pRxAuthFrameBody->authTransactionSeqNumber + 1;
                        authFrame->authStatusCode =
                        eSIR_MAC_AUTH_ALGO_NOT_SUPPORTED_STATUS;

                        limSendAuthMgmtFrame(pMac, authFrame,
                                            pHdr->sa,
                                            LIM_NO_WEP_IN_FC,
                                            psessionEntry, eSIR_FALSE);
                        goto free;
                    }
                    else
                    {

                        if (pRxAuthFrameBody->type !=
                            SIR_MAC_CHALLENGE_TEXT_EID)
                        {
                            // Log error
                            PELOGE(limLog(pMac, LOGE,
                                   FL("received Auth frame with invalid "
                                   "challenge text IE"));)

                            goto free;
                        }

                        /**
                         * Check if there exists a key mappping key
                         * for the STA that sent Authentication frame
                         */
                        pKeyMapEntry = limLookUpKeyMappings(
                                                           pHdr->sa);

                        if (pKeyMapEntry)
                        {
                            if (pKeyMapEntry->key == NULL)
                            {
                                // Log error
                                PELOGE(limLog(pMac, LOGE,
                                       FL("received Auth frame from peer when "
                                       "key mapping key is NULL"MAC_ADDRESS_STR),
                                       MAC_ADDR_ARRAY(pHdr->sa));)

                                /**
                                 * Key Mapping entry has null key.
                                 * Send Auth frame with
                                 * challenge failure status code
                                 */
                                authFrame->authAlgoNumber =
                                pRxAuthFrameBody->authAlgoNumber;
                                authFrame->authTransactionSeqNumber =
                                pRxAuthFrameBody->authTransactionSeqNumber + 1;
                                authFrame->authStatusCode =
                                eSIR_MAC_CHALLENGE_FAILURE_STATUS;

                                limSendAuthMgmtFrame(pMac, authFrame,
                                                     pHdr->sa,
                                                     LIM_NO_WEP_IN_FC,
                                                     psessionEntry, eSIR_FALSE);

                                limRestoreFromAuthState(pMac, eSIR_SME_NO_KEY_MAPPING_KEY_FOR_PEER,
                                                              eSIR_MAC_UNSPEC_FAILURE_REASON,psessionEntry);

                                goto free;
                            } // if (pKeyMapEntry->key == NULL)
                            else
                            {
                                ((tpSirMacAuthFrameBody) plainBody)->authAlgoNumber =
                                sirSwapU16ifNeeded(pRxAuthFrameBody->authAlgoNumber);
                                ((tpSirMacAuthFrameBody) plainBody)->authTransactionSeqNumber =
                                sirSwapU16ifNeeded((tANI_U16) (pRxAuthFrameBody->authTransactionSeqNumber + 1));
                                ((tpSirMacAuthFrameBody) plainBody)->authStatusCode = eSIR_MAC_SUCCESS_STATUS;
                                ((tpSirMacAuthFrameBody) plainBody)->type   = SIR_MAC_CHALLENGE_TEXT_EID;
                                ((tpSirMacAuthFrameBody) plainBody)->length = pRxAuthFrameBody->length;
                                vos_mem_copy((tANI_U8 *) ((tpSirMacAuthFrameBody) plainBody)->challengeText,
                                              pRxAuthFrameBody->challengeText,
                                              pRxAuthFrameBody->length);

                                encrAuthFrame = vos_mem_malloc(pRxAuthFrameBody->length +
                                                               LIM_ENCR_AUTH_INFO_LEN);
                                if (!encrAuthFrame) {
                                    limLog(pMac, LOGE, FL("failed to allocate memory"));
                                    goto free;
                                }
                                vos_mem_set(encrAuthFrame, pRxAuthFrameBody->length +
                                            LIM_ENCR_AUTH_INFO_LEN, 0);

                                limEncryptAuthFrame(pMac, 0,
                                                    pKeyMapEntry->key,
                                                    plainBody,
                                                    encrAuthFrame,key_length);

                                psessionEntry->limMlmState = eLIM_MLM_WT_AUTH_FRAME4_STATE;
                                MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState));

                                limSendAuthMgmtFrame(pMac,
                                                     (tpSirMacAuthFrameBody) encrAuthFrame,
                                                     pHdr->sa,
                                                     pRxAuthFrameBody->length,
                                                     psessionEntry, eSIR_FALSE);

                                break;
                            } // end if (pKeyMapEntry->key == NULL)
                        } // if (pKeyMapEntry)
                        else
                        {
                            if (wlan_cfgGetInt(pMac, WNI_CFG_WEP_DEFAULT_KEYID,
                                          &val) != eSIR_SUCCESS)
                            {
                                /**
                                 * Could not get Default keyId
                                 * from CFG. Log error.
                                 */
                                limLog(pMac, LOGP,
                                       FL("could not retrieve Default keyId"));
                            }
                            keyId = (tANI_U8)val;

                            val = SIR_MAC_KEY_LENGTH;

                            if(psessionEntry->limSystemRole == eLIM_AP_ROLE)
                            {
                                tpSirKeys pKey;
                                pKey =  &psessionEntry->WEPKeyMaterial[keyId].key[0];
                                vos_mem_copy(defaultKey, pKey->key, pKey->keyLength);
                            }
                            else
                            if (wlan_cfgGetStr(pMac, (tANI_U16) (WNI_CFG_WEP_DEFAULT_KEY_1 + keyId),
                                          defaultKey,
                                          &val)
                                != eSIR_SUCCESS)
                            {
                                /// Could not get Default key from CFG.
                                //Log error.
                                limLog(pMac, LOGP,
                                       FL("could not retrieve Default key"));

                                authFrame->authAlgoNumber =
                                pRxAuthFrameBody->authAlgoNumber;
                                authFrame->authTransactionSeqNumber =
                                pRxAuthFrameBody->authTransactionSeqNumber + 1;
                                authFrame->authStatusCode =
                                eSIR_MAC_CHALLENGE_FAILURE_STATUS;

                                limSendAuthMgmtFrame(
                                                    pMac, authFrame,
                                                    pHdr->sa,
                                                    LIM_NO_WEP_IN_FC,
                                                    psessionEntry, eSIR_FALSE);

                                limRestoreFromAuthState(pMac, eSIR_SME_INVALID_WEP_DEFAULT_KEY,
                                                              eSIR_MAC_UNSPEC_FAILURE_REASON,psessionEntry);

                                break;
                            }
                                key_length=val;
                                ((tpSirMacAuthFrameBody) plainBody)->authAlgoNumber =
                                sirSwapU16ifNeeded(pRxAuthFrameBody->authAlgoNumber);
                                ((tpSirMacAuthFrameBody) plainBody)->authTransactionSeqNumber =
                                sirSwapU16ifNeeded((tANI_U16) (pRxAuthFrameBody->authTransactionSeqNumber + 1));
                                ((tpSirMacAuthFrameBody) plainBody)->authStatusCode = eSIR_MAC_SUCCESS_STATUS;
                                ((tpSirMacAuthFrameBody) plainBody)->type   = SIR_MAC_CHALLENGE_TEXT_EID;
                                ((tpSirMacAuthFrameBody) plainBody)->length = pRxAuthFrameBody->length;
                                vos_mem_copy((tANI_U8 *) ((tpSirMacAuthFrameBody) plainBody)->challengeText,
                                              pRxAuthFrameBody->challengeText,
                                              pRxAuthFrameBody->length);

                                encrAuthFrame = vos_mem_malloc(pRxAuthFrameBody->length +
                                                               LIM_ENCR_AUTH_INFO_LEN);
                                if (!encrAuthFrame) {
                                    limLog(pMac, LOGE, FL("failed to allocate memory"));
                                    goto free;
                                }
                                vos_mem_set(encrAuthFrame, pRxAuthFrameBody->length +
                                            LIM_ENCR_AUTH_INFO_LEN, 0);

                                limEncryptAuthFrame(pMac, keyId,
                                                    defaultKey,
                                                    plainBody,
                                                    encrAuthFrame,key_length);

                                psessionEntry->limMlmState =
                                eLIM_MLM_WT_AUTH_FRAME4_STATE;
                                MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState));

                                limSendAuthMgmtFrame(pMac,
                                                     (tpSirMacAuthFrameBody) encrAuthFrame,
                                                     pHdr->sa,
                                                     pRxAuthFrameBody->length,
                                                     psessionEntry, eSIR_FALSE);

                                break;
                        } // end if (pKeyMapEntry)
                    } // end if (!wlan_cfgGetInt(CFG_PRIVACY_OPTION_IMPLEMENTED))
                } // end if (pRxAuthFrameBody->authAlgoNumber == eSIR_OPEN_SYSTEM)
            } // if (pRxAuthFrameBody->authStatusCode == eSIR_MAC_SUCCESS_STATUS)
            else
            {
                /**
                 * Authentication failure.
                 * Return Auth confirm with received failure code to SME
                 */

                // Log error
                PELOGE(limLog(pMac, LOGE,
                       FL("received Auth frame from peer with failure code %d "
                       MAC_ADDRESS_STR), pRxAuthFrameBody->authStatusCode, 
                       MAC_ADDR_ARRAY(pHdr->sa));)

                limRestoreFromAuthState(pMac, eSIR_SME_AUTH_REFUSED,
                                              pRxAuthFrameBody->authStatusCode,psessionEntry);
            } // end if (pRxAuthFrameBody->authStatusCode == eSIR_MAC_SUCCESS_STATUS)

            break;

        case SIR_MAC_AUTH_FRAME_3:
            // AuthFrame 3

            if (pRxAuthFrameBody->authAlgoNumber != eSIR_SHARED_KEY)
            {
                // Log error
                PELOGE(limLog(pMac, LOGE,
                       FL("received Auth frame3 from peer with auth algo "
                       "number %d "MAC_ADDRESS_STR),
                       pRxAuthFrameBody->authAlgoNumber,
                       MAC_ADDR_ARRAY(pHdr->sa));)

                /**
                 * Received Authentication frame3 with algorithm other than
                 * Shared Key authentication type. Reject with Auth frame4
                 * with 'out of sequence' status code.
                 */
                authFrame->authAlgoNumber = eSIR_SHARED_KEY;
                authFrame->authTransactionSeqNumber =
                SIR_MAC_AUTH_FRAME_4;
                authFrame->authStatusCode =
                eSIR_MAC_AUTH_FRAME_OUT_OF_SEQ_STATUS;

                limSendAuthMgmtFrame(pMac, authFrame,
                                     pHdr->sa,
                                     LIM_NO_WEP_IN_FC,
                                     psessionEntry, eSIR_FALSE);

                goto free;
            }

            if (psessionEntry->limSystemRole == eLIM_AP_ROLE || psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE ||
                psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE)
            {
                /**
                 * Check if wep bit was set in FC. If not set,
                 * reject with Authentication frame4 with
                 * 'challenge failure' status code.
                 */
                if (!pHdr->fc.wep)
                {
                    // Log error
                    PELOGE(limLog(pMac, LOGE,
                           FL("received Auth frame3 from peer with no WEP bit "
                           "set "MAC_ADDRESS_STR),
                           MAC_ADDR_ARRAY(pHdr->sa));)

                    /// WEP bit is not set in FC of Auth Frame3
                    authFrame->authAlgoNumber = eSIR_SHARED_KEY;
                    authFrame->authTransactionSeqNumber =
                    SIR_MAC_AUTH_FRAME_4;
                    authFrame->authStatusCode =
                    eSIR_MAC_CHALLENGE_FAILURE_STATUS;

                    limSendAuthMgmtFrame(pMac, authFrame,
                                         pHdr->sa,
                                         LIM_NO_WEP_IN_FC,
                                         psessionEntry, eSIR_FALSE);

                    goto free;
                }

                pAuthNode = limSearchPreAuthList(pMac,
                                                pHdr->sa);
                if (pAuthNode == NULL)
                {
                     // Log error
                    PELOGE(limLog(pMac, LOGW,
                           FL("received AuthFrame3 from peer that has no "
                           "preauth context "MAC_ADDRESS_STR),
                            MAC_ADDR_ARRAY(pHdr->sa));)

                    /**
                     * No 'pre-auth' context exists for
                     * this STA that sent an Authentication
                     * frame3.
                     * Send Auth frame4 with 'out of sequence'
                     * status code.
                     */
                    authFrame->authAlgoNumber = eSIR_SHARED_KEY;
                    authFrame->authTransactionSeqNumber =
                    SIR_MAC_AUTH_FRAME_4;
                    authFrame->authStatusCode =
                    eSIR_MAC_AUTH_FRAME_OUT_OF_SEQ_STATUS;

                    limSendAuthMgmtFrame(pMac, authFrame,
                                         pHdr->sa,
                                         LIM_NO_WEP_IN_FC,
                                         psessionEntry, eSIR_FALSE);

                    goto free;
                }

                if (pAuthNode->mlmState == eLIM_MLM_AUTH_RSP_TIMEOUT_STATE)
                {
                    // Log error
                    limLog(pMac, LOGW,
                           FL("auth response timer timedout for peer "
                           MAC_ADDRESS_STR),MAC_ADDR_ARRAY(pHdr->sa));
                    /**
                     * Received Auth Frame3 after Auth Response timeout.
                     * Reject by sending Auth Frame4 with
                     * Auth respone timeout Status Code.
                     */
                    authFrame->authAlgoNumber = eSIR_SHARED_KEY;
                    authFrame->authTransactionSeqNumber =
                    SIR_MAC_AUTH_FRAME_4;
                    authFrame->authStatusCode =
                    eSIR_MAC_AUTH_RSP_TIMEOUT_STATUS;

                    limSendAuthMgmtFrame(
                                        pMac, authFrame,
                                        pHdr->sa,
                                        LIM_NO_WEP_IN_FC,
                                        psessionEntry, eSIR_FALSE);

                    /// Delete pre-auth context of STA
                    limDeletePreAuthNode(pMac,
                                         pHdr->sa);

                    goto free;
                } // end switch (pAuthNode->mlmState)

                if (pRxAuthFrameBody->authStatusCode != eSIR_MAC_SUCCESS_STATUS)
                {
                    /**
                     * Received Authenetication Frame 3 with status code
                     * other than success. Wait until Auth response timeout
                     * to delete STA context.
                     */

                    // Log error
                    PELOGE(limLog(pMac, LOGE,
                           FL("received Auth frame3 from peer with status code %d "
                           MAC_ADDRESS_STR), pRxAuthFrameBody->authStatusCode, 
                           MAC_ADDR_ARRAY(pHdr->sa));)

                    goto free;
                }

                /**
                 * Check if received challenge text is same as one sent in
                 * Authentication frame3
                 */

                if (vos_mem_compare(pRxAuthFrameBody->challengeText,
                                    pAuthNode->challengeText,
                                    SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH))
                {
                    /// Challenge match. STA is autheticated !

                    /// Delete Authentication response timer if running
                    limDeactivateAndChangePerStaIdTimer(pMac,
                                                        eLIM_AUTH_RSP_TIMER,
                                                        pAuthNode->authNodeIdx);

                    pAuthNode->fTimerStarted = 0;
                    pAuthNode->mlmState = eLIM_MLM_AUTHENTICATED_STATE;

                    /**
                     * Send Authentication Frame4 with 'success' Status Code.
                     */
                    authFrame->authAlgoNumber = eSIR_SHARED_KEY;
                    authFrame->authTransactionSeqNumber =
                        SIR_MAC_AUTH_FRAME_4;
                    authFrame->authStatusCode = eSIR_MAC_SUCCESS_STATUS;

                    limSendAuthMgmtFrame(pMac, authFrame,
                                         pHdr->sa,
                                         LIM_NO_WEP_IN_FC,
                                         psessionEntry, eSIR_FALSE);

                    /// Send Auth indication to SME
                    vos_mem_copy((tANI_U8 *) mlmAuthInd.peerMacAddr,
                                 (tANI_U8 *) pHdr->sa,
                                  sizeof(tSirMacAddr));
                    mlmAuthInd.authType = (tAniAuthType)
                                          pRxAuthFrameBody->authAlgoNumber;
                    mlmAuthInd.sessionId = psessionEntry->smeSessionId;

                    limPostSmeMessage(pMac,
                                      LIM_MLM_AUTH_IND,
                                      (tANI_U32 *) &mlmAuthInd);

                    break;
                }
                else
                {
                     // Log error
                    PELOGE( limLog(pMac, LOGW,
                                   FL("Challenge failure for peer "
                                   MAC_ADDRESS_STR),
                                   MAC_ADDR_ARRAY(pHdr->sa));)
                    /**
                     * Challenge Failure.
                     * Send Authentication frame4 with 'challenge failure'
                     * status code and wait until Auth response timeout to
                     * delete STA context.
                     */

                    authFrame->authAlgoNumber =
                        pRxAuthFrameBody->authAlgoNumber;
                    authFrame->authTransactionSeqNumber =
                        SIR_MAC_AUTH_FRAME_4;
                    authFrame->authStatusCode =
                        eSIR_MAC_CHALLENGE_FAILURE_STATUS;

                    limSendAuthMgmtFrame(pMac, authFrame,
                                         pHdr->sa,
                                         LIM_NO_WEP_IN_FC,
                                         psessionEntry, eSIR_FALSE);

                    goto free;
                }
            } // if (pMac->lim.gLimSystemRole == eLIM_AP_ROLE || ...

            break;

        case SIR_MAC_AUTH_FRAME_4:
            // AuthFrame 4
            if (psessionEntry->limMlmState != eLIM_MLM_WT_AUTH_FRAME4_STATE)
            {
                /**
                 * Received Authentication frame4 in an unexpected state.
                 * Log error and ignore the frame.
                 */

                // Log error
                limLog(pMac, LOG1,
                       FL("received unexpected Auth frame4 from peer in state "
                       "%d, addr "MAC_ADDRESS_STR), psessionEntry->limMlmState,
                       MAC_ADDR_ARRAY(pHdr->sa));

                goto free;
            }

            if (pRxAuthFrameBody->authAlgoNumber != eSIR_SHARED_KEY)
            {
                /**
                 * Received Authentication frame4 with algorithm other than
                 * Shared Key authentication type.
                 * Wait until Auth failure timeout to report authentication
                 * failure to SME.
                 */

                // Log error
                PELOGE(limLog(pMac, LOGE,
                       FL("received Auth frame4 from peer with invalid auth "
                       "algo %d "MAC_ADDRESS_STR), pRxAuthFrameBody->authAlgoNumber,
                       MAC_ADDR_ARRAY(pHdr->sa));)

                goto free;
            }

            if ( !vos_mem_compare((tANI_U8 *) pHdr->sa,
                                  (tANI_U8 *) &pMac->lim.gpLimMlmAuthReq->peerMacAddr,
                                  sizeof(tSirMacAddr)) )
            {
                /**
                 * Received Authentication frame from an entity
                 * other than one to which request was initiated.
                 * Wait until Authentication Failure Timeout.
                 */

                // Log error
                PELOGE(limLog(pMac, LOGW,
                       FL("received Auth frame4 from unexpected peer "
                       MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pHdr->sa));)

                break;
            }

            if (pRxAuthFrameBody->authAlgoNumber !=
                pMac->lim.gpLimMlmAuthReq->authType)
            {
                /**
                 * Received Authentication frame with an auth algorithm
                 * other than one requested.
                 * Wait until Authentication Failure Timeout.
                 */

                PELOGE(limLog(pMac, LOGE,
                       FL("received Authentication frame from peer with "
                       "invalid auth seq number %d "
                       MAC_ADDRESS_STR), pRxAuthFrameBody->authTransactionSeqNumber,
                       MAC_ADDR_ARRAY(pHdr->sa));)

                break;
            }

            if (pRxAuthFrameBody->authStatusCode ==
                eSIR_MAC_SUCCESS_STATUS)
            {
                /**
                 * Authentication Success !
                 * Inform SME of same.
                 */
                psessionEntry->limCurrentAuthType = eSIR_SHARED_KEY;

                pAuthNode = limAcquireFreePreAuthNode(pMac, &pMac->lim.gLimPreAuthTimerTable);
                if (pAuthNode == NULL)
                {
                    // Log error
                    limLog(pMac, LOGW,
                           FL("Max pre-auth nodes reached "));
                    limPrintMacAddr(pMac, pHdr->sa, LOGW);

                    goto free;
                }
                limLog(pMac, LOG1,
                         FL("Alloc new data: peer " MAC_ADDRESS_STR),
                                              MAC_ADDR_ARRAY(pHdr->sa));

                vos_mem_copy((tANI_U8 *) pAuthNode->peerMacAddr,
                             pMac->lim.gpLimMlmAuthReq->peerMacAddr,
                             sizeof(tSirMacAddr));
                pAuthNode->fTimerStarted = 0;
                pAuthNode->authType = pMac->lim.gpLimMlmAuthReq->authType;
                pAuthNode->seqNo = ((pHdr->seqControl.seqNumHi << 4) |
                                    (pHdr->seqControl.seqNumLo));
                pAuthNode->timestamp = vos_timer_get_system_ticks();
                limAddPreAuthNode(pMac, pAuthNode);

                limRestoreFromAuthState(pMac, eSIR_SME_SUCCESS,
                                              pRxAuthFrameBody->authStatusCode,psessionEntry);

            } // if (pRxAuthFrameBody->authStatusCode == eSIR_MAC_SUCCESS_STATUS)
            else
            {
                /**
                 * Authentication failure.
                 * Return Auth confirm with received failure code to SME
                 */

                // Log error
                PELOGE(limLog(pMac, LOGE, FL("Authentication failure from peer "
                       MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pHdr->sa));)

                limRestoreFromAuthState(pMac, eSIR_SME_AUTH_REFUSED,
                                              pRxAuthFrameBody->authStatusCode,psessionEntry);
            } // end if (pRxAuthFrameBody->Status == 0)

            break;

        default:
            /// Invalid Authentication Frame received. Ignore it.

            // Log error
            PELOGE(limLog(pMac, LOGE,
                   FL("received Auth frame from peer with invalid auth seq "
                   "number %d " MAC_ADDRESS_STR),
                   pRxAuthFrameBody->authTransactionSeqNumber,
                   MAC_ADDR_ARRAY(pHdr->sa));)

            break;
    } // end switch (pRxAuthFrameBody->authTransactionSeqNumber)

free:
    if (authFrame)
        vos_mem_free(authFrame);
    if (rxAuthFrame)
        vos_mem_free(rxAuthFrame);
    if (encrAuthFrame)
        vos_mem_free(encrAuthFrame);
    if (plainBody)
        vos_mem_free(plainBody);
    if (challengeTextArray)
        vos_mem_free(challengeTextArray);

} /*** end limProcessAuthFrame() ***/





#ifdef WLAN_FEATURE_VOWIFI_11R

/*----------------------------------------------------------------------
 *
 * Pass the received Auth frame. This is possibly the pre-auth from the
 * neighbor AP, in the same mobility domain.
 * This will be used in case of 11r FT.
 *
 * !!!! This is going to be renoved for the next checkin. We will be creating
 * the session before sending out the Auth. Thus when auth response
 * is received we will have a session in progress. !!!!!
 *----------------------------------------------------------------------
 */
tSirRetStatus limProcessAuthFrameNoSession(tpAniSirGlobal pMac, tANI_U8 *pBd, void *body)
{
    tpSirMacMgmtHdr pHdr;
    tpPESession psessionEntry = NULL;
    tANI_U8 *pBody;
    tANI_U16  frameLen;
    tSirMacAuthFrameBody rxAuthFrame;
    tSirMacAuthFrameBody *pRxAuthFrameBody = NULL;
    tSirRetStatus ret_status = eSIR_FAILURE;

    pHdr = WDA_GET_RX_MAC_HEADER(pBd);
    pBody = WDA_GET_RX_MPDU_DATA(pBd);
    frameLen = WDA_GET_RX_PAYLOAD_LEN(pBd);

    /*
     * since, roaming is not supported in sta + mon scc, ignore
     * pre-auth when capture on monitor mode is started
     */
    if (vos_check_monitor_state())
    {
        limLog(pMac, LOG1, FL("Ignore pre-auth frame in monitor mode"));
        return eSIR_FAILURE;
    }

    limLog(pMac, LOG1, FL("Auth Frame Received: BSSID " MAC_ADDRESS_STR
    " (RSSI %d)"),MAC_ADDR_ARRAY(pHdr->bssId),
    (uint)abs((tANI_S8)WDA_GET_RX_RSSI_DB(pBd)));
    // Check for the operating channel and see what needs to be done next.
    psessionEntry = pMac->ft.ftPEContext.psavedsessionEntry;
    if (psessionEntry == NULL) 
    {
        limLog(pMac, LOGE, FL("Error: Unable to find session id while in "
        "pre-auth phase for FT"));
        return eSIR_FAILURE;
    }

    if (pMac->ft.ftPEContext.pFTPreAuthReq == NULL)
    {
        limLog(pMac, LOGE, FL("Error: No FT"));
        // No FT in progress.
        return eSIR_FAILURE;
    }

    if (frameLen == 0) 
    {
        limLog(pMac, LOGE, FL("Error: Frame len = 0"));
        return eSIR_FAILURE;
    }
#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
    limPrintMacAddr(pMac, pHdr->bssId, LOG2);
    limPrintMacAddr(pMac, pMac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId, LOG2);
    limLog(pMac,LOG2,FL("seqControl 0x%X"),
            ((pHdr->seqControl.seqNumHi << 8) | 
            (pHdr->seqControl.seqNumLo << 4) |
            (pHdr->seqControl.fragNum)));
#endif

    // Check that its the same bssId we have for preAuth
    if (!vos_mem_compare(pMac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId,
                         pHdr->bssId, sizeof( tSirMacAddr )))
    {
        limLog(pMac, LOGE, FL("Error: NOT same bssid as preauth BSSID"));
        // In this case SME if indeed has triggered a 
        // pre auth it will time out.
        return eSIR_FAILURE;
    }

    if (eANI_BOOLEAN_TRUE ==
        pMac->ft.ftPEContext.pFTPreAuthReq->bPreAuthRspProcessed)
    {
        /*
         * This is likely a duplicate for the same pre-auth request.
         * PE/LIM already posted a response to SME. Hence, drop it.
         * TBD: 
         * 1) How did we even receive multiple auth responses?
         * 2) Do we need to delete pre-auth session? Suppose we
         * previously received an auth resp with failure which
         * would not have created the session and forwarded to SME.
         * And, we subsequently received an auth resp with success
         * which would have created the session. This will now be
         * dropped without being forwarded to SME! However, it is
         * very unlikely to receive auth responses from the same
         * AP with different reason codes.
         * NOTE: return eSIR_SUCCESS so that the packet is dropped
         * as this was indeed a response from the BSSID we tried to 
         * pre-auth.
         */
        PELOGE(limLog(pMac,LOG1,"Auth rsp already posted to SME"
               " (session %pK, FT session %pK)", psessionEntry,
               pMac->ft.ftPEContext.pftSessionEntry););
        return eSIR_SUCCESS;
    }
    else
    {
        PELOGE(limLog(pMac,LOGW,"Auth rsp not yet posted to SME"
               " (session %pK, FT session %pK)", psessionEntry,
               pMac->ft.ftPEContext.pftSessionEntry););
        pMac->ft.ftPEContext.pFTPreAuthReq->bPreAuthRspProcessed =
            eANI_BOOLEAN_TRUE;
    }

#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
    limLog(pMac, LOG1, FL("Pre-Auth response received from neighbor"));
    limLog(pMac, LOG1, FL("Pre-Auth done state"));
#endif

    limLog(pMac, LOG1, FL("is_preauth_lfr_mbb %d"),
                          pMac->ft.ftSmeContext.is_preauth_lfr_mbb);

    // Stopping timer now, that we have our unicast from the AP
    // of our choice.
    if (!pMac->ft.ftSmeContext.is_preauth_lfr_mbb)
        limDeactivateAndChangeTimer(pMac, eLIM_FT_PREAUTH_RSP_TIMER);

#ifdef WLAN_FEATURE_LFR_MBB
    if (pMac->ft.ftSmeContext.is_preauth_lfr_mbb)
        limDeactivateAndChangeTimer(pMac, eLIM_PREAUTH_MBB_RSP_TIMER);
#endif


    // Save off the auth resp.
    if ((sirConvertAuthFrame2Struct(pMac, pBody, frameLen, &rxAuthFrame) != eSIR_SUCCESS))
    {
        limLog(pMac, LOGE, FL("failed to convert Auth frame to struct"));

#ifdef WLAN_FEATURE_LFR_MBB
        if (pMac->ft.ftSmeContext.is_preauth_lfr_mbb) {
            lim_handle_pre_auth_mbb_rsp(pMac, eSIR_FAILURE, psessionEntry);
            return eSIR_FAILURE;
        }
#endif

        limHandleFTPreAuthRsp(pMac, eSIR_FAILURE, NULL, 0, psessionEntry);
        return eSIR_FAILURE;
    }
    pRxAuthFrameBody = &rxAuthFrame;

#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
    PELOGE(limLog(pMac, LOG1,
           FL("Received Auth frame with type=%d seqnum=%d, status=%d (%d)"),
           (tANI_U32) pRxAuthFrameBody->authAlgoNumber,
           (tANI_U32) pRxAuthFrameBody->authTransactionSeqNumber,
           (tANI_U32) pRxAuthFrameBody->authStatusCode,(tANI_U32)pMac->lim.gLimNumPreAuthContexts);)
#endif

    switch (pRxAuthFrameBody->authTransactionSeqNumber)
    {
        case SIR_MAC_AUTH_FRAME_2:
            if (pRxAuthFrameBody->authStatusCode != eSIR_MAC_SUCCESS_STATUS)
            {
#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
                PELOGE(limLog( pMac, LOGE, "Auth status code received is %d",
                    (tANI_U32) pRxAuthFrameBody->authStatusCode););
#endif
                if (eSIR_MAC_MAX_ASSOC_STA_REACHED_STATUS == pRxAuthFrameBody->authStatusCode)
                    ret_status = eSIR_LIM_MAX_STA_REACHED_ERROR;
            }
            else 
            {
                ret_status = eSIR_SUCCESS;
            }
            break;

        default:
#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
            PELOGE(limLog( pMac, LOGE, "Seq. no incorrect expected 2 received %d",
                (tANI_U32) pRxAuthFrameBody->authTransactionSeqNumber);)
#endif
            break;
    }

#ifdef WLAN_FEATURE_LFR_MBB
        if (pMac->ft.ftSmeContext.is_preauth_lfr_mbb) {
            lim_handle_pre_auth_mbb_rsp(pMac, ret_status, psessionEntry);
            return ret_status;
        }
#endif

    // Send the Auth response to SME
    limHandleFTPreAuthRsp(pMac, ret_status, pBody, frameLen, psessionEntry);

    return ret_status;
}

#endif /* WLAN_FEATURE_VOWIFI_11R */

