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

/*
 *
 * 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 "wni_cfg.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"
#include "lim_process_fils.h"

/**
 * 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 = 1;

    if (((auth->authTransactionSeqNumber == SIR_MAC_AUTH_FRAME_1) ||
         (auth->authTransactionSeqNumber == SIR_MAC_AUTH_FRAME_3)) &&
         (LIM_IS_STA_ROLE(sessionEntry) ||
          LIM_IS_BT_AMP_STA_ROLE(sessionEntry)))
        valid = 0;

    if (((auth->authTransactionSeqNumber == SIR_MAC_AUTH_FRAME_2) ||
         (auth->authTransactionSeqNumber == SIR_MAC_AUTH_FRAME_4)) &&
         (LIM_IS_AP_ROLE(sessionEntry) || LIM_IS_BT_AMP_AP_ROLE(sessionEntry)))
        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;
}


/**
 * 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                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                currSeqNum = 0;

    // 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
        PELOGE(limLog(pMac, LOGE,
               FL("received Auth frame from a BC/MC address - "));)
        PELOGE( limPrintMacAddr(pMac, pHdr->sa, LOGE);)

        return;
    }
    currSeqNum = (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, GET_LIM_SYSTEM_ROLE(psessionEntry),
               psessionEntry->limMlmState, MAC_ADDR_ARRAY(pHdr->bssId),
              (uint)abs((tANI_S8)WDA_GET_RX_RSSI_NORMALIZED(pRxPacketInfo)));

    pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);

    //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) &&
             LIM_IS_AP_ROLE(psessionEntry)) {
            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 (LIM_IS_STA_ROLE(psessionEntry) ||
            LIM_IS_BT_AMP_STA_ROLE(psessionEntry)) {
            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), GET_LIM_SYSTEM_ROLE(psessionEntry),
                   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 (LIM_IS_AP_ROLE(psessionEntry)) {
            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)
                    {
                        // 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 (LIM_IS_AP_ROLE(psessionEntry)) {
                    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)
                    {
                         // 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))
    } // 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);)
    if (!lim_is_valid_fils_auth_frame(pMac, psessionEntry, pRxAuthFrameBody))
    {
        limLog(pMac, LOGE, FL("Received invalid FILS auth packet"));
        goto free;
    }
    // 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, just delete the STA here as it will
                 * retry to connect back after timeout.
                 *
                 * 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
#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);
                    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 (pHdr->fc.retry == 0 || pAuthNode->seqNum != currSeqNum)
                {
                    /**
                     * 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);
                    }
                    limLog(pMac, LOGW, 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
                     * */
                    limLog(pMac, LOGW, 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;
                        }

                        PELOG1(limLog(pMac, LOG1, FL("Alloc new data: %pK peer"), pAuthNode);
                        limPrintMacAddr(pMac, pHdr->sa, LOG1);)

                        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->seqNum = ((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 (LIM_IS_AP_ROLE(psessionEntry)) {
                            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->seqNum =
                                    ((pHdr->seqControl.seqNumHi << 4) |
                                     (pHdr->seqControl.seqNumLo));
                            pAuthNode->timestamp = vos_timer_get_system_ticks();
                            limAddPreAuthNode(pMac, pAuthNode);

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

                            /// 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)
            {
#ifdef WLAN_FEATURE_VOWIFI_11R
                /**
                 * Check if a Reassociation is in progress and this is a
                 * Pre-Auth frame
                 */
                if ((LIM_IS_STA_ROLE(psessionEntry) ||
                     LIM_IS_BT_AMP_STA_ROLE(psessionEntry)) &&
                    (psessionEntry->limSmeState == eLIM_SME_WT_REASSOC_STATE) &&
                    (pRxAuthFrameBody->authStatusCode == eSIR_MAC_SUCCESS_STATUS) &&
                    (psessionEntry->ftPEContext.pFTPreAuthReq != NULL) &&
                    (vos_mem_compare(
                        psessionEntry->ftPEContext.pFTPreAuthReq->preAuthbssId,
                        pHdr->sa, sizeof(tSirMacAddr))))
                {
                    // Update the FTIEs in the saved auth response
                    PELOGW(limLog(pMac, LOGW, FL("received another PreAuth frame2"
                           " from peer " MAC_ADDRESS_STR" in Smestate %d"),
                           MAC_ADDR_ARRAY(pHdr->sa), psessionEntry->limSmeState);)

                    psessionEntry->ftPEContext.saved_auth_rsp_length = 0;
                    if ((pBody != NULL) && (frameLen < MAX_FTIE_SIZE))
                    {
                        vos_mem_copy(psessionEntry->ftPEContext.saved_auth_rsp,
                                     pBody, frameLen);
                        psessionEntry->ftPEContext.saved_auth_rsp_length = frameLen;
                    }
                }
                else
#endif
                {
                    /**
                     * Received Authentication frame2 in an unexpected state.
                     * Log error and ignore the frame.
                     */

                    // Log error
                    PELOG1(limLog(pMac, LOG1,
                           FL("received Auth frame2 from peer in state %d, addr "),
                           psessionEntry->limMlmState);)
                    PELOG1(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)
            {
                /**
                 * 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 number %d "
                       MAC_ADDRESS_STR), pRxAuthFrameBody->authAlgoNumber,
                       MAC_ADDR_ARRAY(pHdr->sa));)

                break;
            }

            if (pRxAuthFrameBody->authStatusCode ==
                eSIR_MAC_SUCCESS_STATUS)
            {
                if (lim_process_fils_auth_frame2(pMac, psessionEntry, pRxAuthFrameBody))
                {
                    limRestoreFromAuthState(pMac, eSIR_SME_SUCCESS,
                                           pRxAuthFrameBody->authStatusCode, psessionEntry);
                    goto free;
                }
                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;
                    }

                    PELOG1(limLog(pMac, LOG1, FL("Alloc new data: %pK peer "), pAuthNode);)
                    PELOG1(limPrintMacAddr(pMac, pHdr->sa, LOG1);)

                    vos_mem_copy((tANI_U8 *) pAuthNode->peerMacAddr,
                                 pMac->lim.gpLimMlmAuthReq->peerMacAddr,
                                 sizeof(tSirMacAddr));
                    pAuthNode->fTimerStarted = 0;
                    pAuthNode->seqNum = ((pHdr->seqControl.seqNumHi << 4) |
                                    (pHdr->seqControl.seqNumLo));
                    pAuthNode->authType = pMac->lim.gpLimMlmAuthReq->authType;
                    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 (LIM_IS_AP_ROLE(psessionEntry)) {
                        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)
                        {
                                ((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;
                        } // 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 (LIM_IS_AP_ROLE(psessionEntry)) {
                                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 (LIM_IS_AP_ROLE(psessionEntry) ||
                LIM_IS_BT_AMP_AP_ROLE(psessionEntry) ||
                LIM_IS_IBSS_ROLE(psessionEntry)) {
                /**
                 * 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
                PELOG1(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;
                }
                PELOG1(limLog(pMac, LOG1, FL("Alloc new data: %pK peer "), pAuthNode);
                limPrintMacAddr(pMac, pHdr->sa, LOG1);)

                vos_mem_copy((tANI_U8 *) pAuthNode->peerMacAddr,
                             pMac->lim.gpLimMlmAuthReq->peerMacAddr,
                             sizeof(tSirMacAddr));
                pAuthNode->fTimerStarted = 0;
                pAuthNode->authType = pMac->lim.gpLimMlmAuthReq->authType;
                pAuthNode->seqNum = ((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 = NULL;
    tSirMacAuthFrameBody *pRxAuthFrameBody = NULL;
    tSirRetStatus ret_status = eSIR_FAILURE;
    int i;

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

    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_NORMALIZED(pBd)));

    /* Auth frame has come on a new BSS, however, we need to find the session
     * from where the auth-req was sent to the new AP
     */
    for (i = 0; i < pMac->lim.maxBssId; i++) {
        /* Find first free room in session table */
        if (pMac->lim.gpSession[i].valid == TRUE &&
           pMac->lim.gpSession[i].ftPEContext.ftPreAuthSession == VOS_TRUE) {
            /* Found the session */
            psessionEntry = &pMac->lim.gpSession[i];
            pMac->lim.gpSession[i].ftPEContext.ftPreAuthSession = VOS_FALSE;
        }
    }

    if (psessionEntry == NULL)
    {
        limLog(pMac, LOGE,
        FL("Error: Unable to find session id while in pre-auth phase for FT"));
        return eSIR_FAILURE;
    }

    if (psessionEntry->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,
                psessionEntry->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(psessionEntry->ftPEContext.pFTPreAuthReq->preAuthbssId,
                         pHdr->bssId, sizeof( tSirMacAddr )))
    {
        limLog(pMac, LOGE, FL("Error: 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 ==
        psessionEntry->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,
               psessionEntry););
        return eSIR_SUCCESS;
    }
    else
    {
        PELOGE(limLog(pMac,LOGW,"Auth rsp not yet posted to SME"
               " (session %pK, FT session %pK)", psessionEntry,
               psessionEntry););
        psessionEntry->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
    // Stopping timer now, that we have our unicast from the AP
    // of our choice.
    limDeactivateAndChangeTimer(pMac, eLIM_FT_PREAUTH_RSP_TIMER);

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


    // Save off the auth resp.
    if ((sirConvertAuthFrame2Struct(pMac, pBody, frameLen, rxAuthFrame) != eSIR_SUCCESS))
    {
        limLog(pMac, LOGE, FL("failed to convert Auth frame to struct"));
        limHandleFTPreAuthRsp(pMac, eSIR_FAILURE, NULL, 0, psessionEntry);
        ret_status = eSIR_FAILURE;
        goto free;
    }
    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;
    }

    // Send the Auth response to SME
    limHandleFTPreAuthRsp(pMac, ret_status, pBody, frameLen, psessionEntry);
free:
    if (rxAuthFrame)
        vos_mem_free(rxAuthFrame);

    return ret_status;
}

#endif /* WLAN_FEATURE_VOWIFI_11R */
