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

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

/**========================================================================

  \file  wlan_hdd_assoc.c
  \brief WLAN Host Device Driver implementation

  ========================================================================*/
/**=========================================================================
                       EDIT HISTORY FOR FILE


  This section contains comments describing changes made to the module.
  Notice that changes are listed in reverse chronological order.


  $Header:$   $DateTime: $ $Author: $


  when        who    what, where, why
  --------    ---    --------------------------------------------------------
  05/06/09     Shailender     Created module.
  ==========================================================================*/

#include "wlan_hdd_includes.h"
#include <aniGlobal.h>
#include "dot11f.h"
#include "wlan_nlink_common.h"
#include "wlan_hdd_power.h"
#include "wlan_hdd_trace.h"
#include <linux/ieee80211.h>
#include <linux/wireless.h>
#include <net/cfg80211.h>
#include "wlan_hdd_cfg80211.h"
#include "csrInsideApi.h"
#include "wlan_hdd_p2p.h"
#ifdef FEATURE_WLAN_TDLS
#include "wlan_hdd_tdls.h"
#endif
#include "sme_Api.h"
#include "wlan_hdd_hostapd.h"
#ifdef IPA_OFFLOAD
#include <wlan_hdd_ipa.h>
#endif
#include <vos_sched.h>
#include <wlan_logging_sock_svc.h>
#include "tl_shim.h"
#include "wlan_hdd_oemdata.h"
#include "wlan_hdd_tsf.h"

#include "adf_trace.h"

#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN
#include "wlan_hdd_hostapd.h"
#endif//#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN

struct ether_addr
{
    u_char  ether_addr_octet[6];
};
// These are needed to recognize WPA and RSN suite types
#define HDD_WPA_OUI_SIZE 4
v_U8_t ccpWpaOui00[ HDD_WPA_OUI_SIZE ] = { 0x00, 0x50, 0xf2, 0x00 };
v_U8_t ccpWpaOui01[ HDD_WPA_OUI_SIZE ] = { 0x00, 0x50, 0xf2, 0x01 };
v_U8_t ccpWpaOui02[ HDD_WPA_OUI_SIZE ] = { 0x00, 0x50, 0xf2, 0x02 };
v_U8_t ccpWpaOui03[ HDD_WPA_OUI_SIZE ] = { 0x00, 0x50, 0xf2, 0x03 };
v_U8_t ccpWpaOui04[ HDD_WPA_OUI_SIZE ] = { 0x00, 0x50, 0xf2, 0x04 };
v_U8_t ccpWpaOui05[ HDD_WPA_OUI_SIZE ] = { 0x00, 0x50, 0xf2, 0x05 };
#ifdef FEATURE_WLAN_ESE
v_U8_t ccpWpaOui06[ HDD_WPA_OUI_SIZE ] = { 0x00, 0x40, 0x96, 0x00 }; // CCKM
#endif /* FEATURE_WLAN_ESE */
#define HDD_RSN_OUI_SIZE 4
v_U8_t ccpRSNOui00[ HDD_RSN_OUI_SIZE ] = { 0x00, 0x0F, 0xAC, 0x00 }; // group cipher
v_U8_t ccpRSNOui01[ HDD_RSN_OUI_SIZE ] = { 0x00, 0x0F, 0xAC, 0x01 }; // WEP-40 or RSN
v_U8_t ccpRSNOui02[ HDD_RSN_OUI_SIZE ] = { 0x00, 0x0F, 0xAC, 0x02 }; // TKIP or RSN-PSK
v_U8_t ccpRSNOui03[ HDD_RSN_OUI_SIZE ] = { 0x00, 0x0F, 0xAC, 0x03 }; // Reserved
v_U8_t ccpRSNOui04[ HDD_RSN_OUI_SIZE ] = { 0x00, 0x0F, 0xAC, 0x04 }; // AES-CCMP
v_U8_t ccpRSNOui05[ HDD_RSN_OUI_SIZE ] = { 0x00, 0x0F, 0xAC, 0x05 }; // WEP-104
#ifdef FEATURE_WLAN_ESE
v_U8_t ccpRSNOui06[ HDD_RSN_OUI_SIZE ] = { 0x00, 0x40, 0x96, 0x00 }; // CCKM
#endif /* FEATURE_WLAN_ESE */
#ifdef WLAN_FEATURE_11W
v_U8_t ccpRSNOui07[ HDD_RSN_OUI_SIZE ] = { 0x00, 0x0F, 0xAC, 0x06 }; // RSN-PSK-SHA256
/* RSN-8021X-SHA256 */
v_U8_t ccpRSNOui08[ HDD_RSN_OUI_SIZE ] = { 0x00, 0x0F, 0xAC, 0x05 };
#endif

#ifdef WLAN_FEATURE_FILS_SK
uint8_t ccp_rsn_oui_0e[HDD_RSN_OUI_SIZE] = {0x00, 0x0F, 0xAC, 0x0E};
uint8_t ccp_rsn_oui_0f[HDD_RSN_OUI_SIZE] = {0x00, 0x0F, 0xAC, 0x0F};
uint8_t ccp_rsn_oui_10[HDD_RSN_OUI_SIZE] = {0x00, 0x0F, 0xAC, 0x10};
uint8_t ccp_rsn_oui_11[HDD_RSN_OUI_SIZE] = {0x00, 0x0F, 0xAC, 0x11};
#endif

#if defined(WLAN_FEATURE_VOWIFI_11R)
// Offset where the EID-Len-IE, start.
#define FT_ASSOC_RSP_IES_OFFSET 6 /* Capability(2) + AID(2) + Status Code(2)*/
#define FT_ASSOC_REQ_IES_OFFSET 4 /* Capability(2) + LI(2) */
#endif

#define BEACON_FRAME_IES_OFFSET 12

#define NUM_BITS_IN_INT 32
static const int beacon_filter_table[] = {
	SIR_MAC_DS_PARAM_SET_EID,
	SIR_MAC_ERP_INFO_EID,
	SIR_MAC_EDCA_PARAM_SET_EID,
	SIR_MAC_QOS_CAPABILITY_EID,
	SIR_MAC_HT_INFO_EID,
#ifdef WLAN_FEATURE_11AC
	SIR_MAC_VHT_OPMODE_EID,
	SIR_MAC_VHT_OPERATION_EID,
#endif
};

static eHalStatus hdd_RoamSetKeyCompleteHandler( hdd_adapter_t *pAdapter,
                                                tCsrRoamInfo *pRoamInfo,
                                                tANI_U32 roamId,
                                                eRoamCmdStatus roamStatus,
                                                eCsrRoamResult roamResult );

static v_VOID_t
hdd_connSetAuthenticated(hdd_adapter_t *pAdapter, v_U8_t authState)
{
   hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
   hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);

   /* save the new connection state */
   hddLog(LOG1, FL("Authenticated state Changed from oldState:%d to State:%d"),
                    pHddStaCtx->conn_info.uIsAuthenticated, authState);
   pHddStaCtx->conn_info.uIsAuthenticated = authState;

   /* Check is pending ROC request or not when auth state changed */
   schedule_delayed_work(&pHddCtx->rocReqWork, 0);
}

v_VOID_t hdd_connSetConnectionState( hdd_adapter_t *pAdapter,
                                                eConnectionState connState )
{
   hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
   hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);

   /* save the new connection state */
   hddLog(LOG1, FL("%pS Changed connectionState from oldState:%d to State:%d"),
                    (void *)_RET_IP_,
                    pHddStaCtx->conn_info.connState, connState);

   hdd_tsf_notify_wlan_state_change(pAdapter,
		   pHddStaCtx->conn_info.connState, connState);
   pHddStaCtx->conn_info.connState = connState;

   /* Check is pending ROC request or not when connection state changed */
   schedule_delayed_work(&pHddCtx->rocReqWork, 0);
}

// returns FALSE if not connected.
// returns TRUE for the two 'connected' states (Infra Associated or IBSS Connected ).
// returns the connection state.  Can specify NULL if you dont' want to get the actual state.

static inline v_BOOL_t hdd_connGetConnectionState( hdd_station_ctx_t *pHddStaCtx,
                                    eConnectionState *pConnState )
{
   v_BOOL_t fConnected;
   eConnectionState connState;

   // get the connection state.
   connState = pHddStaCtx->conn_info.connState;
   // Set the fConnected return variable based on the Connected State.
   if ( eConnectionState_Associated == connState ||
        eConnectionState_IbssConnected == connState ||
        eConnectionState_IbssDisconnected == connState)
   {
      fConnected = VOS_TRUE;
   }
   else
   {
      fConnected = VOS_FALSE;
   }

   if ( pConnState )
   {
      *pConnState = connState;
   }

   return( fConnected );
}

v_BOOL_t hdd_connIsConnected( hdd_station_ctx_t *pHddStaCtx )
{
   return( hdd_connGetConnectionState( pHddStaCtx, NULL ) );
}

bool hdd_is_connecting(hdd_station_ctx_t *hdd_sta_ctx)
{
	return (hdd_sta_ctx->conn_info.connState ==
		eConnectionState_Connecting);
}

eCsrBand hdd_connGetConnectedBand( hdd_station_ctx_t *pHddStaCtx )
{
   v_U8_t staChannel = 0;

   if ( eConnectionState_Associated == pHddStaCtx->conn_info.connState )
   {
       staChannel = pHddStaCtx->conn_info.operationChannel;
   }

   if ( staChannel > 0 && staChannel < 14 )
       return eCSR_BAND_24;
   else if (staChannel >= 36 && staChannel <= 184 )
      return eCSR_BAND_5G;
   else  /* If station is not connected return as eCSR_BAND_ALL */
      return eCSR_BAND_ALL;
}

static inline v_BOOL_t hdd_connGetConnectedCipherAlgo( hdd_station_ctx_t *pHddStaCtx, eCsrEncryptionType *pConnectedCipherAlgo )
{
    v_BOOL_t fConnected = VOS_FALSE;

    fConnected = hdd_connGetConnectionState( pHddStaCtx, NULL );

    if ( pConnectedCipherAlgo )
    {
        *pConnectedCipherAlgo = pHddStaCtx->conn_info.ucEncryptionType;
    }

    return( fConnected );
}

inline v_BOOL_t hdd_connGetConnectedBssType( hdd_station_ctx_t *pHddStaCtx, eMib_dot11DesiredBssType *pConnectedBssType )
{
    v_BOOL_t fConnected = VOS_FALSE;

    fConnected = hdd_connGetConnectionState( pHddStaCtx, NULL );

    if ( pConnectedBssType )
    {
        *pConnectedBssType = pHddStaCtx->conn_info.connDot11DesiredBssType;
    }

    return( fConnected );
}

static inline void hdd_connSaveConnectedBssType( hdd_station_ctx_t *pHddStaCtx, eCsrRoamBssType csrRoamBssType )
{
   switch( csrRoamBssType )
   {
      case eCSR_BSS_TYPE_INFRASTRUCTURE:
          pHddStaCtx->conn_info.connDot11DesiredBssType = eMib_dot11DesiredBssType_infrastructure;
         break;

      case eCSR_BSS_TYPE_IBSS:
      case eCSR_BSS_TYPE_START_IBSS:
          pHddStaCtx->conn_info.connDot11DesiredBssType = eMib_dot11DesiredBssType_independent;
         break;

      /** We will never set the BssType to 'any' when attempting a connection
            so CSR should never send this back to us.*/
      case eCSR_BSS_TYPE_ANY:
      default:
         VOS_ASSERT( 0 );
         break;
   }

}

/**
 * hdd_unset_beacon_filter() - remove beacon filter
 * @adapter: Pointer to the hdd adapter
 *
 * Return: 0 on success and errno on failure
 */
static int hdd_unset_beacon_filter(hdd_adapter_t *adapter)
{
	VOS_STATUS vos_status = VOS_STATUS_E_FAILURE;

	vos_status = sme_unset_beacon_filter(adapter->sessionId);
	if (!VOS_IS_STATUS_SUCCESS(vos_status))
		return -EFAULT;

	return 0;
}

/**
 * hdd_set_beacon_filter() - set beacon filter
 * @adapter: Pointer to the hdd adapter
 *
 * Return: 0 on success and errno on failure
 */
static int hdd_set_beacon_filter(hdd_adapter_t *adapter)
{
	int i;
	uint32_t ie_map[8] = {0};
	VOS_STATUS vos_status = VOS_STATUS_E_FAILURE;
	tHalHandle hal_ptr = WLAN_HDD_GET_HAL_CTX(adapter);
	tpAniSirGlobal mac_ptr = PMAC_STRUCT(hal_ptr);

	for (i = 0; i < ARRAY_SIZE(beacon_filter_table); i++)
		__set_bit(beacon_filter_table[i],
			  (unsigned long int *)ie_map);


	if (TRUE == mac_ptr->sta_change_cc_via_beacon &&
	    adapter->device_mode == WLAN_HDD_INFRA_STATION)
		__set_bit(SIR_MAC_COUNTRY_EID, (unsigned long int *)ie_map);

	vos_status = sme_set_beacon_filter(adapter->sessionId, ie_map);
	if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
		hddLog(LOGE, "%s: failed to set beacon filter",
			 __func__);
		return -EFAULT;
	}
	return 0;
}

/**
 * hdd_copy_vht_caps()- copy vht caps info from roam info to
 *  hdd station context.
 * @hdd_sta_ctx: pointer to hdd station context
 * @roam_info: pointer to roam info
 *
 * Return: None
 */
static void hdd_copy_ht_caps(hdd_station_ctx_t *hdd_sta_ctx,
				     tCsrRoamInfo *roam_info)
{
	tDot11fIEHTCaps *roam_ht_cap = &roam_info->ht_caps;
	struct ieee80211_ht_cap *hdd_ht_cap = &hdd_sta_ctx->conn_info.ht_caps;
	uint32_t i, temp_ht_cap;

	adf_os_mem_zero(hdd_ht_cap, sizeof(struct ieee80211_ht_cap));

	if (roam_ht_cap->advCodingCap)
		hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_LDPC_CODING;
	if (roam_ht_cap->supportedChannelWidthSet)
		hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
	temp_ht_cap = roam_ht_cap->mimoPowerSave &
	    (IEEE80211_HT_CAP_SM_PS >> IEEE80211_HT_CAP_SM_PS_SHIFT);
	if (temp_ht_cap)
		hdd_ht_cap->cap_info |=
			temp_ht_cap << IEEE80211_HT_CAP_SM_PS_SHIFT;
	if (roam_ht_cap->greenField)
		hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_GRN_FLD;
	if (roam_ht_cap->shortGI20MHz)
		hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_SGI_20;
	if (roam_ht_cap->shortGI40MHz)
		hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_SGI_40;
	if (roam_ht_cap->txSTBC)
		hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_TX_STBC;
	temp_ht_cap = roam_ht_cap->rxSTBC & (IEEE80211_HT_CAP_RX_STBC >>
	    IEEE80211_HT_CAP_RX_STBC_SHIFT);
	if (temp_ht_cap)
		hdd_ht_cap->cap_info |=
			temp_ht_cap << IEEE80211_HT_CAP_RX_STBC_SHIFT;
	if (roam_ht_cap->delayedBA)
		hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_DELAY_BA;
	if (roam_ht_cap->maximalAMSDUsize)
		hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_MAX_AMSDU;
	if (roam_ht_cap->dsssCckMode40MHz)
		hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_DSSSCCK40;
	if (roam_ht_cap->psmp)
		hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_RESERVED;
	if (roam_ht_cap->stbcControlFrame)
		hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_40MHZ_INTOLERANT;
	if (roam_ht_cap->lsigTXOPProtection)
		hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_LSIG_TXOP_PROT;

	/* 802.11n HT capability AMPDU settings (for ampdu_params_info) */
	if (roam_ht_cap->maxRxAMPDUFactor)
		hdd_ht_cap->ampdu_params_info |=
			IEEE80211_HT_AMPDU_PARM_FACTOR;
	temp_ht_cap = roam_ht_cap->mpduDensity &
	    (IEEE80211_HT_AMPDU_PARM_DENSITY >>
	     IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT);
	if (temp_ht_cap)
		hdd_ht_cap->ampdu_params_info |=
		temp_ht_cap << IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT;

	/* 802.11n HT extended capabilities masks */
	if (roam_ht_cap->pco)
		hdd_ht_cap->extended_ht_cap_info |=
			IEEE80211_HT_EXT_CAP_PCO;
	temp_ht_cap = roam_ht_cap->transitionTime &
	    (IEEE80211_HT_EXT_CAP_PCO_TIME >>
	    IEEE80211_HT_EXT_CAP_PCO_TIME_SHIFT);
	if (temp_ht_cap)
		hdd_ht_cap->extended_ht_cap_info |=
			temp_ht_cap << IEEE80211_HT_EXT_CAP_PCO_TIME_SHIFT;
	temp_ht_cap = roam_ht_cap->mcsFeedback &
	    (IEEE80211_HT_EXT_CAP_MCS_FB >> IEEE80211_HT_EXT_CAP_MCS_FB_SHIFT);
	if (temp_ht_cap)
		hdd_ht_cap->extended_ht_cap_info |=
			temp_ht_cap << IEEE80211_HT_EXT_CAP_MCS_FB_SHIFT;

	/* tx_bf_cap_info capabilities */
	if (roam_ht_cap->txBF)
		hdd_ht_cap->tx_BF_cap_info |= TX_BF_CAP_INFO_TX_BF;
	if (roam_ht_cap->rxStaggeredSounding)
		hdd_ht_cap->tx_BF_cap_info |=
			TX_BF_CAP_INFO_RX_STAG_RED_SOUNDING;
	if (roam_ht_cap->txStaggeredSounding)
		hdd_ht_cap->tx_BF_cap_info |=
			TX_BF_CAP_INFO_TX_STAG_RED_SOUNDING;
	if (roam_ht_cap->rxZLF)
		hdd_ht_cap->tx_BF_cap_info |= TX_BF_CAP_INFO_RX_ZFL;
	if (roam_ht_cap->txZLF)
		hdd_ht_cap->tx_BF_cap_info |= TX_BF_CAP_INFO_TX_ZFL;
	if (roam_ht_cap->implicitTxBF)
		hdd_ht_cap->tx_BF_cap_info |= TX_BF_CAP_INFO_IMP_TX_BF;
	temp_ht_cap = roam_ht_cap->calibration &
	    (TX_BF_CAP_INFO_CALIBRATION >> TX_BF_CAP_INFO_CALIBRATION_SHIFT);
	if (temp_ht_cap)
		hdd_ht_cap->tx_BF_cap_info |=
			temp_ht_cap << TX_BF_CAP_INFO_CALIBRATION_SHIFT;
	if (roam_ht_cap->explicitCSITxBF)
		hdd_ht_cap->tx_BF_cap_info |= TX_BF_CAP_INFO_EXP_CSIT_BF;
	if (roam_ht_cap->explicitUncompressedSteeringMatrix)
		hdd_ht_cap->tx_BF_cap_info |=
			TX_BF_CAP_INFO_EXP_UNCOMP_STEER_MAT;
	temp_ht_cap = roam_ht_cap->explicitBFCSIFeedback &
	    (TX_BF_CAP_INFO_EXP_BF_CSI_FB >>
	     TX_BF_CAP_INFO_EXP_BF_CSI_FB_SHIFT);
	if (temp_ht_cap)
		hdd_ht_cap->tx_BF_cap_info |=
			temp_ht_cap << TX_BF_CAP_INFO_EXP_BF_CSI_FB_SHIFT;
	temp_ht_cap =
	    roam_ht_cap->explicitUncompressedSteeringMatrixFeedback &
	    (TX_BF_CAP_INFO_EXP_UNCMP_STEER_MAT >>
	     TX_BF_CAP_INFO_EXP_UNCMP_STEER_MAT_SHIFT);
	if (temp_ht_cap)
		hdd_ht_cap->tx_BF_cap_info |=
			temp_ht_cap <<
			TX_BF_CAP_INFO_EXP_UNCMP_STEER_MAT_SHIFT;
	temp_ht_cap =
	    roam_ht_cap->explicitCompressedSteeringMatrixFeedback &
	    (TX_BF_CAP_INFO_EXP_CMP_STEER_MAT_FB >>
	     TX_BF_CAP_INFO_EXP_CMP_STEER_MAT_FB_SHIFT);
	if (temp_ht_cap)
		hdd_ht_cap->tx_BF_cap_info |=
			temp_ht_cap <<
				TX_BF_CAP_INFO_EXP_CMP_STEER_MAT_FB_SHIFT;
	temp_ht_cap = roam_ht_cap->csiNumBFAntennae &
	    (TX_BF_CAP_INFO_CSI_NUM_BF_ANT >>
	     TX_BF_CAP_INFO_CSI_NUM_BF_ANT_SHIFT);
	if (temp_ht_cap)
		hdd_ht_cap->tx_BF_cap_info |=
			temp_ht_cap << TX_BF_CAP_INFO_CSI_NUM_BF_ANT_SHIFT;
	temp_ht_cap = roam_ht_cap->uncompressedSteeringMatrixBFAntennae &
	    (TX_BF_CAP_INFO_UNCOMP_STEER_MAT_BF_ANT >>
	     TX_BF_CAP_INFO_UNCOMP_STEER_MAT_BF_ANT_SHIFT);
	if (temp_ht_cap)
		hdd_ht_cap->tx_BF_cap_info |=
			temp_ht_cap <<
				TX_BF_CAP_INFO_UNCOMP_STEER_MAT_BF_ANT_SHIFT;
	temp_ht_cap = roam_ht_cap->compressedSteeringMatrixBFAntennae &
	    (TX_BF_CAP_INFO_COMP_STEER_MAT_BF_ANT >>
	     TX_BF_CAP_INFO_COMP_STEER_MAT_BF_ANT_SHIFT);
	if (temp_ht_cap)
		hdd_ht_cap->tx_BF_cap_info |=
			temp_ht_cap <<
				TX_BF_CAP_INFO_COMP_STEER_MAT_BF_ANT_SHIFT;

	/* antenna selection */
	if (roam_ht_cap->antennaSelection)
		hdd_ht_cap->antenna_selection_info |= ANTENNA_SEL_INFO;
	if (roam_ht_cap->explicitCSIFeedbackTx)
		hdd_ht_cap->antenna_selection_info |=
			ANTENNA_SEL_INFO_EXP_CSI_FB_TX;
	if (roam_ht_cap->antennaIndicesFeedbackTx)
		hdd_ht_cap->antenna_selection_info |=
			ANTENNA_SEL_INFO_ANT_ID_FB_TX;
	if (roam_ht_cap->explicitCSIFeedback)
		hdd_ht_cap->antenna_selection_info |=
			ANTENNA_SEL_INFO_EXP_CSI_FB;
	if (roam_ht_cap->antennaIndicesFeedback)
		hdd_ht_cap->antenna_selection_info |=
			ANTENNA_SEL_INFO_ANT_ID_FB;
	if (roam_ht_cap->rxAS)
		hdd_ht_cap->antenna_selection_info |=
			ANTENNA_SEL_INFO_RX_AS;
	if (roam_ht_cap->txSoundingPPDUs)
		hdd_ht_cap->antenna_selection_info |=
			ANTENNA_SEL_INFO_TX_SOUNDING_PPDU;

	/* mcs data rate */
	for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; ++i)
		hdd_ht_cap->mcs.rx_mask[i] =
			roam_ht_cap->supportedMCSSet[i];
	hdd_ht_cap->mcs.rx_highest =
			((short) (roam_ht_cap->supportedMCSSet[11]) << 8) |
			((short) (roam_ht_cap->supportedMCSSet[10]));
	hdd_ht_cap->mcs.tx_params =
			roam_ht_cap->supportedMCSSet[12];
}

#define VHT_CAP_MAX_MPDU_LENGTH_MASK 0x00000003
#define VHT_CAP_SUPP_CHAN_WIDTH_MASK_SHIFT 2
#define VHT_CAP_RXSTBC_MASK_SHIFT 8
#define VHT_CAP_BEAMFORMEE_STS_SHIFT 13
#define VHT_CAP_BEAMFORMEE_STS_MASK \
	(0x0000e000 >> VHT_CAP_BEAMFORMEE_STS_SHIFT)
#define VHT_CAP_SOUNDING_DIMENSIONS_SHIFT 16
#define VHT_CAP_SOUNDING_DIMENSIONS_MASK \
	(0x00070000 >> VHT_CAP_SOUNDING_DIMENSIONS_SHIFT)
#define VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK_SHIFT 23
#define VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK \
	(0x03800000 >> VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK_SHIFT)
#define VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB_SHIFT 26

/**
 * hdd_copy_ht_caps()- copy ht caps info from roam info to
 *  hdd station context.
 * @hdd_sta_ctx: pointer to hdd station context
 * @roam_info: pointer to roam info
 *
 * Return: None
 */
static void hdd_copy_vht_caps(hdd_station_ctx_t *hdd_sta_ctx,
				     tCsrRoamInfo *roam_info)
{
	tDot11fIEVHTCaps *roam_vht_cap = &roam_info->vht_caps;
	struct ieee80211_vht_cap *hdd_vht_cap =
		&hdd_sta_ctx->conn_info.vht_caps;
	uint32_t temp_vht_cap;

	adf_os_mem_zero(hdd_vht_cap, sizeof(struct ieee80211_vht_cap));

	temp_vht_cap = roam_vht_cap->maxMPDULen & VHT_CAP_MAX_MPDU_LENGTH_MASK;
	hdd_vht_cap->vht_cap_info |= temp_vht_cap;
	temp_vht_cap = roam_vht_cap->supportedChannelWidthSet &
		(IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK >>
			VHT_CAP_SUPP_CHAN_WIDTH_MASK_SHIFT);
	if (temp_vht_cap) {
		if (roam_vht_cap->supportedChannelWidthSet &
		    (IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ >>
			VHT_CAP_SUPP_CHAN_WIDTH_MASK_SHIFT))
			hdd_vht_cap->vht_cap_info |=
				temp_vht_cap <<
				IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
		if (roam_vht_cap->supportedChannelWidthSet &
		    (IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ >>
			VHT_CAP_SUPP_CHAN_WIDTH_MASK_SHIFT))
			hdd_vht_cap->vht_cap_info |=
			temp_vht_cap <<
			IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
	}
	if (roam_vht_cap->ldpcCodingCap)
		hdd_vht_cap->vht_cap_info |= IEEE80211_VHT_CAP_RXLDPC;
	if (roam_vht_cap->shortGI80MHz)
		hdd_vht_cap->vht_cap_info |= IEEE80211_VHT_CAP_SHORT_GI_80;
	if (roam_vht_cap->shortGI160and80plus80MHz)
		hdd_vht_cap->vht_cap_info |= IEEE80211_VHT_CAP_SHORT_GI_160;
	if (roam_vht_cap->txSTBC)
		hdd_vht_cap->vht_cap_info |= IEEE80211_VHT_CAP_TXSTBC;
	temp_vht_cap = roam_vht_cap->rxSTBC & (IEEE80211_VHT_CAP_RXSTBC_MASK >>
		VHT_CAP_RXSTBC_MASK_SHIFT);
	if (temp_vht_cap)
		hdd_vht_cap->vht_cap_info |=
			temp_vht_cap << VHT_CAP_RXSTBC_MASK_SHIFT;
	if (roam_vht_cap->suBeamFormerCap)
		hdd_vht_cap->vht_cap_info |=
			IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE;
	if (roam_vht_cap->suBeamformeeCap)
		hdd_vht_cap->vht_cap_info |=
			IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE;
	temp_vht_cap = roam_vht_cap->csnofBeamformerAntSup &
			(VHT_CAP_BEAMFORMEE_STS_MASK);
	if (temp_vht_cap)
		hdd_vht_cap->vht_cap_info |=
			temp_vht_cap << VHT_CAP_BEAMFORMEE_STS_SHIFT;
	temp_vht_cap = roam_vht_cap->numSoundingDim &
			(VHT_CAP_SOUNDING_DIMENSIONS_MASK);
	if (temp_vht_cap)
		hdd_vht_cap->vht_cap_info |=
			temp_vht_cap << VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;
	if (roam_vht_cap->muBeamformerCap)
		hdd_vht_cap->vht_cap_info |=
			IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE;
	if (roam_vht_cap->muBeamformeeCap)
		hdd_vht_cap->vht_cap_info |=
			IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
	if (roam_vht_cap->vhtTXOPPS)
		hdd_vht_cap->vht_cap_info |=
			IEEE80211_VHT_CAP_VHT_TXOP_PS;
	if (roam_vht_cap->htcVHTCap)
		hdd_vht_cap->vht_cap_info |=
			IEEE80211_VHT_CAP_HTC_VHT;
	temp_vht_cap = roam_vht_cap->maxAMPDULenExp &
			(VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK);
	if (temp_vht_cap)
		hdd_vht_cap->vht_cap_info |=
			temp_vht_cap <<
			VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK_SHIFT;
	temp_vht_cap = roam_vht_cap->vhtLinkAdaptCap &
		(IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB >>
		 VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB_SHIFT);
	if (temp_vht_cap)
		hdd_vht_cap->vht_cap_info |= temp_vht_cap <<
			VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB_SHIFT;
	if (roam_vht_cap->rxAntPattern)
		hdd_vht_cap->vht_cap_info |=
			IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN;
	if (roam_vht_cap->txAntPattern)
		hdd_vht_cap->vht_cap_info |=
			IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN;
	hdd_vht_cap->supp_mcs.rx_mcs_map = roam_vht_cap->rxMCSMap;
	hdd_vht_cap->supp_mcs.rx_highest =
		((uint16_t)roam_vht_cap->rxHighSupDataRate);
	hdd_vht_cap->supp_mcs.tx_mcs_map = roam_vht_cap->txMCSMap;
	hdd_vht_cap->supp_mcs.tx_highest =
		((uint16_t)roam_vht_cap->txSupDataRate);
}

/* ht param */
#define HT_PARAM_CONTROLLED_ACCESS_ONLY 0x10
#define HT_PARAM_SERVICE_INT_GRAN 0xe0
#define HT_PARAM_SERVICE_INT_GRAN_SHIFT 5

/* operatinon mode */
#define HT_OP_MODE_TX_BURST_LIMIT 0x0008

/* stbc_param */
#define HT_STBC_PARAM_MCS 0x007f

/**
 * hdd_copy_ht_operation()- copy HT operation element from roam info to
 *  hdd station context.
 * @hdd_sta_ctx: pointer to hdd station context
 * @roam_info: pointer to roam info
 *
 * Return: None
 */
static void hdd_copy_ht_operation(hdd_station_ctx_t *hdd_sta_ctx,
					    tCsrRoamInfo *roam_info)
{
	tDot11fIEHTInfo *roam_ht_ops = &roam_info->ht_operation;
	struct ieee80211_ht_operation *hdd_ht_ops =
		&hdd_sta_ctx->conn_info.ht_operation;
	uint32_t i, temp_ht_ops;

	adf_os_mem_zero(hdd_ht_ops, sizeof(struct ieee80211_ht_operation));

	hdd_ht_ops->primary_chan = roam_ht_ops->primaryChannel;

	/* HT_PARAMS */
	temp_ht_ops = roam_ht_ops->secondaryChannelOffset &
		IEEE80211_HT_PARAM_CHA_SEC_OFFSET;
	if (temp_ht_ops)
		hdd_ht_ops->ht_param |= temp_ht_ops;
	else
		hdd_ht_ops->ht_param = IEEE80211_HT_PARAM_CHA_SEC_NONE;
	if (roam_ht_ops->recommendedTxWidthSet)
		hdd_ht_ops->ht_param |= IEEE80211_HT_PARAM_CHAN_WIDTH_ANY;
	if (roam_ht_ops->rifsMode)
		hdd_ht_ops->ht_param |= IEEE80211_HT_PARAM_RIFS_MODE;
	if (roam_ht_ops->controlledAccessOnly)
		hdd_ht_ops->ht_param |= HT_PARAM_CONTROLLED_ACCESS_ONLY;
	temp_ht_ops = roam_ht_ops->serviceIntervalGranularity &
		(HT_PARAM_SERVICE_INT_GRAN >> HT_PARAM_SERVICE_INT_GRAN_SHIFT);
	if (temp_ht_ops)
		hdd_ht_ops->ht_param |= temp_ht_ops <<
			HT_PARAM_SERVICE_INT_GRAN_SHIFT;

	/* operation mode */
	temp_ht_ops = roam_ht_ops->opMode &
			IEEE80211_HT_OP_MODE_PROTECTION;
	switch (temp_ht_ops) {
	case IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER:
		hdd_ht_ops->operation_mode |=
			IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER;
		break;
	case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ:
		hdd_ht_ops->operation_mode |=
			IEEE80211_HT_OP_MODE_PROTECTION_20MHZ;
		break;
	case IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED:
		hdd_ht_ops->operation_mode |=
			IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED;
		break;
	case IEEE80211_HT_OP_MODE_PROTECTION_NONE:
	default:
		hdd_ht_ops->operation_mode |=
			IEEE80211_HT_OP_MODE_PROTECTION_NONE;
	}
	if (roam_ht_ops->nonGFDevicesPresent)
		hdd_ht_ops->operation_mode |=
			IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT;
	if (roam_ht_ops->transmitBurstLimit)
		hdd_ht_ops->operation_mode |=
			HT_OP_MODE_TX_BURST_LIMIT;
	if (roam_ht_ops->obssNonHTStaPresent)
		hdd_ht_ops->operation_mode |=
			IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT;

	/* stbc_param */
	temp_ht_ops = roam_ht_ops->basicSTBCMCS &
			HT_STBC_PARAM_MCS;
	if (temp_ht_ops)
		hdd_ht_ops->stbc_param |= temp_ht_ops;
	if (roam_ht_ops->dualCTSProtection)
		hdd_ht_ops->stbc_param |=
			IEEE80211_HT_STBC_PARAM_DUAL_CTS_PROT;
	if (roam_ht_ops->secondaryBeacon)
		hdd_ht_ops->stbc_param |=
			IEEE80211_HT_STBC_PARAM_STBC_BEACON;
	if (roam_ht_ops->lsigTXOPProtectionFullSupport)
		hdd_ht_ops->stbc_param |=
			IEEE80211_HT_STBC_PARAM_LSIG_TXOP_FULLPROT;
	if (roam_ht_ops->pcoActive)
		hdd_ht_ops->stbc_param |=
			IEEE80211_HT_STBC_PARAM_PCO_ACTIVE;
	if (roam_ht_ops->pcoPhase)
		hdd_ht_ops->stbc_param |=
			IEEE80211_HT_STBC_PARAM_PCO_PHASE;

	/* basic MCs set */
	for (i = 0; i < 16; ++i)
		hdd_ht_ops->basic_set[i] =
			roam_ht_ops->basicMCSSet[i];
}

/**
 * hdd_copy_vht_operation()- copy VHT operations element from roam info to
 *  hdd station context.
 * @hdd_sta_ctx: pointer to hdd station context
 * @roam_info: pointer to roam info
 *
 * Return: None
 */
static void hdd_copy_vht_operation(hdd_station_ctx_t *hdd_sta_ctx,
					      tCsrRoamInfo *roam_info)
{
	tDot11fIEVHTOperation *roam_vht_ops = &roam_info->vht_operation;
	struct ieee80211_vht_operation *hdd_vht_ops =
		&hdd_sta_ctx->conn_info.vht_operation;

	adf_os_mem_zero(hdd_vht_ops, sizeof(struct ieee80211_vht_operation));

	hdd_vht_ops->chan_width = roam_vht_ops->chanWidth;
	hdd_vht_ops->center_freq_seg1_idx = roam_vht_ops->chanCenterFreqSeg1;
	hdd_vht_ops->center_freq_seg2_idx = roam_vht_ops->chanCenterFreqSeg2;
	hdd_vht_ops->basic_mcs_set = roam_vht_ops->basicMCSSet;
}

/**
 * hdd_save_bss_info() - save connection info in hdd sta ctx
 * @adapter: Pointer to adapter
 * @roam_info: pointer to roam info
 *
 * Return: None
 */
static void hdd_save_bss_info(hdd_adapter_t *adapter,
						tCsrRoamInfo *roam_info)
{
	hdd_station_ctx_t *hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);

	hdd_sta_ctx->conn_info.freq = vos_chan_to_freq(
		hdd_sta_ctx->conn_info.operationChannel);
	if (roam_info->vht_caps.present) {
		hdd_sta_ctx->conn_info.conn_flag.vht_present = true;
		hdd_copy_vht_caps(hdd_sta_ctx, roam_info);
	} else {
		hdd_sta_ctx->conn_info.conn_flag.vht_present = false;
	}
	if (roam_info->ht_caps.present) {
		hdd_sta_ctx->conn_info.conn_flag.ht_present = true;
		hdd_copy_ht_caps(hdd_sta_ctx, roam_info);
	} else {
		hdd_sta_ctx->conn_info.conn_flag.ht_present = false;
	}
	if (roam_info->reassoc)
		hdd_sta_ctx->conn_info.roam_count++;
	if (roam_info->hs20vendor_ie.present) {
		hdd_sta_ctx->conn_info.conn_flag.hs20_present = true;
		adf_os_mem_copy(&hdd_sta_ctx->conn_info.hs20vendor_ie,
			     &roam_info->hs20vendor_ie,
			     sizeof(roam_info->hs20vendor_ie));
	} else {
		hdd_sta_ctx->conn_info.conn_flag.hs20_present = false;
	}
	if (roam_info->ht_operation.present) {
		hdd_sta_ctx->conn_info.conn_flag.ht_op_present = true;
		hdd_copy_ht_operation(hdd_sta_ctx, roam_info);
	} else {
		hdd_sta_ctx->conn_info.conn_flag.ht_op_present = false;
	}
	if (roam_info->vht_operation.present) {
		hdd_sta_ctx->conn_info.conn_flag.vht_op_present = true;
		hdd_copy_vht_operation(hdd_sta_ctx, roam_info);
	} else {
		hdd_sta_ctx->conn_info.conn_flag.vht_op_present = false;
	}
}

static void
hdd_connSaveConnectInfo(hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
                        eCsrRoamBssType eBssType)
{
   hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
   eCsrEncryptionType encryptType = eCSR_ENCRYPT_TYPE_NONE;

   VOS_ASSERT( pRoamInfo );

   if ( pRoamInfo )
   {
      // Save the BSSID for the connection...
      if ( eCSR_BSS_TYPE_INFRASTRUCTURE == eBssType )
      {
          VOS_ASSERT( pRoamInfo->pBssDesc );
          vos_mem_copy(pHddStaCtx->conn_info.bssId, pRoamInfo->bssid,6 );

          // Save the Station ID for this station from the 'Roam Info'.
          //For IBSS mode, staId is assigned in NEW_PEER_IND
          //For reassoc, the staID doesn't change and it may be invalid in this structure
          //so no change here.
          if( !pRoamInfo->fReassocReq )
          {
              pHddStaCtx->conn_info.staId [0]= pRoamInfo->staId;
          }
      }
      else if ( eCSR_BSS_TYPE_IBSS == eBssType )
      {
         vos_mem_copy(pHddStaCtx->conn_info.bssId, pRoamInfo->bssid,sizeof(pRoamInfo->bssid) );
      }
      else
      {
         // can't happen.  We need a valid IBSS or Infra setting in the BSSDescription
         // or we can't function.
         VOS_ASSERT( 0 );
      }

      // notify WMM
      hdd_wmm_connect(pAdapter, pRoamInfo, eBssType);

      if( !pRoamInfo->u.pConnectedProfile )
      {
         VOS_ASSERT( pRoamInfo->u.pConnectedProfile );
      }
      else
      {
          // Get Multicast Encryption Type
          encryptType =  pRoamInfo->u.pConnectedProfile->mcEncryptionType;
          pHddStaCtx->conn_info.mcEncryptionType = encryptType;
          /* Get Unicast Encryption Type */
          encryptType =  pRoamInfo->u.pConnectedProfile->EncryptionType;
          pHddStaCtx->conn_info.ucEncryptionType = encryptType;

          pHddStaCtx->conn_info.authType =  pRoamInfo->u.pConnectedProfile->AuthType;
          pHddStaCtx->conn_info.last_auth_type = pHddStaCtx->conn_info.authType;

          pHddStaCtx->conn_info.operationChannel = pRoamInfo->u.pConnectedProfile->operationChannel;

          // Save the ssid for the connection
          vos_mem_copy( &pHddStaCtx->conn_info.SSID.SSID, &pRoamInfo->u.pConnectedProfile->SSID, sizeof( tSirMacSSid ) );
          vos_mem_copy(&pHddStaCtx->conn_info.last_ssid.SSID,
                       &pRoamInfo->u.pConnectedProfile->SSID,
                       sizeof(tSirMacSSid));

          // Save  dot11mode in which STA associated to AP
          pHddStaCtx->conn_info.dot11Mode = pRoamInfo->u.pConnectedProfile->dot11Mode;

          pHddStaCtx->conn_info.proxyARPService = pRoamInfo->u.pConnectedProfile->proxyARPService;
          pHddStaCtx->conn_info.nss        = pRoamInfo->chan_info.nss;
          pHddStaCtx->conn_info.rate_flags = pRoamInfo->chan_info.rate_flags;
      }
      hdd_save_bss_info(pAdapter, pRoamInfo);
   }

   // save the connected BssType
   hdd_connSaveConnectedBssType( pHddStaCtx, eBssType );

}

#if defined(WLAN_FEATURE_VOWIFI_11R)
/*
 * Send the 11R key information to the supplicant.
 * Only then can the supplicant generate the PMK-R1.
 * (BTW, the ESE supplicant also needs the Assoc Resp IEs
 * for the same purpose.)
 *
 * Mainly the Assoc Rsp IEs are passed here. For the IMDA
 * this contains the R1KHID, R0KHID and the MDID.
 * For FT, this consists of the Reassoc Rsp FTIEs.
 * This is the Assoc Response.
 */
static void hdd_SendFTAssocResponse(struct net_device *dev, hdd_adapter_t *pAdapter,
                tCsrRoamInfo *pCsrRoamInfo)
{
    union iwreq_data wrqu;
    char *buff;
    unsigned int len = 0;
    u8 *pFTAssocRsp = NULL;

    if (pCsrRoamInfo->nAssocRspLength == 0)
    {
        hddLog(LOGE,
            "%s: pCsrRoamInfo->nAssocRspLength=%d",
            __func__, (int)pCsrRoamInfo->nAssocRspLength);
        return;
    }

    pFTAssocRsp = (u8 *)(pCsrRoamInfo->pbFrames + pCsrRoamInfo->nBeaconLength +
        pCsrRoamInfo->nAssocReqLength);
    if (pFTAssocRsp == NULL)
    {
        hddLog(LOGE, "%s: AssocReq or AssocRsp is NULL", __func__);
        return;
    }

    // pFTAssocRsp needs to point to the IEs
    pFTAssocRsp += FT_ASSOC_RSP_IES_OFFSET;
    hddLog(LOG1, "%s: AssocRsp is now at %02x%02x", __func__,
        (unsigned int)pFTAssocRsp[0],
        (unsigned int)pFTAssocRsp[1]);

    // We need to send the IEs to the supplicant.
    buff = vos_mem_malloc(IW_GENERIC_IE_MAX);
    if (buff == NULL)
    {
        hddLog(LOGE, "%s: kmalloc unable to allocate memory", __func__);
        return;
    }

    // Send the Assoc Resp, the supplicant needs this for initial Auth.
    len = pCsrRoamInfo->nAssocRspLength - FT_ASSOC_RSP_IES_OFFSET;
    wrqu.data.length = len;
    memset(buff, 0, IW_GENERIC_IE_MAX);
    memcpy(buff, pFTAssocRsp, len);
    wireless_send_event(dev, IWEVASSOCRESPIE, &wrqu, buff);

    vos_mem_free(buff);
}
#endif /* WLAN_FEATURE_VOWIFI_11R */

#ifdef WLAN_FEATURE_VOWIFI_11R

/*---------------------------------------------------
 *
 * Send the FTIEs, RIC IEs during FT. This is eventually
 * used to send the FT events to the supplicant
 *
 * At the reception of Auth2 we send the RIC followed
 * by the auth response IEs to the supplicant.
 * Once both are received in the supplicant, an FT
 * event is generated to the supplicant.
 *
 *---------------------------------------------------
 */
void hdd_SendFTEvent(hdd_adapter_t *pAdapter)
{
    tANI_U16 auth_resp_len = 0;
    tANI_U32 ric_ies_length = 0;
    hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);

#if defined(KERNEL_SUPPORT_11R_CFG80211)
    struct cfg80211_ft_event_params ftEvent;
    v_U8_t ftIe[DOT11F_IE_FTINFO_MAX_LEN];
    v_U8_t ricIe[DOT11F_IE_RICDESCRIPTOR_MAX_LEN];
    struct net_device *dev = pAdapter->dev;
#else
    char *buff;
    union iwreq_data wrqu;
    tANI_U16 str_len;
#endif

#if defined(KERNEL_SUPPORT_11R_CFG80211)
    vos_mem_zero(ftIe, DOT11F_IE_FTINFO_MAX_LEN);
    vos_mem_zero(ricIe, DOT11F_IE_RICDESCRIPTOR_MAX_LEN);

    sme_GetRICIEs( pHddCtx->hHal, pAdapter->sessionId, (u8 *)ricIe,
                  DOT11F_IE_RICDESCRIPTOR_MAX_LEN, &ric_ies_length );
    if (ric_ies_length == 0)
    {
        hddLog(LOGW,
              "%s: RIC IEs is of length 0 not sending RIC Information for now",
              __func__);
    }

    ftEvent.ric_ies = ricIe;
    ftEvent.ric_ies_len = ric_ies_length;
    hddLog(LOG1, "%s: RIC IEs is of length %d", __func__, (int)ric_ies_length);

    sme_GetFTPreAuthResponse(pHddCtx->hHal, pAdapter->sessionId, (u8 *)ftIe,
                DOT11F_IE_FTINFO_MAX_LEN, &auth_resp_len);

    if (auth_resp_len == 0)
    {
        hddLog(LOGE, "%s: AuthRsp FTIES is of length 0", __func__);
        return;
    }

    sme_SetFTPreAuthState(pHddCtx->hHal, pAdapter->sessionId, VOS_TRUE);

    ftEvent.target_ap = ftIe;

    ftEvent.ies = (u8 *)(ftIe + SIR_MAC_ADDR_LENGTH);
    ftEvent.ies_len = auth_resp_len - SIR_MAC_ADDR_LENGTH;

    hddLog(LOG1, "%s ftEvent.ies_len %zu", __FUNCTION__, ftEvent.ies_len);
    hddLog(LOG1, "%s ftEvent.ric_ies_len %zu",
           __FUNCTION__, ftEvent.ric_ies_len );
    hddLog(LOG1, "%s ftEvent.target_ap %2x-%2x-%2x-%2x-%2x-%2x ",
            __FUNCTION__, ftEvent.target_ap[0], ftEvent.target_ap[1],
            ftEvent.target_ap[2], ftEvent.target_ap[3], ftEvent.target_ap[4],
            ftEvent.target_ap[5]);

    (void)cfg80211_ft_event(dev, &ftEvent);

#else
    // We need to send the IEs to the supplicant
    buff = vos_mem_malloc(IW_CUSTOM_MAX);
    if (buff == NULL)
    {
        hddLog(LOGE, "%s: kmalloc unable to allocate memory", __func__);
        return;
    }
    vos_mem_zero(buff, IW_CUSTOM_MAX);

    // Sme needs to send the RIC IEs first
    str_len = strlcpy(buff, "RIC=", IW_CUSTOM_MAX);
    sme_GetRICIEs( pHddCtx->hHal, pAdapter->sessionId, (u8 *)&(buff[str_len]),
            (IW_CUSTOM_MAX - str_len), &ric_ies_length );
    if (ric_ies_length == 0)
    {
        hddLog(LOGW,
               "%s: RIC IEs is of length 0 not sending RIC Information for now",
               __func__);
    }
    else
    {
        wrqu.data.length = str_len + ric_ies_length;
        wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buff);
    }

    // Sme needs to provide the Auth Resp
    vos_mem_zero(buff, IW_CUSTOM_MAX);
    str_len = strlcpy(buff, "AUTH=", IW_CUSTOM_MAX);
    sme_GetFTPreAuthResponse(pHddCtx->hHal, pAdapter->sessionId,
                            (u8 *)&buff[str_len],
                            (IW_CUSTOM_MAX - str_len),
                            &auth_resp_len);

    if (auth_resp_len == 0)
    {
        hddLog(LOGE, "%s: AuthRsp FTIES is of length 0", __func__);
        vos_mem_free(buff);
        return;
    }

    wrqu.data.length = str_len + auth_resp_len;
    wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buff);

    vos_mem_free(buff);
#endif
}

#endif /* WLAN_FEATURE_VOWIFI_11R */

#ifdef FEATURE_WLAN_ESE

/*
 * Send the ESE required "new AP Channel info" to the supplicant.
 * (This keeps the supplicant "up to date" on the current channel.)
 *
 * The current (new AP) channel information is passed in.
 */
static void hdd_SendNewAPChannelInfo(struct net_device *dev, hdd_adapter_t *pAdapter,
                tCsrRoamInfo *pCsrRoamInfo)
{
    union iwreq_data wrqu;
    tSirBssDescription *descriptor = pCsrRoamInfo->pBssDesc;


    if (descriptor == NULL)
    {
        hddLog(LOGE,
            "%s: pCsrRoamInfo->pBssDesc=%pK",
            __func__, descriptor);
        return;
    }

    // Send the Channel event, the supplicant needs this to generate the Adjacent AP report.
    hddLog(LOGW, "%s: Sending up an SIOCGIWFREQ, channelId=%d", __func__, descriptor->channelId);
    memset(&wrqu, '\0', sizeof(wrqu));
    wrqu.freq.m = descriptor->channelId;
    wrqu.freq.e = 0;
    wrqu.freq.i = 0;
    wireless_send_event(pAdapter->dev, SIOCGIWFREQ, &wrqu, NULL);
}

#endif /* FEATURE_WLAN_ESE */

static void
hdd_SendUpdateBeaconIEsEvent(hdd_adapter_t *pAdapter,
                             tCsrRoamInfo *pCsrRoamInfo)
{
    union iwreq_data wrqu;
    u8  *pBeaconIes;
    u8 currentLen = 0;
    char *buff;
    int totalIeLen = 0, currentOffset = 0, strLen;

    memset(&wrqu, '\0', sizeof(wrqu));

    if (0 == pCsrRoamInfo->nBeaconLength)
    {
        hddLog(LOGW, "%s: pCsrRoamInfo->nBeaconFrameLength = 0", __func__);
        return;
    }
    pBeaconIes = (u8 *)(pCsrRoamInfo->pbFrames + BEACON_FRAME_IES_OFFSET);
    if (pBeaconIes == NULL)
    {
        hddLog(LOGW, "%s: Beacon IEs is NULL", __func__);
        return;
    }

    // pBeaconIes needs to point to the IEs
    hddLog(LOG1, "%s: Beacon IEs is now at %02x%02x", __func__,
        (unsigned int)pBeaconIes[0],
        (unsigned int)pBeaconIes[1]);
    hddLog(LOG1, "%s: Beacon IEs length = %d", __func__, pCsrRoamInfo->nBeaconLength - BEACON_FRAME_IES_OFFSET);

   // We need to send the IEs to the supplicant.
    buff = vos_mem_malloc(IW_CUSTOM_MAX);
    if (buff == NULL)
    {
        hddLog(LOGE, "%s: kmalloc unable to allocate memory", __func__);
        return;
    }
    vos_mem_zero(buff, IW_CUSTOM_MAX);

    strLen = strlcpy(buff,"BEACONIEs=", IW_CUSTOM_MAX);
    currentLen = strLen + 1;

    totalIeLen = pCsrRoamInfo->nBeaconLength - BEACON_FRAME_IES_OFFSET;
    do
    {
        /* If the beacon size exceeds max CUSTOM event size, break it into chunks of CUSTOM event
         * max size and send it to supplicant. Changes are done in supplicant to handle this */
        vos_mem_zero(&buff[strLen + 1], IW_CUSTOM_MAX - (strLen + 1));
        currentLen = VOS_MIN(totalIeLen, IW_CUSTOM_MAX - (strLen + 1) - 1);
        vos_mem_copy(&buff[strLen + 1], pBeaconIes+currentOffset, currentLen);
        currentOffset += currentLen;
        totalIeLen -= currentLen;
        wrqu.data.length = strLen + 1 + currentLen;
        if (totalIeLen)
          buff[strLen] = 1;   // This tells supplicant more chunks are pending
        else
          buff[strLen] = 0;   // For last chunk of beacon IE to supplicant

        hddLog(LOG1, "%s: Beacon IEs length to supplicant = %d", __func__, currentLen);
        wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buff);
    } while (totalIeLen > 0);

    vos_mem_free(buff);
}

static void hdd_SendAssociationEvent(struct net_device *dev,tCsrRoamInfo *pCsrRoamInfo)
{
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
    union iwreq_data wrqu;
    int we_event;
    char *msg;
    int type = -1;
    v_MACADDR_t peerMacAddr;

    hdd_adapter_t *mon_adapter = NULL;
#if defined (WLAN_FEATURE_VOWIFI_11R)
    // Added to find the auth type on the fly at run time
    // rather than with cfg to see if FT is enabled
    hdd_wext_state_t  *pWextState =  WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
    tCsrRoamProfile* pRoamProfile = &(pWextState->roamProfile);
#endif

    memset(&wrqu, '\0', sizeof(wrqu));
    wrqu.ap_addr.sa_family = ARPHRD_ETHER;
    we_event = SIOCGIWAP;
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
    if (NULL != pCsrRoamInfo)
        if (pCsrRoamInfo->roamSynchInProgress)
            /* change logging before release */
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
                      "LFR3:hdd_SendAssociationEvent");
#endif
    if(eConnectionState_Associated == pHddStaCtx->conn_info.connState)/* Associated */
    {
        tSirSmeChanInfo chan_info;
        if (!pCsrRoamInfo)
        {
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      "%s: STA in associated state but pCsrRoamInfo is null",
                      __func__);
            return;
        }

        wlan_hdd_incr_active_session(pHddCtx, pAdapter->device_mode);
        memcpy(wrqu.ap_addr.sa_data, pCsrRoamInfo->pBssDesc->bssId, sizeof(pCsrRoamInfo->pBssDesc->bssId));
        type = WLAN_STA_ASSOC_DONE_IND;

#ifdef WLAN_FEATURE_P2P_DEBUG
        if(pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
        {
             if(globalP2PConnectionStatus == P2P_CLIENT_CONNECTING_STATE_1)
             {
                 globalP2PConnectionStatus = P2P_CLIENT_CONNECTED_STATE_1;
                 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
                                "Connecting state to Connected State for 8-way "
                                "Handshake");
             }
             else if(globalP2PConnectionStatus == P2P_CLIENT_CONNECTING_STATE_2)
             {
                 globalP2PConnectionStatus = P2P_CLIENT_COMPLETED_STATE;
                 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
                           "Connecting state to P2P Client Connection Completed");
             }
        }
#endif
        hddLog(VOS_TRACE_LEVEL_ERROR, MAC_ADDRESS_STR " connected to "
                MAC_ADDRESS_STR,
                MAC_ADDR_ARRAY(pAdapter->macAddressCurrent.bytes),
                MAC_ADDR_ARRAY(wrqu.ap_addr.sa_data));
        hdd_SendUpdateBeaconIEsEvent(pAdapter, pCsrRoamInfo);


        /* Send IWEVASSOCRESPIE Event if WLAN_FEATURE_CIQ_METRICS is Enabled Or
         * Send IWEVASSOCRESPIE Event if WLAN_FEATURE_VOWIFI_11R is Enabled
         * and fFTEnable is TRUE */
#ifdef WLAN_FEATURE_VOWIFI_11R
        // Send FT Keys to the supplicant when FT is enabled
        if ((pRoamProfile->AuthType.authType[0] == eCSR_AUTH_TYPE_FT_RSN_PSK) ||
            (pRoamProfile->AuthType.authType[0] == eCSR_AUTH_TYPE_FT_RSN)
#ifdef FEATURE_WLAN_ESE
            || (pRoamProfile->AuthType.authType[0] == eCSR_AUTH_TYPE_CCKM_RSN) ||
            (pRoamProfile->AuthType.authType[0] == eCSR_AUTH_TYPE_CCKM_WPA)
#endif
        )
        {
            hdd_SendFTAssocResponse(dev, pAdapter, pCsrRoamInfo);
        }
#endif

        vos_mem_copy(peerMacAddr.bytes, pHddStaCtx->conn_info.bssId,
                     VOS_MAC_ADDR_SIZE);
        chan_info.chan_id = pCsrRoamInfo->chan_info.chan_id;
        chan_info.mhz = pCsrRoamInfo->chan_info.mhz;
        chan_info.info = pCsrRoamInfo->chan_info.info;
        chan_info.band_center_freq1 =
                   pCsrRoamInfo->chan_info.band_center_freq1;
        chan_info.band_center_freq2 =
                   pCsrRoamInfo->chan_info.band_center_freq2;
        chan_info.reg_info_1 = pCsrRoamInfo->chan_info.reg_info_1;
        chan_info.reg_info_2 = pCsrRoamInfo->chan_info.reg_info_2;

        /* send peer status indication to oem app */
        hdd_SendPeerStatusIndToOemApp(&peerMacAddr, ePeerConnected,
                                      pCsrRoamInfo->timingMeasCap,
                                      pAdapter->sessionId,
                                      &chan_info,
                                      pAdapter->device_mode);

#ifdef FEATURE_WLAN_TDLS
        if (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) {
            hddLog(LOG1,
                   FL("tdls_prohibited: %d, tdls_chan_swit_prohibited: %d"),
                   pCsrRoamInfo->tdls_prohibited,
                   pCsrRoamInfo->tdls_chan_swit_prohibited);

            wlan_hdd_update_tdls_info(pAdapter, pCsrRoamInfo->tdls_prohibited,
                                      pCsrRoamInfo->tdls_chan_swit_prohibited);
        }
#endif

#ifdef FEATURE_BUS_BANDWIDTH
        /* start timer in sta/p2p_cli */
        SPIN_LOCK_BH(&pHddCtx->bus_bw_lock);
        pAdapter->prev_tx_packets = pAdapter->stats.tx_packets;
        pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
        tlshim_get_intra_bss_fwd_pkts_count(pAdapter->sessionId,
             &pAdapter->prev_fwd_tx_packets, &pAdapter->prev_fwd_rx_packets);
        pAdapter->prev_tx_bytes = pAdapter->stats.tx_bytes;
        SPIN_UNLOCK_BH(&pHddCtx->bus_bw_lock);
        hdd_start_bus_bw_compute_timer(pAdapter);
#endif
        if (pHddCtx->cfg_ini->mon_on_sta_enable &&
            (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)) {
            /* monitor mode interface should be ready */
            mon_adapter = hdd_get_adapter(pHddCtx, WLAN_HDD_MONITOR);

            if (mon_adapter && (WLAN_HDD_ADAPTER_MAGIC == mon_adapter->magic) &&
                tlshim_get_rxmon_cbk()) {
               wlan_hdd_monitor_mode_enable(pHddCtx, true);
           }
        }
    }
    else if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState) // IBss Associated
    {
        wlan_hdd_incr_active_session(pHddCtx, pAdapter->device_mode);
        memcpy(wrqu.ap_addr.sa_data, pHddStaCtx->conn_info.bssId, ETH_ALEN);
        type = WLAN_STA_ASSOC_DONE_IND;

        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                 "wlan: new IBSS connection to " MAC_ADDRESS_STR,
                 MAC_ADDR_ARRAY(pHddStaCtx->conn_info.bssId));
    }
    else /* Not Associated */
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                 "wlan: disconnected");
        type = WLAN_STA_DISASSOC_DONE_IND;
        memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
        wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
#if defined(FEATURE_WLAN_LFR) && defined(WLAN_FEATURE_ROAM_SCAN_OFFLOAD)
        wlan_hdd_enable_roaming(pAdapter);
#endif

#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
        wlan_hdd_auto_shutdown_enable(pHddCtx, VOS_TRUE);
#endif

        if ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
           (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)) {
             vos_mem_copy(peerMacAddr.bytes, pHddStaCtx->conn_info.bssId,
                         sizeof(pHddStaCtx->conn_info.bssId));

             /* send peer status indication to oem app */
             hdd_SendPeerStatusIndToOemApp(&peerMacAddr, ePeerDisconnected,
                                          0, pAdapter->sessionId,
                                          NULL,
                                          pAdapter->device_mode);
        }

#ifdef WLAN_FEATURE_LPSS
        pAdapter->rssi_send = VOS_FALSE;
        if (pHddCtx->isUnloadInProgress != TRUE)
                wlan_hdd_send_status_pkg(pAdapter, pHddStaCtx, 1, 0);
#endif

#ifdef FEATURE_BUS_BANDWIDTH
        /* stop timer in sta/p2p_cli */
        SPIN_LOCK_BH(&pHddCtx->bus_bw_lock);
        pAdapter->prev_tx_packets = 0;
        pAdapter->prev_rx_packets = 0;
        pAdapter->prev_fwd_tx_packets = 0;
        pAdapter->prev_fwd_rx_packets = 0;
        pAdapter->prev_tx_bytes = 0;
        SPIN_UNLOCK_BH(&pHddCtx->bus_bw_lock);
        hdd_stop_bus_bw_compute_timer(pAdapter);
#endif
        if (pHddCtx->cfg_ini->mon_on_sta_enable &&
            (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) &&
            (true == pHddCtx->is_mon_enable)) {
            wlan_hdd_monitor_mode_enable(pHddCtx, false);
        }
    }
    hdd_dump_concurrency_info(pHddCtx);

    msg = NULL;
    /*During the WLAN uninitialization,supplicant is stopped before the
      driver so not sending the status of the connection to supplicant*/
    if ((pHddCtx->isLoadInProgress != TRUE) &&
        (pHddCtx->isUnloadInProgress != TRUE))
    {
        wireless_send_event(dev, we_event, &wrqu, msg);
#ifdef FEATURE_WLAN_ESE
        if(eConnectionState_Associated == pHddStaCtx->conn_info.connState)/* Associated */
        {
            if ( (pRoamProfile->AuthType.authType[0] == eCSR_AUTH_TYPE_CCKM_RSN) ||
                (pRoamProfile->AuthType.authType[0] == eCSR_AUTH_TYPE_CCKM_WPA) )
            hdd_SendNewAPChannelInfo(dev, pAdapter, pCsrRoamInfo);
        }
#endif
    }
}

static void hdd_connRemoveConnectInfo(hdd_station_ctx_t *pHddStaCtx)
{
   // Remove staId, bssId and peerMacAddress
   pHddStaCtx->conn_info.staId [ 0 ] = 0;
   vos_mem_zero( &pHddStaCtx->conn_info.bssId, sizeof( v_MACADDR_t ) );
   vos_mem_zero( &pHddStaCtx->conn_info.peerMacAddress[ 0 ], sizeof( v_MACADDR_t ) );

   // Clear all security settings
   pHddStaCtx->conn_info.authType         = eCSR_AUTH_TYPE_OPEN_SYSTEM;
   pHddStaCtx->conn_info.mcEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
   pHddStaCtx->conn_info.ucEncryptionType = eCSR_ENCRYPT_TYPE_NONE;

   vos_mem_zero( &pHddStaCtx->conn_info.Keys, sizeof( tCsrKeys ) );
   vos_mem_zero( &pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey) );

   // Set not-connected state
   pHddStaCtx->conn_info.connDot11DesiredBssType = eCSR_BSS_TYPE_ANY;
   pHddStaCtx->conn_info.proxyARPService = 0;

   vos_mem_zero( &pHddStaCtx->conn_info.SSID, sizeof( tCsrSSIDInfo ) );
}

/**
 * hdd_roamDeregisterSTA() - Deregister STA from data path
 * @pAdapter - HDD context
 * @staId - Station ID
 *
 * Return: 0 or VOS_STATUS error code
 */
VOS_STATUS hdd_roamDeregisterSTA(hdd_adapter_t *pAdapter, tANI_U8 staId)
{
    VOS_STATUS vosStatus;
    hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);

    if (WLAN_HDD_IBSS != pAdapter->device_mode)
    {
       hdd_disconnect_tx_rx(pAdapter);
    }
    else
    {
       // Need to cleanup all queues only if the last peer leaves
       if (eConnectionState_IbssDisconnected == pHddStaCtx->conn_info.connState)
       {
       /* Do not set the carrier off when the last peer leaves.
        * We will set the carrier off while stopping the IBSS.
        */
          hdd_disconnect_tx_rx(pAdapter);
       }
       else
       {
          // There is atleast one more peer, do not cleanup all queues
          hdd_flush_ibss_tx_queues(pAdapter, staId);
       }
    }

    vosStatus = WLANTL_ClearSTAClient( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, staId );
    if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                   "%s: WLANTL_ClearSTAClient() failed to for staID %d.  "
                   "Status= %d [0x%08X]",
                   __func__, staId, vosStatus, vosStatus );
    }
    return( vosStatus );
}

/**
 * hdd_print_bss_info() - print bss info
 * @hdd_sta_ctx: pointer to hdd station context
 *
 * Return: None
 */
static void hdd_print_bss_info(hdd_station_ctx_t *hdd_sta_ctx)
{
	uint32_t *cap_info;

	hddLog(VOS_TRACE_LEVEL_INFO, "WIFI DATA LOGGER");
	hddLog(VOS_TRACE_LEVEL_INFO, "channel: %d",
	       hdd_sta_ctx->conn_info.freq);
	hddLog(VOS_TRACE_LEVEL_INFO, "dot11mode: %d",
	       hdd_sta_ctx->conn_info.dot11Mode);
	hddLog(VOS_TRACE_LEVEL_INFO, "AKM: %d",
	       hdd_sta_ctx->conn_info.last_auth_type);
	hddLog(VOS_TRACE_LEVEL_INFO, "ssid: %.*s",
	       hdd_sta_ctx->conn_info.last_ssid.SSID.length,
	       hdd_sta_ctx->conn_info.last_ssid.SSID.ssId);
	hddLog(VOS_TRACE_LEVEL_INFO, "roam count: %d",
	       hdd_sta_ctx->conn_info.roam_count);
	hddLog(VOS_TRACE_LEVEL_INFO, "ant_info: %d",
	       hdd_sta_ctx->conn_info.txrate.nss);
	hddLog(VOS_TRACE_LEVEL_INFO, "datarate legacy %d",
	       hdd_sta_ctx->conn_info.txrate.legacy);
	hddLog(VOS_TRACE_LEVEL_INFO, "datarate mcs: %d",
	       hdd_sta_ctx->conn_info.txrate.mcs);
	if (hdd_sta_ctx->conn_info.conn_flag.ht_present) {
		cap_info = (uint32_t *)&hdd_sta_ctx->conn_info.ht_caps;
		hddLog(VOS_TRACE_LEVEL_INFO, "ht caps: %x", *cap_info);
	}
	if (hdd_sta_ctx->conn_info.conn_flag.vht_present) {
		cap_info = (uint32_t *)&hdd_sta_ctx->conn_info.vht_caps;
		hddLog(VOS_TRACE_LEVEL_INFO, "vht caps: %x", *cap_info);
	}
	if (hdd_sta_ctx->conn_info.conn_flag.hs20_present)
		hddLog(VOS_TRACE_LEVEL_INFO, "hs20 info: %x",
		       hdd_sta_ctx->conn_info.hs20vendor_ie.release_num);
	hddLog(VOS_TRACE_LEVEL_INFO, "signal: %d",
	       hdd_sta_ctx->conn_info.signal);
	hddLog(VOS_TRACE_LEVEL_INFO, "noise: %d",
	       hdd_sta_ctx->conn_info.noise);
	hddLog(VOS_TRACE_LEVEL_INFO, "assoc_reject.status: %d",
	       hdd_sta_ctx->conn_info.assoc_status_code);
}

static eHalStatus hdd_DisConnectHandler( hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
                                            tANI_U32 roamId, eRoamCmdStatus roamStatus,
                                            eCsrRoamResult roamResult )
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    VOS_STATUS vstatus;
    struct net_device *dev = pAdapter->dev;
    hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
    v_U8_t sta_id;
    v_BOOL_t sendDisconInd = TRUE;

    // Sanity check
    if(dev == NULL)
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
               "%s: net_dev is released return", __func__);
        return eHAL_STATUS_FAILURE;
    }

    // notify apps that we can't pass traffic anymore
    hddLog(LOG1, FL("Disabling queues"));
    wlan_hdd_netif_queue_control(pAdapter, WLAN_NETIF_TX_DISABLE_N_CARRIER,
                      WLAN_CONTROL_PATH);

#ifdef IPA_OFFLOAD
    if (hdd_ipa_is_enabled(pHddCtx))
        hdd_ipa_wlan_evt(pAdapter, pHddStaCtx->conn_info.staId[0],
                WLAN_STA_DISCONNECT, pHddStaCtx->conn_info.bssId);
#endif
#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
        wlan_hdd_auto_shutdown_enable(pHddCtx, VOS_TRUE);
#endif

#ifdef QCA_PKT_PROTO_TRACE
     /* STA disconnected, update into trace buffer */
     if (pHddCtx->cfg_ini->gEnableDebugLog)
     {
        vos_pkt_trace_buf_update("ST:DISASC");
     }
#endif /* QCA_PKT_PROTO_TRACE */

    DPTRACE(adf_dp_trace_mgmt_pkt(ADF_DP_TRACE_MGMT_PACKET_RECORD,
                   pAdapter->sessionId,
                   ADF_PROTO_TYPE_MGMT, ADF_PROTO_MGMT_DISASSOC));

    /* HDD has initiated disconnect, do not send disconnect indication
     * to kernel. Sending disconnected event to kernel for userspace
     * initiated disconnect will be handled by diconnect handler call
     * to cfg80211_disconnected
     */
    if ((eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState) ||
        (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState))
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                   FL(" HDD has initiated a disconnect, no need to send"
                   " disconnect indication to kernel"));
       sendDisconInd = FALSE;
    }

    if(pHddStaCtx->conn_info.connState != eConnectionState_Disconnecting)
    {
        INIT_COMPLETION(pAdapter->disconnect_comp_var);
        hdd_connSetConnectionState(pAdapter,
                   eConnectionState_Disconnecting);
    }

    /* If only STA mode is on */
    if((pHddCtx->concurrency_mode <= 1) &&
       (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
    {
        pHddCtx->isAmpAllowed = VOS_TRUE;
    }
    hdd_clearRoamProfileIe( pAdapter );
    hdd_wmm_init( pAdapter );
    hddLog(VOS_TRACE_LEVEL_INFO,
           FL("Invoking packetdump deregistration API"));
    wlan_deregister_txrx_packetdump();
    // indicate 'disconnect' status to wpa_supplicant...
    hdd_SendAssociationEvent(dev,pRoamInfo);
    /* indicate disconnected event to nl80211 */
    if(roamStatus != eCSR_ROAM_IBSS_LEAVE)
    {
        /* Only send indication to kernel if not initiated by kernel */
        if (sendDisconInd) {
            /* To avoid wpa_supplicant sending "HANGED" CMD to ICS UI */
            if (eCSR_ROAM_LOSTLINK == roamStatus)
            {
               if (pRoamInfo->reasonCode ==
                               eSIR_MAC_PEER_STA_REQ_LEAVING_BSS_REASON)
                       pr_info(
                       "wlan: disconnected due to poor signal, rssi is %d dB\n",
                       pRoamInfo->rxRssi);
               wlan_hdd_cfg80211_indicate_disconnect(dev, false,
                                                     pRoamInfo->reasonCode);
            }
            else
               wlan_hdd_cfg80211_indicate_disconnect(dev, false,
                                                     WLAN_REASON_UNSPECIFIED);

            hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
                   FL("sent disconnected event to nl80211, reason code %d"),
                      (eCSR_ROAM_LOSTLINK == roamStatus) ?
                      pRoamInfo->reasonCode : WLAN_REASON_UNSPECIFIED);
        }

        if ((pHddCtx->isLoadInProgress != TRUE) &&
            (pHddCtx->isUnloadInProgress != TRUE))
        {
#ifdef WLAN_FEATURE_P2P_DEBUG
            if(pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
            {
                if(globalP2PConnectionStatus == P2P_CLIENT_CONNECTED_STATE_1)
                {
                    globalP2PConnectionStatus = P2P_CLIENT_DISCONNECTED_STATE;
                    hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] 8 way Handshake completed "
                          "and moved to disconnected state");
                }
                else if(globalP2PConnectionStatus == P2P_CLIENT_COMPLETED_STATE)
                {
                    globalP2PConnectionStatus = P2P_NOT_ACTIVE;
                    hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] P2P Client is removed "
                          "and moved to inactive state");
                }
            }
#endif

#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN
            if((pAdapter->device_mode == WLAN_HDD_INFRA_STATION) &&
                    vos_is_ch_switch_with_csa_enabled())
            {
                struct wlan_sap_csa_info csa_info;
                hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
                    "%s: Indicate disconnected event to HostApd",
                    __func__);

                csa_info.sta_channel = 0;
                /*Indicate to HostApd about Station interface state change*/
                hdd_sta_state_sap_notify(pHddCtx, STA_NOTIFY_DISCONNECTED, csa_info);
            }
#endif//#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN

            //If the Device Mode is Station
            // and the P2P Client is Connected
            //Enable BMPS

            /*
             * In case of JB, as Change-Iface may or may not be called for p2p0
             * Enable BMPS/IMPS in case P2P_CLIENT disconnected
             * If power save offload is enabled, Fw will take care
             * of power save in case of concurrency.
             */
            if((VOS_STATUS_SUCCESS == hdd_issta_p2p_clientconnected(pHddCtx))
               && !pHddCtx->cfg_ini->enablePowersaveOffload)
            {
               //Enable BMPS only of other Session is P2P Client
               hdd_context_t *pHddCtx = NULL;
               v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );

               if (NULL != pVosContext)
               {
                   pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);

                   if(NULL != pHddCtx)
                   {
                       //Only P2P Client is there Enable Bmps back
                       if((0 == pHddCtx->no_of_open_sessions[VOS_STA_SAP_MODE]) &&
                          (0 == pHddCtx->no_of_open_sessions[VOS_P2P_GO_MODE]))
                       {
                           if (pHddCtx->hdd_wlan_suspended)
                           {
                               hdd_set_pwrparams(pHddCtx);
                           }
                           hdd_enable_bmps_imps(pHddCtx);
                      }
                   }
               }
            }
        }
    }

     hdd_wmm_adapter_clear(pAdapter);
#if defined(WLAN_FEATURE_VOWIFI_11R)
    sme_FTReset(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId);
#endif
    if (hdd_unset_beacon_filter(pAdapter) != 0)
        hddLog(LOGE,
               FL("hdd_unset_beacon_filter() failed"));

    if (eCSR_ROAM_IBSS_LEAVE == roamStatus) {
        v_U8_t i;

        sta_id = IBSS_BROADCAST_STAID;
        vstatus = hdd_roamDeregisterSTA(pAdapter, sta_id);
        if (!VOS_IS_STATUS_SUCCESS(vstatus)) {
            hddLog(LOGE,
                   FL("hdd_roamDeregisterSTA() failed for staID %d Status=%d [0x%x]"),
                   sta_id, status, status);
            status = eHAL_STATUS_FAILURE;
        }
        pHddCtx->sta_to_adapter[sta_id] = NULL;

       /*Clear all the peer sta register with TL.*/
        for (i =0; i < HDD_MAX_NUM_IBSS_STA; i++) {
            if (0 != pHddStaCtx->conn_info.staId[i]) {
               sta_id = pHddStaCtx->conn_info.staId[i];
               VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                     FL("Deregister StaID %d"),sta_id);
               vstatus = hdd_roamDeregisterSTA( pAdapter, sta_id );
               if (!VOS_IS_STATUS_SUCCESS(vstatus)) {
                   VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      FL("hdd_roamDeregisterSTA() failed to for staID %d.  "
                      "Status= %d [0x%x]"),
                      sta_id, status, status);
                   status = eHAL_STATUS_FAILURE;
               }

               /*set the staid and peer mac as 0, all other reset are
                * done in hdd_connRemoveConnectInfo.
                */
               pHddStaCtx->conn_info.staId[i]= 0;
               vos_mem_zero(&pHddStaCtx->conn_info.peerMacAddress[i], sizeof(v_MACADDR_t));
               if (sta_id < (WLAN_MAX_STA_COUNT + 3))
                    pHddCtx->sta_to_adapter[sta_id] = NULL;
            }
        }
    } else {
       sta_id = pHddStaCtx->conn_info.staId[0];

       /* clear scan cache for Link Lost */
       if (pRoamInfo && !pRoamInfo->reasonCode &&
           (eCSR_ROAM_RESULT_DEAUTH_IND == roamResult)) {
           wlan_hdd_cfg80211_update_bss_list(pAdapter,
                               pHddStaCtx->conn_info.bssId);
           sme_remove_bssid_from_scan_list(pHddCtx->hHal,
                               pHddStaCtx->conn_info.bssId);
        }

       //We should clear all sta register with TL, for now, only one.
       vstatus = hdd_roamDeregisterSTA( pAdapter, sta_id );
       if (!VOS_IS_STATUS_SUCCESS(vstatus)) {
           VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  FL("hdd_roamDeregisterSTA() failed to for staID %d.  "
                  "Status= %d [0x%x]"),
                  sta_id, status, status);

           status = eHAL_STATUS_FAILURE;
       }
       pHddCtx->sta_to_adapter[sta_id] = NULL;
    }


    // Clear saved connection information in HDD
    hdd_connRemoveConnectInfo( pHddStaCtx );
    hdd_connSetConnectionState(pAdapter,
                            eConnectionState_NotConnected);
#ifdef WLAN_FEATURE_GTK_OFFLOAD
    if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
        (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
    {
        memset(&pHddStaCtx->gtkOffloadReqParams, 0,
              sizeof (tSirGtkOffloadParams));
        pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
    }
#endif

#ifdef FEATURE_WLAN_TDLS
    if (eCSR_ROAM_IBSS_LEAVE != roamStatus)
    {
        wlan_hdd_tdls_disconnection_callback(pAdapter);
    }
#endif

    if (pHddCtx->cfg_ini->enablePowersaveOffload &&
       ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
        (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)))
    {
       sme_PsOffloadDisableDeferredPowerSave(
                   WLAN_HDD_GET_HAL_CTX(pAdapter),
                   pAdapter->sessionId);
    }

    wlan_hdd_clear_link_layer_stats(pAdapter);

    /* Decide ANTENNA_MODE on STA/CLI disconnect */
    if (pHddCtx->cfg_ini->enable_dynamic_sta_chainmask)
       hdd_decide_dynamic_chain_mask(pHddCtx,
                          HDD_ANTENNA_MODE_INVALID);

    //Unblock anyone waiting for disconnect to complete
    complete(&pAdapter->disconnect_comp_var);
    hdd_print_bss_info(pHddStaCtx);
    return( status );
}

/**
 * hdd_roamRegisterSTA() - Registers new STA to TL module
 * @pAdapter: pointer to adapter context
 * @pRoamInfo: roam info struct pointer
 * @staId: station ID
 * @pPeerMacAddress: mac address of new STA
 * @pBssDesc: bss descriptor
 *
 * Return: status of operation
 */
VOS_STATUS hdd_roamRegisterSTA(hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
                               uint8_t staId, v_MACADDR_t *pPeerMacAddress,
                               tSirBssDescription *pBssDesc)
{
   VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
   WLAN_STADescType staDesc = {0};
   eCsrEncryptionType connectedCipherAlgo;
   v_BOOL_t  fConnected;
   hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
   hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);

   if ( NULL == pBssDesc)
   {
       return VOS_STATUS_E_FAILURE;
   }
   /* Get the Station ID from the one saved during the association */
   staDesc.ucSTAId = staId;

   if ( pHddStaCtx->conn_info.connDot11DesiredBssType == eMib_dot11DesiredBssType_infrastructure)
   {
      staDesc.wSTAType = WLAN_STA_INFRA;

      // grab the bssid from the connection info in the adapter structure and hand that
      // over to TL when registering.
      vos_mem_copy( staDesc.vSTAMACAddress.bytes, pHddStaCtx->conn_info.bssId,sizeof(pHddStaCtx->conn_info.bssId) );
   }
   else
   {
      // for an IBSS 'connect', setup the Station Descriptor for TL.
      staDesc.wSTAType = WLAN_STA_IBSS;

      /*
       * Note that for IBSS, the STA MAC address and BSSID are going to be
       * different where in infrastructure, they are the same (BSSID is the
       * MAC address of the AP). So, for IBSS we have a second field to pass
       * to TL in the STA descriptor that we don't pass when making an
       * Infrastructure connection.
       */
      vos_mem_copy( staDesc.vSTAMACAddress.bytes, pPeerMacAddress->bytes,sizeof(pPeerMacAddress->bytes) );
      vos_mem_copy( staDesc.vBSSIDforIBSS.bytes, pHddStaCtx->conn_info.bssId,6 );
   }

   vos_copy_macaddr( &staDesc.vSelfMACAddress, &pAdapter->macAddressCurrent );

   // set the QoS field appropriately
   if (hdd_wmm_is_active(pAdapter))
   {
      staDesc.ucQosEnabled = 1;
   }
   else
   {
      staDesc.ucQosEnabled = 0;
   }

   fConnected = hdd_connGetConnectedCipherAlgo( pHddStaCtx, &connectedCipherAlgo );
   if ( connectedCipherAlgo != eCSR_ENCRYPT_TYPE_NONE )
   {
      staDesc.ucProtectedFrame = 1;
   }
   else
   {
      staDesc.ucProtectedFrame = 0;

   }

#ifdef FEATURE_WLAN_ESE
   staDesc.ucIsEseSta = pRoamInfo->isESEAssoc;
#endif //FEATURE_WLAN_ESE

#ifdef VOLANS_ENABLE_SW_REPLAY_CHECK
   /* check whether replay check is valid for the station or not */
   if( (eCSR_ENCRYPT_TYPE_TKIP == connectedCipherAlgo) || (eCSR_ENCRYPT_TYPE_AES == connectedCipherAlgo))
   {
       /* Encryption mode is either TKIP or AES
          and replay check is valid for only these
          two encryption modes */
       staDesc.ucIsReplayCheckValid = VOS_TRUE;
       VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                 "HDD register TL ucIsReplayCheckValid %d: Replay check is needed for station", staDesc.ucIsReplayCheckValid);
   }

   else
   {
      /* For other encryption modes replay check is
         not needed */
        staDesc.ucIsReplayCheckValid = VOS_FALSE;
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                 "HDD register TL ucIsReplayCheckValid %d", staDesc.ucIsReplayCheckValid);
   }
#endif

#ifdef FEATURE_WLAN_WAPI
   hddLog(LOG1, "%s: WAPI STA Registered: %d", __func__, pAdapter->wapi_info.fIsWapiSta);
   if (pAdapter->wapi_info.fIsWapiSta)
   {
      staDesc.ucIsWapiSta = 1;
   }
   else
   {
      staDesc.ucIsWapiSta = 0;
   }
#endif /* FEATURE_WLAN_WAPI */

   VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
                 "HDD register TL Sec_enabled= %d.", staDesc.ucProtectedFrame );

   // UMA is Not ready yet, Xlation will be done by TL
   staDesc.ucSwFrameTXXlation = 1;
   staDesc.ucSwFrameRXXlation = 1;
   staDesc.ucAddRmvLLC = 1;
   VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "HDD register TL QoS_enabled=%d",
              staDesc.ucQosEnabled );
   // Initialize signatures and state
   staDesc.ucUcastSig  = pRoamInfo->ucastSig;
   staDesc.ucBcastSig  = pRoamInfo->bcastSig;
   staDesc.ucInitState = pRoamInfo->fAuthRequired ?
      WLANTL_STA_CONNECTED : WLANTL_STA_AUTHENTICATED;
   // Register the Station with TL...
   VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "%s: HDD register TL ucInitState=%d", __func__, staDesc.ucInitState );

   /* Incase Micro controller data path offload enabled,
    * All the traffic routed to WLAN host driver, do not need to
    * route IPA. It should be routed kernel network stack */
#if defined(IPA_OFFLOAD) && !defined(IPA_UC_OFFLOAD)
   if (hdd_ipa_is_enabled(pHddCtx))
      vosStatus = WLANTL_RegisterSTAClient(pHddCtx->pvosContext,
                                         hdd_ipa_process_rxt,
                                         &staDesc,
                                         pBssDesc->rssi);
   else
#endif
   vosStatus = WLANTL_RegisterSTAClient(pHddCtx->pvosContext,
                                         hdd_rx_packet_cbk,
                                         &staDesc,
                                         pBssDesc->rssi);
   if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
   {
      VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
                 "WLANTL_RegisterSTAClient() failed to register.  Status= %d [0x%08X]",
                 vosStatus, vosStatus );
      return vosStatus;
   }

   // if (WPA), tell TL to go to 'connected' and after keys come to the driver,
   // then go to 'authenticated'.  For all other authentication types
   // (those that donot require upper layer authentication) we can put
   // TL directly into 'authenticated' state.
   if (staDesc.wSTAType != WLAN_STA_IBSS) {
      VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
                 "STA type %d fConnected %d", staDesc.wSTAType, fConnected);
   }


   if ( !pRoamInfo->fAuthRequired )
   {
      // Connections that do not need Upper layer auth, transition TL directly
      // to 'Authenticated' state.
      vosStatus = WLANTL_ChangeSTAState(pHddCtx->pvosContext, staDesc.ucSTAId,
                                        WLANTL_STA_AUTHENTICATED,
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
                                        pRoamInfo->roamSynchInProgress
#else
                                        VOS_FALSE
#endif
                                       );

      hdd_connSetAuthenticated(pAdapter, VOS_TRUE);
   }
   else
   {
      VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
                 "ULA auth StaId= %d. Changing TL state to CONNECTED"
                 "at Join time", pHddStaCtx->conn_info.staId[0] );
      vosStatus = WLANTL_ChangeSTAState(pHddCtx->pvosContext, staDesc.ucSTAId,
                                        WLANTL_STA_CONNECTED,
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
                                        pRoamInfo->roamSynchInProgress
#else
                                        VOS_FALSE
#endif
                                       );
      hdd_connSetAuthenticated(pAdapter, VOS_FALSE);
   }
   return( vosStatus );
}

#ifdef WLAN_FEATURE_ROAM_OFFLOAD
/**
 * hdd_send_roam_auth_event() - send roamed and authed event
 * @hdd_ctx:   pointer to hdd context.
 * @bssid:    pointer to bssid of roamed AP.
 * @req_rsn_ie:    pointer to request RSN IE
 * @req_rsn_len:   length of the request RSN IE
 * @rsp_rsn_ie:    pointer to response RSN IE
 * @rsp_rsn_len:   length of the response RSN IE
 * @roam_info: pointer to the roaming related information
 *
 * this routine includes a condition check before call
 * wlan_hdd_send_roam_auth_event.
 */
static int hdd_send_roam_auth_event(hdd_context_t *hdd_ctx,
		uint8_t *bssid, uint8_t *req_rsn_ie,
		uint32_t req_rsn_len, uint8_t *rsp_rsn_ie,
		uint32_t rsp_rsn_len,
		tCsrRoamInfo *roam_info)
{
	if (hdd_ctx->cfg_ini->isRoamOffloadEnabled &&
	    roam_info->roamSynchInProgress)
		wlan_hdd_send_roam_auth_event(hdd_ctx, bssid,
					req_rsn_ie, req_rsn_len,
					rsp_rsn_ie, rsp_rsn_len,
					roam_info);
	return 0;
}
/**
 * hdd_is_roam_sync_in_progress()- Check if roam offloaded
 *
 * Return: roam sync status if roaming offloaded else false
 */
static inline bool hdd_is_roam_sync_in_progress(tCsrRoamInfo *roaminfo)
{
	return roaminfo->roamSynchInProgress;
}
#else
static inline bool hdd_is_roam_sync_in_progress(tCsrRoamInfo *roaminfo)
{
	return false;
}

static inline int hdd_send_roam_auth_event(hdd_context_t *hdd_ctx,
		uint8_t *bssid, uint8_t *req_rsn_ie, uint32_t req_rsn_length,
		uint8_t *rsp_rsn_ie, uint32_t rsp_rsn_length,
		tCsrRoamInfo *roam_info)
{
	return 0;
}
#endif

static void hdd_SendReAssocEvent(struct net_device *dev,
                                 hdd_adapter_t *pAdapter,
                                 tCsrRoamInfo *pCsrRoamInfo, v_U8_t *reqRsnIe,
                                 tANI_U32 reqRsnLength)
{
    unsigned int len = 0;
    u8 *pFTAssocRsp = NULL;
    v_U8_t *rspRsnIe = vos_mem_malloc(IW_GENERIC_IE_MAX);
    tANI_U32 rspRsnLength = 0;
    struct ieee80211_channel *chan;
    hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    uint8_t buf_ssid_ie[2 + SIR_MAC_SSID_EID_MAX]; /* 2 bytes for EID and len */
    uint8_t *buf_ptr, ssid_ie_len;
    struct cfg80211_bss *bss = NULL;
    uint8_t *final_req_ie = NULL;
    tCsrRoamConnectedProfile roam_profile;
    tHalHandle hal_handle = WLAN_HDD_GET_HAL_CTX(pAdapter);

    if (!rspRsnIe) {
        hddLog(LOGE, FL("Unable to allocate RSN IE"));
        return;
    }

    if (pCsrRoamInfo == NULL) {
        hddLog(LOGE, FL("Invalid CSR roam info"));
        goto done;
    }

    if (pCsrRoamInfo->nAssocRspLength == 0) {
        hddLog(LOGE, FL("Invalid assoc response length"));
        goto done;
    }

    pFTAssocRsp = (u8 *)(pCsrRoamInfo->pbFrames + pCsrRoamInfo->nBeaconLength +
                    pCsrRoamInfo->nAssocReqLength);
    if (pFTAssocRsp == NULL)
        goto done;

    /* pFTAssocRsp needs to point to the IEs */
    pFTAssocRsp += FT_ASSOC_RSP_IES_OFFSET;
    hddLog(LOG1, FL("AssocRsp is now at %02x%02x"),
                   (unsigned int)pFTAssocRsp[0], (unsigned int)pFTAssocRsp[1]);

   /* Active session count is decremented upon disconnection, but during
    * roaming, there is no disconnect indication and hence active session
    * count is not decremented.
    * After roaming is completed, active session count is incremented
    * as a part of connect indication but effectively after roaming the
    * active session count should still be the same and hence upon
    * successful reassoc decrement the active session count here */
    wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);

    /* Send the Assoc Resp, the supplicant needs this for initial Auth */
    len = pCsrRoamInfo->nAssocRspLength - FT_ASSOC_RSP_IES_OFFSET;
    rspRsnLength = len;
    memcpy(rspRsnIe, pFTAssocRsp, len);
    memset(rspRsnIe + len, 0, IW_GENERIC_IE_MAX - len);

    chan = ieee80211_get_channel(pAdapter->wdev.wiphy,
                                 (int)pCsrRoamInfo->pBssDesc->channelId);
    memset(&roam_profile, 0, sizeof(tCsrRoamConnectedProfile));
    sme_RoamGetConnectProfile(hal_handle, pAdapter->sessionId, &roam_profile);
    bss = hdd_cfg80211_get_bss(pAdapter->wdev.wiphy,
            chan, pCsrRoamInfo->bssid,
            &roam_profile.SSID.ssId[0],
            roam_profile.SSID.length);
    if (bss == NULL)
        hddLog(LOGE, FL("Get BSS returned NULL"));
    buf_ptr = buf_ssid_ie;
    *buf_ptr = SIR_MAC_SSID_EID;
    buf_ptr++;
    *buf_ptr = roam_profile.SSID.length; /*len of ssid*/
    buf_ptr++;
    vos_mem_copy(buf_ptr, &roam_profile.SSID.ssId[0],
    roam_profile.SSID.length);
    ssid_ie_len = 2 + roam_profile.SSID.length;
    hddLog(LOG2, FL("SSIDIE:"));
    VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
       buf_ssid_ie, ssid_ie_len);
    final_req_ie = vos_mem_malloc(IW_GENERIC_IE_MAX);
    if (final_req_ie == NULL)
        goto done;
    buf_ptr = final_req_ie;
    vos_mem_copy(buf_ptr, buf_ssid_ie, ssid_ie_len);
    buf_ptr += ssid_ie_len;
    vos_mem_copy(buf_ptr, reqRsnIe, reqRsnLength);
    memcpy(rspRsnIe, pFTAssocRsp, len);
    memset(final_req_ie + (ssid_ie_len + reqRsnLength), 0,
    IW_GENERIC_IE_MAX - (ssid_ie_len + reqRsnLength));
    hddLog(LOG2, FL("Req RSN IE:"));
    VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
       final_req_ie, (ssid_ie_len +reqRsnLength));
    cfg80211_roamed_bss(dev, bss,
       final_req_ie, (ssid_ie_len + reqRsnLength),
       rspRsnIe, rspRsnLength, GFP_KERNEL);

    hdd_send_roam_auth_event(pHddCtx, pCsrRoamInfo->bssid,
                    reqRsnIe, reqRsnLength, rspRsnIe,
                    rspRsnLength, pCsrRoamInfo);
done:
   sme_RoamFreeConnectProfile(hal_handle, &roam_profile);
   if (final_req_ie)
      vos_mem_free(final_req_ie);
   vos_mem_free(rspRsnIe);
}


/**
 * hdd_change_sta_state_authenticated()-
 * This function changes STA state to authenticated
 * @adapter:  pointer to the adapter structure.
 * @roaminfo: pointer to the RoamInfo structure.
 *
 * This is called from hdd_RoamSetKeyCompleteHandler
 * in context to eCSR_ROAM_SET_KEY_COMPLETE event from fw.
 *
 * Return: 0 on success and errno on failure
 */
static int hdd_change_sta_state_authenticated(hdd_adapter_t *adapter,
						 tCsrRoamInfo *roaminfo)
{
	int ret;
	hdd_context_t *hddctx = WLAN_HDD_GET_CTX(adapter);
	hdd_station_ctx_t *hddstactx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);

	hddLog(LOG1,
		"Changing TL state to AUTHENTICATED for StaId= %d",
		hddstactx->conn_info.staId[0]);

	/* Connections that do not need Upper layer authentication,
	 * transition TL to 'Authenticated' state after the keys are set
	 */
	ret = WLANTL_ChangeSTAState(hddctx->pvosContext,
			hddstactx->conn_info.staId[0],
			WLANTL_STA_AUTHENTICATED,
			hdd_is_roam_sync_in_progress(roaminfo));
	hdd_connSetAuthenticated(adapter, VOS_TRUE);
	if (hddctx->cfg_ini->enablePowersaveOffload &&
		(false == hddctx->is_mon_enable) &&
		((WLAN_HDD_INFRA_STATION == adapter->device_mode) ||
		(WLAN_HDD_P2P_CLIENT == adapter->device_mode))) {
		sme_PsOffloadEnableDeferredPowerSave(
			WLAN_HDD_GET_HAL_CTX(adapter),
			adapter->sessionId,
			hddstactx->hdd_ReassocScenario);
	}

	return ret;
}

void hdd_PerformRoamSetKeyComplete(hdd_adapter_t *pAdapter)
{
    eHalStatus halStatus = eHAL_STATUS_SUCCESS;
    hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
    tCsrRoamInfo roamInfo;
    roamInfo.fAuthRequired = FALSE;
    vos_mem_copy(roamInfo.bssid,
                 pHddStaCtx->roam_info.bssid,
                 VOS_MAC_ADDR_SIZE);
    vos_mem_copy(roamInfo.peerMac,
                 pHddStaCtx->roam_info.peerMac,
                 VOS_MAC_ADDR_SIZE);

    halStatus = hdd_RoamSetKeyCompleteHandler(pAdapter,
                                  &roamInfo,
                                  pHddStaCtx->roam_info.roamId,
                                  pHddStaCtx->roam_info.roamStatus,
                                  eCSR_ROAM_RESULT_AUTHENTICATED);
    if (halStatus != eHAL_STATUS_SUCCESS)
    {
        hddLog(LOGE, "%s: Set Key complete failure", __func__);
    }
    pHddStaCtx->roam_info.deferKeyComplete = FALSE;
}

#if defined(WLAN_FEATURE_FILS_SK) && defined(CFG80211_FILS_SK_OFFLOAD_SUPPORT)
static void hdd_clear_fils_connection_info(hdd_adapter_t *adapter)
{
       hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);

       if (wext_state->roamProfile.fils_con_info) {
              vos_mem_free(wext_state->roamProfile.fils_con_info);
              wext_state->roamProfile.fils_con_info = NULL;
       }
}
#else
static void hdd_clear_fils_connection_info(hdd_adapter_t *adapter)
{ }
#endif

/**
 * hdd_sap_restart_handle() - to handle restarting of SAP
 * @work: name of the work
 *
 * Purpose of this function is to trigger sap start. this function
 * will be called from workqueue.
 *
 * Return: void.
 */
void hdd_sap_restart_handle(struct work_struct *work)
{
    hdd_adapter_t *sap_adapter;
    hdd_context_t *hdd_ctx = container_of(work,
                                          hdd_context_t,
                                          sap_start_work);
    vos_ssr_protect(__func__);
    if (0 != wlan_hdd_validate_context(hdd_ctx)) {
        vos_ssr_unprotect(__func__);
        return;
    }
    sap_adapter = hdd_get_adapter(hdd_ctx,
                                  WLAN_HDD_SOFTAP);
    if (sap_adapter == NULL) {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  FL("sap_adapter is NULL"));
        vos_ssr_unprotect(__func__);
        return;
    }

    if (hdd_ctx->is_ch_avoid_in_progress) {
        sap_adapter->sessionCtx.ap.sapConfig.channel = AUTO_CHANNEL_SELECT;
        wlan_hdd_restart_sap(sap_adapter);
        hdd_change_ch_avoidance_status(hdd_ctx, false);
    } else {
        wlan_hdd_start_sap(sap_adapter, false);
        hdd_change_sap_restart_required_status(hdd_ctx, false);
    }
    vos_ssr_unprotect(__func__);
}

static eHalStatus hdd_AssociationCompletionHandler( hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
                                                    tANI_U32 roamId, eRoamCmdStatus roamStatus,
                                                    eCsrRoamResult roamResult )
{
    struct net_device *dev = pAdapter->dev;
    hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
#ifdef FEATURE_WLAN_FORCE_SAP_SCC
    hdd_adapter_t *pHostapdAdapter;
#endif /* FEATURE_WLAN_FORCE_SAP_SCC */
    VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
    v_U8_t reqRsnIe[DOT11F_IE_RSN_MAX_LEN];
    tANI_U32 reqRsnLength = DOT11F_IE_RSN_MAX_LEN;
#if  defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) || defined (WLAN_FEATURE_VOWIFI_11R)
    int ft_carrier_on = FALSE;
#endif
    v_BOOL_t hddDisconInProgress = FALSE;
    tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
    unsigned long rc;
    hdd_adapter_t *sap_adapter;
    hdd_ap_ctx_t *hdd_ap_ctx;
    uint8_t default_sap_channel = 6;
    tSirResultCodes timeout_reason = 0;
    struct wireless_dev *wdev = dev->ieee80211_ptr;
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
    if (pRoamInfo && pRoamInfo->roamSynchInProgress) {
       /* change logging before release */
        hddLog(VOS_TRACE_LEVEL_DEBUG, "LFR3:hdd_AssociationCompletionHandler");
    }
#endif

    /* HDD has initiated disconnect, do not send connect result indication
     * to kernel as it will be handled by __cfg80211_disconnect.
     */
    if(((eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState) ||
         (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)) &&
        ((eCSR_ROAM_RESULT_ASSOCIATED == roamResult) ||
        (eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus)))
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                FL(" Disconnect from HDD in progress "));
        hddDisconInProgress  = TRUE;
    }

    if ( eCSR_ROAM_RESULT_ASSOCIATED == roamResult )
    {
        if (NULL == pRoamInfo) {
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      FL("pRoamInfo is NULL"));
            return eHAL_STATUS_FAILURE;
        }
        if ( !hddDisconInProgress )
        {
            hdd_connSetConnectionState(pAdapter,
                                       eConnectionState_Associated);
        }

        // Save the connection info from CSR...
        hdd_connSaveConnectInfo( pAdapter, pRoamInfo, eCSR_BSS_TYPE_INFRASTRUCTURE );

        if (hdd_set_beacon_filter(pAdapter) != 0)
            hddLog(LOGE,
                   FL("hdd_set_beacon_filter() failed"));

#ifdef FEATURE_WLAN_WAPI
        if ( pRoamInfo->u.pConnectedProfile->AuthType == eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE ||
                pRoamInfo->u.pConnectedProfile->AuthType == eCSR_AUTH_TYPE_WAPI_WAI_PSK )
        {
            pAdapter->wapi_info.fIsWapiSta = 1;
        }
        else
        {
            pAdapter->wapi_info.fIsWapiSta = 0;
        }
#endif  /* FEATURE_WLAN_WAPI */

        /* Indicate 'connect' status to user space */
        hdd_SendAssociationEvent(dev,pRoamInfo);

	if (hdd_is_mcc_in_24G(pHddCtx)) {
		if ((pMac != NULL) && (pHddCtx->miracast_value)) {
			hdd_set_mas(pAdapter, pHddCtx->miracast_value);
		}
	}

        // Initialize the Linkup event completion variable
        INIT_COMPLETION(pAdapter->linkup_event_var);

        /*
           Sometimes Switching ON the Carrier is taking time to activate the device properly. Before allowing any
           packet to go up to the application, device activation has to be ensured for proper queue mapping by the
           kernel. we have registered net device notifier for device change notification. With this we will come to
           know that the device is getting activated properly.
           */
#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
        if (pHddStaCtx->ft_carrier_on == FALSE)
        {
#endif
            // Enable Linkup Event Servicing which allows the net device notifier to set the linkup event variable
            pAdapter->isLinkUpSvcNeeded = TRUE;

            // Enable Linkup Event Servicing which allows the net device notifier to set the linkup event variable
            pAdapter->isLinkUpSvcNeeded = TRUE;

            // Switch on the Carrier to activate the device
            wlan_hdd_netif_queue_control(pAdapter, WLAN_NETIF_CARRIER_ON,
                             WLAN_CONTROL_PATH);

            // Wait for the Link to up to ensure all the queues are set properly by the kernel
            rc = wait_for_completion_timeout(&pAdapter->linkup_event_var,
                                                   msecs_to_jiffies(ASSOC_LINKUP_TIMEOUT));
            if (!rc) {
                hddLog(VOS_TRACE_LEVEL_WARN, "%s: Warning:ASSOC_LINKUP_TIMEOUT", __func__);
            }

            // Disable Linkup Event Servicing - no more service required from the net device notifier call
            pAdapter->isLinkUpSvcNeeded = FALSE;
#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
        }
        else {
            pHddStaCtx->ft_carrier_on = FALSE;
            ft_carrier_on = TRUE;
        }
#endif
        /* Check for STAID */
        if ((WLAN_MAX_STA_COUNT + 3) > pRoamInfo->staId)
           pHddCtx->sta_to_adapter[pRoamInfo->staId] = pAdapter;
        else
           hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Wrong Staid: %d", __func__,
                                                       pRoamInfo->staId);

#ifdef IPA_OFFLOAD
        if (hdd_ipa_is_enabled(pHddCtx))
            hdd_ipa_wlan_evt(pAdapter, pRoamInfo->staId, WLAN_STA_CONNECT,
                    pRoamInfo->bssid);
#endif
#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
        wlan_hdd_auto_shutdown_enable(pHddCtx, VOS_FALSE);
#endif
        /* validate cfg_ini */
        if (!pHddCtx->cfg_ini) {
                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                          "cfg_ini is NULL");
                return eHAL_STATUS_E_NULL_VALUE;
        }
#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
        if ((pHddCtx->cfg_ini->WlanMccToSccSwitchMode
                != VOS_MCC_TO_SCC_SWITCH_DISABLE) &&
            ((0 == pHddCtx->cfg_ini->conc_custom_rule1) &&
             (0 == pHddCtx->cfg_ini->conc_custom_rule2))
#ifdef FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE
            && !VOS_IS_DFS_CH(pHddStaCtx->conn_info.operationChannel)
#endif
           ) {
            adf_os_create_work(0, &pHddCtx->sta_ap_intf_check_work,
                wlan_hdd_check_sta_ap_concurrent_ch_intf, (void *)pAdapter);
            adf_os_sched_work(0, &pHddCtx->sta_ap_intf_check_work);
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                                "Checking for Concurrent Change interference");
        }
#endif

#ifdef QCA_PKT_PROTO_TRACE
        /* STA Associated, update into trace buffer */
        if (pHddCtx->cfg_ini->gEnableDebugLog)
        {
           vos_pkt_trace_buf_update("ST:ASSOC");
        }
#endif /* QCA_PKT_PROTO_TRACE */

        DPTRACE(adf_dp_trace_mgmt_pkt(ADF_DP_TRACE_MGMT_PACKET_RECORD,
                       pAdapter->sessionId,
                       ADF_PROTO_TYPE_MGMT, ADF_PROTO_MGMT_ASSOC));

        //For reassoc, the station is already registered, all we need is to change the state
        //of the STA in TL.
        //If authentication is required (WPA/WPA2/DWEP), change TL to CONNECTED instead of AUTHENTICATED
        if( !pRoamInfo->fReassocReq )
        {
            struct cfg80211_bss *bss;
#ifdef WLAN_FEATURE_VOWIFI_11R
            u8 *pFTAssocRsp = NULL;
            unsigned int assocRsplen = 0;
            u8 *pFTAssocReq = NULL;
            unsigned int assocReqlen = 0;
            struct ieee80211_channel *chan;
#endif
            v_U8_t rspRsnIe[DOT11F_IE_RSN_MAX_LEN];
            tANI_U32 rspRsnLength = DOT11F_IE_RSN_MAX_LEN;

            /* add bss_id to cfg80211 data base */
            bss = wlan_hdd_cfg80211_update_bss_db(pAdapter, pRoamInfo);
            if (NULL == bss) {
                hddLog(LOGE,
                     FL("Not able to add BSS entry"));
                wlan_hdd_netif_queue_control(pAdapter,
                    WLAN_NETIF_CARRIER_OFF,
                    WLAN_CONTROL_PATH);
                if (!hddDisconInProgress) {
                   /*
                    * Here driver was not able to add bss in cfg80211 database
                    * this can happen if connected channel is not valid,
                    * i.e reg domain was changed during connection.
                    * Queue disconnect for the session if disconnect is
                    * not in progress.
                    */
                    hddLog(LOGE, FL("Disconnecting..."));
                    sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
                                 pAdapter->sessionId,
                                 eCSR_DISCONNECT_REASON_UNSPECIFIED);
                }
                return eHAL_STATUS_FAILURE;
            }
#ifdef WLAN_FEATURE_VOWIFI_11R
            if(pRoamInfo->u.pConnectedProfile->AuthType == eCSR_AUTH_TYPE_FT_RSN ||
                pRoamInfo->u.pConnectedProfile->AuthType == eCSR_AUTH_TYPE_FT_RSN_PSK )
            {

                //Association Response
                pFTAssocRsp = (u8 *)(pRoamInfo->pbFrames + pRoamInfo->nBeaconLength +
                                    pRoamInfo->nAssocReqLength);
                if (pFTAssocRsp != NULL)
                {
                    // pFTAssocRsp needs to point to the IEs
                    pFTAssocRsp += FT_ASSOC_RSP_IES_OFFSET;
                    hddLog(LOG1, "%s: AssocRsp is now at %02x%02x", __func__,
                                        (unsigned int)pFTAssocRsp[0],
                                        (unsigned int)pFTAssocRsp[1]);
                    assocRsplen = pRoamInfo->nAssocRspLength - FT_ASSOC_RSP_IES_OFFSET;
                }
                else
                {
                    hddLog(LOGE, "%s:AssocRsp is NULL", __func__);
                    assocRsplen = 0;
                }

                //Association Request
                pFTAssocReq = (u8 *)(pRoamInfo->pbFrames +
                                     pRoamInfo->nBeaconLength);
                if (pFTAssocReq != NULL)
                {
                    if(!ft_carrier_on)
                    {
                         // pFTAssocReq needs to point to the IEs
                        pFTAssocReq += FT_ASSOC_REQ_IES_OFFSET;
                        hddLog(LOG1, "%s: pFTAssocReq is now at %02x%02x", __func__,
                                              (unsigned int)pFTAssocReq[0],
                                              (unsigned int)pFTAssocReq[1]);
                        assocReqlen = pRoamInfo->nAssocReqLength - FT_ASSOC_REQ_IES_OFFSET;
                    }
                    else
                    {
                        /* This should contain only the FTIEs */
                        assocReqlen = pRoamInfo->nAssocReqLength;
                    }
                }
                else
                {
                    hddLog(LOGE, "%s:AssocReq is NULL", __func__);
                    assocReqlen = 0;
                }

                if(ft_carrier_on)
                {
                    if ( !hddDisconInProgress )
                    {
                        struct cfg80211_bss *roam_bss;

                        /* After roaming is completed, active session count is
                         * incremented as a part of connect indication but
                         * effectively the active session count should still
                         * be the same and hence upon successful reassoc
                         * decrement the active session count here */
                        wlan_hdd_decr_active_session(pHddCtx,
                                                     pAdapter->device_mode);

                        hddLog(LOG1, "%s ft_carrier_on is %d, sending roamed "
                                     "indication", __FUNCTION__, ft_carrier_on);
                        chan = ieee80211_get_channel(pAdapter->wdev.wiphy,
                                             (int)pRoamInfo->pBssDesc->channelId);
                        hddLog(LOG1, "assocReqlen %d assocRsplen %d", assocReqlen,
                                             assocRsplen);
                        roam_bss =
                            hdd_cfg80211_get_bss(
                               pAdapter->wdev.wiphy,
                               chan,
                               pRoamInfo->bssid,
                               pRoamInfo->u.
                               pConnectedProfile->SSID.ssId,
                               pRoamInfo->u.
                               pConnectedProfile->SSID.length);
                        cfg80211_roamed_bss(dev, roam_bss,
                               pFTAssocReq, assocReqlen,
                               pFTAssocRsp, assocRsplen,
                               GFP_KERNEL);
                    }
                    if (sme_GetFTPTKState(WLAN_HDD_GET_HAL_CTX(pAdapter),
                                          pAdapter->sessionId))
                    {
                        sme_SetFTPTKState(WLAN_HDD_GET_HAL_CTX(pAdapter),
                                          pAdapter->sessionId, FALSE);
                        pRoamInfo->fAuthRequired = FALSE;

                        vos_mem_copy(pHddStaCtx->roam_info.bssid,
                                     pRoamInfo->bssid,
                                     HDD_MAC_ADDR_LEN);
                        vos_mem_copy(pHddStaCtx->roam_info.peerMac,
                                     pRoamInfo->peerMac,
                                     HDD_MAC_ADDR_LEN);
                        pHddStaCtx->roam_info.roamId = roamId;
                        pHddStaCtx->roam_info.roamStatus = roamStatus;
                        pHddStaCtx->roam_info.deferKeyComplete = TRUE;
                    }
                }
                else if ( !hddDisconInProgress )
                {
                    hddLog(LOG1, "%s ft_carrier_on is %d, sending connect "
                                 "indication", __FUNCTION__, ft_carrier_on);

		    if(wdev->ssid_len != 0)
			    hdd_connect_result(dev, pRoamInfo->bssid, pRoamInfo,
					       pFTAssocReq, assocReqlen,
					       pFTAssocRsp, assocRsplen,
					       WLAN_STATUS_SUCCESS,
					       GFP_KERNEL, false,
					       pRoamInfo->statusCode);
                }
            }
            else
#endif
            {
                /* wpa supplicant expecting WPA/RSN IE in connect result */
                csrRoamGetWpaRsnReqIE(WLAN_HDD_GET_HAL_CTX(pAdapter),
                        pAdapter->sessionId,
                        &reqRsnLength,
                        reqRsnIe);

                csrRoamGetWpaRsnRspIE(WLAN_HDD_GET_HAL_CTX(pAdapter),
                        pAdapter->sessionId,
                        &rspRsnLength,
                        rspRsnIe);
                if ( !hddDisconInProgress )
                {
#if  defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
                    if(ft_carrier_on)
                        hdd_SendReAssocEvent(dev, pAdapter, pRoamInfo, reqRsnIe, reqRsnLength);
                    else
#endif /* FEATURE_WLAN_ESE */

                    {
                        hddLog(VOS_TRACE_LEVEL_INFO,
                               "%s: sending connect indication to nl80211:for bssid " MAC_ADDRESS_STR " result:%d and Status:%d",
                               __func__, MAC_ADDR_ARRAY(pRoamInfo->bssid),
                               roamResult, roamStatus);

                        /* inform connect result to nl80211 */
			if(wdev->ssid_len != 0)
				hdd_connect_result(dev, pRoamInfo->bssid, pRoamInfo,
					reqRsnIe, reqRsnLength,
					rspRsnIe, rspRsnLength,
					WLAN_STATUS_SUCCESS,
					GFP_KERNEL, false, pRoamInfo->statusCode);
                    }
                }
            }
            if ( !hddDisconInProgress )
            {
                cfg80211_put_bss(
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)) || defined(WITH_BACKPORTS)
                                 pHddCtx->wiphy,
#endif
                                 bss);

                // perform any WMM-related association processing
                hdd_wmm_assoc(pAdapter, pRoamInfo, eCSR_BSS_TYPE_INFRASTRUCTURE);

                /* Start the Queue - Start tx queues before hdd_roamRegisterSTA,
                   since hdd_roamRegisterSTA will flush any cached data frames
                   immediately */
                hddLog(LOG1, FL("Enabling queues"));
                wlan_hdd_netif_queue_control(pAdapter,
                    WLAN_WAKE_ALL_NETIF_QUEUE,
                    WLAN_CONTROL_PATH);

                // Register the Station with TL after associated...
                vosStatus = hdd_roamRegisterSTA( pAdapter,
                        pRoamInfo,
                        pHddStaCtx->conn_info.staId[ 0 ],
                        NULL,
                        pRoamInfo->pBssDesc );
            }

#ifdef FEATURE_WLAN_TDLS
        wlan_hdd_tdls_connection_callback(pAdapter);
#endif
        }
        else
        {
            /* wpa supplicant expecting WPA/RSN IE in connect result */
            /*  in case of reassociation also need to indicate it to supplicant */
            csrRoamGetWpaRsnReqIE(WLAN_HDD_GET_HAL_CTX(pAdapter),
                    pAdapter->sessionId,
                    &reqRsnLength,
                    reqRsnIe);

            hdd_SendReAssocEvent(dev, pAdapter, pRoamInfo, reqRsnIe, reqRsnLength);
            //Reassoc successfully
            if( pRoamInfo->fAuthRequired )
            {
                vosStatus = WLANTL_ChangeSTAState(pHddCtx->pvosContext,
                                                  pHddStaCtx->conn_info.staId[0],
                                                  WLANTL_STA_CONNECTED,
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
                                                  pRoamInfo->roamSynchInProgress
#else
                                                  VOS_FALSE
#endif
                                                 );
                hdd_connSetAuthenticated(pAdapter, VOS_FALSE);
            }
            else
            {
                VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
                          "%s: staId: %d Changing TL state to AUTHENTICATED",
                          __func__, pHddStaCtx->conn_info.staId[ 0 ] );
                vosStatus = WLANTL_ChangeSTAState(pHddCtx->pvosContext,
                                                  pHddStaCtx->conn_info.staId[0],
                                                  WLANTL_STA_AUTHENTICATED,
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
                                                  pRoamInfo->roamSynchInProgress
#else
                                                  VOS_FALSE
#endif
                                                 );
                hdd_connSetAuthenticated(pAdapter, VOS_TRUE);
            }

            if ( VOS_IS_STATUS_SUCCESS( vosStatus ) )
            {
                // perform any WMM-related association processing
                hdd_wmm_assoc(pAdapter, pRoamInfo, eCSR_BSS_TYPE_INFRASTRUCTURE);
            }

            /* Start the tx queues */
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
            if (pRoamInfo->roamSynchInProgress) {
               hddLog(VOS_TRACE_LEVEL_DEBUG, "LFR3:netif_tx_wake_all_queues");
            }
#endif
            hddLog(LOG1, FL("Enabling queues"));
            wlan_hdd_netif_queue_control(pAdapter,
                WLAN_WAKE_ALL_NETIF_QUEUE,
                WLAN_CONTROL_PATH);
        }

        if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
        {
            VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                    "Cannot register STA with TL.  Failed with vosStatus = %d [%08X]",
                    vosStatus, vosStatus );
        }
#ifdef WLAN_FEATURE_11W
        vos_mem_zero( &pAdapter->hdd_stats.hddPmfStats,
                      sizeof(pAdapter->hdd_stats.hddPmfStats) );
#endif
    }
    else
    {
        hdd_context_t* pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
        bool connect_timeout = false;

        hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
        if (pRoamInfo)
            VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                    "wlan: connection failed with " MAC_ADDRESS_STR " result:%d and Status:%d",
                    MAC_ADDR_ARRAY(pRoamInfo->bssid), roamResult, roamStatus);
        else
            VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                    "wlan: connection failed with " MAC_ADDRESS_STR " result:%d and Status:%d",
                    MAC_ADDR_ARRAY(pWextState->req_bssId),
                    roamResult, roamStatus);

        /* Set connection state to eConnectionState_NotConnected only when CSR
         * has completed operation - with a ASSOCIATION_FAILURE status
         */
        if ( eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus &&  !hddDisconInProgress )
        {
            hdd_connSetConnectionState(pAdapter,
                                             eConnectionState_NotConnected);
        }
        if((pHddCtx->concurrency_mode <= 1) &&
           (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
        {
            pHddCtx->isAmpAllowed = VOS_TRUE;
        }

        //If the Device Mode is Station
        // and the P2P Client is Connected
        //Enable BMPS

        /*
         * In case of JB, as Change-Iface may or may not be called for p2p0
         * Enable BMPS/IMPS in case P2P_CLIENT disconnected
         * If ps offload is enabled, fw will take care in case of concurrency.
         */
        if(((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
            (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)) &&
            (vos_concurrent_open_sessions_running()) &&
            !pHddCtx->cfg_ini->enablePowersaveOffload)
        {
           //Enable BMPS only of other Session is P2P Client
           hdd_context_t *pHddCtx = NULL;
           v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );

           if (NULL != pVosContext)
           {
               pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);

               if(NULL != pHddCtx)
               {
                    //Only P2P Client is there Enable Bmps back
                    if((0 == pHddCtx->no_of_open_sessions[VOS_STA_SAP_MODE]) &&
                       (0 == pHddCtx->no_of_open_sessions[VOS_P2P_GO_MODE]))
                    {
                         if (pHddCtx->hdd_wlan_suspended)
                         {
                             hdd_set_pwrparams(pHddCtx);
                         }
                         hdd_enable_bmps_imps(pHddCtx);
                    }
               }
           }
        }

        if ((eCSR_ROAM_RESULT_SCAN_FOR_SSID_FAILURE == roamResult) ||
           (pRoamInfo &&
           ((eSIR_SME_JOIN_TIMEOUT_RESULT_CODE == pRoamInfo->statusCode) ||
           (eSIR_SME_AUTH_TIMEOUT_RESULT_CODE == pRoamInfo->statusCode) ||
           (eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE == pRoamInfo->statusCode)))) {
             wlan_hdd_cfg80211_update_bss_list(pAdapter,
                    pRoamInfo ? pRoamInfo->bssid : pWextState->req_bssId);
             sme_remove_bssid_from_scan_list(hHal,
                    pRoamInfo ? pRoamInfo->bssid : pWextState->req_bssId);
             connect_timeout = true;
        }

        /* CR465478: Only send up a connection failure result when CSR has
         * completed operation - with a ASSOCIATION_FAILURE status.*/
        if ( eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus &&  !hddDisconInProgress )
        {
            if (pRoamInfo) {
                hddLog(VOS_TRACE_LEVEL_ERROR,
                       "%s: send connect failure to nl80211: for bssid " MAC_ADDRESS_STR" result:%d and Status:%d reasonCode %d" ,
                       __func__, MAC_ADDR_ARRAY(pRoamInfo->bssid),
                       roamResult, roamStatus, pRoamInfo->reasonCode);
                pHddStaCtx->conn_info.assoc_status_code = pRoamInfo->statusCode;
            } else {
                hddLog(VOS_TRACE_LEVEL_ERROR,
                       "%s: connect failed: for bssid " MAC_ADDRESS_STR " result:%d and Status:%d " ,
                       __func__, MAC_ADDR_ARRAY(pWextState->req_bssId),
                       roamResult, roamStatus);
            }

            hddLog(LOG1, FL("Invoking packetdump deregistration API"));
            wlan_deregister_txrx_packetdump();

            /* inform association failure event to nl80211 */
            if ( eCSR_ROAM_RESULT_ASSOC_FAIL_CON_CHANNEL == roamResult )
            {
               if (pRoamInfo)
                   hdd_connect_result(dev, pRoamInfo->bssid,
                        pRoamInfo,
                        NULL, 0, NULL, 0,
                        WLAN_STATUS_ASSOC_DENIED_UNSPEC,
                        GFP_KERNEL, connect_timeout, pRoamInfo->statusCode);
               else
                   hdd_connect_result(dev, pWextState->req_bssId, NULL,
                        NULL, 0, NULL, 0,
                        WLAN_STATUS_ASSOC_DENIED_UNSPEC,
                        GFP_KERNEL, connect_timeout, timeout_reason);
            }
            else
            {
               if (pRoamInfo)
                   hdd_connect_result(dev, pRoamInfo->bssid,
                        pRoamInfo,
                        NULL, 0, NULL, 0,
                        pRoamInfo->reasonCode ?
                        pRoamInfo->reasonCode :
                        WLAN_STATUS_UNSPECIFIED_FAILURE,
                        GFP_KERNEL, connect_timeout, pRoamInfo->statusCode);
               else
                   hdd_connect_result(dev, pWextState->req_bssId, NULL,
                        NULL, 0, NULL, 0,
                        WLAN_STATUS_UNSPECIFIED_FAILURE,
                        GFP_KERNEL, connect_timeout, timeout_reason);
            }
            /* Clear the roam profile */
            hdd_clearRoamProfileIe(pAdapter);

        }

        hdd_wmm_init( pAdapter );

        hddLog(LOG1, FL("Disabling queues"));
        wlan_hdd_netif_queue_control(pAdapter,
            WLAN_NETIF_TX_DISABLE_N_CARRIER,
            WLAN_CONTROL_PATH);

    }

    if (pHddCtx->cfg_ini->conc_custom_rule1 &&
        (true == hdd_is_sap_restart_required(pHddCtx))) {
        sap_adapter = hdd_get_adapter(pHddCtx, WLAN_HDD_SOFTAP);
        if (sap_adapter == NULL) {
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      FL("sap_adapter is NULL"));
            return eHAL_STATUS_FAILURE;
        }

        if (test_bit(SOFTAP_BSS_STARTED, &sap_adapter->event_flags)) {
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      FL("Oops SAP is already in started state"));
            return eHAL_STATUS_FAILURE;
        }

        hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(sap_adapter);
        if ((eCSR_ROAM_RESULT_ASSOCIATED == roamResult) &&
             pHddStaCtx->conn_info.operationChannel < SIR_11A_CHANNEL_BEGIN) {
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  FL("Starting SAP on channel [%d] after STA assoc complete"),
                  pHddStaCtx->conn_info.operationChannel);
            hdd_ap_ctx->operatingChannel =
                    pHddStaCtx->conn_info.operationChannel;
        } else {
            /* start on default SAP channel */
            hdd_ap_ctx->operatingChannel =
                    default_sap_channel;
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                      FL("Starting SAP on channel [%d] after STA assoc failed"),
                      default_sap_channel);
        }
        hdd_ap_ctx->sapConfig.vht_channel_width =
                                            hdd_ap_ctx->sapConfig.ch_width_orig;
        sme_SelectCBMode(WLAN_HDD_GET_HAL_CTX(sap_adapter),
                         hdd_ap_ctx->sapConfig.SapHw_mode,
                         hdd_ap_ctx->operatingChannel,
                         hdd_ap_ctx->sapConfig.sec_ch,
                         &hdd_ap_ctx->sapConfig.vht_channel_width,
                         hdd_ap_ctx->sapConfig.ch_width_orig);
        /*
         * Create a workqueue and let the workqueue handle the restarting
         * sap task. if we directly call sap restart function without
         * creating workqueue then our main thread might go to sleep which
         * is not acceptable.
         */

         /*
          * If channel avoidance is intiated, don't schedule the work.
          * Channel avoidance takes care restarting SAP.
          */
         if (true == hdd_is_sap_restart_required(pHddCtx))
             schedule_work(&pHddCtx->sap_start_work);


    }
    hdd_clear_fils_connection_info(pAdapter);
    /*
     * Call hdd_decide_dynamic_chain_mask only when CSR has
     * completed connect with failure or success i.e. with
     * ASSOCIATION_FAILURE status or with eCSR_ROAM_RESULT_ASSOCIATED
     * result.
     */
    if (pHddCtx->cfg_ini->enable_dynamic_sta_chainmask &&
       ((eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus) ||
       (eCSR_ROAM_RESULT_ASSOCIATED == roamResult)))
         hdd_decide_dynamic_chain_mask(pHddCtx,
                         HDD_ANTENNA_MODE_INVALID);

#ifdef FEATURE_WLAN_FORCE_SAP_SCC
    if (eCSR_ROAM_RESULT_ASSOCIATED == roamResult &&
        pHddCtx->cfg_ini->SapSccChanAvoidance) {
        pHostapdAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_SOFTAP);
        if (pHostapdAdapter != NULL) {
             /* Restart SAP if its operating channel is different
              * from AP channel.
              */
             if (pHostapdAdapter->sessionCtx.ap.operatingChannel !=
                pRoamInfo->pBssDesc->channelId) {
                hddLog(VOS_TRACE_LEVEL_ERROR,
                       "Restart Sap as SAP channel is %d and STA channel is %d",
                       pHostapdAdapter->sessionCtx.ap.operatingChannel,
                       pRoamInfo->pBssDesc->channelId);
                hdd_restart_softap(pHddCtx, pHostapdAdapter);
             }
        }
    }
#endif /* FEATURE_WLAN_FORCE_SAP_SCC */
    return eHAL_STATUS_SUCCESS;
}

/**============================================================================
 *
  @brief hdd_RoamIbssIndicationHandler() - Here we update the status of the
  Ibss when we receive information that we have started/joined an ibss session

  ===========================================================================*/
static void hdd_RoamIbssIndicationHandler( hdd_adapter_t *pAdapter,
                                           tCsrRoamInfo *pRoamInfo,
                                           tANI_U32 roamId,
                                           eRoamCmdStatus roamStatus,
                                           eCsrRoamResult roamResult )
{
   hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s: id %d, status %d, result %d",
          __func__, pAdapter->dev->name, roamId, roamStatus, roamResult);

   switch( roamResult )
   {
      // both IBSS Started and IBSS Join should come in here.
      case eCSR_ROAM_RESULT_IBSS_STARTED:
      case eCSR_ROAM_RESULT_IBSS_JOIN_SUCCESS:
      case eCSR_ROAM_RESULT_IBSS_COALESCED:
      {
         hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
         v_MACADDR_t broadcastMacAddr = VOS_MAC_ADDR_BROADCAST_INITIALIZER;

         if (NULL == pRoamInfo)
         {
            VOS_ASSERT(0);
            return;
         }

         /* When IBSS Started comes from CSR, we need to move
          * connection state to IBSS Disconnected (meaning no peers
          * are in the IBSS).
          */
         hdd_connSetConnectionState(pAdapter,
                                     eConnectionState_IbssDisconnected);
         /* Notify wmm */
         hdd_wmm_connect(pAdapter, pRoamInfo, eCSR_BSS_TYPE_IBSS);
         pHddCtx->sta_to_adapter[IBSS_BROADCAST_STAID] = pAdapter;
         hdd_roamRegisterSTA (pAdapter, pRoamInfo,
                      IBSS_BROADCAST_STAID,
                      &broadcastMacAddr, pRoamInfo->pBssDesc);

         if (pRoamInfo->pBssDesc)
         {
            struct cfg80211_bss *bss;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0)) || defined(WITH_BACKPORTS)
            struct ieee80211_channel *chan;
            int chan_no;
            unsigned int freq;
#endif
            /* we created the IBSS, notify supplicant */
            hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s: created ibss "
                   MAC_ADDRESS_STR,
                   __func__, pAdapter->dev->name,
                   MAC_ADDR_ARRAY(pRoamInfo->pBssDesc->bssId));

            /* we must first give cfg80211 the BSS information */
            bss = wlan_hdd_cfg80211_update_bss_db(pAdapter, pRoamInfo);
            if (NULL == bss)
            {
               hddLog(VOS_TRACE_LEVEL_ERROR,
                      "%s: %s: unable to create IBSS entry",
                      __func__, pAdapter->dev->name);
               return;
            }
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0)) || defined(WITH_BACKPORTS)
            chan_no = pRoamInfo->pBssDesc->channelId;

            if (chan_no <= 14)
                freq = ieee80211_channel_to_frequency(chan_no,
                                                      IEEE80211_BAND_2GHZ);
            else
                freq = ieee80211_channel_to_frequency(chan_no,
                                                      IEEE80211_BAND_5GHZ);

            chan = ieee80211_get_channel(pAdapter->wdev.wiphy, freq);

            if (chan)
                cfg80211_ibss_joined(pAdapter->dev, bss->bssid,
                                     chan, GFP_KERNEL);
            else
                hddLog(LOGE, FL("%s: chanId: %d, can't find channel"),
                       pAdapter->dev->name,
                       (int)pRoamInfo->pBssDesc->channelId);
#else

            wlan_hdd_netif_queue_control(pAdapter,
                WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
                WLAN_CONTROL_PATH);
            cfg80211_ibss_joined(pAdapter->dev, bss->bssid, GFP_KERNEL);
#endif
            cfg80211_put_bss(
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)) || defined(WITH_BACKPORTS)
                             pHddCtx->wiphy,
#endif
                             bss);
         }

         break;
      }

      case eCSR_ROAM_RESULT_IBSS_START_FAILED:
      {
         hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s: unable to create IBSS",
                __func__, pAdapter->dev->name);
         break;
      }

      default:
         hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s: unexpected result %d",
                __func__, pAdapter->dev->name, (int)roamResult);
         break;
   }

   return;
}

/**
 * hdd_save_peer() - Save peer MAC address in adapter peer table.
 * @sta_ctx: pointer to hdd station context
 * @sta_id: station ID
 * @peer_mac_addr: mac address of new peer
 *
 * This information is passed to iwconfig later. The peer that joined
 * last is passed as information to iwconfig.

 * Return: true if success, false otherwise
 */
bool hdd_save_peer(hdd_station_ctx_t *sta_ctx, uint8_t sta_id,
		   v_MACADDR_t *peer_mac_addr)
{
	int idx;

	for (idx = 0; idx < HDD_MAX_NUM_IBSS_STA; idx++) {
		if (0 == sta_ctx->conn_info.staId[idx]) {
			hddLog(VOS_TRACE_LEVEL_DEBUG,
			       FL("adding peer: %pM, sta_id: %d, at idx: %d"),
			       peer_mac_addr, sta_id, idx);
			sta_ctx->conn_info.staId[idx] = sta_id;
			vos_copy_macaddr(
				&sta_ctx->conn_info.peerMacAddress[idx],
				peer_mac_addr);
			return true;
		}
	}
	return false;
}

/**
 * hdd_delete_peer() - removes peer from hdd station context peer table
 * @sta_ctx: pointer to hdd station context
 * @sta_id: station ID
 *
 * Return: none
 */
void hdd_delete_peer(hdd_station_ctx_t *sta_ctx, uint8_t sta_id)
{
	int i;

	for (i = 0; i < HDD_MAX_NUM_IBSS_STA; i++) {
		if (sta_id == sta_ctx->conn_info.staId[i]) {
			sta_ctx->conn_info.staId[i] = 0;
			return;
		}
	}

	hddLog(LOGE, FL("sta_id %d is not present in peer table"), sta_id);
}

/**============================================================================
 *
  @brief roamRemoveIbssStation() - Remove the IBSS peer MAC address in the adapter.
  If we remove HDD_MAX_NUM_IBSS_STA or less STA we return success else we
  return FALSE.

  ===========================================================================*/
static int roamRemoveIbssStation( hdd_adapter_t *pAdapter, v_U8_t staId )
{
   int fSuccess = FALSE;
   int idx = 0;
   v_U8_t  valid_idx   = 0;
   v_U8_t  del_idx   = 0;
   v_U8_t  empty_slots = 0;
   hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);

   for ( idx = 0; idx < HDD_MAX_NUM_IBSS_STA; idx++ )
   {
      if ( staId == pHddStaCtx->conn_info.staId[ idx ] )
      {
         pHddStaCtx->conn_info.staId[ idx ] = 0;

         vos_zero_macaddr( &pHddStaCtx->conn_info.peerMacAddress[ idx ] );

         fSuccess = TRUE;

         // Note the deleted Index, if its 0 we need special handling
         del_idx = idx;

         empty_slots++;
      }
      else
      {
         if (pHddStaCtx->conn_info.staId[idx] != 0)
         {
            valid_idx = idx;
         }
         else
         {
            // Found an empty slot
            empty_slots++;
         }
      }
   }

   if (HDD_MAX_NUM_IBSS_STA == empty_slots)
   {
      // Last peer departed, set the IBSS state appropriately
      pHddStaCtx->conn_info.connState = eConnectionState_IbssDisconnected;
      VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                 "Last IBSS Peer Departed!!!" );
   }

   // Find next active staId, to have a valid sta trigger for TL.
   if (fSuccess == TRUE)
   {
      if (del_idx == 0)
      {
         if (pHddStaCtx->conn_info.staId[valid_idx] != 0)
         {
            pHddStaCtx->conn_info.staId[0] = pHddStaCtx->conn_info.staId[valid_idx];
            vos_copy_macaddr( &pHddStaCtx->conn_info.peerMacAddress[ 0 ],
               &pHddStaCtx->conn_info.peerMacAddress[ valid_idx ]);

            pHddStaCtx->conn_info.staId[valid_idx] = 0;
            vos_zero_macaddr( &pHddStaCtx->conn_info.peerMacAddress[ valid_idx ] );
         }
      }
   }
   return( fSuccess );
}

/**============================================================================
 *
  @brief roamIbssConnectHandler() : We update the status of the IBSS to
  connected in this function.

  ===========================================================================*/
static eHalStatus roamIbssConnectHandler( hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo )
{
   struct cfg80211_bss *bss;
   hddLog(LOG1, FL("IBSS Connect Indication from SME!!! "));
   // Set the internal connection state to show 'IBSS Connected' (IBSS with a partner stations)...
   hdd_connSetConnectionState(pAdapter,
                              eConnectionState_IbssConnected);

   // Save the connection info from CSR...
   hdd_connSaveConnectInfo( pAdapter, pRoamInfo, eCSR_BSS_TYPE_IBSS );

   // Send the bssid address to the wext.
   hdd_SendAssociationEvent(pAdapter->dev, pRoamInfo);
   /* add bss_id to cfg80211 data base */
   bss = wlan_hdd_cfg80211_update_bss_db(pAdapter, pRoamInfo);
   if (NULL == bss)
   {
      hddLog(VOS_TRACE_LEVEL_ERROR,
             "%s: %s: unable to create IBSS entry",
             __func__, pAdapter->dev->name);
      return eHAL_STATUS_FAILURE;
   }
   cfg80211_put_bss(
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)) || defined(WITH_BACKPORTS)
                    WLAN_HDD_GET_CTX(pAdapter)->wiphy,
#endif
                    bss);

   return( eHAL_STATUS_SUCCESS );
}
/**============================================================================
 *
  @brief hdd_RoamSetKeyCompleteHandler() - Update the security parameters.

  ===========================================================================*/
static eHalStatus hdd_RoamSetKeyCompleteHandler( hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
                                                 tANI_U32 roamId, eRoamCmdStatus roamStatus,
                                                 eCsrRoamResult roamResult )
{
   eCsrEncryptionType connectedCipherAlgo;
   v_BOOL_t fConnected   = FALSE;
   VOS_STATUS vosStatus    = VOS_STATUS_E_FAILURE;
   hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
   hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
   ENTER();

   if (NULL == pRoamInfo)
   {
       VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "pRoamInfo is NULL");
       return eHAL_STATUS_FAILURE;
   }
   // if ( WPA ), tell TL to go to 'authenticated' after the keys are set.
   // then go to 'authenticated'.  For all other authentication types (those that do
   // not require upper layer authentication) we can put TL directly into 'authenticated'
   // state.
   VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
       "Set Key completion roamStatus=%d roamResult=%d encryptionType=%d "
       MAC_ADDRESS_STR, roamStatus, roamResult,
       pHddStaCtx->conn_info.ucEncryptionType,
       MAC_ADDR_ARRAY(pRoamInfo->peerMac));

   fConnected = hdd_connGetConnectedCipherAlgo( pHddStaCtx, &connectedCipherAlgo );
   if( fConnected )
   {
      if ( WLAN_HDD_IBSS == pAdapter->device_mode )
      {
         v_U8_t staId;

         v_MACADDR_t broadcastMacAddr = VOS_MAC_ADDR_BROADCAST_INITIALIZER;

         if ( 0 == memcmp( pRoamInfo->peerMac,
                      &broadcastMacAddr, VOS_MAC_ADDR_SIZE ) )
         {
            vosStatus = WLANTL_STAPtkInstalled( pHddCtx->pvosContext,
                                                IBSS_BROADCAST_STAID);
            pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
         }
         else
         {
            vosStatus = hdd_get_peer_sta_id(pHddStaCtx,
                              (v_MACADDR_t*)pRoamInfo->peerMac,
                              &staId);
            if ( VOS_STATUS_SUCCESS == vosStatus )
            {
               VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
                "WLAN TL STA Ptk Installed for STAID=%d", staId);
               vosStatus = WLANTL_STAPtkInstalled( pHddCtx->pvosContext,
                                                  staId);
               pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
            }
         }
      }
      else
      {
         /*
          * TODO: Considering getting a state machine in HDD later.
          * This routine is invoked twice. 1)set PTK 2)set GTK.
          * The following if statement will be TRUE when setting GTK.
          * At this time we don't handle the state in detail.
          * Related CR: 174048 - TL not in authenticated state
          */
      if (eCSR_ROAM_RESULT_AUTHENTICATED == roamResult) {
          pHddStaCtx->conn_info.gtk_installed = true;
          /*
           * PTK exchange happens in preauthentication itself if key_mgmt is
           * FT-PSK, ptk_installed was false as there is no set PTK after
           * roaming. STA TL state moves to athenticated only if ptk_installed
           * is true. So, make ptk_installed to true in case of 11R roaming.
           */
#ifdef WLAN_FEATURE_VOWIFI_11R
          if (pRoamInfo->is11rAssoc)
              pHddStaCtx->conn_info.ptk_installed = true;
#endif
      } else {
          pHddStaCtx->conn_info.ptk_installed = true;
      }

         /* In WPA case move STA to authenticated when ptk is installed.
          * Earlier in WEP case STA was moved to AUTHENTICATED prior to
          * setting the unicast key and it was resulting in sending
          * few un-encrypted packet. Now in WEP case STA state will
          * be moved to AUTHENTICATED after we set the unicast
          * and broadcast key.
          */
      if ((pHddStaCtx->conn_info.ucEncryptionType ==
          eCSR_ENCRYPT_TYPE_WEP40) ||
          (pHddStaCtx->conn_info.ucEncryptionType ==
          eCSR_ENCRYPT_TYPE_WEP104) ||
          (pHddStaCtx->conn_info.ucEncryptionType ==
          eCSR_ENCRYPT_TYPE_WEP40_STATICKEY) ||
          (pHddStaCtx->conn_info.ucEncryptionType ==
          eCSR_ENCRYPT_TYPE_WEP104_STATICKEY)) {
          if (pHddStaCtx->conn_info.gtk_installed &&
              pHddStaCtx->conn_info.ptk_installed)
              vosStatus = hdd_change_sta_state_authenticated(pAdapter,
                                    pRoamInfo);
      } else if (pHddStaCtx->conn_info.ptk_installed)
          vosStatus = hdd_change_sta_state_authenticated(pAdapter,
                                pRoamInfo);

      if (pHddStaCtx->conn_info.gtk_installed &&
          pHddStaCtx->conn_info.ptk_installed) {
          pHddStaCtx->conn_info.gtk_installed = false;
          pHddStaCtx->conn_info.ptk_installed = false;
      }

         pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
      }
   }
   else
   {
      // possible disassoc after issuing set key and waiting set key complete
      pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
   }

   EXIT();
   return( eHAL_STATUS_SUCCESS );
}
/**============================================================================
 *
  @brief hdd_RoamMicErrorIndicationHandler() - This function indicates the Mic failure to the supplicant.
  ===========================================================================*/
static eHalStatus hdd_RoamMicErrorIndicationHandler( hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
                                                 tANI_U32 roamId, eRoamCmdStatus roamStatus,                                                                              eCsrRoamResult roamResult )
{
   hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);

   if( eConnectionState_Associated == pHddStaCtx->conn_info.connState &&
      TKIP_COUNTER_MEASURE_STOPED == pHddStaCtx->WextState.mTKIPCounterMeasures )
   {
      struct iw_michaelmicfailure msg;
      union iwreq_data wreq;
      memset(&msg, '\0', sizeof(msg));
      msg.src_addr.sa_family = ARPHRD_ETHER;
      memcpy(msg.src_addr.sa_data, pRoamInfo->u.pMICFailureInfo->taMacAddr, sizeof(pRoamInfo->u.pMICFailureInfo->taMacAddr));
      hddLog(LOG1, "MIC MAC " MAC_ADDRESS_STR,
             MAC_ADDR_ARRAY(msg.src_addr.sa_data));

      if(pRoamInfo->u.pMICFailureInfo->multicast == eSIR_TRUE)
         msg.flags = IW_MICFAILURE_GROUP;
      else
         msg.flags = IW_MICFAILURE_PAIRWISE;
      memset(&wreq, 0, sizeof(wreq));
      wreq.data.length = sizeof(msg);
      wireless_send_event(pAdapter->dev, IWEVMICHAELMICFAILURE, &wreq, (char *)&msg);
      /* inform mic failure to nl80211 */
      cfg80211_michael_mic_failure(pAdapter->dev,
              pRoamInfo->u.pMICFailureInfo->taMacAddr,
              ((pRoamInfo->u.pMICFailureInfo->multicast == eSIR_TRUE) ?
               NL80211_KEYTYPE_GROUP :
               NL80211_KEYTYPE_PAIRWISE),
              pRoamInfo->u.pMICFailureInfo->keyId,
              pRoamInfo->u.pMICFailureInfo->TSC,
              GFP_KERNEL);

   }

   return( eHAL_STATUS_SUCCESS );
}

/**============================================================================
 *
  @brief roamRoamConnectStatusUpdateHandler() - The Ibss connection status is
  updated regularly here in this function.

  ===========================================================================*/
static eHalStatus roamRoamConnectStatusUpdateHandler( hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
   tANI_U32 roamId, eRoamCmdStatus roamStatus,
   eCsrRoamResult roamResult )
{
   VOS_STATUS vosStatus;

   hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
   switch( roamResult )
   {
      case eCSR_ROAM_RESULT_IBSS_NEW_PEER:
      {
         hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
         struct station_info *stainfo;

         VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                   "IBSS New Peer indication from SME with peerMac " MAC_ADDRESS_STR " BSSID: " MAC_ADDRESS_STR " and stationID= %d",
                    MAC_ADDR_ARRAY(pRoamInfo->peerMac),
                    MAC_ADDR_ARRAY(pHddStaCtx->conn_info.bssId),
                    pRoamInfo->staId );

         if (!hdd_save_peer(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
                            pRoamInfo->staId,
                            (v_MACADDR_t *)pRoamInfo->peerMac)) {
            VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
                       "New IBSS peer but we already have the max we can handle.  Can't register this one" );
            break;
         }

         pHddCtx->sta_to_adapter[pRoamInfo->staId] = pAdapter;

         pHddCtx->sta_to_adapter[IBSS_BROADCAST_STAID] = pAdapter;
         WLANTL_UpdateSTABssIdforIBSS(pHddCtx->pvosContext,
                      IBSS_BROADCAST_STAID,pHddStaCtx->conn_info.bssId);

         // Register the Station with TL for the new peer.
         vosStatus = hdd_roamRegisterSTA( pAdapter,
                                          pRoamInfo,
                                          pRoamInfo->staId,
                                          (v_MACADDR_t *)pRoamInfo->peerMac,
                                          pRoamInfo->pBssDesc );
         if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
         {
            VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
               "Cannot register STA with TL for IBSS.  Failed with vosStatus = %d [%08X]",
               vosStatus, vosStatus );
         }
         pHddStaCtx->ibss_sta_generation++;
         stainfo = vos_mem_malloc(sizeof(*stainfo));
         if (stainfo == NULL) {
             VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                       "memory allocation for station_info failed");
             return eHAL_STATUS_FAILED_ALLOC;
         }
         memset(stainfo, 0, sizeof(*stainfo));
         stainfo->filled = 0;
         stainfo->generation = pHddStaCtx->ibss_sta_generation;

         cfg80211_new_sta(pAdapter->dev,
                          (const u8 *)pRoamInfo->peerMac,
                          stainfo, GFP_KERNEL);
         vos_mem_free(stainfo);

         if ( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == pHddStaCtx->ibss_enc_key.encType
            ||eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == pHddStaCtx->ibss_enc_key.encType
            ||eCSR_ENCRYPT_TYPE_TKIP == pHddStaCtx->ibss_enc_key.encType
            ||eCSR_ENCRYPT_TYPE_AES == pHddStaCtx->ibss_enc_key.encType )
         {
            pHddStaCtx->ibss_enc_key.keyDirection = eSIR_TX_RX;
            memcpy(&pHddStaCtx->ibss_enc_key.peerMac,
                              pRoamInfo->peerMac, VOS_MAC_ADDR_SIZE);

            VOS_TRACE( VOS_MODULE_ID_HDD,
               VOS_TRACE_LEVEL_INFO_HIGH, "New peer joined set PTK encType=%d",
               pHddStaCtx->ibss_enc_key.encType);

            vosStatus = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
               pAdapter->sessionId, &pHddStaCtx->ibss_enc_key, &roamId );

            if ( VOS_STATUS_SUCCESS != vosStatus )
            {
               hddLog(VOS_TRACE_LEVEL_ERROR,
                       "%s: sme_RoamSetKey failed, returned %d",
                       __func__, vosStatus);
               return eHAL_STATUS_FAILURE;
            }
         }
         hddLog(LOG1, FL("Enabling queues"));
         wlan_hdd_netif_queue_control(pAdapter,
            WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
            WLAN_CONTROL_PATH);
         break;
      }

      case eCSR_ROAM_RESULT_IBSS_CONNECT:
      {

         roamIbssConnectHandler( pAdapter, pRoamInfo );

         break;
      }
      case eCSR_ROAM_RESULT_IBSS_PEER_DEPARTED:
      {
         hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);

         if (!roamRemoveIbssStation(pAdapter, pRoamInfo->staId)) {
            VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
                    "IBSS peer departed by cannot find peer in our registration table with TL" );
         }

          VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                   "IBSS Peer Departed from SME with peerMac " MAC_ADDRESS_STR " BSSID: " MAC_ADDRESS_STR " and stationID= %d",
                    MAC_ADDR_ARRAY(pRoamInfo->peerMac),
                    MAC_ADDR_ARRAY(pHddStaCtx->conn_info.bssId),
                    pRoamInfo->staId );

         hdd_roamDeregisterSTA( pAdapter, pRoamInfo->staId );

         pHddCtx->sta_to_adapter[pRoamInfo->staId] = NULL;
         pHddStaCtx->ibss_sta_generation++;

         cfg80211_del_sta(pAdapter->dev,
                         (const u8 *)&pRoamInfo->peerMac,
                         GFP_KERNEL);
         break;
      }
      case eCSR_ROAM_RESULT_IBSS_INACTIVE:
      {
          VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
                    "Received eCSR_ROAM_RESULT_IBSS_INACTIVE from SME");
         // Stop only when we are inactive
         hddLog(LOG1, FL("Disabling queues"));
         wlan_hdd_netif_queue_control(pAdapter,
            WLAN_NETIF_TX_DISABLE_N_CARRIER,
            WLAN_CONTROL_PATH);

         hdd_connSetConnectionState(pAdapter,
                                     eConnectionState_NotConnected);

         // Send the bssid address to the wext.
         hdd_SendAssociationEvent(pAdapter->dev, pRoamInfo);
         // clean up data path
         hdd_disconnect_tx_rx(pAdapter);
         break;
      }
      default:
         break;

   }

   return( eHAL_STATUS_SUCCESS );
}

#ifdef FEATURE_WLAN_TDLS
/**============================================================================
 *
  @brief hdd_roamRegisterTDLSSTA() - Construct the staDesc and register with
  TL the new STA. This is called as part of ADD_STA in the TDLS setup
  Return: VOS_STATUS

  ===========================================================================*/
VOS_STATUS hdd_roamRegisterTDLSSTA(hdd_adapter_t *pAdapter,
                                   const tANI_U8 *peerMac, tANI_U16 staId,
                                   tANI_U8 ucastSig, uint8_t qos)
{
    hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
    v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
    VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
    WLAN_STADescType staDesc = {0};
    eCsrEncryptionType connectedCipherAlgo = eCSR_ENCRYPT_TYPE_UNKNOWN;
    v_BOOL_t fConnected   = FALSE;

    fConnected = hdd_connGetConnectedCipherAlgo( pHddStaCtx, &connectedCipherAlgo );
    if (!fConnected) {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                     "%s not connected. ignored", __func__);
        return VOS_FALSE;
    }

    /*
     * TDLS sta in BSS should be set as STA type TDLS and STA MAC should
     * be peer MAC, here we are working on direct Link
     */
    staDesc.ucSTAId = staId ;

    staDesc.wSTAType = WLAN_STA_TDLS ;

    vos_mem_copy( staDesc.vSTAMACAddress.bytes, peerMac,
                                         sizeof(tSirMacAddr) );

    vos_mem_copy(staDesc.vBSSIDforIBSS.bytes, pHddStaCtx->conn_info.bssId,6 );
    vos_copy_macaddr( &staDesc.vSelfMACAddress, &pAdapter->macAddressCurrent );

    /* set the QoS field appropriately ..*/
    staDesc.ucQosEnabled = qos;

    VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
               "HDD register TL QoS_enabled=%d", staDesc.ucQosEnabled );

    staDesc.ucProtectedFrame = (connectedCipherAlgo != eCSR_ENCRYPT_TYPE_NONE) ;

    VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
               "HDD register TL Sec_enabled= %d.", staDesc.ucProtectedFrame );

    /*
     * UMA is ready we inform TL  to do frame translation.
     */
    staDesc.ucSwFrameTXXlation = 1;
    staDesc.ucSwFrameRXXlation = 1;
    staDesc.ucAddRmvLLC = 1;

    /* Initialize signatures and state */
    staDesc.ucUcastSig  = ucastSig ;

    /* tdls Direct Link do not need bcastSig */
    staDesc.ucBcastSig  = 0 ;

#ifdef VOLANS_ENABLE_SW_REPLAY_CHECK
    if(staDesc.ucProtectedFrame)
        staDesc.ucIsReplayCheckValid = VOS_TRUE;
    else
        staDesc.ucIsReplayCheckValid = VOS_FALSE;
#endif

    staDesc.ucInitState = WLANTL_STA_CONNECTED ;

   /* Register the Station with TL...  */
   /* Incase Micro controller data path offload enabled,
    * All the traffic routed to WLAN host driver, do not need to
    * route IPA. It should be routed kernel network stack */
#if defined(IPA_OFFLOAD) && !defined(IPA_UC_OFFLOAD)
    if (hdd_ipa_is_enabled(WLAN_HDD_GET_CTX(pAdapter)))
       vosStatus = WLANTL_RegisterSTAClient(pVosContext,
                                          hdd_ipa_process_rxt,
                                          &staDesc, 0);
    else
#endif
    vosStatus = WLANTL_RegisterSTAClient(pVosContext,
                                          hdd_rx_packet_cbk,
                                          &staDesc, 0);

    if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                   "%s: WLANTL_RegisterSTAClient() failed to register.  "
                   "Status= %d [0x%08X]", __func__, vosStatus, vosStatus );
         return vosStatus;
    }

    return( vosStatus );
}

VOS_STATUS hdd_roamDeregisterTDLSSTA(hdd_adapter_t *pAdapter, tANI_U8 staId)
{
    VOS_STATUS vosStatus;
    vosStatus = WLANTL_ClearSTAClient( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, staId );
    if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
                   "%s: WLANTL_ClearSTAClient() failed to for staID %d.  "
                   "Status= %d [0x%08X]",
                   __func__, staId, vosStatus, vosStatus );
    }
    return( vosStatus );
}


/*
 * HDD interface between SME and TL to ensure TDLS client registration with
 * TL in case of new TDLS client is added and deregistration at the time
 * TDLS client is deleted.
 */

static eHalStatus
hdd_RoamTdlsStatusUpdateHandler(hdd_adapter_t *pAdapter,
                                tCsrRoamInfo *pRoamInfo, tANI_U32 roamId,
                                eRoamCmdStatus roamStatus,
                                eCsrRoamResult roamResult)
{
    hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
#ifdef CONFIG_TDLS_IMPLICIT
    tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
#endif
    tSmeTdlsPeerStateParams smeTdlsPeerStateParams;
    eHalStatus status = eHAL_STATUS_FAILURE ;
    tANI_U8 staIdx;
    hddTdlsPeer_t *curr_peer;
    tANI_U32 reason;

    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
    ("hdd_tdlsStatusUpdate: %s staIdx %d " MAC_ADDRESS_STR),
      roamResult == eCSR_ROAM_RESULT_ADD_TDLS_PEER ? "ADD_TDLS_PEER" :
      roamResult == eCSR_ROAM_RESULT_DELETE_TDLS_PEER ? "DEL_TDLS_PEER" :
      roamResult == eCSR_ROAM_RESULT_TEARDOWN_TDLS_PEER_IND ? "DEL_TDLS_PEER_IND" :
      roamResult == eCSR_ROAM_RESULT_DELETE_ALL_TDLS_PEER_IND? "DEL_ALL_TDLS_PEER_IND" :
      roamResult == eCSR_ROAM_RESULT_UPDATE_TDLS_PEER? "UPDATE_TDLS_PEER" :
      roamResult == eCSR_ROAM_RESULT_LINK_ESTABLISH_REQ_RSP? "LINK_ESTABLISH_REQ_RSP" :
      roamResult == eCSR_ROAM_RESULT_TDLS_SHOULD_DISCOVER? "TDLS_SHOULD_DISCOVER" :
      roamResult == eCSR_ROAM_RESULT_TDLS_SHOULD_TEARDOWN? "TDLS_SHOULD_TEARDOWN" :
      roamResult == eCSR_ROAM_RESULT_TDLS_SHOULD_PEER_DISCONNECTED? "TDLS_SHOULD_PEER_DISCONNECTED" :
      "UNKNOWN",
       pRoamInfo->staId,
       MAC_ADDR_ARRAY(pRoamInfo->peerMac)) ;

#ifdef CONFIG_TDLS_IMPLICIT
    if (!pHddTdlsCtx)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                  "%s: TDLS ctx is null, ignore roamResult (%d)",
                  __func__, roamResult);
        return status;
    }
#endif

    switch( roamResult )
    {
        case eCSR_ROAM_RESULT_ADD_TDLS_PEER:
        {
            if(eSIR_SME_SUCCESS != pRoamInfo->statusCode)
            {
                hddTdlsPeer_t *curr_peer;
                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                     ("%s: Add Sta is failed. %d"),__func__, pRoamInfo->statusCode);
                mutex_lock(&pHddCtx->tdls_lock);
                curr_peer = wlan_hdd_tdls_find_peer(pAdapter,
                                     pRoamInfo->peerMac, FALSE);
                if (curr_peer)
                    curr_peer->link_status = eTDLS_LINK_TEARING;
                else
                    hddLog(LOG1, FL("curr_peer is Null"));
                mutex_unlock(&pHddCtx->tdls_lock);
            }
            else
            {

                /* check if there is available index for this new TDLS STA */
                for ( staIdx = 0; staIdx < pHddCtx->max_num_tdls_sta; staIdx++ )
                {
                    if (0 == pHddCtx->tdlsConnInfo[staIdx].staId )
                    {
                        pHddCtx->tdlsConnInfo[staIdx].sessionId = pRoamInfo->sessionId;
                        pHddCtx->tdlsConnInfo[staIdx].staId = pRoamInfo->staId;

                        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
                                  ("TDLS: STA IDX at %d is %d "
                                  "of mac " MAC_ADDRESS_STR),
                                  staIdx, pHddCtx->tdlsConnInfo[staIdx].staId,
                                  MAC_ADDR_ARRAY(pRoamInfo->peerMac));

                        vos_copy_macaddr(&pHddCtx->tdlsConnInfo[staIdx].peerMac,
                                         (v_MACADDR_t *)pRoamInfo->peerMac) ;
                        status = eHAL_STATUS_SUCCESS ;
                        break ;
                    }
                }
                if (staIdx < pHddCtx->max_num_tdls_sta)
                {
                    if (-1 == wlan_hdd_tdls_set_sta_id(pAdapter, pRoamInfo->peerMac, pRoamInfo->staId)) {
                        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                                     "wlan_hdd_tdls_set_sta_id() failed");
                        return VOS_FALSE;
                    }

                    (WLAN_HDD_GET_CTX(pAdapter))->sta_to_adapter[pRoamInfo->staId] = pAdapter;
                    /* store the ucast signature , if required for further reference. */

                    wlan_hdd_tdls_set_signature( pAdapter, pRoamInfo->peerMac, pRoamInfo->ucastSig );
                }
                else
                {
                    status = eHAL_STATUS_FAILURE;
                    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                    "%s: no available slot in conn_info. staId %d cannot be stored", __func__, pRoamInfo->staId);
                }
                pAdapter->tdlsAddStaStatus = status;
            }
            complete(&pAdapter->tdls_add_station_comp);
            break ;
        }
        case eCSR_ROAM_RESULT_UPDATE_TDLS_PEER:
        {
            if (eSIR_SME_SUCCESS != pRoamInfo->statusCode)
            {
                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                     "%s: Add Sta is failed. %d", __func__, pRoamInfo->statusCode);
            }
            /* store the ucast signature which will be used later when
             * registering to TL
             */
            pAdapter->tdlsAddStaStatus = pRoamInfo->statusCode;
            complete(&pAdapter->tdls_add_station_comp);
            break;
        }
        case eCSR_ROAM_RESULT_LINK_ESTABLISH_REQ_RSP:
        {

            hddTdlsPeer_t *curr_peer;
            if (eSIR_SME_SUCCESS != pRoamInfo->statusCode)
            {
                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                     "%s: Link Establish Request failed. %d", __func__, pRoamInfo->statusCode);
                mutex_lock(&pHddCtx->tdls_lock);
                curr_peer = wlan_hdd_tdls_find_peer(pAdapter,
                                          pRoamInfo->peerMac, FALSE);
                if (curr_peer)
                    curr_peer->link_status = eTDLS_LINK_TEARING;
                else
                    hddLog(LOGE, FL("curr_peer is Null"));

                mutex_unlock(&pHddCtx->tdls_lock);
            }
            complete(&pAdapter->tdls_link_establish_req_comp);
            break;
        }
        case eCSR_ROAM_RESULT_DELETE_TDLS_PEER:
        {
            for (staIdx = 0; staIdx < pHddCtx->max_num_tdls_sta; staIdx++)
            {
                if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pRoamInfo->sessionId) &&
                    pRoamInfo->staId == pHddCtx->tdlsConnInfo[staIdx].staId)
                {
                    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
                                   ("HDD: del STA IDX = %x"), pRoamInfo->staId) ;

                    curr_peer = wlan_hdd_tdls_find_peer(pAdapter, pRoamInfo->peerMac, TRUE);
                    if (NULL != curr_peer)
                    {
                       VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                                 " Current status for peer" MAC_ADDRESS_STR "is %d",
                                 MAC_ADDR_ARRAY(pRoamInfo->peerMac), curr_peer->link_status);
                       if (TDLS_IS_CONNECTED(curr_peer))
                       {
                           hdd_roamDeregisterTDLSSTA ( pAdapter, pRoamInfo->staId );
                           wlan_hdd_tdls_decrement_peer_count(pAdapter);
                       }
                       else if (eTDLS_LINK_CONNECTING == curr_peer->link_status)
                       {
                           hdd_roamDeregisterTDLSSTA ( pAdapter, pRoamInfo->staId );
                       }
                    }
                    wlan_hdd_tdls_reset_peer(pAdapter, pRoamInfo->peerMac);

                    pHddCtx->tdlsConnInfo[staIdx].staId = 0 ;
                    pHddCtx->tdlsConnInfo[staIdx].sessionId = 255;
                    vos_mem_zero(&pHddCtx->tdlsConnInfo[staIdx].peerMac,
                                               sizeof(v_MACADDR_t)) ;
                    status = eHAL_STATUS_SUCCESS ;
                    break ;
                }
            }
            complete(&pAdapter->tdls_del_station_comp);
        }
        break ;
        case  eCSR_ROAM_TDLS_CHECK_BMPS:
        {
            wlan_hdd_tdls_check_bmps(pAdapter);
            status = eHAL_STATUS_SUCCESS ;
            break;
        }
        case eCSR_ROAM_RESULT_TEARDOWN_TDLS_PEER_IND:
        {
            VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                       "%s: Sending teardown to supplicant with reason code %u",
                       __func__, pRoamInfo->reasonCode);

#ifdef CONFIG_TDLS_IMPLICIT
            curr_peer = wlan_hdd_tdls_find_peer(pAdapter, pRoamInfo->peerMac, TRUE);
            wlan_hdd_tdls_indicate_teardown(pAdapter, curr_peer, pRoamInfo->reasonCode);
            hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_BSS_DISCONNECT,
                                                          curr_peer->peerMac);
#endif
            status = eHAL_STATUS_SUCCESS ;
            break ;
        }
        case eCSR_ROAM_RESULT_DELETE_ALL_TDLS_PEER_IND:
        {
            /* 0 staIdx is assigned to AP we dont want to touch that */
            for (staIdx = 0; staIdx < pHddCtx->max_num_tdls_sta; staIdx++)
            {
                if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pRoamInfo->sessionId) &&
                    pHddCtx->tdlsConnInfo[staIdx].staId)
                {
                    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
                              ("hdd_tdlsStatusUpdate: staIdx %d " MAC_ADDRESS_STR),
                                pHddCtx->tdlsConnInfo[staIdx].staId,
                                MAC_ADDR_ARRAY(pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes));
                    wlan_hdd_tdls_reset_peer(pAdapter, pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes);
                    hdd_roamDeregisterTDLSSTA ( pAdapter,  pHddCtx->tdlsConnInfo[staIdx].staId );
                    vos_mem_zero(&smeTdlsPeerStateParams,
                                 sizeof(smeTdlsPeerStateParams));
                    smeTdlsPeerStateParams.vdevId =
                                 pHddCtx->tdlsConnInfo[staIdx].sessionId;
                    vos_mem_copy(&smeTdlsPeerStateParams.peerMacAddr,
                                 &pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes,
                                 VOS_MAC_ADDR_SIZE);
                    smeTdlsPeerStateParams.peerState =
                                 eSME_TDLS_PEER_STATE_TEARDOWN;

                    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                              ("hdd_tdlsStatusUpdate: calling sme_UpdateTdlsPeerState for staIdx %d " MAC_ADDRESS_STR),
                                pHddCtx->tdlsConnInfo[staIdx].staId,
                                MAC_ADDR_ARRAY(pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes));
                    status = sme_UpdateTdlsPeerState(pHddCtx->hHal,
                                                     &smeTdlsPeerStateParams);
                    if (eHAL_STATUS_SUCCESS != status)
                    {
                       VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                                 "%s: sme_UpdateTdlsPeerState failed for "
                                 MAC_ADDRESS_STR, __func__,
                                 MAC_ADDR_ARRAY(pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes));
                    }
                    wlan_hdd_tdls_decrement_peer_count(pAdapter);

                    vos_mem_zero(&pHddCtx->tdlsConnInfo[staIdx].peerMac,
                                               sizeof(v_MACADDR_t)) ;
                    pHddCtx->tdlsConnInfo[staIdx].staId = 0 ;
                    pHddCtx->tdlsConnInfo[staIdx].sessionId = 255;

                    status = eHAL_STATUS_SUCCESS ;
                }
            }
            wlan_hdd_tdls_check_bmps(pAdapter);
            break ;
        }
        case eCSR_ROAM_RESULT_TDLS_SHOULD_DISCOVER:
        {
#ifdef CONFIG_TDLS_IMPLICIT
            /* ignore TDLS_SHOULD_DISCOVER if any concurrency detected */
            if (((1 << VOS_STA_MODE) != pHddCtx->concurrency_mode) ||
                (pHddCtx->no_of_active_sessions[VOS_STA_MODE] > 1)) {
                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
                         FL("concurrency detected. ignore SHOULD_DISCOVER concurrency_mode: 0x%x, active_sessions: %d"),
                         pHddCtx->concurrency_mode,
                         pHddCtx->no_of_active_sessions[VOS_STA_MODE]);
                status = eHAL_STATUS_FAILURE;
                break;
            }

            if (pHddCtx->tdls_nss_switch_in_progress) {
                hddLog(LOGE,
                       FL("TDLS antenna switch is in progress, ignore SHOULD_DISCOVER"));
                status = eHAL_STATUS_SUCCESS;
                break;
            }

            curr_peer = wlan_hdd_tdls_get_peer(pAdapter, pRoamInfo->peerMac,
                                               TRUE);
            if (!curr_peer)
            {
                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                          "%s: curr_peer null", __func__);
                status = eHAL_STATUS_FAILURE;
            }
            else
            {
                if (eTDLS_LINK_CONNECTED == curr_peer->link_status)
                {
                    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                              "%s: TDLS link status is connected, ignore SHOULD_DISCOVER", __func__);
                }
                else
                {
                    /* if external control is enabled then initiate TDLS
                     * only if forced peer is set otherwise ignore
                     * Should Discover trigger from fw
                     */
                    if (pHddCtx->cfg_ini->fTDLSExternalControl &&
                        (FALSE == curr_peer->isForcedPeer))
                    {
                        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
                                  FL("TDLS ExternalControl enabled but curr_peer is not forced, ignore SHOULD_DISCOVER"));
                        status = eHAL_STATUS_SUCCESS;
                        break;
                    }
                    else
                    {
                        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
                                  FL("initiate TDLS setup on SHOULD_DISCOVER, fTDLSExternalControl: %d, curr_peer->isForcedPeer: %d, reason: %d"),
                                  pHddCtx->cfg_ini->fTDLSExternalControl,
                                  curr_peer->isForcedPeer,
                                  pRoamInfo->reasonCode);
                    }
                    pHddTdlsCtx->curr_candidate = curr_peer;

                    wlan_hdd_tdls_implicit_send_discovery_request(pHddTdlsCtx);
                }
                status = eHAL_STATUS_SUCCESS;
            }
#else
            status = eHAL_STATUS_SUCCESS;
#endif
            break ;
        }

        case eCSR_ROAM_RESULT_TDLS_SHOULD_TEARDOWN:
        {
#ifdef CONFIG_TDLS_IMPLICIT
            curr_peer = wlan_hdd_tdls_find_peer(pAdapter, pRoamInfo->peerMac, TRUE);
            if (!curr_peer)
            {
                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                          "%s: curr_peer null", __func__);
                status = eHAL_STATUS_FAILURE;
            }
            else
            {
                if (eTDLS_LINK_CONNECTED == curr_peer->link_status)
                {
                    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                              FL("Received SHOULD_TEARDOWN for peer "
                                  MAC_ADDRESS_STR " staId: %d, reason: %d"),
                              MAC_ADDR_ARRAY(pRoamInfo->peerMac),
                              pRoamInfo->staId,
                              pRoamInfo->reasonCode);

                    if (pRoamInfo->reasonCode ==
                            eWNI_TDLS_TEARDOWN_REASON_RSSI ||
                        pRoamInfo->reasonCode ==
                            eWNI_TDLS_DISCONNECTED_REASON_PEER_DELETE ||
                        pRoamInfo->reasonCode ==
                            eWNI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT ||
                        pRoamInfo->reasonCode ==
                            eWNI_TDLS_TEARDOWN_REASON_NO_RESPONSE)
                    {
                        reason = eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE;
                    }
                    else
                        reason = eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON;

                    wlan_hdd_tdls_indicate_teardown(pHddTdlsCtx->pAdapter,
                                                    curr_peer,
                                                    reason);
                    hdd_send_wlan_tdls_teardown_event(
                                       eTDLS_TEARDOWN_BSS_DISCONNECT,
                                       curr_peer->peerMac);
                }
                else
                {
                    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                              FL("TDLS link is not connected, ignore SHOULD_TEARDOWN, reason: %d"),
                              pRoamInfo->reasonCode);
                }
                status = eHAL_STATUS_SUCCESS;
            }
#else
            status = eHAL_STATUS_SUCCESS;
#endif
            break ;
        }

        case eCSR_ROAM_RESULT_TDLS_SHOULD_PEER_DISCONNECTED:
        {
#ifdef CONFIG_TDLS_IMPLICIT
            curr_peer = wlan_hdd_tdls_find_peer(pAdapter, pRoamInfo->peerMac, TRUE);
            if (!curr_peer)
            {
                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                          "%s: curr_peer null", __func__);
                status = eHAL_STATUS_FAILURE;
            }
            else
            {
                if (eTDLS_LINK_CONNECTED == curr_peer->link_status)
                {
                    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                              FL("Received SHOULD_PEER_DISCONNECTED for peer "
                                  MAC_ADDRESS_STR " staId: %d, reason: %d"),
                              MAC_ADDR_ARRAY(pRoamInfo->peerMac),
                              pRoamInfo->staId,
                              pRoamInfo->reasonCode);

                    if (pRoamInfo->reasonCode ==
                            eWNI_TDLS_TEARDOWN_REASON_RSSI ||
                        pRoamInfo->reasonCode ==
                            eWNI_TDLS_DISCONNECTED_REASON_PEER_DELETE ||
                        pRoamInfo->reasonCode ==
                            eWNI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT ||
                        pRoamInfo->reasonCode ==
                            eWNI_TDLS_TEARDOWN_REASON_NO_RESPONSE)
                    {
                        reason = eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE;
                    }
                    else
                        reason = eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON;

                    wlan_hdd_tdls_indicate_teardown(pHddTdlsCtx->pAdapter,
                                                    curr_peer,
                                                    reason);
                    hdd_send_wlan_tdls_teardown_event(
                                         eTDLS_TEARDOWN_BSS_DISCONNECT,
                                         curr_peer->peerMac);
                }
                else
                {
                    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                              FL("TDLS link is not connected, ignore SHOULD_PEER_DISCONNECTED, reason: %d"),
                              pRoamInfo->reasonCode);
                }
                status = eHAL_STATUS_SUCCESS;
            }
#else
            status = eHAL_STATUS_SUCCESS;
#endif
            break ;
        }
        default:
        {
            break ;
        }
    }

    return status ;
}
#endif

static void iw_full_power_cbfn (void *pContext, eHalStatus status)
{
    hdd_adapter_t *pAdapter = (hdd_adapter_t *)pContext;
    hdd_context_t *pHddCtx = NULL;
    int ret;

    ENTER();

    if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
    {
        hddLog(VOS_TRACE_LEVEL_ERROR,
             "%s: Bad param, pAdapter [%pK]",
               __func__, pAdapter);
        return;
    }

    pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    ret = wlan_hdd_validate_context(pHddCtx);
    if (0 != ret)
        return;

    if (pHddCtx->cfg_ini->fIsBmpsEnabled)
    {
        sme_RequestBmps(WLAN_HDD_GET_HAL_CTX(pAdapter), NULL, NULL);
    }
    EXIT();
}

#ifdef WLAN_FEATURE_11W
/**
 * hdd_indicateUnprotMgmtFrame() - indicate unprotected management frame
 * @pAdapter:     pointer to the adapter
 * @nFrameLength: Length of the unprotected frame being passed
 * @pbFrames:     Pointer to the frame buffer
 * @frameType:    802.11 frame type
 *
 * This function forwards the unprotected management frame to the supplicant.
 *
 * Return: nothing
 */
static void
hdd_indicateUnprotMgmtFrame(hdd_adapter_t *pAdapter, tANI_U32 nFrameLength,
                            tANI_U8* pbFrames, tANI_U8 frameType)
{
    tANI_U8 type = 0;
    tANI_U8 subType = 0;

    hddLog(LOG1, FL("Frame Type(%d) Frame Length(%d)"),
           frameType, nFrameLength);

    /* Sanity Checks */
    if (NULL == pAdapter) {
        hddLog(LOGE, FL("pAdapter is NULL"));
        return;
    }

    if (NULL == pAdapter->dev) {
        hddLog(LOGE, FL("pAdapter->dev is NULL"));
        return;
    }

    if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) {
        hddLog(LOGE, FL("pAdapter has invalid magic"));
        return;
    }

    if(!nFrameLength) {
        hddLog(LOGE, FL("Frame Length is Invalid ZERO"));
        return;
    }

    if (NULL == pbFrames) {
        hddLog(LOGE, FL("pbFrames is NULL"));
        return;
    }

    type = WLAN_HDD_GET_TYPE_FRM_FC(pbFrames[0]);
    subType = WLAN_HDD_GET_SUBTYPE_FRM_FC(pbFrames[0]);

    /* Get pAdapter from Destination mac address of the frame */
    if (type == SIR_MAC_MGMT_FRAME && subType == SIR_MAC_MGMT_DISASSOC) {
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)) || defined(WITH_BACKPORTS)
        cfg80211_rx_unprot_mlme_mgmt(pAdapter->dev, pbFrames, nFrameLength);
#else
        cfg80211_send_unprot_disassoc(pAdapter->dev, pbFrames, nFrameLength);
#endif
        pAdapter->hdd_stats.hddPmfStats.numUnprotDisassocRx++;
    } else if (type == SIR_MAC_MGMT_FRAME && subType == SIR_MAC_MGMT_DEAUTH) {
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)) || defined(WITH_BACKPORTS)
        cfg80211_rx_unprot_mlme_mgmt(pAdapter->dev, pbFrames, nFrameLength);
#else
        cfg80211_send_unprot_deauth(pAdapter->dev, pbFrames, nFrameLength);
#endif
        pAdapter->hdd_stats.hddPmfStats.numUnprotDeauthRx++;
    } else {
        hddLog(LOGE, FL("Frame type %d and subtype %d are not valid"), type, subType);
        return;
    }
}
#endif

#if defined (FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
static void
hdd_indicateTsmIe(hdd_adapter_t *pAdapter, tANI_U8 tid,
                  tANI_U8 state, tANI_U16 measInterval)
{
    union iwreq_data wrqu;
    char buf[IW_CUSTOM_MAX + 1];
    int nBytes = 0;

    if (NULL == pAdapter)
        return;

    // create the event
    memset(&wrqu, '\0', sizeof(wrqu));
    memset(buf, '\0', sizeof(buf));

    hddLog(VOS_TRACE_LEVEL_INFO, "TSM Ind tid(%d) state(%d) MeasInt(%d)",
                        tid, state, measInterval);

    nBytes = snprintf(buf, IW_CUSTOM_MAX, "TSMIE=%d:%d:%d",tid,state,measInterval);

    wrqu.data.pointer = buf;
    wrqu.data.length = nBytes;
    // send the event
    wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
}

void hdd_indicateCckmPreAuth(hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo)
{
    union iwreq_data wrqu;
    char buf[IW_CUSTOM_MAX + 1];
    char *pos = buf;
    int nBytes = 0, freeBytes = IW_CUSTOM_MAX;

    if ((NULL == pAdapter) || (NULL == pRoamInfo))
        return;

    // create the event
    memset(&wrqu, '\0', sizeof(wrqu));
    memset(buf, '\0', sizeof(buf));

    /* Timestamp0 is lower 32 bits and Timestamp1 is upper 32 bits */
    hddLog(VOS_TRACE_LEVEL_INFO,
           "CCXPREAUTHNOTIFY=" MAC_ADDRESS_STR" %d:%d",
           MAC_ADDR_ARRAY(pRoamInfo->bssid),
           pRoamInfo->timestamp[0],
           pRoamInfo->timestamp[1]);

    nBytes = snprintf(pos, freeBytes, "CCXPREAUTHNOTIFY=");
    pos += nBytes;
    freeBytes -= nBytes;

    vos_mem_copy(pos, pRoamInfo->bssid, VOS_MAC_ADDR_SIZE);
    pos += VOS_MAC_ADDR_SIZE;
    freeBytes -= VOS_MAC_ADDR_SIZE;

    nBytes = snprintf(pos, freeBytes, " %u:%u",
             pRoamInfo->timestamp[0], pRoamInfo->timestamp[1]);
    freeBytes -= nBytes;

    wrqu.data.pointer = buf;
    wrqu.data.length = (IW_CUSTOM_MAX - freeBytes);

    // send the event
    wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
}

static void
hdd_indicateEseAdjApRepInd(hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo)
{
    union iwreq_data wrqu;
    char buf[IW_CUSTOM_MAX + 1];
    int nBytes = 0;

    if ((NULL == pAdapter) || (NULL == pRoamInfo))
        return;

    // create the event
    memset(&wrqu, '\0', sizeof(wrqu));
    memset(buf, '\0', sizeof(buf));

    hddLog(VOS_TRACE_LEVEL_INFO, "CCXADJAPREP=%u", pRoamInfo->tsmRoamDelay);

    nBytes = snprintf(buf, IW_CUSTOM_MAX, "CCXADJAPREP=%u", pRoamInfo->tsmRoamDelay);

    wrqu.data.pointer = buf;
    wrqu.data.length = nBytes;

    // send the event
    wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
}

void hdd_indicateEseBcnReportNoResults(const hdd_adapter_t *pAdapter,
                                       const tANI_U16 measurementToken,
                                       const tANI_BOOLEAN flag,
                                       const tANI_U8 numBss)
{
    union iwreq_data wrqu;
    char buf[IW_CUSTOM_MAX];
    char *pos = buf;
    int nBytes = 0, freeBytes = IW_CUSTOM_MAX;

    memset(&wrqu, '\0', sizeof(wrqu));
    memset(buf, '\0', sizeof(buf));

    hddLog(VOS_TRACE_LEVEL_INFO, FL("CCXBCNREP=%d %d %d"), measurementToken, flag,
           numBss);

    nBytes = snprintf(pos, freeBytes, "CCXBCNREP=%d %d %d", measurementToken,
                      flag, numBss);

    wrqu.data.pointer = buf;
    wrqu.data.length = nBytes;
    // send the event
    wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
}

static void
hdd_indicateEseBcnReportInd(const hdd_adapter_t *pAdapter,
                            const tCsrRoamInfo *pRoamInfo)
{
    union iwreq_data wrqu;
    char buf[IW_CUSTOM_MAX];
    char *pos = buf;
    int nBytes = 0, freeBytes = IW_CUSTOM_MAX;
    tANI_U8 i = 0, len = 0;
    tANI_U8 tot_bcn_ieLen = 0;  /* total size of the beacon report data */
    tANI_U8 lastSent = 0, sendBss = 0;
    int bcnRepFieldSize = sizeof(pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[0].bcnReportFields);
    tANI_U8 ieLenByte = 1;
    /* CCXBCNREP=meas_tok<sp>flag<sp>no_of_bss<sp>tot_bcn_ie_len = 18 bytes */
#define ESEBCNREPHEADER_LEN  (18)

    if ((NULL == pAdapter) || (NULL == pRoamInfo))
        return;

    /* Custom event can pass maximum of 256 bytes of data,
       based on the IE len we need to identify how many BSS info can
       be filled in to custom event data */
    /*
       meas_tok<sp>flag<sp>no_of_bss<sp>tot_bcn_ie_len bcn_rep_data
         bcn_rep_data will have bcn_rep_fields,ie_len,ie without any spaces
         CCXBCNREP=meas_tok<sp>flag<sp>no_of_bss<sp>tot_bcn_ie_len = 18 bytes
    */

    if ((pRoamInfo->pEseBcnReportRsp->flag >> 1) && (!pRoamInfo->pEseBcnReportRsp->numBss))
    {
        hddLog(VOS_TRACE_LEVEL_INFO, "Measurement Done but no scan results");
        /* If the measurement is none and no scan results found,
            indicate the supplicant about measurement done */
        hdd_indicateEseBcnReportNoResults(pAdapter,
                                 pRoamInfo->pEseBcnReportRsp->measurementToken,
                                 pRoamInfo->pEseBcnReportRsp->flag,
            pRoamInfo->pEseBcnReportRsp->numBss);
    }
    else
    {
        while (lastSent < pRoamInfo->pEseBcnReportRsp->numBss)
        {
            memset(&wrqu, '\0', sizeof(wrqu));
            memset(buf, '\0', sizeof(buf));
            tot_bcn_ieLen = 0;
            sendBss = 0;
            pos = buf;
            freeBytes = IW_CUSTOM_MAX;

            for (i = lastSent; i < pRoamInfo->pEseBcnReportRsp->numBss; i++)
            {
                len = bcnRepFieldSize + ieLenByte + pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i].ieLen;
                if ((len + tot_bcn_ieLen) > (IW_CUSTOM_MAX - ESEBCNREPHEADER_LEN))
                {
                    break;
                }
                tot_bcn_ieLen += len;
                sendBss++;
                hddLog(VOS_TRACE_LEVEL_INFO, "i(%d) sizeof bcnReportFields(%d)"
                             "IeLength(%d) Length of Ie(%d) totLen(%d)",
                              i, bcnRepFieldSize, 1,
                              pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i].ieLen,
                              tot_bcn_ieLen);
            }

            hddLog(VOS_TRACE_LEVEL_INFO, "Sending %d BSS Info", sendBss);
            hddLog(VOS_TRACE_LEVEL_INFO, "CCXBCNREP=%d %d %d %d",
                pRoamInfo->pEseBcnReportRsp->measurementToken, pRoamInfo->pEseBcnReportRsp->flag,
                sendBss, tot_bcn_ieLen);

            nBytes = snprintf(pos, freeBytes, "CCXBCNREP=%d %d %d ",
                pRoamInfo->pEseBcnReportRsp->measurementToken, pRoamInfo->pEseBcnReportRsp->flag,
                sendBss);
            pos += nBytes;
            freeBytes -= nBytes;

            /* Copy total Beacon report data length */
            vos_mem_copy(pos, (char*)&tot_bcn_ieLen, sizeof(tot_bcn_ieLen));
            pos += sizeof(tot_bcn_ieLen);
            freeBytes -= sizeof(tot_bcn_ieLen);

            for (i = 0; i < sendBss; i++)
            {
                hddLog(VOS_TRACE_LEVEL_INFO, "ChanNum(%d) Spare(%d) MeasDuration(%d)"
                       " PhyType(%d) RecvSigPower(%d) ParentTSF(%u)"
                       " TargetTSF[0](%u) TargetTSF[1](%u) BeaconInterval(%u)"
                       " CapabilityInfo(%d) BSSID(%02X:%02X:%02X:%02X:%02X:%02X)",
                        pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields.ChanNum,
                        pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields.Spare,
                        pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields.MeasDuration,
                        pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields.PhyType,
                        pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields.RecvSigPower,
                        pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields.ParentTsf,
                        pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields.TargetTsf[0],
                        pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields.TargetTsf[1],
                        pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields.BcnInterval,
                        pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields.CapabilityInfo,
                        pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields.Bssid[0],
                        pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields.Bssid[1],
                        pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields.Bssid[2],
                        pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields.Bssid[3],
                        pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields.Bssid[4],
                        pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields.Bssid[5]);

                /* bcn report fields are copied */
                len = sizeof(pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields);
                vos_mem_copy(pos, (char*)&pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields, len);
                pos += len;
                freeBytes -= len;

                /* Add 1 byte of ie len */
                len = pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].ieLen;
                vos_mem_copy(pos, (char*)&len, sizeof(len));
                pos += sizeof(len);
                freeBytes -= sizeof(len);

                /* copy IE from scan results */
                vos_mem_copy(pos, (char*)pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].pBuf, len);
                pos += len;
                freeBytes -= len;
            }

            wrqu.data.pointer = buf;
            wrqu.data.length = IW_CUSTOM_MAX - freeBytes;

            // send the event
            wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
            lastSent += sendBss;
        }
    }
}

#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */


eHalStatus
hdd_smeRoamCallback(void *pContext, tCsrRoamInfo *pRoamInfo, tANI_U32 roamId,
                    eRoamCmdStatus roamStatus, eCsrRoamResult roamResult)
{
    eHalStatus halStatus = eHAL_STATUS_SUCCESS;
    hdd_adapter_t *pAdapter = (hdd_adapter_t *)pContext;
    hdd_wext_state_t *pWextState = NULL;
    hdd_station_ctx_t *pHddStaCtx = NULL;
    VOS_STATUS status = VOS_STATUS_SUCCESS;
    hdd_context_t *pHddCtx = NULL;
    struct cfg80211_bss *bss_status;
    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
            "CSR Callback: status= %d result= %d roamID=%d",
                    roamStatus, roamResult, roamId );

    /* Sanity check */
    if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) {
       VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
          "invalid adapter or adapter has invalid magic");
       return eHAL_STATUS_FAILURE;
    }

    pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
    pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);

    MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_RX_SME_MSG,
                          pAdapter->sessionId, roamStatus));
    switch( roamStatus )
    {
        case eCSR_ROAM_SESSION_OPENED:
            set_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
            complete(&pAdapter->session_open_comp_var);
            hddLog(LOG1, FL("session %d opened"), pAdapter->sessionId);
            break;

#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
            /* We did pre-auth,then we attempted a 11r or ese reassoc.
             * reassoc failed due to failure, timeout, reject from ap
             * in any case tell the OS, our carrier is off and mark
             * interface down */
        case eCSR_ROAM_FT_REASSOC_FAILED:
            hddLog(LOGE, FL("Reassoc Failed with roamStatus: %d roamResult: %d SessionID: %d"),
                   roamStatus, roamResult, pAdapter->sessionId);
            halStatus = hdd_DisConnectHandler( pAdapter, pRoamInfo, roamId, roamStatus, roamResult );
            /* Check if Mcast/Bcast Filters are set, if yes clear the filters here */
            if ((WLAN_HDD_GET_CTX(pAdapter))->hdd_mcastbcast_filter_set == TRUE) {
                    (WLAN_HDD_GET_CTX(pAdapter))->hdd_mcastbcast_filter_set = FALSE;
            }
            pHddStaCtx->ft_carrier_on = FALSE;
            pHddStaCtx->hdd_ReassocScenario = FALSE;
            hddLog(LOG1,
                   FL("hdd_ReassocScenario set to: %d, ReAssoc Failed, session: %d"),
                   pHddStaCtx->hdd_ReassocScenario, pAdapter->sessionId);
            break;

        case eCSR_ROAM_FT_START:
            // When we roam for ESE and 11r, we dont want the
            // OS to be informed that the link is down. So mark
            // the link ready for ft_start. After this the
            // eCSR_ROAM_SHOULD_ROAM will be received.
            // Where in we will not mark the link down
            // Also we want to stop tx at this point when we will be
            // doing disassoc at this time. This saves 30-60 msec
            // after reassoc.
            {
                hddLog(LOG1, FL("Disabling queues"));
                wlan_hdd_netif_queue_control(pAdapter, WLAN_NETIF_TX_DISABLE,
                            WLAN_CONTROL_PATH);
                /*
                 * Deregister for this STA with TL with the objective to flush
                 * all the packets for this STA from wmm_tx_queue. If not done here,
                 * we would run into a race condition (CR390567) wherein TX
                 * thread would schedule packets from wmm_tx_queue AFTER peer STA has
                 * been deleted. And, these packets get assigned with a STA idx of
                 * self-sta (since the peer STA has been deleted) and get transmitted
                 * on the new channel before the reassoc request. Since there will be
                 * no ACK on the new channel, each packet gets retransmitted which
                 * takes several seconds before the transmission of reassoc request.
                 * This leads to reassoc-timeout and roam failure.
                 */
                status = hdd_roamDeregisterSTA( pAdapter, pHddStaCtx->conn_info.staId [0] );
                if ( !VOS_IS_STATUS_SUCCESS(status ) )
                {
                    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
                            FL("hdd_roamDeregisterSTA() failed to for staID %d.  Status= %d [0x%x]"),
                            pHddStaCtx->conn_info.staId[0], status, status );
                    halStatus = eHAL_STATUS_FAILURE;
                }
            }
            pHddStaCtx->ft_carrier_on = TRUE;
            pHddStaCtx->hdd_ReassocScenario = VOS_TRUE;
            hddLog(LOG1,
                   FL("hdd_ReassocScenario set to: %d due to eCSR_ROAM_FT_START, session: %d"),
                   pHddStaCtx->hdd_ReassocScenario, pAdapter->sessionId);
            break;
#endif

        case eCSR_ROAM_SHOULD_ROAM:
           // Dont need to do anything
            {
                hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
                // notify apps that we can't pass traffic anymore
                hddLog(LOG1, FL("Disabling queues"));
                wlan_hdd_netif_queue_control(pAdapter,
                    WLAN_NETIF_TX_DISABLE,
                    WLAN_CONTROL_PATH);
#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
                if (pHddStaCtx->ft_carrier_on == FALSE)
                {
#endif
                    wlan_hdd_netif_queue_control(pAdapter,
                        WLAN_NETIF_CARRIER_OFF,
                        WLAN_CONTROL_PATH);
#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
                }
#endif

#if  !(defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR))
                //We should clear all sta register with TL, for now, only one.
                status = hdd_roamDeregisterSTA( pAdapter, pHddStaCtx->conn_info.staId [0] );
                if ( !VOS_IS_STATUS_SUCCESS(status ) )
                {
                    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
                        FL("hdd_roamDeregisterSTA() failed to for staID %d.  Status= %d [0x%x]"),
                                        pHddStaCtx->conn_info.staId[0], status, status );
                    halStatus = eHAL_STATUS_FAILURE;
                }
#endif
            }
           break;
        case eCSR_ROAM_LOSTLINK:
            if(roamResult == eCSR_ROAM_RESULT_LOSTLINK) {
                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
                          "Roaming started due to connection lost");
                hddLog(LOG1, FL("Disabling queues"));
                wlan_hdd_netif_queue_control(pAdapter,
                    WLAN_NETIF_TX_DISABLE_N_CARRIER,
                    WLAN_CONTROL_PATH);
                break;
            }
        case eCSR_ROAM_DISASSOCIATED:
            {
                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                        "****eCSR_ROAM_DISASSOCIATED****");
                halStatus = hdd_DisConnectHandler( pAdapter, pRoamInfo, roamId, roamStatus, roamResult );
                /* Check if Mcast/Bcast Filters are set, if yes clear the filters here */
                pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
                if (pHddCtx->hdd_mcastbcast_filter_set == TRUE)
                {
                    hdd_conf_mcastbcast_filter(pHddCtx, FALSE);

                    if (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid) {
                        pHddCtx->configuredMcastBcastFilter =
                            pHddCtx->sus_res_mcastbcast_filter;
                        pHddCtx->sus_res_mcastbcast_filter_valid = VOS_FALSE;
                    }

                    hddLog(VOS_TRACE_LEVEL_INFO,
                           "offload: disassociation happening, restoring configuredMcastBcastFilter");
                    hddLog(VOS_TRACE_LEVEL_INFO,"McastBcastFilter = %d",
                           pHddCtx->configuredMcastBcastFilter);
                    hddLog(VOS_TRACE_LEVEL_INFO,
                           "offload: already called mcastbcast filter");
                    (WLAN_HDD_GET_CTX(pAdapter))->hdd_mcastbcast_filter_set = FALSE;
                }
#ifdef WLAN_FEATURE_PACKET_FILTERING
                /* Call to clear any MC Addr List filter applied after
                 * successful connection.
                 */
                if (wlan_hdd_set_mc_addr_list(pAdapter, FALSE))
                    hddLog(VOS_TRACE_LEVEL_ERROR, FL("failed to clear mc addr list"));
#endif
            }
            break;
        case eCSR_ROAM_IBSS_LEAVE:
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                    "****eCSR_ROAM_IBSS_LEAVE****");
            halStatus = hdd_DisConnectHandler( pAdapter, pRoamInfo, roamId, roamStatus, roamResult );
            break;
        case eCSR_ROAM_ASSOCIATION_COMPLETION:
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                    "****eCSR_ROAM_ASSOCIATION_COMPLETION****");
            // To Do - address probable memory leak with WEP encryption upon successful association
            if (eCSR_ROAM_RESULT_ASSOCIATED != roamResult)
            {
               //Clear saved connection information in HDD
               hdd_connRemoveConnectInfo( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter) );
            }
            halStatus = hdd_AssociationCompletionHandler( pAdapter, pRoamInfo, roamId, roamStatus, roamResult );
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
            if (pRoamInfo)
                pRoamInfo->roamSynchInProgress = VOS_FALSE;
#endif
            break;
        case eCSR_ROAM_ASSOCIATION_FAILURE:
            halStatus = hdd_AssociationCompletionHandler( pAdapter,
                    pRoamInfo, roamId, roamStatus, roamResult );
            break;
        case eCSR_ROAM_IBSS_IND:
            hdd_RoamIbssIndicationHandler( pAdapter, pRoamInfo, roamId,
                                           roamStatus, roamResult );
            break;

        case eCSR_ROAM_CONNECT_STATUS_UPDATE:
            halStatus = roamRoamConnectStatusUpdateHandler( pAdapter, pRoamInfo, roamId, roamStatus, roamResult );
            break;

        case eCSR_ROAM_MIC_ERROR_IND:
            halStatus = hdd_RoamMicErrorIndicationHandler( pAdapter, pRoamInfo, roamId, roamStatus, roamResult );
            break;

        case eCSR_ROAM_SET_KEY_COMPLETE:
            {
                hdd_context_t* pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;

                if((pHddCtx) &&
                   (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario) &&
                   (TRUE == pHddCtx->hdd_wlan_suspended) &&
                   ((eCSR_ROAM_RESULT_NONE == roamResult)||
                     (pRoamInfo && pRoamInfo->is11rAssoc))) {
                    /* Send DTIM period to the FW; only if the wlan is already
                       in suspend. This is the case with roaming (reassoc),
                       DELETE_BSS_REQ zeroes out Modulated/Dynamic DTIM sent in
                       previous suspend_wlan. Sending SET_POWER_PARAMS_REQ
                       before the ENTER_BMPS_REQ ensures Listen Interval is
                       regained back to LI * Modulated DTIM */
                    hdd_set_pwrparams(pHddCtx);

                    /* At this point, device should not be in BMPS;
                       if due to unexpected scenario, if we are in BMPS,
                       then trigger Exit and Enter BMPS to take DTIM period
                       effective */
                    if (BMPS == pmcGetPmcState(pHddCtx->hHal))
                    {
                        hddLog( LOGE, FL("Not expected: device is already in BMPS mode, Exit & Enter BMPS again!"));

                        sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
                                         iw_full_power_cbfn, pAdapter,
                                         eSME_FULL_PWR_NEEDED_BY_HDD);
                    }
                }
                if ((pHddCtx) &&
                    (FULL_POWER == pmcGetPmcState(pHddCtx->hHal)) &&
                    (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario) &&
                    ((eCSR_ROAM_RESULT_NONE == roamResult) ||
                      (pRoamInfo && pRoamInfo->is11rAssoc))) {
                     hddLog(LOG1,
                           FL("Device in full power, Stop and start traffic timer for roaming"));
                     pmcStopTrafficTimer(pHddCtx->hHal);

                     if (pmcStartTrafficTimer(pHddCtx->hHal,
                         TRAFFIC_TIMER_ROAMING) != eHAL_STATUS_SUCCESS)
                         hddLog(LOGP, FL("Cannot start traffic timer"));
                }
                halStatus = hdd_RoamSetKeyCompleteHandler( pAdapter, pRoamInfo, roamId, roamStatus, roamResult );
                if ((eCSR_ROAM_RESULT_NONE == roamResult) ||
                     (pRoamInfo && pRoamInfo->is11rAssoc)) {
                    pHddStaCtx->hdd_ReassocScenario = VOS_FALSE;
                    hddLog(LOG1,
                           FL("hdd_ReassocScenario set to: %d, set key complete, session: %d"),
                           pHddStaCtx->hdd_ReassocScenario,
                           pAdapter->sessionId);
                }
            }
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
            if (pRoamInfo != NULL)
                pRoamInfo->roamSynchInProgress = VOS_FALSE;
#endif
            break;
#ifdef WLAN_FEATURE_VOWIFI_11R
        case eCSR_ROAM_FT_RESPONSE:
            hdd_SendFTEvent(pAdapter);
            break;
#endif
#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)) \
	    || defined(WITH_BACKPORTS)
        case eCSR_ROAM_PMK_NOTIFY:
           if (eCSR_AUTH_TYPE_RSN == pHddStaCtx->conn_info.authType
#ifdef WLAN_FEATURE_11W
               || (eCSR_AUTH_TYPE_RSN_8021X_SHA256 ==
                                 pHddStaCtx->conn_info.authType)
#endif
                                                              )
           {
               /* Notify the supplicant of a new candidate */
               halStatus = wlan_hdd_cfg80211_pmksa_candidate_notify(pAdapter, pRoamInfo, 1, false);
           }
           break;
#endif

#ifdef FEATURE_WLAN_LFR_METRICS
        case eCSR_ROAM_PREAUTH_INIT_NOTIFY:
           /* This event is to notify pre-auth initiation */
           if (VOS_STATUS_SUCCESS !=
               wlan_hdd_cfg80211_roam_metrics_preauth(pAdapter, pRoamInfo))
           {
               halStatus = eHAL_STATUS_FAILURE;
           }
           break;
        case eCSR_ROAM_PREAUTH_STATUS_SUCCESS:
           /* This event will notify pre-auth completion in case of success */
           if (VOS_STATUS_SUCCESS !=
               wlan_hdd_cfg80211_roam_metrics_preauth_status(pAdapter,
                                                             pRoamInfo, 1))
           {
               halStatus = eHAL_STATUS_FAILURE;
           }
           break;
        case eCSR_ROAM_PREAUTH_STATUS_FAILURE:
           /* This event will notify pre-auth completion in case of failure. */
           if (VOS_STATUS_SUCCESS !=
               wlan_hdd_cfg80211_roam_metrics_preauth_status(pAdapter,
                                                             pRoamInfo, 0))
           {
               halStatus = eHAL_STATUS_FAILURE;
           }
           break;
        case eCSR_ROAM_HANDOVER_SUCCESS:
           /* This event is to notify handover success.
              It will be only invoked on success */
           if (VOS_STATUS_SUCCESS !=
               wlan_hdd_cfg80211_roam_metrics_handover(pAdapter, pRoamInfo))
           {
               halStatus = eHAL_STATUS_FAILURE;
           }
           break;
#endif
        case eCSR_ROAM_REMAIN_CHAN_READY:
            hdd_remainChanReadyHandler( pAdapter );
            break;
#ifdef FEATURE_WLAN_TDLS
        case eCSR_ROAM_TDLS_STATUS_UPDATE:
            halStatus = hdd_RoamTdlsStatusUpdateHandler( pAdapter, pRoamInfo,
                                                roamId, roamStatus, roamResult );
            break ;
        case eCSR_ROAM_RESULT_MGMT_TX_COMPLETE_IND:
            wlan_hdd_tdls_mgmt_completion_callback(pAdapter, pRoamInfo->reasonCode);
            break;

#endif
#ifdef WLAN_FEATURE_11W
       case eCSR_ROAM_UNPROT_MGMT_FRAME_IND:
            hdd_indicateUnprotMgmtFrame(pAdapter, pRoamInfo->nFrameLength,
                                         pRoamInfo->pbFrames,
                                         pRoamInfo->frameType);
            break;
#endif
#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
       case eCSR_ROAM_TSM_IE_IND:
            hdd_indicateTsmIe(pAdapter, pRoamInfo->tsmIe.tsid,
                pRoamInfo->tsmIe.state, pRoamInfo->tsmIe.msmt_interval);
           break;

       case eCSR_ROAM_CCKM_PREAUTH_NOTIFY:
          {
              if (eCSR_AUTH_TYPE_CCKM_WPA == pHddStaCtx->conn_info.authType ||
                  eCSR_AUTH_TYPE_CCKM_RSN == pHddStaCtx->conn_info.authType)
              {
                  hdd_indicateCckmPreAuth(pAdapter, pRoamInfo);
              }
              break;
          }

       case eCSR_ROAM_ESE_ADJ_AP_REPORT_IND:
         {
             hdd_indicateEseAdjApRepInd(pAdapter, pRoamInfo);
             break;
         }

       case eCSR_ROAM_ESE_BCN_REPORT_IND:
         {
            hdd_indicateEseBcnReportInd(pAdapter, pRoamInfo);
            break;
         }
#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
      case eCSR_ROAM_UPDATE_SCAN_RESULT:
         if ((NULL != pRoamInfo) && (NULL != pRoamInfo->pBssDesc)) {
              bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
                                pRoamInfo->pBssDesc);
              if (NULL == bss_status)
                  hddLog(VOS_TRACE_LEVEL_INFO,
                            FL("UPDATE_SCAN_RESULT returned NULL"));
              else
                  cfg80211_put_bss(
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)) || defined(WITH_BACKPORTS)
                                   (WLAN_HDD_GET_CTX(pAdapter))->wiphy,
#endif
                                   bss_status);
         }
         break;
        case eCSR_ROAM_NDP_STATUS_UPDATE:
            hdd_ndp_event_handler(pAdapter, pRoamInfo, roamId, roamStatus,
                roamResult );
            break;
        default:
            break;
    }
    return( halStatus );
}

#ifdef WLAN_FEATURE_FILS_SK
/**
 * hdd_translate_fils_rsn_to_csr_auth() - Translate FILS RSN to CSR auth type
 * @auth_suite: auth suite
 * @auth_type: pointer to eCsrAuthType
 *
 * Return: None
 */
static void hdd_translate_fils_rsn_to_csr_auth(u_int8_t auth_suite[4],
					eCsrAuthType *auth_type)
{
	if (!memcmp(auth_suite, ccp_rsn_oui_0e, 4))
		*auth_type = eCSR_AUTH_TYPE_FILS_SHA256;
	else if (!memcmp(auth_suite, ccp_rsn_oui_0f, 4))
		*auth_type = eCSR_AUTH_TYPE_FILS_SHA384;
	else if (!memcmp(auth_suite, ccp_rsn_oui_10, 4))
		*auth_type = eCSR_AUTH_TYPE_FT_FILS_SHA256;
	else if (!memcmp(auth_suite, ccp_rsn_oui_11, 4))
		*auth_type = eCSR_AUTH_TYPE_FT_FILS_SHA384;
}
#else
static inline void hdd_translate_fils_rsn_to_csr_auth(u_int8_t auth_suite[4],
					eCsrAuthType *auth_type)
{
}
#endif

eCsrAuthType hdd_TranslateRSNToCsrAuthType( u_int8_t auth_suite[4])
{
    eCsrAuthType auth_type = eCSR_AUTH_TYPE_UNKNOWN;
    // is the auth type supported?
    if ( memcmp(auth_suite , ccpRSNOui01, 4) == 0)
    {
        auth_type = eCSR_AUTH_TYPE_RSN;
    } else
    if (memcmp(auth_suite , ccpRSNOui02, 4) == 0)
    {
        auth_type = eCSR_AUTH_TYPE_RSN_PSK;
    } else
#ifdef WLAN_FEATURE_VOWIFI_11R
    if (memcmp(auth_suite , ccpRSNOui04, 4) == 0)
    {
        // Check for 11r FT Authentication with PSK
        auth_type = eCSR_AUTH_TYPE_FT_RSN_PSK;
    } else
    if (memcmp(auth_suite , ccpRSNOui03, 4) == 0)
    {
        // Check for 11R FT Authentication with 802.1X
        auth_type = eCSR_AUTH_TYPE_FT_RSN;
    } else
#endif
#ifdef FEATURE_WLAN_ESE
    if (memcmp(auth_suite , ccpRSNOui06, 4) == 0)
    {
        auth_type = eCSR_AUTH_TYPE_CCKM_RSN;
    } else
#endif /* FEATURE_WLAN_ESE */
#ifdef WLAN_FEATURE_11W
    if (memcmp(auth_suite , ccpRSNOui07, 4) == 0)
    {
        auth_type = eCSR_AUTH_TYPE_RSN_PSK_SHA256;
    } else
    if (memcmp(auth_suite , ccpRSNOui08, 4) == 0)
    {
        auth_type = eCSR_AUTH_TYPE_RSN_8021X_SHA256;
    } else
#endif
	/* If auth suite is of fils, auth_type will be
	 * overwritten in hdd_translate_fils_rsn_to_csr_auth
	 */
	hdd_translate_fils_rsn_to_csr_auth(auth_suite, &auth_type);
    return auth_type;
}

eCsrAuthType
hdd_TranslateWPAToCsrAuthType(u_int8_t auth_suite[4])
{
    eCsrAuthType auth_type = eCSR_AUTH_TYPE_UNKNOWN;
    // is the auth type supported?
    if ( memcmp(auth_suite , ccpWpaOui01, 4) == 0)
    {
        auth_type = eCSR_AUTH_TYPE_WPA;
    } else
    if (memcmp(auth_suite , ccpWpaOui02, 4) == 0)
    {
        auth_type = eCSR_AUTH_TYPE_WPA_PSK;
    } else
#ifdef FEATURE_WLAN_ESE
    if (memcmp(auth_suite , ccpWpaOui06, 4) == 0)
    {
        auth_type = eCSR_AUTH_TYPE_CCKM_WPA;
    } else
#endif /* FEATURE_WLAN_ESE */
	/* If auth suite is of fils, auth_type will be
	 * overwritten in hdd_translate_fils_rsn_to_csr_auth
	 */
	hdd_translate_fils_rsn_to_csr_auth(auth_suite, &auth_type);

    hddLog(LOG1, FL("auth_type: %d"), auth_type);
    return auth_type;
}

eCsrEncryptionType
hdd_TranslateRSNToCsrEncryptionType(u_int8_t cipher_suite[4])
{
    eCsrEncryptionType cipher_type;
    // is the cipher type supported?
    if ( memcmp(cipher_suite , ccpRSNOui04, 4) == 0)
    {
        cipher_type = eCSR_ENCRYPT_TYPE_AES;
    }
    else if (memcmp(cipher_suite , ccpRSNOui02, 4) == 0)
    {
        cipher_type = eCSR_ENCRYPT_TYPE_TKIP;
    }
    else if (memcmp(cipher_suite , ccpRSNOui00, 4) == 0)
    {
        cipher_type = eCSR_ENCRYPT_TYPE_NONE;
    }
    else if (memcmp(cipher_suite , ccpRSNOui01, 4) == 0)
    {
        cipher_type = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
    }
    else if (memcmp(cipher_suite , ccpRSNOui05, 4) == 0)
    {
        cipher_type = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
    }
    else
    {
        cipher_type = eCSR_ENCRYPT_TYPE_FAILED;
    }
    hddLog(LOG1, FL("cipher_type: %d"), cipher_type);
    return cipher_type;
}
/* To find if the MAC address is NULL */
static tANI_U8 hdd_IsMACAddrNULL (tANI_U8 *macAddr, tANI_U8 length)
{
    int i;
    for (i = 0; i < length; i++)
    {
        if (0x00 != (macAddr[i]))
        {
            return FALSE;
        }
    }
    return TRUE;
} /****** end hdd_IsMACAddrNULL() ******/

eCsrEncryptionType
hdd_TranslateWPAToCsrEncryptionType(u_int8_t cipher_suite[4])
{
    eCsrEncryptionType cipher_type;
    // is the cipher type supported?
    if ( memcmp(cipher_suite , ccpWpaOui04, 4) == 0)
    {
        cipher_type = eCSR_ENCRYPT_TYPE_AES;
    } else
    if (memcmp(cipher_suite , ccpWpaOui02, 4) == 0)
    {
        cipher_type = eCSR_ENCRYPT_TYPE_TKIP;
    } else
    if (memcmp(cipher_suite , ccpWpaOui00, 4) == 0)
    {
        cipher_type = eCSR_ENCRYPT_TYPE_NONE;
    } else
    if (memcmp(cipher_suite , ccpWpaOui01, 4) == 0)
    {
        cipher_type = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
    } else
    if (memcmp(cipher_suite , ccpWpaOui05, 4) == 0)
    {
        cipher_type = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
    } else
    {
        cipher_type = eCSR_ENCRYPT_TYPE_FAILED;
    }
    hddLog(LOG1, FL("cipher_type: %d"), cipher_type);
    return cipher_type;
}

#ifdef WLAN_FEATURE_FILS_SK
/*
 * hdd_is_fils_connection: API to determine if connection is FILS
 * @adapter: hdd adapter
 *
 * Return: true if fils connection else false
*/
static inline bool hdd_is_fils_connection(hdd_adapter_t *adapter)
{
    hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
    if (wext_state->roamProfile.fils_con_info)
        return wext_state->roamProfile.fils_con_info->is_fils_connection;

    return false;
}
#else
static inline bool hdd_is_fils_connection(hdd_adapter_t *adapter)
{
    return false;
}
#endif

static tANI_S32 hdd_ProcessGENIE(hdd_adapter_t *pAdapter,
                struct ether_addr *pBssid,
                eCsrEncryptionType *pEncryptType,
                eCsrEncryptionType *mcEncryptType,
                eCsrAuthType *pAuthType,
#ifdef WLAN_FEATURE_11W
                u_int8_t *pMfpRequired,
                u_int8_t *pMfpCapable,
#endif
                u_int16_t gen_ie_len,
                u_int8_t *gen_ie)
{
    tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
    eHalStatus result;
    tDot11fIERSN dot11RSNIE;
    tDot11fIEWPA dot11WPAIE;
    tANI_U32 i;
    tANI_U32 status;
    tANI_U8 *pRsnIe;
    tANI_U16 RSNIeLen;
    tPmkidCacheInfo PMKIDCache[4]; // Local transfer memory
    v_BOOL_t updatePMKCache = FALSE;

    vos_mem_zero(PMKIDCache, sizeof PMKIDCache);
    /* Clear struct of tDot11fIERSN and tDot11fIEWPA specifically setting present
       flag to 0 */
    memset( &dot11WPAIE, 0 , sizeof(tDot11fIEWPA) );
    memset( &dot11RSNIE, 0 , sizeof(tDot11fIERSN) );

    // Type check
    if ( gen_ie[0] ==  DOT11F_EID_RSN)
    {
        // Validity checks
        if ((gen_ie_len < DOT11F_IE_RSN_MIN_LEN ) ||
                (gen_ie_len > DOT11F_IE_RSN_MAX_LEN) )
        {
            hddLog(LOGE, "%s: Invalid DOT11F RSN IE length :%d",
                   __func__, gen_ie_len);
            return -EINVAL;
        }
        // Skip past the EID byte and length byte
        pRsnIe = gen_ie + 2;
        RSNIeLen = gen_ie_len - 2;
        // Unpack the RSN IE
        status = dot11fUnpackIeRSN((tpAniSirGlobal) halHandle,
                            pRsnIe,
                            RSNIeLen,
                            &dot11RSNIE);
        if (DOT11F_FAILED(status))
        {
            hddLog(LOGE,
                       FL("Parse failure in hdd_ProcessGENIE (0x%08x)"),
                       status);
            return -EINVAL;
        }
        // Copy out the encryption and authentication types
        hddLog(LOG1, FL("%s: pairwise cipher suite count: %d"),
                __func__, dot11RSNIE.pwise_cipher_suite_count );
        hddLog(LOG1, FL("%s: authentication suite count: %d"),
                __func__, dot11RSNIE.akm_suite_count);
        /*Here we have followed the apple base code,
          but probably I suspect we can do something different*/
        //dot11RSNIE.akm_suite_count
        // Just translate the FIRST one
        *pAuthType =  hdd_TranslateRSNToCsrAuthType(dot11RSNIE.akm_suites[0]);
        //dot11RSNIE.pwise_cipher_suite_count
        *pEncryptType = hdd_TranslateRSNToCsrEncryptionType(dot11RSNIE.pwise_cipher_suites[0]);
        //dot11RSNIE.gp_cipher_suite_count
        *mcEncryptType = hdd_TranslateRSNToCsrEncryptionType(dot11RSNIE.gp_cipher_suite);
#ifdef WLAN_FEATURE_11W
        *pMfpRequired = (dot11RSNIE.RSN_Cap[0] >> 6) & 0x1 ;
        *pMfpCapable = (dot11RSNIE.RSN_Cap[0] >> 7) & 0x1 ;
#endif
        // Set the PMKSA ID Cache for this interface
        for (i=0; i<dot11RSNIE.pmkid_count; i++)
        {
            if ( pBssid == NULL)
            {
                hddLog(LOGE, "%s: pBssid passed is NULL", __func__);
                break;
            }
            if ( hdd_IsMACAddrNULL( (u_char *) pBssid->ether_addr_octet , 6))
            {
                hddLog(LOGE, "%s: Invalid MAC adrr", __func__);
                break;
            }
            updatePMKCache = TRUE;
            // For right now, I assume setASSOCIATE() has passed in the bssid.
            vos_mem_copy(PMKIDCache[i].BSSID,
                            pBssid, ETHER_ADDR_LEN);
            vos_mem_copy(PMKIDCache[i].PMKID,
                            dot11RSNIE.pmkid[i],
                            CSR_RSN_PMKID_SIZE);
        }

        if (updatePMKCache)
        {
            // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
            hddLog(LOG1, FL("%s: Calling csrRoamSetPMKIDCache with cache entry %d."),
                                                                            __func__, i );
            // Finally set the PMKSA ID Cache in CSR
            result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
                                           PMKIDCache,
                                           dot11RSNIE.pmkid_count,
                                           FALSE);
        }
    }
    else if (gen_ie[0] == DOT11F_EID_WPA)
    {
        // Validity checks
        if ((gen_ie_len < DOT11F_IE_WPA_MIN_LEN ) ||
                    (gen_ie_len > DOT11F_IE_WPA_MAX_LEN))
        {
            hddLog(LOGE, "%s: Invalid DOT11F WPA IE length :%d",
                   __func__, gen_ie_len);
            return -EINVAL;
        }
        // Skip past the EID byte and length byte - and four byte WiFi OUI
        pRsnIe = gen_ie + 2 + 4;
        RSNIeLen = gen_ie_len - (2 + 4);
        // Unpack the WPA IE
        dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
                            pRsnIe,
                            RSNIeLen,
                            &dot11WPAIE);
        // Copy out the encryption and authentication types
        hddLog(LOG1, FL("%s: WPA unicast cipher suite count: %d"),
               __func__, dot11WPAIE.unicast_cipher_count );
        hddLog(LOG1, FL("%s: WPA authentication suite count: %d"),
               __func__, dot11WPAIE.auth_suite_count);
        //dot11WPAIE.auth_suite_count
        // Just translate the FIRST one
        *pAuthType =  hdd_TranslateWPAToCsrAuthType(dot11WPAIE.auth_suites[0]);
        //dot11WPAIE.unicast_cipher_count
        *pEncryptType = hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.unicast_ciphers[0]);
        //dot11WPAIE.unicast_cipher_count
        *mcEncryptType = hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
    }
    else
    {
        hddLog(LOGW, FL("gen_ie[0]: %d"), gen_ie[0]);
        return -EINVAL;
    }
    return 0;
}
int hdd_SetGENIEToCsr( hdd_adapter_t *pAdapter, eCsrAuthType *RSNAuthType)
{
    hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
    v_U32_t status = 0;
    eCsrEncryptionType RSNEncryptType;
    eCsrEncryptionType mcRSNEncryptType;
#ifdef WLAN_FEATURE_11W
    u_int8_t RSNMfpRequired = 0;
    u_int8_t RSNMfpCapable = 0;
#endif
    struct ether_addr   bSsid;   // MAC address of assoc peer
    // MAC address of assoc peer
    // But, this routine is only called when we are NOT associated.
    vos_mem_copy(bSsid.ether_addr_octet,
            pWextState->roamProfile.BSSIDs.bssid,
            sizeof(bSsid.ether_addr_octet));
    if (pWextState->WPARSNIE[0] == DOT11F_EID_RSN || pWextState->WPARSNIE[0] == DOT11F_EID_WPA)
    {
        //continue
    }
    else
    {
        return 0;
    }
    // The actual processing may eventually be more extensive than this.
    // Right now, just consume any PMKIDs that are  sent in by the app.
    status = hdd_ProcessGENIE(pAdapter,
            &bSsid,   // MAC address of assoc peer
            &RSNEncryptType,
            &mcRSNEncryptType,
            RSNAuthType,
#ifdef WLAN_FEATURE_11W
            &RSNMfpRequired,
            &RSNMfpCapable,
#endif
            pWextState->WPARSNIE[1]+2,
            pWextState->WPARSNIE);
    if (status == 0)
    {
        // Now copy over all the security attributes you have parsed out
        pWextState->roamProfile.EncryptionType.numEntries = 1;
        pWextState->roamProfile.mcEncryptionType.numEntries = 1;

        pWextState->roamProfile.EncryptionType.encryptionType[0] = RSNEncryptType; // Use the cipher type in the RSN IE
        pWextState->roamProfile.mcEncryptionType.encryptionType[0] = mcRSNEncryptType;

        if ( (WLAN_HDD_IBSS == pAdapter->device_mode) &&
             ((eCSR_ENCRYPT_TYPE_AES == mcRSNEncryptType) ||
             (eCSR_ENCRYPT_TYPE_TKIP == mcRSNEncryptType)))
        {
           /*For wpa none supplicant sends the WPA IE with unicast cipher as
             eCSR_ENCRYPT_TYPE_NONE ,where as the multicast cipher as
             either AES/TKIP based on group cipher configuration
             mentioned in the wpa_supplicant.conf.*/

           /*Set the unicast cipher same as multicast cipher*/
           pWextState->roamProfile.EncryptionType.encryptionType[0]
                                                     = mcRSNEncryptType;
        }

#ifdef WLAN_FEATURE_11W
        hddLog( LOG1, FL("RSNMfpRequired = %d, RSNMfpCapable = %d"),
                                       RSNMfpRequired, RSNMfpCapable);
        pWextState->roamProfile.MFPRequired = RSNMfpRequired;
        pWextState->roamProfile.MFPCapable = RSNMfpCapable;
#endif
        hddLog( LOG1,
          FL("CSR AuthType = %d, EncryptionType = %d mcEncryptionType = %d"),
           *RSNAuthType, RSNEncryptType, mcRSNEncryptType);
    }
    return 0;
}

#ifdef WLAN_FEATURE_FILS_SK
/**
 * hdd_check_fils_rsn_n_set_auth_type() - This API checks whether a give
 * auth type is fils if yes, sets it in profile.
 * @rsn_auth_type: auth type
 *
 * Return: true if FILS auth else false
 */
static bool hdd_check_fils_rsn_n_set_auth_type(tCsrRoamProfile *roam_profile,
			    eCsrAuthType rsn_auth_type)
{
	bool is_fils_rsn = false;

	if ((rsn_auth_type == eCSR_AUTH_TYPE_FILS_SHA256) ||
	   (rsn_auth_type == eCSR_AUTH_TYPE_FILS_SHA384) ||
	   (rsn_auth_type == eCSR_AUTH_TYPE_FT_FILS_SHA256) ||
	   (rsn_auth_type == eCSR_AUTH_TYPE_FT_FILS_SHA384))
		is_fils_rsn = true;
	if (is_fils_rsn)
		roam_profile->fils_con_info->akm_type = rsn_auth_type;

	return is_fils_rsn;
}
#endif

int hdd_set_csr_auth_type ( hdd_adapter_t  *pAdapter, eCsrAuthType RSNAuthType)
{
    hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
    tCsrRoamProfile* pRoamProfile = &(pWextState->roamProfile);
    hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);

    pRoamProfile->AuthType.numEntries = 1;
    hddLog( LOG1, "%s: pHddStaCtx->conn_info.authType = %d", __func__, pHddStaCtx->conn_info.authType);

    switch( pHddStaCtx->conn_info.authType)
    {
       case eCSR_AUTH_TYPE_OPEN_SYSTEM:
#ifdef FEATURE_WLAN_ESE
       case eCSR_AUTH_TYPE_CCKM_WPA:
       case eCSR_AUTH_TYPE_CCKM_RSN:
#endif
        if (pWextState->wpaVersion & IW_AUTH_WPA_VERSION_DISABLED) {

           pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_OPEN_SYSTEM ;
        } else
        if (pWextState->wpaVersion & IW_AUTH_WPA_VERSION_WPA) {

#ifdef FEATURE_WLAN_ESE
            if ((RSNAuthType == eCSR_AUTH_TYPE_CCKM_WPA) &&
                ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
                 == IW_AUTH_KEY_MGMT_802_1X)) {
                hddLog( LOG1, "%s: set authType to CCKM WPA. AKM also 802.1X.", __func__);
                pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_CCKM_WPA;
            } else
            if ((RSNAuthType == eCSR_AUTH_TYPE_CCKM_WPA)) {
                hddLog( LOG1, "%s: Last chance to set authType to CCKM WPA.", __func__);
                pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_CCKM_WPA;
            } else
#endif
            if((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
                    == IW_AUTH_KEY_MGMT_802_1X) {
               pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WPA;
            } else
            if ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_PSK)
                    == IW_AUTH_KEY_MGMT_PSK) {
               pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WPA_PSK;
            } else {
               pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WPA_NONE;
            }
        }
        if (pWextState->wpaVersion & IW_AUTH_WPA_VERSION_WPA2) {
#ifdef FEATURE_WLAN_ESE
            if ((RSNAuthType == eCSR_AUTH_TYPE_CCKM_RSN) &&
                ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
                 == IW_AUTH_KEY_MGMT_802_1X)) {
                hddLog( LOG1, "%s: set authType to CCKM RSN. AKM also 802.1X.", __func__);
                pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_CCKM_RSN;
            } else
            if ((RSNAuthType == eCSR_AUTH_TYPE_CCKM_RSN)) {
                hddLog( LOG1, "%s: Last chance to set authType to CCKM RSN.", __func__);
                pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_CCKM_RSN;
            } else
#endif

#ifdef WLAN_FEATURE_VOWIFI_11R
            if ((RSNAuthType == eCSR_AUTH_TYPE_FT_RSN) &&
                ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
                 == IW_AUTH_KEY_MGMT_802_1X)) {
               pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_FT_RSN;
            }else
            if ((RSNAuthType == eCSR_AUTH_TYPE_FT_RSN_PSK) &&
                ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_PSK)
                 == IW_AUTH_KEY_MGMT_PSK)) {
               pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_FT_RSN_PSK;
            } else
#endif

#ifdef WLAN_FEATURE_11W
            if (RSNAuthType == eCSR_AUTH_TYPE_RSN_PSK_SHA256) {
                pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_RSN_PSK_SHA256;
            } else
            if (RSNAuthType == eCSR_AUTH_TYPE_RSN_8021X_SHA256) {
                pRoamProfile->AuthType.authType[0] =
                                            eCSR_AUTH_TYPE_RSN_8021X_SHA256;
            } else
#endif
#ifdef WLAN_FEATURE_FILS_SK
            if (hdd_check_fils_rsn_n_set_auth_type(pRoamProfile, RSNAuthType)) {
				pRoamProfile->AuthType.authType[0] = RSNAuthType;
				hddLog(LOG1, "updated profile authtype as %d", RSNAuthType);
            } else
#endif
            if( (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
                    == IW_AUTH_KEY_MGMT_802_1X) {
               pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_RSN;
            } else
            if ( (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_PSK)
                    == IW_AUTH_KEY_MGMT_PSK) {
               pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_RSN_PSK;
            } else {
               pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_UNKNOWN;
            }
        }
        break;

       case eCSR_AUTH_TYPE_SHARED_KEY:

          pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_SHARED_KEY;
          break;
        default:

#ifdef FEATURE_WLAN_ESE
           hddLog( LOG1, "%s: In default, unknown auth type.", __func__);
#endif /* FEATURE_WLAN_ESE */
           pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_UNKNOWN;
           break;
    }

    hddLog( LOG1, "%s Set roam Authtype to %d",
            __func__, pWextState->roamProfile.AuthType.authType[0]);

    return 0;
}

/**
 * __iw_set_essid() - This function sets the ssid received from wpa_supplicant
 *			to the CSR roam profile.
 * @dev: Pointer to the net device.
 * @info: Pointer to the iw_request_info.
 * @wrqu: Pointer to the iwreq_data.
 * @extra: Pointer to the data.
 *
 * Return: 0 for success, error number on failure
 */
static int __iw_set_essid(struct net_device *dev,
                        struct iw_request_info *info,
                        union iwreq_data *wrqu, char *extra)
{
    v_U32_t status = 0;
    hdd_wext_state_t *pWextState;
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    v_U32_t roamId;
    tCsrRoamProfile          *pRoamProfile;
    hdd_context_t *pHddCtx;
    eCsrAuthType RSNAuthType;
    uint16_t ch_width;
    tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
    int ret;

    ENTER();

    pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    ret = wlan_hdd_validate_context(pHddCtx);
    if (0 != ret)
        return ret;

    pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);

    if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION &&
        pAdapter->device_mode != WLAN_HDD_P2P_CLIENT) {
        hddLog(LOGW, FL("Device mode %s(%d) is not allowed"),
               hdd_device_mode_to_string(pAdapter->device_mode),
               pAdapter->device_mode);
        return -EINVAL;
    }

    if(pWextState->mTKIPCounterMeasures == TKIP_COUNTER_MEASURE_STARTED) {
        hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s :Counter measure is in progress", __func__);
        return -EBUSY;
    }
    if( SIR_MAC_MAX_SSID_LENGTH < wrqu->essid.length )
        return -EINVAL;

    pRoamProfile = &pWextState->roamProfile;

    /*Try disconnecting if already in connected state*/
    status = wlan_hdd_try_disconnect(pAdapter);
    if (0 > status)
    {
      hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
            " connection"));
      return -EALREADY;
    }
    /** when cfg80211 defined, wpa_supplicant wext driver uses
      zero-length, null-string ssid for force disconnection.
      after disconnection (if previously connected) and cleaning ssid,
      driver MUST return success */
    if ( 0 == wrqu->essid.length ) {
        return 0;
    }

    status = hdd_wmm_get_uapsd_mask(pAdapter,
                                    &pWextState->roamProfile.uapsd_mask);
    if (VOS_STATUS_SUCCESS != status)
    {
       pWextState->roamProfile.uapsd_mask = 0;
    }
    pWextState->roamProfile.SSIDs.numOfSSIDs = 1;

    pWextState->roamProfile.SSIDs.SSIDList->SSID.length = wrqu->essid.length;

    vos_mem_zero(pWextState->roamProfile.SSIDs.SSIDList->SSID.ssId, sizeof(pWextState->roamProfile.SSIDs.SSIDList->SSID.ssId));
    vos_mem_copy((void *)(pWextState->roamProfile.SSIDs.SSIDList->SSID.ssId), extra, wrqu->essid.length);
    if (IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion ||
        IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion ) {

        //set gen ie
        hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);

        //set auth
        hdd_set_csr_auth_type(pAdapter, RSNAuthType);
    }
#ifdef FEATURE_WLAN_WAPI
    hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
    if (pAdapter->wapi_info.nWapiMode)
    {
        switch (pAdapter->wapi_info.wapiAuthMode)
        {
            case WAPI_AUTH_MODE_PSK:
            {
                hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__, pAdapter->wapi_info.wapiAuthMode);
                pRoamProfile->AuthType.numEntries = 1;
                pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
                break;
            }
            case WAPI_AUTH_MODE_CERT:
            {
                hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__, pAdapter->wapi_info.wapiAuthMode);
                pRoamProfile->AuthType.numEntries = 1;
                pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
                break;
            }
        } // End of switch
        if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
             pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
        {
            hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
            pRoamProfile->EncryptionType.numEntries = 1;
            pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
            pRoamProfile->mcEncryptionType.numEntries = 1;
            pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
        }
    }
#endif /* FEATURE_WLAN_WAPI */
    /* if previous genIE is not NULL, update AssocIE */
    if (0 != pWextState->genIE.length)
    {
        memset( &pWextState->assocAddIE, 0, sizeof(pWextState->assocAddIE) );
        memcpy( pWextState->assocAddIE.addIEdata, pWextState->genIE.addIEdata,
            pWextState->genIE.length);
        pWextState->assocAddIE.length = pWextState->genIE.length;
        pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
        pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;

        /* clear previous genIE after use it */
        memset( &pWextState->genIE, 0, sizeof(pWextState->genIE) );
    }

    /* assumes it is not WPS Association by default, except when pAddIEAssoc has WPS IE */
    pWextState->roamProfile.bWPSAssociation = FALSE;

    if (NULL != wlan_hdd_get_wps_ie_ptr(pWextState->roamProfile.pAddIEAssoc,
        pWextState->roamProfile.nAddIEAssocLength))
        pWextState->roamProfile.bWPSAssociation = TRUE;


    // Disable auto BMPS entry by PMC until DHCP is done
    sme_SetDHCPTillPowerActiveFlag(WLAN_HDD_GET_HAL_CTX(pAdapter), TRUE);

    pWextState->roamProfile.csrPersona = pAdapter->device_mode;
    (WLAN_HDD_GET_CTX(pAdapter))->isAmpAllowed = VOS_FALSE;

    if ( eCSR_BSS_TYPE_START_IBSS == pRoamProfile->BSSType )
    {
        hdd_select_cbmode(pAdapter, pHddCtx->cfg_ini->AdHocChannel5G,
                        &ch_width);
        pRoamProfile->vht_channel_width = ch_width;
    }
    /*
     * Change conn_state to connecting before sme_RoamConnect(),
     * because sme_RoamConnect() has a direct path to call
     * hdd_smeRoamCallback(), which will change the conn_state
     * If direct path, conn_state will be accordingly changed
     * to NotConnected or Associated by either
     * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
     * in sme_RoamCallback()
     * if sme_RomConnect is to be queued,
     * Connecting state will remain until it is completed.
     *
     * If connection state is not changed,
     * connection state will remain in eConnectionState_NotConnected state.
     * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
     * if conn state is eConnectionState_NotConnected.
     * If "hddDisconInProgress" is set to true then cfg80211 layer is not
     * informed of connect result indication which is an issue.
     */
    if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
            WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) {
        hdd_connSetConnectionState(pAdapter,
                eConnectionState_Connecting);
    }
    status = sme_RoamConnect( hHal,pAdapter->sessionId,
            &(pWextState->roamProfile), &roamId);

    if ((eHAL_STATUS_SUCCESS != status) &&
            (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
             WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)) {
        hddLog(LOGE,
                FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
                pAdapter->sessionId, status);
        /* change back to NotAssociated */
        hdd_connSetConnectionState(pAdapter,
                eConnectionState_NotConnected);
    }
    pRoamProfile->ChannelInfo.ChannelList = NULL;
    pRoamProfile->ChannelInfo.numOfChannels = 0;

    EXIT();
    return status;
}

/**
 * iw_set_essid() - set essid handler function
 * @dev: Pointer to the net device.
 * @info: Pointer to the iw_request_info.
 * @wrqu: Pointer to the iwreq_data.
 * @extra: Pointer to the data.
 *
 * Return: 0 for success, error number on failure
 */
int iw_set_essid(struct net_device *dev,
		 struct iw_request_info *info,
		 union iwreq_data *wrqu, char *extra)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __iw_set_essid(dev, info, wrqu, extra);
	vos_ssr_unprotect(__func__);

	return ret;
}

/**
 * __iw_get_essid() - This function returns the essid to the wpa_supplicant
 * @dev: Pointer to the net device.
 * @info: Pointer to the iw_request_info.
 * @wrqu: Pointer to the iwreq_data.
 * @extra: Pointer to the data.
 *
 * Return: 0 for success, error number on failure
 */
static int __iw_get_essid(struct net_device *dev,
			  struct iw_request_info *info,
			  struct iw_point *dwrq, char *extra)
{
   hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
   hdd_context_t *hdd_ctx;
   hdd_wext_state_t *wextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
   hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
   int ret;

   ENTER();

   hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
   ret = wlan_hdd_validate_context(hdd_ctx);
   if (0 != ret)
       return ret;

   if((pHddStaCtx->conn_info.connState == eConnectionState_Associated &&
     wextBuf->roamProfile.SSIDs.SSIDList->SSID.length > 0) ||
      ((pHddStaCtx->conn_info.connState == eConnectionState_IbssConnected ||
        pHddStaCtx->conn_info.connState == eConnectionState_IbssDisconnected) &&
        wextBuf->roamProfile.SSIDs.SSIDList->SSID.length > 0))
   {
       dwrq->length = pHddStaCtx->conn_info.SSID.SSID.length;
       memcpy(extra, pHddStaCtx->conn_info.SSID.SSID.ssId, dwrq->length);
       dwrq->flags = 1;
   } else {
       memset(extra, 0, dwrq->length);
       dwrq->length = 0;
       dwrq->flags = 0;
   }
   EXIT();
   return 0;
}

/**
 * iw_get_essid() - get essid handler function
 * @dev: Pointer to the net device.
 * @info: Pointer to the iw_request_info.
 * @wrqu: Pointer to the iwreq_data.
 * @extra: Pointer to the data.
 *
 * Return: 0 for success, error number on failure
 */
int iw_get_essid(struct net_device *dev,
		 struct iw_request_info *info,
		 struct iw_point *wrqu, char *extra)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __iw_get_essid(dev, info, wrqu, extra);
	vos_ssr_unprotect(__func__);

	return ret;
}

/**
 * __iw_set_auth() - This function sets the auth type received
 *			from the wpa_supplicant.
 * @dev: Pointer to the net device.
 * @info: Pointer to the iw_request_info.
 * @wrqu: Pointer to the iwreq_data.
 * @extra: Pointer to the data.
 *
 * Return: 0 for success, error number on failure.
 */
static int __iw_set_auth(struct net_device *dev, struct iw_request_info *info,
			 union iwreq_data *wrqu, char *extra)
{
   hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
   hdd_context_t *hdd_ctx;
   hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
   hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
   tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
   eCsrEncryptionType mcEncryptionType;
   eCsrEncryptionType ucEncryptionType;
   int ret;

   ENTER();

   hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
   ret = wlan_hdd_validate_context(hdd_ctx);
   if (0 != ret)
       return ret;

   switch(wrqu->param.flags & IW_AUTH_INDEX)
   {
      case IW_AUTH_WPA_VERSION:

         pWextState->wpaVersion = wrqu->param.value;

         break;

   case IW_AUTH_CIPHER_PAIRWISE:
   {
      if(wrqu->param.value & IW_AUTH_CIPHER_NONE) {
         ucEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
      }
      else if(wrqu->param.value & IW_AUTH_CIPHER_TKIP) {
         ucEncryptionType = eCSR_ENCRYPT_TYPE_TKIP;
      }
      else if(wrqu->param.value & IW_AUTH_CIPHER_CCMP) {
         ucEncryptionType = eCSR_ENCRYPT_TYPE_AES;
      }

     else if(wrqu->param.value & IW_AUTH_CIPHER_WEP40) {

         if( (IW_AUTH_KEY_MGMT_802_1X
                     == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)  )
                 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType) )
                /*Dynamic WEP key*/
             ucEncryptionType = eCSR_ENCRYPT_TYPE_WEP40;
         else
                /*Static WEP key*/
             ucEncryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
      }
      else if(wrqu->param.value & IW_AUTH_CIPHER_WEP104) {

         if( ( IW_AUTH_KEY_MGMT_802_1X
                     == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X) )
                 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))
                  /*Dynamic WEP key*/
            ucEncryptionType = eCSR_ENCRYPT_TYPE_WEP104;
         else
                /*Static WEP key*/
            ucEncryptionType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;

         }
         else {

               hddLog(LOGW, "%s value %d UNKNOWN IW_AUTH_CIPHER",
                      __func__, wrqu->param.value);
               return -EINVAL;
         }

         pRoamProfile->EncryptionType.numEntries = 1;
         pRoamProfile->EncryptionType.encryptionType[0] = ucEncryptionType;
      }
      break;
      case IW_AUTH_CIPHER_GROUP:
      {
          if(wrqu->param.value & IW_AUTH_CIPHER_NONE) {
            mcEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
      }

      else if(wrqu->param.value & IW_AUTH_CIPHER_TKIP) {
             mcEncryptionType = eCSR_ENCRYPT_TYPE_TKIP;
      }

      else if(wrqu->param.value & IW_AUTH_CIPHER_CCMP) {
              mcEncryptionType = eCSR_ENCRYPT_TYPE_AES;
      }

      else if(wrqu->param.value & IW_AUTH_CIPHER_WEP40) {

         if( ( IW_AUTH_KEY_MGMT_802_1X
                     == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
                 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))

            mcEncryptionType = eCSR_ENCRYPT_TYPE_WEP40;

         else
               mcEncryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
      }

      else if(wrqu->param.value & IW_AUTH_CIPHER_WEP104)
      {
             /*Dynamic WEP keys won't work with shared keys*/
         if( ( IW_AUTH_KEY_MGMT_802_1X
                     == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
                 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))
         {
            mcEncryptionType = eCSR_ENCRYPT_TYPE_WEP104;
         }
         else
         {
            mcEncryptionType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
         }
      }
      else {

          hddLog(LOGW, "%s value %d UNKNOWN IW_AUTH_CIPHER",
                 __func__, wrqu->param.value);
          return -EINVAL;
       }

         pRoamProfile->mcEncryptionType.numEntries = 1;
         pRoamProfile->mcEncryptionType.encryptionType[0] = mcEncryptionType;
      }
      break;

      case IW_AUTH_80211_AUTH_ALG:
      {
           /*Save the auth algo here and set auth type to SME Roam profile
                in the iw_set_ap_address*/
          if( wrqu->param.value & IW_AUTH_ALG_OPEN_SYSTEM)
             pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;

          else if(wrqu->param.value & IW_AUTH_ALG_SHARED_KEY)
             pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;

          else if(wrqu->param.value & IW_AUTH_ALG_LEAP)
            /*Not supported*/
             pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
          pWextState->roamProfile.AuthType.authType[0] = pHddStaCtx->conn_info.authType;
      }
      break;

      case IW_AUTH_KEY_MGMT:
      {
#ifdef FEATURE_WLAN_ESE
#define IW_AUTH_KEY_MGMT_CCKM       8  /* Should be in linux/wireless.h */
         /*Check for CCKM AKM type */
         if ( wrqu->param.value & IW_AUTH_KEY_MGMT_CCKM) {
            hddLog(VOS_TRACE_LEVEL_INFO,"%s: CCKM AKM Set %d",
                   __func__, wrqu->param.value);
            /* Set the CCKM bit in authKeyMgmt */
            /* Right now, this breaks all ref to authKeyMgmt because our
             * code doesn't realize it is a "bitfield"
             */
            pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
            /*Set the key management to 802.1X*/
            //pWextState->authKeyMgmt = IW_AUTH_KEY_MGMT_802_1X;
            pWextState->isESEConnection = eANI_BOOLEAN_TRUE;
            //This is test code. I need to actually KNOW whether this is an RSN Assoc or WPA.
            pWextState->collectedAuthType = eCSR_AUTH_TYPE_CCKM_RSN;
         } else if ( wrqu->param.value & IW_AUTH_KEY_MGMT_PSK) {
            /*Save the key management*/
            pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
            //pWextState->authKeyMgmt = wrqu->param.value;
            //This is test code. I need to actually KNOW whether this is an RSN Assoc or WPA.
            pWextState->collectedAuthType = eCSR_AUTH_TYPE_RSN;
         } else if (!( wrqu->param.value & IW_AUTH_KEY_MGMT_802_1X)) {
            pWextState->collectedAuthType = eCSR_AUTH_TYPE_NONE; //eCSR_AUTH_TYPE_WPA_NONE
            /*Save the key management anyway*/
            pWextState->authKeyMgmt = wrqu->param.value;
         } else { // It must be IW_AUTH_KEY_MGMT_802_1X
            /*Save the key management*/
            pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
            //pWextState->authKeyMgmt = wrqu->param.value;
            //This is test code. I need to actually KNOW whether this is an RSN Assoc or WPA.
            pWextState->collectedAuthType = eCSR_AUTH_TYPE_RSN;
         }
#else
         /*Save the key management*/
         pWextState->authKeyMgmt = wrqu->param.value;
#endif /* FEATURE_WLAN_ESE */
      }
      break;

      case IW_AUTH_TKIP_COUNTERMEASURES:
      {
         if(wrqu->param.value) {
            hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
                   "Counter Measure started %d", wrqu->param.value);
            pWextState->mTKIPCounterMeasures = TKIP_COUNTER_MEASURE_STARTED;
         }
         else {
            hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
                   "Counter Measure stopped=%d", wrqu->param.value);
            pWextState->mTKIPCounterMeasures = TKIP_COUNTER_MEASURE_STOPED;
         }
      }
      break;
      case IW_AUTH_DROP_UNENCRYPTED:
      case IW_AUTH_WPA_ENABLED:
      case IW_AUTH_RX_UNENCRYPTED_EAPOL:
      case IW_AUTH_ROAMING_CONTROL:
      case IW_AUTH_PRIVACY_INVOKED:

      default:

         hddLog(LOGW, "%s called with unsupported auth type %d", __func__,
               wrqu->param.flags & IW_AUTH_INDEX);
      break;
   }

   EXIT();
   return 0;
}

/**
 * iw_set_auth() - set auth callback function
 * @dev: Pointer to the net device.
 * @info: Pointer to the iw_request_info.
 * @wrqu: Pointer to the iwreq_data.
 * @extra: Pointer to the data.
 *
 * Return: 0 for success, error number on failure.
 */
int iw_set_auth(struct net_device *dev, struct iw_request_info *info,
		union iwreq_data *wrqu, char *extra)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __iw_set_auth(dev, info, wrqu, extra);
	vos_ssr_unprotect(__func__);

	return ret;
}

/**
 * __iw_get_auth() - This function returns the auth type to the wpa_supplicant.
 * @dev: Pointer to the net device.
 * @info: Pointer to the iw_request_info.
 * @wrqu: Pointer to the iwreq_data.
 * @extra: Pointer to the data.
 *
 * Return: 0 for success, error number on failure.
 */
static int __iw_get_auth(struct net_device *dev, struct iw_request_info *info,
			 union iwreq_data *wrqu, char *extra)
{
    hdd_adapter_t* pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_context_t *hdd_ctx;
    hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
    tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
    int ret;

    ENTER();

    hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
    ret = wlan_hdd_validate_context(hdd_ctx);
    if (0 != ret)
        return ret;

    switch(pRoamProfile->negotiatedAuthType)
    {
        case eCSR_AUTH_TYPE_WPA_NONE:
            wrqu->param.flags = IW_AUTH_WPA_VERSION;
            wrqu->param.value =  IW_AUTH_WPA_VERSION_DISABLED;
            break;
        case eCSR_AUTH_TYPE_WPA:
            wrqu->param.flags = IW_AUTH_WPA_VERSION;
            wrqu->param.value = IW_AUTH_WPA_VERSION_WPA;
            break;
#ifdef WLAN_FEATURE_VOWIFI_11R
        case eCSR_AUTH_TYPE_FT_RSN:
#endif
        case eCSR_AUTH_TYPE_RSN:
            wrqu->param.flags = IW_AUTH_WPA_VERSION;
            wrqu->param.value =  IW_AUTH_WPA_VERSION_WPA2;
            break;
         case eCSR_AUTH_TYPE_OPEN_SYSTEM:
             wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
             break;
         case eCSR_AUTH_TYPE_SHARED_KEY:
             wrqu->param.value =  IW_AUTH_ALG_SHARED_KEY;
             break;
         case eCSR_AUTH_TYPE_UNKNOWN:
             hddLog(LOG1,"%s called with unknown auth type", __func__);
             wrqu->param.value =  IW_AUTH_ALG_OPEN_SYSTEM;
             break;
         case eCSR_AUTH_TYPE_AUTOSWITCH:
             wrqu->param.value =  IW_AUTH_ALG_OPEN_SYSTEM;
             break;
         case eCSR_AUTH_TYPE_WPA_PSK:
             hddLog(LOG1,"%s called with WPA PSK auth type", __func__);
             wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
             return -EIO;
#ifdef WLAN_FEATURE_VOWIFI_11R
         case eCSR_AUTH_TYPE_FT_RSN_PSK:
#endif
         case eCSR_AUTH_TYPE_RSN_PSK:
#ifdef WLAN_FEATURE_11W
         case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
         case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
#endif
             hddLog(LOG1,"%s called with RSN PSK auth type", __func__);
             wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
             return -EIO;
         default:
             hddLog(LOGE,"%s called with unknown auth type", __func__);
             wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
             return -EIO;
    }
    if(((wrqu->param.flags & IW_AUTH_INDEX) == IW_AUTH_CIPHER_PAIRWISE))
    {
        switch(pRoamProfile->negotiatedUCEncryptionType)
        {
            case eCSR_ENCRYPT_TYPE_NONE:
                wrqu->param.value = IW_AUTH_CIPHER_NONE;
                break;
            case eCSR_ENCRYPT_TYPE_WEP40:
            case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
                wrqu->param.value = IW_AUTH_CIPHER_WEP40;
                break;
            case eCSR_ENCRYPT_TYPE_TKIP:
                wrqu->param.value = IW_AUTH_CIPHER_TKIP;
                break;
            case eCSR_ENCRYPT_TYPE_WEP104:
            case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
                wrqu->param.value = IW_AUTH_CIPHER_WEP104;
                break;
            case eCSR_ENCRYPT_TYPE_AES:
                wrqu->param.value = IW_AUTH_CIPHER_CCMP;
                break;
            default:
                hddLog(LOG1, "%s called with unknown auth type %d ",
                       __func__, pRoamProfile->negotiatedUCEncryptionType);
                return -EIO;
        }
   }

    if(((wrqu->param.flags & IW_AUTH_INDEX) == IW_AUTH_CIPHER_GROUP))
    {
        switch(pRoamProfile->negotiatedMCEncryptionType)
        {
        case eCSR_ENCRYPT_TYPE_NONE:
            wrqu->param.value = IW_AUTH_CIPHER_NONE;
            break;
        case eCSR_ENCRYPT_TYPE_WEP40:
        case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
            wrqu->param.value = IW_AUTH_CIPHER_WEP40;
            break;
        case eCSR_ENCRYPT_TYPE_TKIP:
            wrqu->param.value = IW_AUTH_CIPHER_TKIP;
            break;
         case eCSR_ENCRYPT_TYPE_WEP104:
         case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
             wrqu->param.value = IW_AUTH_CIPHER_WEP104;
             break;
         case eCSR_ENCRYPT_TYPE_AES:
             wrqu->param.value = IW_AUTH_CIPHER_CCMP;
             break;
         default:
             hddLog(LOG1, "%s called with unknown auth type %d ",
                    __func__, pRoamProfile->negotiatedMCEncryptionType);
            return -EIO;
       }
   }

    hddLog(LOG1, "%s called with auth type %d",
           __func__, pRoamProfile->AuthType.authType[0]);
    EXIT();
    return 0;
}

/**
 * iw_get_auth() - get auth callback function
 * @dev: Pointer to the net device.
 * @info: Pointer to the iw_request_info.
 * @wrqu: Pointer to the iwreq_data.
 * @extra: Pointer to the data.
 *
 * Return: 0 for success, error number on failure.
 */
int iw_get_auth(struct net_device *dev, struct iw_request_info *info,
		union iwreq_data *wrqu, char *extra)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __iw_get_auth(dev, info, wrqu, extra);
	vos_ssr_unprotect(__func__);

	return ret;
}

/**
 * __iw_set_ap_address() - This function calls the sme_RoamConnect function
 *			to associate to the AP with the specified
 *			BSSID received from the wpa_supplicant.
 * @dev: Pointer to the net device.
 * @info: Pointer to the iw_request_info.
 * @wrqu: Pointer to the iwreq_data.
 * @extra: Pointer to the data.
 *
 * Return: 0 for success, error number on failure.
 */
static int __iw_set_ap_address(struct net_device *dev,
        struct iw_request_info *info,
        union iwreq_data *wrqu, char *extra)
{

    hdd_adapter_t *adapter;
    hdd_context_t *hdd_ctx;
    hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(WLAN_HDD_GET_PRIV_PTR(dev));
    v_U8_t  *pMacAddress=NULL;
    int ret;

    ENTER();

    adapter = WLAN_HDD_GET_PRIV_PTR(dev);

    hdd_ctx = WLAN_HDD_GET_CTX(adapter);
    ret = wlan_hdd_validate_context(hdd_ctx);
    if (0 != ret)
        return ret;

    pMacAddress = (v_U8_t*) wrqu->ap_addr.sa_data;
    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s "MAC_ADDRESS_STR,
              __func__, MAC_ADDR_ARRAY(pMacAddress));
    vos_mem_copy( pHddStaCtx->conn_info.bssId, pMacAddress, sizeof( tCsrBssid ));
    EXIT();

    return 0;
}

/**
 * iw_set_ap_address() - set ap addresses callback function
 * @dev: Pointer to the net device.
 * @info: Pointer to the iw_request_info.
 * @wrqu: Pointer to the iwreq_data.
 * @extra: Pointer to the data.
 *
 * Return: 0 for success, error number on failure.
 */
int iw_set_ap_address(struct net_device *dev, struct iw_request_info *info,
			union iwreq_data *wrqu, char *extra)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __iw_set_ap_address(dev, info, wrqu, extra);
	vos_ssr_unprotect(__func__);

	return ret;
}

/**
 * __iw_get_ap_address() - This function returns the BSSID to the wpa_supplicant
 * @dev: Pointer to the net device.
 * @info: Pointer to the iw_request_info.
 * @wrqu: Pointer to the iwreq_data.
 * @extra: Pointer to the data.
 *
 * Return: 0 for success, error number on failure.
 */
static int __iw_get_ap_address(struct net_device *dev,
                             struct iw_request_info *info,
                             union iwreq_data *wrqu, char *extra)
{
    hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_context_t *hdd_ctx;
    hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
    int ret;

    ENTER();

    hdd_ctx = WLAN_HDD_GET_CTX(adapter);
    ret = wlan_hdd_validate_context(hdd_ctx);
    if (0 != ret)
        return ret;

    if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
        (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
    {
        memcpy(wrqu->ap_addr.sa_data,pHddStaCtx->conn_info.bssId,ETH_ALEN);
    }
    else
    {
        memset(wrqu->ap_addr.sa_data,0,sizeof(wrqu->ap_addr.sa_data));
    }
    EXIT();
    return 0;
}

/**
 * iw_get_ap_address() - get ap addresses callback function
 * @dev: Pointer to the net device.
 * @info: Pointer to the iw_request_info.
 * @wrqu: Pointer to the iwreq_data.
 * @extra: Pointer to the data.
 *
 * Return: 0 for success, error number on failure.
 */
int iw_get_ap_address(struct net_device *dev, struct iw_request_info *info,
			union iwreq_data *wrqu, char *extra)
{
	int ret;

	vos_ssr_protect(__func__);
	ret = __iw_get_ap_address(dev, info, wrqu, extra);
	vos_ssr_unprotect(__func__);

	return ret;
}
