/*
 * Copyright (c) 2011-2015, 2017-2018, 2020 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_external_auth_add_pre_auth_node()- Add preauth node for the peer
 *                                        performing external authentication
 * @mac_ctx: MAC context
 * @mac_hdr: Mac header of the packet
 * @mlm_state: MLM state to be marked to track SAE authentication
 *
 * Return: None
 */
static void lim_external_auth_add_pre_auth_node(tpAniSirGlobal mac_ctx,
                                                tpSirMacMgmtHdr mac_hdr,
                                                tLimMlmStates mlm_state)
{
    struct tLimPreAuthNode *auth_node;
    tpLimPreAuthTable preauth_table = &mac_ctx->lim.gLimPreAuthTimerTable;

    limLog(mac_ctx, LOG1, FL("=======> eSIR_AUTH_TYPE_SAE"));
    /* Create entry for this STA in pre-auth list */
    auth_node = limAcquireFreePreAuthNode(mac_ctx, preauth_table);
    if (!auth_node) {
        limLog(mac_ctx, LOG1,
                "Max pre-auth nodes reached " MAC_ADDRESS_STR,
                MAC_ADDR_ARRAY(mac_hdr->sa));
        return;
    }
    limLog(mac_ctx, LOG1,
            "Creating preauth node for SAE peer " MAC_ADDRESS_STR,
            MAC_ADDR_ARRAY(mac_hdr->sa));
    vos_mem_copy((uint8_t *)auth_node->peerMacAddr,
                mac_hdr->sa, sizeof(tSirMacAddr));
    auth_node->mlmState = mlm_state;
    auth_node->authType = eSIR_AUTH_TYPE_SAE;
    auth_node->timestamp = vos_timer_get_system_ticks();
    auth_node->seqNo = ((mac_hdr->seqControl.seqNumHi << 4) |
                        (mac_hdr->seqControl.seqNumLo));
    auth_node->assoc_req.present = false;
    limAddPreAuthNode(mac_ctx, auth_node);
}


/**
 * 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;
    enum rxmgmt_flags rx_flags = RXMGMT_FLAG_NONE;

    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 (LIM_IS_STA_ROLE(pe_session) &&
        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);

    if(LIM_IS_AP_ROLE(pe_session)) {
            struct tLimPreAuthNode *sta_pre_auth_ctx;

            rx_flags = RXMGMT_FLAG_EXTERNAL_AUTH;
            /* Add preauth node when the first SAE authentication frame
             * is received and mark state as authenticating.
             * It's not good to track SAE authentication frames with
             * authTransactionSeqNumber as it's subjected to
             * SAE protocol optimizations.
             */
            /* Extract pre-auth context for the STA, if any. */
            sta_pre_auth_ctx = limSearchPreAuthList(mac_ctx,
                                                    mac_hdr->sa);
            if (!sta_pre_auth_ctx ||
                (sta_pre_auth_ctx->mlmState != eLIM_MLM_WT_SAE_AUTH_STATE &&
                sta_pre_auth_ctx->mlmState !=
                eLIM_MLM_AUTHENTICATED_STATE)) {
                    lim_external_auth_add_pre_auth_node(mac_ctx, mac_hdr,
                                                    eLIM_MLM_WT_SAE_AUTH_STATE);
            }
    }

    limSendSmeMgmtFrameInd(mac_ctx, pe_session->peSessionId,
                           rx_pkt_info, pe_session,
                           WDA_GET_RX_RSSI_DB(rx_pkt_info), rx_flags);
}
#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) {
         if (LIM_IS_STA_ROLE(psessionEntry) ||
             LIM_IS_AP_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("Auth frame received in mlm state: %d(staId: %d, assocId: %d)"),
                            pStaDs->mlmStaContext.mlmState,
                            pStaDs->staIndex, assocId);
                    if (pStaDs->mlmStaContext.mlmState ==
                        eLIM_MLM_LINK_ESTABLISHED_STATE) {
                        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 */

