qcacld-3.0: Initial snapshot of ihelium wlan driver

qcacld-3.0: Initial snapshot of ihelium wlan driver
to match code-scanned SU Release 5.0.0.139. This is
open-source version of wlan for next Android release.

Change-Id: Icf598ca97da74f84bea607e4e902d1889806f507
diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c
new file mode 100644
index 0000000..9074f37
--- /dev/null
+++ b/core/sme/src/csr/csr_api_roam.c
@@ -0,0 +1,18860 @@
+/*
+ * Copyright (c) 2012-2015 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 csr_api_roam.c
+
+    Implementation for the Common Roaming interfaces.
+   ========================================================================== */
+#include "ani_global.h"          /* for tpAniSirGlobal */
+#include "wma_types.h"
+#include "wma_if.h"          /* for STA_INVALID_IDX. */
+#include "lim_utils.h"
+#include "cds_mq.h"
+#include "csr_inside_api.h"
+#include "sms_debug.h"
+#include "sme_qos_internal.h"
+#include "sme_inside.h"
+#include "host_diag_core_event.h"
+#include "host_diag_core_log.h"
+#include "csr_api.h"
+#include "csr_internal.h"
+#include "cds_reg_service.h"
+#include "mac_trace.h"
+#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
+#include "csr_neighbor_roam.h"
+#endif /* WLAN_FEATURE_NEIGHBOR_ROAMING */
+#include "cds_regdomain_common.h"
+#include "cds_utils.h"
+#include "sir_types.h"
+#include "cfg_api.h"
+#include "sme_power_save_api.h"
+#include "wma.h"
+#include "cds_concurrency.h"
+
+#define CSR_NUM_IBSS_START_CHANNELS_50      4
+#define CSR_NUM_IBSS_START_CHANNELS_24      3
+/* 5 seconds, for WPA, WPA2, CCKM */
+#define CSR_WAIT_FOR_KEY_TIMEOUT_PERIOD     (5 * CDF_MC_TIMER_TO_SEC_UNIT)
+/* 120 seconds, for WPS */
+#define CSR_WAIT_FOR_WPS_KEY_TIMEOUT_PERIOD (120 * CDF_MC_TIMER_TO_SEC_UNIT)
+
+/*---------------------------------------------------------------------------
+   OBIWAN recommends [8 10]% : pick 9%
+   ---------------------------------------------------------------------------*/
+#define CSR_VCC_UL_MAC_LOSS_THRESHOLD 9
+/*---------------------------------------------------------------------------
+   OBIWAN recommends -85dBm
+   ---------------------------------------------------------------------------*/
+#define CSR_VCC_RSSI_THRESHOLD 80
+#define CSR_MIN_GLOBAL_STAT_QUERY_PERIOD   500  /* ms */
+#define CSR_MIN_GLOBAL_STAT_QUERY_PERIOD_IN_BMPS 2000   /* ms */
+#define CSR_MIN_TL_STAT_QUERY_PERIOD       500  /* ms */
+/* Flag to send/do not send disassoc frame over the air */
+#define CSR_DONT_SEND_DISASSOC_OVER_THE_AIR 1
+#define RSSI_HACK_BMPS (-40)
+#define MAX_CB_VALUE_IN_INI (2)
+
+#define MAX_SOCIAL_CHANNELS  3
+/* Choose the largest possible value that can be accomodates in 8 bit signed */
+/* variable. */
+#define SNR_HACK_BMPS                         (127)
+
+static bool b_roam_scan_offload_started;
+
+/*--------------------------------------------------------------------------
+   Static Type declarations
+   ------------------------------------------------------------------------*/
+static tCsrRoamSession csr_roam_roam_session[CSR_ROAM_SESSION_MAX];
+
+/*--------------------------------------------------------------------------
+   Type declarations
+   ------------------------------------------------------------------------*/
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+int diag_auth_type_from_csr_type(eCsrAuthType authType)
+{
+	int n = AUTH_OPEN;
+	switch (authType) {
+	case eCSR_AUTH_TYPE_SHARED_KEY:
+		n = AUTH_SHARED;
+		break;
+	case eCSR_AUTH_TYPE_WPA:
+		n = AUTH_WPA_EAP;
+		break;
+	case eCSR_AUTH_TYPE_WPA_PSK:
+		n = AUTH_WPA_PSK;
+		break;
+	case eCSR_AUTH_TYPE_RSN:
+#ifdef WLAN_FEATURE_11W
+	case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
+#endif
+		n = AUTH_WPA2_EAP;
+		break;
+	case eCSR_AUTH_TYPE_RSN_PSK:
+#ifdef WLAN_FEATURE_11W
+	case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
+#endif
+		n = AUTH_WPA2_PSK;
+		break;
+#ifdef FEATURE_WLAN_WAPI
+	case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE:
+		n = AUTH_WAPI_CERT;
+		break;
+	case eCSR_AUTH_TYPE_WAPI_WAI_PSK:
+		n = AUTH_WAPI_PSK;
+		break;
+#endif /* FEATURE_WLAN_WAPI */
+	default:
+		break;
+	}
+	return n;
+}
+
+int diag_enc_type_from_csr_type(eCsrEncryptionType encType)
+{
+	int n = ENC_MODE_OPEN;
+	switch (encType) {
+	case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
+	case eCSR_ENCRYPT_TYPE_WEP40:
+		n = ENC_MODE_WEP40;
+		break;
+	case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
+	case eCSR_ENCRYPT_TYPE_WEP104:
+		n = ENC_MODE_WEP104;
+		break;
+	case eCSR_ENCRYPT_TYPE_TKIP:
+		n = ENC_MODE_TKIP;
+		break;
+	case eCSR_ENCRYPT_TYPE_AES:
+		n = ENC_MODE_AES;
+		break;
+#ifdef FEATURE_WLAN_WAPI
+	case eCSR_ENCRYPT_TYPE_WPI:
+		n = ENC_MODE_SMS4;
+		break;
+#endif /* FEATURE_WLAN_WAPI */
+	default:
+		break;
+	}
+	return n;
+}
+#endif /* #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR */
+static const uint8_t
+ csr_start_ibss_channels50[CSR_NUM_IBSS_START_CHANNELS_50] = { 36, 40, 44, 48 };
+static const uint8_t
+ csr_start_ibss_channels24[CSR_NUM_IBSS_START_CHANNELS_24] = { 1, 6, 11 };
+static void init_config_param(tpAniSirGlobal pMac);
+static bool csr_roam_process_results(tpAniSirGlobal pMac, tSmeCmd *pCommand,
+				     eCsrRoamCompleteResult Result,
+				     void *Context);
+static CDF_STATUS csr_roam_start_ibss(tpAniSirGlobal pMac, uint32_t sessionId,
+				      tCsrRoamProfile *pProfile,
+				      bool *pfSameIbss);
+static void csr_roam_update_connected_profile_from_new_bss(tpAniSirGlobal pMac,
+							   uint32_t sessionId,
+							   tSirSmeNewBssInfo *
+							   pNewBss);
+static void csr_roam_prepare_bss_params(tpAniSirGlobal pMac, uint32_t sessionId,
+					tCsrRoamProfile *pProfile,
+					tSirBssDescription *pBssDesc,
+					tBssConfigParam *pBssConfig,
+					tDot11fBeaconIEs *pIes);
+static ePhyChanBondState csr_get_cb_mode_from_ies(tpAniSirGlobal pMac,
+						  uint8_t primaryChn,
+						  tDot11fBeaconIEs *pIes);
+
+static void csr_roaming_state_config_cnf_processor(tpAniSirGlobal pMac,
+						   uint32_t result);
+CDF_STATUS csr_roam_open(tpAniSirGlobal pMac);
+CDF_STATUS csr_roam_close(tpAniSirGlobal pMac);
+void csr_roamMICErrorTimerHandler(void *pv);
+void csr_roamTKIPCounterMeasureTimerHandler(void *pv);
+bool csr_roam_is_same_profile_keys(tpAniSirGlobal pMac,
+				   tCsrRoamConnectedProfile *pConnProfile,
+				   tCsrRoamProfile *pProfile2);
+
+static CDF_STATUS csr_roam_start_roaming_timer(tpAniSirGlobal pMac,
+					       uint32_t sessionId,
+					       uint32_t interval);
+static CDF_STATUS csr_roam_stop_roaming_timer(tpAniSirGlobal pMac,
+					      uint32_t sessionId);
+static void csr_roam_roaming_timer_handler(void *pv);
+CDF_STATUS csr_roam_start_wait_for_key_timer(tpAniSirGlobal pMac, uint32_t interval);
+CDF_STATUS csr_roam_stop_wait_for_key_timer(tpAniSirGlobal pMac);
+static void csr_roam_wait_for_key_time_out_handler(void *pv);
+static CDF_STATUS csr_init11d_info(tpAniSirGlobal pMac, tCsr11dinfo *ps11dinfo);
+static CDF_STATUS csr_init_channel_power_list(tpAniSirGlobal pMac,
+					      tCsr11dinfo *ps11dinfo);
+static CDF_STATUS csr_roam_free_connected_info(tpAniSirGlobal pMac,
+					       tCsrRoamConnectedInfo *
+					       pConnectedInfo);
+CDF_STATUS csr_send_mb_set_context_req_msg(tpAniSirGlobal pMac, uint32_t sessionId,
+					   tSirMacAddr peerMacAddr, uint8_t numKeys,
+					   tAniEdType edType, bool fUnicast,
+					   tAniKeyDirection aniKeyDirection,
+					   uint8_t keyId, uint8_t keyLength,
+					   uint8_t *pKey, uint8_t paeRole,
+					   uint8_t *pKeyRsc);
+static CDF_STATUS csr_roam_issue_reassociate(tpAniSirGlobal pMac,
+					     uint32_t sessionId,
+					     tSirBssDescription *pSirBssDesc,
+					     tDot11fBeaconIEs *pIes,
+					     tCsrRoamProfile *pProfile);
+void csr_roamStatisticsTimerHandler(void *pv);
+void csr_roamStatsGlobalClassDTimerHandler(void *pv);
+static void csr_roam_link_up(tpAniSirGlobal pMac, struct cdf_mac_addr bssid);
+static void csr_roam_link_down(tpAniSirGlobal pMac, uint32_t sessionId);
+void csr_roam_vcc_trigger(tpAniSirGlobal pMac);
+CDF_STATUS csr_send_mb_stats_req_msg(tpAniSirGlobal pMac, uint32_t statsMask,
+				     uint8_t staId, uint8_t sessionId);
+/*
+    pStaEntry is no longer invalid upon the return of this function.
+ */
+static void csr_roam_remove_stat_list_entry(tpAniSirGlobal pMac, tListElem *pEntry);
+static eCsrCfgDot11Mode csr_roam_get_phy_mode_band_for_bss(tpAniSirGlobal pMac,
+							   tCsrRoamProfile *pProfile,
+							   uint8_t operationChn,
+							   eCsrBand *pBand);
+static CDF_STATUS csr_roam_get_qos_info_from_bss(tpAniSirGlobal pMac,
+						 tSirBssDescription *pBssDesc);
+tCsrStatsClientReqInfo *csr_roam_insert_entry_into_list(tpAniSirGlobal pMac,
+							tDblLinkList *pStaList,
+							tCsrStatsClientReqInfo *
+							pStaEntry);
+void csr_roam_stats_client_timer_handler(void *pv);
+tCsrPeStatsReqInfo *csr_roam_check_pe_stats_req_list(tpAniSirGlobal pMac,
+						     uint32_t statsMask,
+						     uint32_t periodicity,
+						     bool *pFound, uint8_t staId,
+						     uint8_t sessionId);
+void csr_roam_report_statistics(tpAniSirGlobal pMac, uint32_t statsMask,
+				tCsrStatsCallback callback, uint8_t staId,
+				void *pContext);
+void csr_roam_tl_stats_timer_handler(void *pv);
+void csr_roam_pe_stats_timer_handler(void *pv);
+tListElem *csr_roam_check_client_req_list(tpAniSirGlobal pMac, uint32_t statsMask);
+void csr_roam_remove_entry_from_pe_stats_req_list(tpAniSirGlobal pMac,
+						  tCsrPeStatsReqInfo *pPeStaEntry);
+tListElem *csr_roam_find_in_pe_stats_req_list(tpAniSirGlobal pMac, uint32_t statsMask);
+CDF_STATUS csr_roam_dereg_statistics_req(tpAniSirGlobal pMac);
+static uint32_t csr_find_ibss_session(tpAniSirGlobal pMac);
+static uint32_t csr_find_session_by_type(tpAniSirGlobal, tCDF_CON_MODE);
+static bool csr_is_conn_allow_2g_band(tpAniSirGlobal pMac, uint32_t chnl);
+static bool csr_is_conn_allow_5g_band(tpAniSirGlobal pMac, uint32_t chnl);
+static CDF_STATUS csr_roam_start_wds(tpAniSirGlobal pMac, uint32_t sessionId,
+				     tCsrRoamProfile *pProfile,
+				     tSirBssDescription *pBssDesc);
+static void csr_init_session(tpAniSirGlobal pMac, uint32_t sessionId);
+static CDF_STATUS csr_roam_issue_set_key_command(tpAniSirGlobal pMac,
+						 uint32_t sessionId,
+						 tCsrRoamSetKey *pSetKey,
+						 uint32_t roamId);
+static CDF_STATUS csr_roam_get_qos_info_from_bss(tpAniSirGlobal pMac,
+						 tSirBssDescription *pBssDesc);
+void csr_roam_reissue_roam_command(tpAniSirGlobal pMac);
+static void csr_ser_des_unpack_diassoc_rsp(uint8_t *pBuf,
+					   tSirSmeDisassocRsp *pRsp);
+void csr_reinit_preauth_cmd(tpAniSirGlobal pMac, tSmeCmd *pCommand);
+void csr_init_operating_classes(tHalHandle hHal);
+
+/* Initialize global variables */
+static void csr_roam_init_globals(tpAniSirGlobal pMac)
+{
+	if (pMac) {
+		cdf_mem_zero(&csr_roam_roam_session, sizeof(csr_roam_roam_session));
+		pMac->roam.roamSession = csr_roam_roam_session;
+	}
+	return;
+}
+
+static void csr_roam_de_init_globals(tpAniSirGlobal pMac)
+{
+	if (pMac) {
+		pMac->roam.roamSession = NULL;
+	}
+	return;
+}
+
+CDF_STATUS csr_open(tpAniSirGlobal pMac)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	uint32_t i;
+
+	do {
+		/* Initialize CSR Roam Globals */
+		csr_roam_init_globals(pMac);
+		for (i = 0; i < CSR_ROAM_SESSION_MAX; i++)
+			csr_roam_state_change(pMac, eCSR_ROAMING_STATE_STOP, i);
+
+		init_config_param(pMac);
+		status = csr_scan_open(pMac);
+		if (!CDF_IS_STATUS_SUCCESS(status))
+			break;
+		status = csr_roam_open(pMac);
+		if (!CDF_IS_STATUS_SUCCESS(status))
+			break;
+		pMac->roam.nextRoamId = 1;      /* Must not be 0 */
+		if (!CDF_IS_STATUS_SUCCESS
+			    (csr_ll_open(pMac->hHdd,
+					 &pMac->roam.statsClientReqList)))
+			break;
+		if (!CDF_IS_STATUS_SUCCESS
+			    (csr_ll_open(pMac->hHdd,
+					 &pMac->roam.peStatsReqList)))
+			break;
+		if (!CDF_IS_STATUS_SUCCESS
+			    (csr_ll_open(pMac->hHdd,
+					 &pMac->roam.roamCmdPendingList)))
+			break;
+	} while (0);
+
+	return status;
+}
+
+CDF_STATUS csr_init_chan_list(tpAniSirGlobal mac, uint8_t *alpha2)
+{
+	CDF_STATUS status;
+	v_REGDOMAIN_t reg_id;
+	v_CountryInfoSource_t source = COUNTRY_INIT;
+
+	mac->scan.countryCodeDefault[0] = alpha2[0];
+	mac->scan.countryCodeDefault[1] = alpha2[1];
+	mac->scan.countryCodeDefault[2] = alpha2[2];
+
+	sms_log(mac, LOGE, FL("init time country code %.2s"),
+		mac->scan.countryCodeDefault);
+
+	status = csr_get_regulatory_domain_for_country(mac,
+						       mac->scan.countryCodeDefault,
+						       &reg_id, source);
+	if (status != CDF_STATUS_SUCCESS) {
+		sms_log(mac, LOGE,
+			FL("csr_get_regulatory_domain_for_country failed"));
+		return status;
+	}
+
+	if (cds_set_reg_domain(mac, reg_id) != CDF_STATUS_SUCCESS) {
+		sms_log(mac, LOGE, FL("cds_set_reg_domain failed"));
+		return CDF_STATUS_E_FAILURE;
+	}
+	mac->scan.domainIdDefault = reg_id;
+	mac->scan.domainIdCurrent = mac->scan.domainIdDefault;
+	cdf_mem_copy(mac->scan.countryCodeCurrent,
+		     mac->scan.countryCodeDefault, WNI_CFG_COUNTRY_CODE_LEN);
+	cdf_mem_copy(mac->scan.countryCodeElected,
+		     mac->scan.countryCodeDefault, WNI_CFG_COUNTRY_CODE_LEN);
+	status = csr_get_channel_and_power_list(mac);
+	csr_clear_votes_for_country_info(mac);
+	return status;
+}
+
+CDF_STATUS csr_set_reg_info(tHalHandle hHal, uint8_t *apCntryCode)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	v_REGDOMAIN_t regId;
+	uint8_t cntryCodeLength;
+	if (NULL == apCntryCode) {
+		sms_log(pMac, LOGE, FL(" Invalid country Code Pointer"));
+		return CDF_STATUS_E_FAILURE;
+	}
+	sms_log(pMac, LOG1, FL(" country Code %.2s"), apCntryCode);
+
+	cntryCodeLength = WNI_CFG_COUNTRY_CODE_LEN;
+	status = csr_get_regulatory_domain_for_country(pMac, apCntryCode, &regId,
+						       COUNTRY_USER);
+	if (status != CDF_STATUS_SUCCESS) {
+		sms_log(pMac, LOGE,
+			FL("  fail to get regId for country Code %.2s"),
+			apCntryCode);
+		return status;
+	}
+	status = wma_set_reg_domain(hHal, regId);
+	if (status != CDF_STATUS_SUCCESS) {
+		sms_log(pMac, LOGE,
+			FL("  fail to get regId for country Code %.2s"),
+			apCntryCode);
+		return status;
+	}
+	pMac->scan.domainIdDefault = regId;
+	pMac->scan.domainIdCurrent = pMac->scan.domainIdDefault;
+	/* Clear CC field */
+	cdf_mem_set(pMac->scan.countryCodeDefault, WNI_CFG_COUNTRY_CODE_LEN, 0);
+
+	/* Copy 2 or 3 bytes country code */
+	cdf_mem_copy(pMac->scan.countryCodeDefault, apCntryCode,
+		     cntryCodeLength);
+
+	/* If 2 bytes country code, 3rd byte must be filled with space */
+	if ((WNI_CFG_COUNTRY_CODE_LEN - 1) == cntryCodeLength) {
+		cdf_mem_set(pMac->scan.countryCodeDefault + 2, 1, 0x20);
+	}
+	cdf_mem_copy(pMac->scan.countryCodeCurrent,
+		     pMac->scan.countryCodeDefault, WNI_CFG_COUNTRY_CODE_LEN);
+	status = csr_get_channel_and_power_list(pMac);
+	return status;
+}
+
+CDF_STATUS csr_set_channels(tHalHandle hHal, tCsrConfigParam *pParam)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	uint8_t index = 0;
+	cdf_mem_copy(pParam->Csr11dinfo.countryCode,
+		     pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
+	for (index = 0; index < pMac->scan.base_channels.numChannels;
+	     index++) {
+		pParam->Csr11dinfo.Channels.channelList[index] =
+			pMac->scan.base_channels.channelList[index];
+		pParam->Csr11dinfo.ChnPower[index].firstChannel =
+			pMac->scan.base_channels.channelList[index];
+		pParam->Csr11dinfo.ChnPower[index].numChannels = 1;
+		pParam->Csr11dinfo.ChnPower[index].maxtxPower =
+			pMac->scan.defaultPowerTable[index].pwr;
+	}
+	pParam->Csr11dinfo.Channels.numChannels =
+		pMac->scan.base_channels.numChannels;
+
+	return status;
+}
+
+CDF_STATUS csr_close(tpAniSirGlobal pMac)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+
+	csr_roam_close(pMac);
+	csr_scan_close(pMac);
+	csr_ll_close(&pMac->roam.statsClientReqList);
+	csr_ll_close(&pMac->roam.peStatsReqList);
+	csr_ll_close(&pMac->roam.roamCmdPendingList);
+	/* DeInit Globals */
+	csr_roam_de_init_globals(pMac);
+	return status;
+}
+
+static tPowerdBm csr_find_channel_pwr(tChannelListWithPower *
+					     pdefaultPowerTable,
+					     uint8_t ChannelNum)
+{
+	uint8_t i;
+	/* TODO: if defaultPowerTable is guaranteed to be in ascending */
+	/* order of channel numbers, we can employ binary search */
+	for (i = 0; i < WNI_CFG_VALID_CHANNEL_LIST_LEN; i++) {
+		if (pdefaultPowerTable[i].chanId == ChannelNum)
+			return pdefaultPowerTable[i].pwr;
+	}
+	/* could not find the channel list in default list */
+	/* this should not have occured */
+	CDF_ASSERT(0);
+	return 0;
+}
+
+CDF_STATUS csr_update_channel_list(tpAniSirGlobal pMac)
+{
+	tSirUpdateChanList *pChanList;
+	tCsrScanStruct *pScan = &pMac->scan;
+	uint8_t numChan = pScan->base_channels.numChannels;
+	uint8_t num_channel = 0;
+	uint32_t bufLen;
+	cds_msg_t msg;
+	uint8_t i, j, social_channel[MAX_SOCIAL_CHANNELS] = { 1, 6, 11 };
+	uint8_t channel_state;
+
+	if (CSR_IS_5G_BAND_ONLY(pMac)) {
+		for (i = 0; i < MAX_SOCIAL_CHANNELS; i++) {
+			if (cds_get_channel_state(social_channel[i])
+			    == CHANNEL_STATE_ENABLE)
+				numChan++;
+		}
+	}
+
+	bufLen = sizeof(tSirUpdateChanList) +
+		 (sizeof(tSirUpdateChanParam) * (numChan));
+
+	csr_init_operating_classes((tHalHandle) pMac);
+	pChanList = (tSirUpdateChanList *) cdf_mem_malloc(bufLen);
+	if (!pChanList) {
+		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
+			  "Failed to allocate memory for tSirUpdateChanList");
+		return CDF_STATUS_E_NOMEM;
+	}
+	cdf_mem_zero(pChanList, bufLen);
+
+	for (i = 0; i < pScan->base_channels.numChannels; i++) {
+		/* Scan is not performed on DSRC channels*/
+		if (pScan->base_channels.channelList[i] >= MIN_11P_CHANNEL)
+			continue;
+		if (pScan->fcc_constraint) {
+			if (pScan->base_channels.channelList[i] == 12)
+				continue;
+			if (pScan->base_channels.channelList[i] == 13)
+				continue;
+		}
+		channel_state =
+			cds_get_channel_state(
+				pScan->base_channels.channelList[i]);
+		if ((CHANNEL_STATE_ENABLE == channel_state) ||
+		    pMac->scan.fEnableDFSChnlScan) {
+			pChanList->chanParam[num_channel].chanId =
+				pScan->base_channels.channelList[i];
+			pChanList->chanParam[num_channel].pwr =
+				csr_find_channel_pwr(pScan->defaultPowerTable,
+						  pChanList->chanParam[num_channel].chanId);
+			if (CHANNEL_STATE_ENABLE == channel_state)
+				pChanList->chanParam[num_channel].dfsSet =
+					false;
+			else
+				pChanList->chanParam[num_channel].dfsSet =
+					true;
+			num_channel++;
+		}
+	}
+
+	if (CSR_IS_5G_BAND_ONLY(pMac)) {
+		for (j = 0; j < MAX_SOCIAL_CHANNELS; j++) {
+			if (cds_get_channel_state(social_channel[j])
+			    == CHANNEL_STATE_ENABLE) {
+				pChanList->chanParam[num_channel].chanId =
+					social_channel[j];
+				pChanList->chanParam[num_channel].pwr =
+					csr_find_channel_pwr(pScan->defaultPowerTable,
+							  social_channel[j]);
+				pChanList->chanParam[num_channel].dfsSet = false;
+				num_channel++;
+			}
+		}
+	}
+
+	msg.type = WMA_UPDATE_CHAN_LIST_REQ;
+	msg.reserved = 0;
+	msg.bodyptr = pChanList;
+	pChanList->numChan = num_channel;
+
+	if (CDF_STATUS_SUCCESS != cds_mq_post_message(CDF_MODULE_ID_WMA, &msg)) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_FATAL,
+			  "%s: Failed to post msg to WMA", __func__);
+		cdf_mem_free(pChanList);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	return CDF_STATUS_SUCCESS;
+}
+
+CDF_STATUS csr_start(tpAniSirGlobal pMac)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	uint32_t i;
+
+	do {
+		/* save the global cds context */
+		pMac->roam.g_cds_context = cds_get_global_context();
+		for (i = 0; i < CSR_ROAM_SESSION_MAX; i++)
+			csr_roam_state_change(pMac, eCSR_ROAMING_STATE_IDLE, i);
+
+		status = csr_roam_start(pMac);
+		if (!CDF_IS_STATUS_SUCCESS(status))
+			break;
+
+		pMac->roam.sPendingCommands = 0;
+		csr_scan_enable(pMac);
+#if   defined WLAN_FEATURE_NEIGHBOR_ROAMING
+		for (i = 0; i < CSR_ROAM_SESSION_MAX; i++)
+			status = csr_neighbor_roam_init(pMac, i);
+#endif /* WLAN_FEATURE_NEIGHBOR_ROAMING */
+		pMac->roam.tlStatsReqInfo.numClient = 0;
+		pMac->roam.tlStatsReqInfo.periodicity = 0;
+		pMac->roam.tlStatsReqInfo.timerRunning = false;
+		/* init the link quality indication also */
+		pMac->roam.vccLinkQuality = eCSR_ROAM_LINK_QUAL_MIN_IND;
+		if (!CDF_IS_STATUS_SUCCESS(status)) {
+			sms_log(pMac, LOGW,
+				" csr_start: Couldn't Init HO control blk ");
+			break;
+		}
+
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
+			  "Scan offload is enabled, update default chan list");
+		status = csr_update_channel_list(pMac);
+
+	} while (0);
+	return status;
+}
+
+CDF_STATUS csr_stop(tpAniSirGlobal pMac, tHalStopType stopType)
+{
+	uint32_t sessionId;
+
+	for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++) {
+		csr_roam_close_session(pMac, sessionId, true, NULL, NULL);
+	}
+	csr_scan_disable(pMac);
+	pMac->scan.fCancelIdleScan = false;
+	pMac->scan.fRestartIdleScan = false;
+	csr_ll_purge(&pMac->roam.roamCmdPendingList, true);
+
+#if   defined WLAN_FEATURE_NEIGHBOR_ROAMING
+	for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++)
+		csr_neighbor_roam_close(pMac, sessionId);
+#endif
+	for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++)
+		if (CSR_IS_SESSION_VALID(pMac, sessionId))
+			csr_scan_flush_result(pMac);
+
+	/* Reset the domain back to the deault */
+	pMac->scan.domainIdCurrent = pMac->scan.domainIdDefault;
+
+	for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++) {
+		csr_roam_state_change(pMac, eCSR_ROAMING_STATE_STOP, sessionId);
+		pMac->roam.curSubState[sessionId] = eCSR_ROAM_SUBSTATE_NONE;
+	}
+
+	/* When HAL resets all the context information
+	 * in HAL is lost, so we might need to send the
+	 * scan offload request again when it comes
+	 * out of reset for scan offload to be functional
+	 */
+	if (HAL_STOP_TYPE_SYS_RESET == stopType) {
+		b_roam_scan_offload_started = false;
+	}
+
+	return CDF_STATUS_SUCCESS;
+}
+
+CDF_STATUS csr_ready(tpAniSirGlobal pMac)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	/* If the gScanAgingTime is set to '0' then scan results aging timeout
+	   based  on timer feature is not enabled */
+
+	if (0 != pMac->scan.scanResultCfgAgingTime) {
+		csr_scan_start_result_cfg_aging_timer(pMac);
+	}
+	status = csr_apply_channel_and_power_list(pMac);
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		sms_log(pMac, LOGE,
+			"csr_apply_channel_and_power_list failed during csr_ready with status=%d",
+			status);
+	}
+	return status;
+}
+
+void csr_set_default_dot11_mode(tpAniSirGlobal pMac)
+{
+	uint32_t wniDot11mode = 0;
+	wniDot11mode =
+		csr_translate_to_wni_cfg_dot11_mode(pMac,
+						    pMac->roam.configParam.uCfgDot11Mode);
+	cfg_set_int(pMac, WNI_CFG_DOT11_MODE, wniDot11mode);
+}
+
+void csr_set_global_cfgs(tpAniSirGlobal pMac)
+{
+
+	cfg_set_int(pMac, WNI_CFG_FRAGMENTATION_THRESHOLD,
+			csr_get_frag_thresh(pMac));
+	cfg_set_int(pMac, WNI_CFG_RTS_THRESHOLD, csr_get_rts_thresh(pMac));
+	cfg_set_int(pMac, WNI_CFG_11D_ENABLED,
+			((pMac->roam.configParam.Is11hSupportEnabled) ? pMac->roam.
+			 configParam.Is11dSupportEnabled : pMac->roam.configParam.
+			 Is11dSupportEnabled));
+	cfg_set_int(pMac, WNI_CFG_11H_ENABLED,
+			pMac->roam.configParam.Is11hSupportEnabled);
+	/* For now we will just use the 5GHz CB mode ini parameter to decide whether CB supported or not in Probes when there is no session
+	 * Once session is established we will use the session related params stored in PE session for CB mode
+	 */
+	cfg_set_int(pMac, WNI_CFG_CHANNEL_BONDING_MODE,
+			!!(pMac->roam.configParam.channelBondingMode5GHz));
+	cfg_set_int(pMac, WNI_CFG_HEART_BEAT_THRESHOLD,
+			pMac->roam.configParam.HeartbeatThresh24);
+
+	/* Update the operating mode to configured value during initialization, */
+	/* So that client can advertise full capabilities in Probe request frame. */
+	csr_set_default_dot11_mode(pMac);
+}
+
+CDF_STATUS csr_roam_open(tpAniSirGlobal pMac)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	uint32_t i;
+	tCsrRoamSession *pSession;
+	do {
+		for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
+			pSession = CSR_GET_SESSION(pMac, i);
+			pSession->roamingTimerInfo.pMac = pMac;
+			pSession->roamingTimerInfo.sessionId =
+				CSR_SESSION_ID_INVALID;
+		}
+		pMac->roam.WaitForKeyTimerInfo.pMac = pMac;
+		pMac->roam.WaitForKeyTimerInfo.sessionId =
+			CSR_SESSION_ID_INVALID;
+		status =
+			cdf_mc_timer_init(&pMac->roam.hTimerWaitForKey,
+					  CDF_TIMER_TYPE_SW,
+					  csr_roam_wait_for_key_time_out_handler,
+					  &pMac->roam.WaitForKeyTimerInfo);
+		if (!CDF_IS_STATUS_SUCCESS(status)) {
+			sms_log(pMac, LOGE,
+				FL
+					("cannot allocate memory for WaitForKey time out timer"));
+			break;
+		}
+		status =
+			cdf_mc_timer_init(&pMac->roam.tlStatsReqInfo.hTlStatsTimer,
+					  CDF_TIMER_TYPE_SW,
+					  csr_roam_tl_stats_timer_handler, pMac);
+		if (!CDF_IS_STATUS_SUCCESS(status)) {
+			sms_log(pMac, LOGE,
+				FL
+					("cannot allocate memory for summary Statistics timer"));
+			return CDF_STATUS_E_FAILURE;
+		}
+	} while (0);
+	return status;
+}
+
+CDF_STATUS csr_roam_close(tpAniSirGlobal pMac)
+{
+	uint32_t sessionId;
+	for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++) {
+		csr_roam_close_session(pMac, sessionId, true, NULL, NULL);
+	}
+	cdf_mc_timer_stop(&pMac->roam.hTimerWaitForKey);
+	cdf_mc_timer_destroy(&pMac->roam.hTimerWaitForKey);
+	cdf_mc_timer_stop(&pMac->roam.tlStatsReqInfo.hTlStatsTimer);
+	cdf_mc_timer_destroy(&pMac->roam.tlStatsReqInfo.hTlStatsTimer);
+	return CDF_STATUS_SUCCESS;
+}
+
+CDF_STATUS csr_roam_start(tpAniSirGlobal pMac)
+{
+	(void)pMac;
+	return CDF_STATUS_SUCCESS;
+}
+
+void csr_roam_stop(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	csr_roam_stop_roaming_timer(pMac, sessionId);
+	/* deregister the clients requesting stats from PE/TL & also stop the corresponding timers */
+	csr_roam_dereg_statistics_req(pMac);
+}
+
+CDF_STATUS csr_roam_get_connect_state(tpAniSirGlobal pMac, uint32_t sessionId,
+				      eCsrConnectState *pState)
+{
+	CDF_STATUS status = CDF_STATUS_E_INVAL;
+	if (CSR_IS_SESSION_VALID(pMac, sessionId) && (NULL != pState)) {
+		status = CDF_STATUS_SUCCESS;
+		*pState = pMac->roam.roamSession[sessionId].connectState;
+	}
+	return status;
+}
+
+CDF_STATUS csr_roam_copy_connect_profile(tpAniSirGlobal pMac,
+			uint32_t sessionId, tCsrRoamConnectedProfile *pProfile)
+{
+	CDF_STATUS status = CDF_STATUS_E_FAILURE;
+	uint32_t size = 0;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+	tCsrRoamConnectedProfile *connected_prof;
+
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("  session %d not found "), sessionId);
+		return CDF_STATUS_E_FAILURE;
+	}
+	if (!pProfile) {
+		sms_log(pMac, LOGE, FL("profile not found"));
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	if (pSession->pConnectBssDesc) {
+		size = pSession->pConnectBssDesc->length +
+			sizeof(pSession->pConnectBssDesc->length);
+		if (size) {
+			pProfile->pBssDesc = cdf_mem_malloc(size);
+			if (NULL != pProfile->pBssDesc) {
+				cdf_mem_copy(pProfile->pBssDesc,
+					pSession->pConnectBssDesc,
+					size);
+				status = CDF_STATUS_SUCCESS;
+			} else {
+				return CDF_STATUS_E_FAILURE;
+			}
+		} else {
+			pProfile->pBssDesc = NULL;
+		}
+		connected_prof = &(pSession->connectedProfile);
+		pProfile->AuthType = connected_prof->AuthType;
+		pProfile->EncryptionType = connected_prof->EncryptionType;
+		pProfile->mcEncryptionType = connected_prof->mcEncryptionType;
+		pProfile->BSSType = connected_prof->BSSType;
+		pProfile->operationChannel = connected_prof->operationChannel;
+		pProfile->CBMode = connected_prof->CBMode;
+		cdf_mem_copy(&pProfile->bssid, &connected_prof->bssid,
+			sizeof(struct cdf_mac_addr));
+		cdf_mem_copy(&pProfile->SSID, &connected_prof->SSID,
+			sizeof(tSirMacSSid));
+#ifdef WLAN_FEATURE_VOWIFI_11R
+		if (connected_prof->MDID.mdiePresent) {
+			pProfile->MDID.mdiePresent = 1;
+			pProfile->MDID.mobilityDomain =
+				connected_prof->MDID.mobilityDomain;
+		} else {
+			pProfile->MDID.mdiePresent = 0;
+			pProfile->MDID.mobilityDomain = 0;
+		}
+#endif
+#ifdef FEATURE_WLAN_ESE
+		pProfile->isESEAssoc = connected_prof->isESEAssoc;
+		if (csr_is_auth_type_ese(connected_prof->AuthType)) {
+			cdf_mem_copy(pProfile->eseCckmInfo.krk,
+				connected_prof->eseCckmInfo.krk,
+				SIR_KRK_KEY_LEN);
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+			cdf_mem_copy(pProfile->eseCckmInfo.btk,
+				connected_prof->eseCckmInfo.btk,
+				SIR_BTK_KEY_LEN);
+#endif
+			pProfile->eseCckmInfo.reassoc_req_num =
+				connected_prof->eseCckmInfo.reassoc_req_num;
+			pProfile->eseCckmInfo.krk_plumbed =
+				connected_prof->eseCckmInfo.krk_plumbed;
+		}
+#endif
+	}
+	return status;
+}
+
+CDF_STATUS csr_roam_get_connect_profile(tpAniSirGlobal pMac, uint32_t sessionId,
+					tCsrRoamConnectedProfile *pProfile)
+{
+	CDF_STATUS status = CDF_STATUS_E_FAILURE;
+
+	if ((csr_is_conn_state_connected(pMac, sessionId)) ||
+	    (csr_is_conn_state_ibss(pMac, sessionId))) {
+		if (pProfile) {
+			status =
+				csr_roam_copy_connect_profile(pMac, sessionId,
+							      pProfile);
+		}
+	}
+	return status;
+}
+
+CDF_STATUS csr_roam_free_connect_profile(tpAniSirGlobal pMac,
+					 tCsrRoamConnectedProfile *pProfile)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+
+	if (pProfile->pBssDesc) {
+		cdf_mem_free(pProfile->pBssDesc);
+	}
+	if (pProfile->pAddIEAssoc) {
+		cdf_mem_free(pProfile->pAddIEAssoc);
+	}
+	cdf_mem_set(pProfile, sizeof(tCsrRoamConnectedProfile), 0);
+
+	pProfile->AuthType = eCSR_AUTH_TYPE_UNKNOWN;
+	return status;
+}
+
+static CDF_STATUS csr_roam_free_connected_info(tpAniSirGlobal pMac,
+					       tCsrRoamConnectedInfo *
+					       pConnectedInfo)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	if (pConnectedInfo->pbFrames) {
+		cdf_mem_free(pConnectedInfo->pbFrames);
+		pConnectedInfo->pbFrames = NULL;
+	}
+	pConnectedInfo->nBeaconLength = 0;
+	pConnectedInfo->nAssocReqLength = 0;
+	pConnectedInfo->nAssocRspLength = 0;
+	pConnectedInfo->staId = 0;
+#ifdef WLAN_FEATURE_VOWIFI_11R
+	pConnectedInfo->nRICRspLength = 0;
+#endif
+#ifdef FEATURE_WLAN_ESE
+	pConnectedInfo->nTspecIeLength = 0;
+#endif
+	return status;
+}
+
+void csr_release_command_preauth(tpAniSirGlobal pMac, tSmeCmd *pCommand)
+{
+	csr_reinit_preauth_cmd(pMac, pCommand);
+	csr_release_command(pMac, pCommand);
+}
+
+void csr_release_command_roam(tpAniSirGlobal pMac, tSmeCmd *pCommand)
+{
+	csr_reinit_roam_cmd(pMac, pCommand);
+	csr_release_command(pMac, pCommand);
+}
+
+void csr_release_command_scan(tpAniSirGlobal pMac, tSmeCmd *pCommand)
+{
+	cdf_mc_timer_stop(&pCommand->u.scanCmd.csr_scan_timer);
+	cdf_mc_timer_destroy(&pCommand->u.scanCmd.csr_scan_timer);
+	csr_reinit_scan_cmd(pMac, pCommand);
+	csr_release_command(pMac, pCommand);
+}
+
+void csr_release_command_wm_status_change(tpAniSirGlobal pMac, tSmeCmd *pCommand)
+{
+	csr_reinit_wm_status_change_cmd(pMac, pCommand);
+	csr_release_command(pMac, pCommand);
+}
+
+void csr_reinit_set_key_cmd(tpAniSirGlobal pMac, tSmeCmd *pCommand)
+{
+	cdf_mem_set(&pCommand->u.setKeyCmd, sizeof(tSetKeyCmd), 0);
+}
+
+void csr_release_command_set_key(tpAniSirGlobal pMac, tSmeCmd *pCommand)
+{
+	csr_reinit_set_key_cmd(pMac, pCommand);
+	csr_release_command(pMac, pCommand);
+}
+
+/**
+ * csr_release_roc_req_cmd() - Release the command
+ * @mac_ctx: Global MAC Context
+ *
+ * Release the remain on channel request command from the queue
+ *
+ * Return: None
+ */
+void csr_release_roc_req_cmd(tpAniSirGlobal mac_ctx)
+{
+	tListElem *entry;
+	tSmeCmd *cmd = NULL;
+
+	entry = csr_ll_peek_head(&mac_ctx->sme.smeCmdActiveList,
+			LL_ACCESS_LOCK);
+	if (entry) {
+		cmd = GET_BASE_ADDR(entry, tSmeCmd, Link);
+		if (eSmeCommandRemainOnChannel == cmd->command) {
+			remainOnChanCallback callback =
+				cmd->u.remainChlCmd.callback;
+			/* process the msg */
+			if (callback)
+				callback(mac_ctx,
+					cmd->u.remainChlCmd.callbackCtx, 0,
+					cmd->u.remainChlCmd.scan_id);
+			sms_log(mac_ctx, LOGE,
+				FL("Remove RoC Request from Active Cmd List"));
+			/* Put this cmd back on the available command list */
+			if (csr_ll_remove_entry(&mac_ctx->sme.smeCmdActiveList,
+						entry, LL_ACCESS_LOCK))
+				sme_release_command(mac_ctx, cmd);
+		}
+	}
+}
+
+void csr_abort_command(tpAniSirGlobal pMac, tSmeCmd *pCommand, bool fStopping)
+{
+
+	if (eSmeCsrCommandMask & pCommand->command) {
+		switch (pCommand->command) {
+		case eSmeCommandScan:
+			/* We need to inform the requester before dropping the scan command */
+			sms_log(pMac, LOGW,
+				"%s: Drop scan reason %d callback %p", __func__,
+				pCommand->u.scanCmd.reason,
+				pCommand->u.scanCmd.callback);
+			if (NULL != pCommand->u.scanCmd.callback) {
+				sms_log(pMac, LOGW, "%s callback scan requester",
+					__func__);
+				csr_scan_call_callback(pMac, pCommand,
+						       eCSR_SCAN_ABORT);
+			}
+			csr_release_command_scan(pMac, pCommand);
+			break;
+		case eSmeCommandRoam:
+			csr_release_command_roam(pMac, pCommand);
+			break;
+
+		case eSmeCommandWmStatusChange:
+			csr_release_command_wm_status_change(pMac, pCommand);
+			break;
+
+		case eSmeCommandSetKey:
+			csr_release_command_set_key(pMac, pCommand);
+			break;
+
+		default:
+			sms_log(pMac, LOGW, " CSR abort standard command %d",
+				pCommand->command);
+			csr_release_command(pMac, pCommand);
+			break;
+		}
+	}
+}
+
+void csr_roam_substate_change(tpAniSirGlobal pMac, eCsrRoamSubState NewSubstate,
+			      uint32_t sessionId)
+{
+	sms_log(pMac, LOG1, FL("CSR RoamSubstate: [ %s <== %s ]"),
+		mac_trace_getcsr_roam_sub_state(NewSubstate),
+		mac_trace_getcsr_roam_sub_state(pMac->roam.curSubState[sessionId]));
+	if (pMac->roam.curSubState[sessionId] == NewSubstate) {
+		return;
+	}
+	pMac->roam.curSubState[sessionId] = NewSubstate;
+}
+
+eCsrRoamState csr_roam_state_change(tpAniSirGlobal pMac,
+				    eCsrRoamState NewRoamState, uint8_t sessionId)
+{
+	eCsrRoamState PreviousState;
+
+	sms_log(pMac, LOG1, FL("CSR RoamState[%hu]: [ %s <== %s ]"), sessionId,
+		mac_trace_getcsr_roam_state(NewRoamState),
+		mac_trace_getcsr_roam_state(pMac->roam.curState[sessionId]));
+	PreviousState = pMac->roam.curState[sessionId];
+
+	if (NewRoamState != pMac->roam.curState[sessionId]) {
+		/* Whenever we transition OUT of the Roaming state, clear the Roaming substate... */
+		if (CSR_IS_ROAM_JOINING(pMac, sessionId)) {
+			csr_roam_substate_change(pMac, eCSR_ROAM_SUBSTATE_NONE,
+						 sessionId);
+		}
+
+		pMac->roam.curState[sessionId] = NewRoamState;
+	}
+	return PreviousState;
+}
+
+void csr_assign_rssi_for_category(tpAniSirGlobal pMac, int8_t bestApRssi,
+				  uint8_t catOffset)
+{
+	int i;
+	if (catOffset) {
+		pMac->roam.configParam.bCatRssiOffset = catOffset;
+		for (i = 0; i < CSR_NUM_RSSI_CAT; i++) {
+			pMac->roam.configParam.RSSICat[CSR_NUM_RSSI_CAT - i -
+						       1] =
+				(int)bestApRssi -
+				pMac->roam.configParam.nSelect5GHzMargin -
+				(int)(i * catOffset);
+		}
+	}
+}
+
+static void init_config_param(tpAniSirGlobal pMac)
+{
+	int i;
+	pMac->roam.configParam.agingCount = CSR_AGING_COUNT;
+	pMac->roam.configParam.channelBondingMode24GHz =
+		WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
+	pMac->roam.configParam.channelBondingMode5GHz =
+		WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
+
+	pMac->roam.configParam.phyMode = eCSR_DOT11_MODE_AUTO;
+	pMac->roam.configParam.eBand = eCSR_BAND_ALL;
+	pMac->roam.configParam.uCfgDot11Mode = eCSR_CFG_DOT11_MODE_AUTO;
+	pMac->roam.configParam.FragmentationThreshold =
+		eCSR_DOT11_FRAG_THRESH_DEFAULT;
+	pMac->roam.configParam.HeartbeatThresh24 = 40;
+	pMac->roam.configParam.HeartbeatThresh50 = 40;
+	pMac->roam.configParam.Is11dSupportEnabled = false;
+	pMac->roam.configParam.Is11dSupportEnabledOriginal = false;
+	pMac->roam.configParam.Is11eSupportEnabled = true;
+	pMac->roam.configParam.Is11hSupportEnabled = true;
+	pMac->roam.configParam.RTSThreshold = 2346;
+	pMac->roam.configParam.shortSlotTime = true;
+	pMac->roam.configParam.WMMSupportMode = eCsrRoamWmmAuto;
+	pMac->roam.configParam.ProprietaryRatesEnabled = true;
+	pMac->roam.configParam.TxRate = eCSR_TX_RATE_AUTO;
+	pMac->roam.configParam.scanAgeTimeNCNPS =
+		CSR_SCAN_AGING_TIME_NOT_CONNECT_NO_PS;
+	pMac->roam.configParam.scanAgeTimeNCPS =
+		CSR_SCAN_AGING_TIME_NOT_CONNECT_W_PS;
+	pMac->roam.configParam.scanAgeTimeCNPS =
+		CSR_SCAN_AGING_TIME_CONNECT_NO_PS;
+	pMac->roam.configParam.scanAgeTimeCPS =
+		CSR_SCAN_AGING_TIME_CONNECT_W_PS;
+	for (i = 0; i < CSR_NUM_RSSI_CAT; i++) {
+		pMac->roam.configParam.BssPreferValue[i] = i;
+	}
+	csr_assign_rssi_for_category(pMac, CSR_BEST_RSSI_VALUE,
+				     CSR_DEFAULT_RSSI_DB_GAP);
+	pMac->roam.configParam.nRoamingTime = CSR_DEFAULT_ROAMING_TIME;
+	pMac->roam.configParam.fSupplicantCountryCodeHasPriority = false;
+	pMac->roam.configParam.nActiveMaxChnTime = CSR_ACTIVE_MAX_CHANNEL_TIME;
+	pMac->roam.configParam.nActiveMinChnTime = CSR_ACTIVE_MIN_CHANNEL_TIME;
+	pMac->roam.configParam.nPassiveMaxChnTime =
+		CSR_PASSIVE_MAX_CHANNEL_TIME;
+	pMac->roam.configParam.nPassiveMinChnTime =
+		CSR_PASSIVE_MIN_CHANNEL_TIME;
+#ifdef WLAN_AP_STA_CONCURRENCY
+	pMac->roam.configParam.nActiveMaxChnTimeConc =
+		CSR_ACTIVE_MAX_CHANNEL_TIME_CONC;
+	pMac->roam.configParam.nActiveMinChnTimeConc =
+		CSR_ACTIVE_MIN_CHANNEL_TIME_CONC;
+	pMac->roam.configParam.nPassiveMaxChnTimeConc =
+		CSR_PASSIVE_MAX_CHANNEL_TIME_CONC;
+	pMac->roam.configParam.nPassiveMinChnTimeConc =
+		CSR_PASSIVE_MIN_CHANNEL_TIME_CONC;
+	pMac->roam.configParam.nRestTimeConc = CSR_REST_TIME_CONC;
+	pMac->roam.configParam.nNumStaChanCombinedConc =
+		CSR_NUM_STA_CHAN_COMBINED_CONC;
+	pMac->roam.configParam.nNumP2PChanCombinedConc =
+		CSR_NUM_P2P_CHAN_COMBINED_CONC;
+#endif
+	pMac->roam.configParam.nTxPowerCap = CSR_MAX_TX_POWER;
+	pMac->roam.configParam.statsReqPeriodicity =
+		CSR_MIN_GLOBAL_STAT_QUERY_PERIOD;
+	pMac->roam.configParam.statsReqPeriodicityInPS =
+		CSR_MIN_GLOBAL_STAT_QUERY_PERIOD_IN_BMPS;
+#ifdef WLAN_FEATURE_VOWIFI_11R
+	pMac->roam.configParam.csr11rConfig.IsFTResourceReqSupported = 0;
+#endif
+#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
+	pMac->roam.configParam.neighborRoamConfig.nMaxNeighborRetries = 3;
+	pMac->roam.configParam.neighborRoamConfig.nNeighborLookupRssiThreshold =
+		120;
+	pMac->roam.configParam.neighborRoamConfig.nOpportunisticThresholdDiff =
+		30;
+	pMac->roam.configParam.neighborRoamConfig.nRoamRescanRssiDiff = 5;
+	pMac->roam.configParam.neighborRoamConfig.nNeighborScanMinChanTime = 20;
+	pMac->roam.configParam.neighborRoamConfig.nNeighborScanMaxChanTime = 40;
+	pMac->roam.configParam.neighborRoamConfig.nNeighborScanTimerPeriod =
+		200;
+	pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.
+	numChannels = 3;
+	pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.
+	channelList[0] = 1;
+	pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.
+	channelList[1] = 6;
+	pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.
+	channelList[2] = 11;
+	pMac->roam.configParam.neighborRoamConfig.nNeighborResultsRefreshPeriod = 20000;        /* 20 seconds */
+	pMac->roam.configParam.neighborRoamConfig.nEmptyScanRefreshPeriod = 0;
+	pMac->roam.configParam.neighborRoamConfig.nRoamBmissFirstBcnt = 10;
+	pMac->roam.configParam.neighborRoamConfig.nRoamBmissFinalBcnt = 10;
+	pMac->roam.configParam.neighborRoamConfig.nRoamBeaconRssiWeight = 14;
+#endif
+#ifdef WLAN_FEATURE_11AC
+	pMac->roam.configParam.nVhtChannelWidth =
+		WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ + 1;
+#endif
+
+	pMac->roam.configParam.addTSWhenACMIsOff = 0;
+	pMac->roam.configParam.fScanTwice = false;
+
+	/* Remove this code once SLM_Sessionization is supported */
+	/* BMPS_WORKAROUND_NOT_NEEDED */
+	pMac->roam.configParam.doBMPSWorkaround = 0;
+
+	pMac->roam.configParam.nInitialDwellTime = 0;
+	pMac->roam.configParam.initial_scan_no_dfs_chnl = 0;
+}
+
+eCsrBand csr_get_current_band(tHalHandle hHal)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	return pMac->roam.configParam.bandCapability;
+}
+
+#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
+/*
+   This function flushes the roam scan cache
+ */
+CDF_STATUS csr_flush_roam_scan_roam_channel_list(tpAniSirGlobal pMac,
+						 uint8_t sessionId)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo
+		= &pMac->roam.neighborRoamInfo[sessionId];
+	/* Free up the memory first (if required) */
+	if (NULL !=
+	    pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.
+	    ChannelList) {
+		cdf_mem_free(pNeighborRoamInfo->roamChannelInfo.
+			     currentChannelListInfo.ChannelList);
+		pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.
+		ChannelList = NULL;
+		pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.
+		numOfChannels = 0;
+	}
+	return status;
+}
+#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
+
+#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
+/*
+   This function flushes the roam scan cache
+ */
+CDF_STATUS csr_flush_cfg_bg_scan_roam_channel_list(tpAniSirGlobal pMac,
+						   uint8_t sessionId)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+		&pMac->roam.neighborRoamInfo[sessionId];
+
+	/* Free up the memory first (if required) */
+	if (NULL != pNeighborRoamInfo->cfgParams.channelInfo.ChannelList) {
+		cdf_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.
+			     ChannelList);
+		pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL;
+		pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels = 0;
+	}
+	return status;
+}
+
+/*
+   This function flushes the roam scan cache and creates fresh cache
+   based on the input channel list
+ */
+CDF_STATUS csr_create_bg_scan_roam_channel_list(tpAniSirGlobal pMac,
+						uint8_t sessionId,
+						const uint8_t *pChannelList,
+						const uint8_t numChannels)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+		&pMac->roam.neighborRoamInfo[sessionId];
+
+	pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels = numChannels;
+
+	pNeighborRoamInfo->cfgParams.channelInfo.ChannelList =
+		cdf_mem_malloc(pNeighborRoamInfo->cfgParams.channelInfo.
+			       numOfChannels);
+
+	if (NULL == pNeighborRoamInfo->cfgParams.channelInfo.ChannelList) {
+		sms_log(pMac, LOGE,
+			FL("Memory Allocation for CFG Channel List failed"));
+		pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels = 0;
+		return CDF_STATUS_E_NOMEM;
+	}
+
+	/* Update the roam global structure */
+	cdf_mem_copy(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList,
+		     pChannelList,
+		     pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels);
+	return status;
+}
+
+#endif
+
+#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
+/*
+ * This function modifies the roam scan channel list as per AP neighbor
+ * report; AP neighbor report may be empty or may include only other AP
+ * channels; in any case, we merge the channel list with the learned occupied
+ * channels list.
+ * if the band is 2.4G, then make sure channel list contains only 2.4G
+ * valid channels if the band is 5G, then make sure channel list contains
+ * only 5G valid channels
+ */
+CDF_STATUS csr_create_roam_scan_channel_list(tpAniSirGlobal pMac,
+					     uint8_t sessionId,
+					     uint8_t *pChannelList,
+					     uint8_t numChannels,
+					     const eCsrBand eBand)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo
+		= &pMac->roam.neighborRoamInfo[sessionId];
+	uint8_t outNumChannels = 0;
+	uint8_t inNumChannels = numChannels;
+	uint8_t *inPtr = pChannelList;
+	uint8_t i = 0;
+	uint8_t ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = { 0 };
+	uint8_t tmpChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = { 0 };
+	uint8_t mergedOutputNumOfChannels = 0;
+	tpCsrChannelInfo currChannelListInfo
+		= &pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo;
+	/*
+	 * Create a Union of occupied channel list learnt by the DUT along
+	 * with the Neighbor report Channels. This increases the chances of
+	 * the DUT to get a candidate AP while roaming even if the Neighbor
+	 * Report is not able to provide sufficient information.
+	 */
+	if (pMac->scan.occupiedChannels[sessionId].numChannels) {
+		csr_neighbor_roam_merge_channel_lists(pMac,
+						      &pMac->scan.
+						      occupiedChannels[sessionId].
+						      channelList[0],
+						      pMac->scan.
+						      occupiedChannels[sessionId].
+						      numChannels, inPtr,
+						      inNumChannels,
+						      &mergedOutputNumOfChannels);
+		inNumChannels = mergedOutputNumOfChannels;
+	}
+	if (eCSR_BAND_24 == eBand) {
+		for (i = 0; i < inNumChannels; i++) {
+			if (CDS_IS_CHANNEL_24GHZ(inPtr[i])
+			    && csr_roam_is_channel_valid(pMac, inPtr[i])) {
+				ChannelList[outNumChannels++] = inPtr[i];
+			}
+		}
+	} else if (eCSR_BAND_5G == eBand) {
+		for (i = 0; i < inNumChannels; i++) {
+			/* Add 5G Non-DFS channel */
+			if (CDS_IS_CHANNEL_5GHZ(inPtr[i]) &&
+			    csr_roam_is_channel_valid(pMac, inPtr[i]) &&
+			    !CDS_IS_DFS_CH(inPtr[i])) {
+				ChannelList[outNumChannels++] = inPtr[i];
+			}
+		}
+	} else if (eCSR_BAND_ALL == eBand) {
+		for (i = 0; i < inNumChannels; i++) {
+			if (csr_roam_is_channel_valid(pMac, inPtr[i]) &&
+			    !CDS_IS_DFS_CH(inPtr[i])) {
+				ChannelList[outNumChannels++] = inPtr[i];
+			}
+		}
+	} else {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_WARN,
+			  "Invalid band, No operation carried out (Band %d)",
+			  eBand);
+		return CDF_STATUS_E_INVAL;
+	}
+	/*
+	 * if roaming within band is enabled, then select only the
+	 * in band channels .
+	 * This is required only if the band capability is set to ALL,
+	 * E.g., if band capability is only 2.4G then all the channels in the
+	 * list are already filtered for 2.4G channels, hence ignore this check
+	 */
+	if ((eCSR_BAND_ALL == eBand) && CSR_IS_ROAM_INTRA_BAND_ENABLED(pMac)) {
+		csr_neighbor_roam_channels_filter_by_current_band(pMac,
+								  sessionId,
+								  ChannelList,
+								  outNumChannels,
+								  tmpChannelList,
+								  &outNumChannels);
+		cdf_mem_copy(ChannelList, tmpChannelList, outNumChannels);
+	}
+	/* Prepare final roam scan channel list */
+	if (outNumChannels) {
+		/* Clear the channel list first */
+		if (NULL != currChannelListInfo->ChannelList) {
+			cdf_mem_free(currChannelListInfo->ChannelList);
+			currChannelListInfo->ChannelList = NULL;
+			currChannelListInfo->numOfChannels = 0;
+		}
+		currChannelListInfo->ChannelList
+			= cdf_mem_malloc(outNumChannels * sizeof(uint8_t));
+		if (NULL == currChannelListInfo->ChannelList) {
+			CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_FATAL,
+				  "Failed to allocate memory for roam scan channel list");
+			currChannelListInfo->numOfChannels = 0;
+			return CDF_STATUS_E_NOMEM;
+		}
+		cdf_mem_copy(currChannelListInfo->ChannelList,
+			     ChannelList, outNumChannels);
+	}
+	return status;
+}
+#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
+
+CDF_STATUS csr_set_band(tHalHandle hHal, uint8_t sessionId, eCsrBand eBand)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	if (CSR_IS_PHY_MODE_A_ONLY(pMac) && (eBand == eCSR_BAND_24)) {
+		/* DOT11 mode configured to 11a only and received
+		   request to change the band to 2.4 GHz */
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+			  "failed to set band cfg80211 = %u, band = %u",
+			  pMac->roam.configParam.uCfgDot11Mode, eBand);
+		return CDF_STATUS_E_INVAL;
+	}
+	if ((CSR_IS_PHY_MODE_B_ONLY(pMac) ||
+	     CSR_IS_PHY_MODE_G_ONLY(pMac)) && (eBand == eCSR_BAND_5G)) {
+		/* DOT11 mode configured to 11b/11g only and received
+		   request to change the band to 5 GHz */
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+			  "failed to set band dot11mode = %u, band = %u",
+			  pMac->roam.configParam.uCfgDot11Mode, eBand);
+		return CDF_STATUS_E_INVAL;
+	}
+	CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
+		  "Band changed to %u (0 - ALL, 1 - 2.4 GHZ, 2 - 5GHZ)", eBand);
+	pMac->roam.configParam.eBand = eBand;
+	pMac->roam.configParam.bandCapability = eBand;
+
+	status = csr_get_channel_and_power_list(pMac);
+	if (CDF_STATUS_SUCCESS == status)
+		csr_apply_channel_and_power_list(pMac);
+	return status;
+}
+
+/* The funcns csr_convert_cb_ini_value_to_phy_cb_state and csr_convert_phy_cb_state_to_ini_value have been
+ * introduced to convert the ini value to the ENUM used in csr and MAC for CB state
+ * Ideally we should have kept the ini value and enum value same and representing the same
+ * cb values as in 11n standard i.e.
+ * Set to 1 (SCA) if the secondary channel is above the primary channel
+ * Set to 3 (SCB) if the secondary channel is below the primary channel
+ * Set to 0 (SCN) if no secondary channel is present
+ * However, since our driver is already distributed we will keep the ini definition as it is which is:
+ * 0 - secondary none
+ * 1 - secondary LOW
+ * 2 - secondary HIGH
+ * and convert to enum value used within the driver in csr_change_default_config_param using this funcn
+ * The enum values are as follows:
+ * PHY_SINGLE_CHANNEL_CENTERED          = 0
+ * PHY_DOUBLE_CHANNEL_LOW_PRIMARY   = 1
+ * PHY_DOUBLE_CHANNEL_HIGH_PRIMARY  = 3
+ */
+ePhyChanBondState csr_convert_cb_ini_value_to_phy_cb_state(uint32_t cbIniValue)
+{
+
+	ePhyChanBondState phyCbState;
+	switch (cbIniValue) {
+	/* secondary none */
+	case eCSR_INI_SINGLE_CHANNEL_CENTERED:
+		phyCbState = PHY_SINGLE_CHANNEL_CENTERED;
+		break;
+	/* secondary LOW */
+	case eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY:
+		phyCbState = PHY_DOUBLE_CHANNEL_HIGH_PRIMARY;
+		break;
+	/* secondary HIGH */
+	case eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY:
+		phyCbState = PHY_DOUBLE_CHANNEL_LOW_PRIMARY;
+		break;
+#ifdef WLAN_FEATURE_11AC
+	case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED:
+		phyCbState = PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED;
+		break;
+	case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED:
+		phyCbState =
+			PHY_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED;
+		break;
+	case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED:
+		phyCbState = PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED;
+		break;
+	case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW:
+		phyCbState = PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW;
+		break;
+	case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW:
+		phyCbState = PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW;
+		break;
+	case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH:
+		phyCbState = PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH;
+		break;
+	case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH:
+		phyCbState = PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH;
+		break;
+#endif
+	default:
+		/* If an invalid value is passed, disable CHANNEL BONDING */
+		phyCbState = PHY_SINGLE_CHANNEL_CENTERED;
+		break;
+	}
+	return phyCbState;
+}
+
+uint32_t csr_convert_phy_cb_state_to_ini_value(ePhyChanBondState phyCbState)
+{
+
+	uint32_t cbIniValue;
+	switch (phyCbState) {
+	/* secondary none */
+	case PHY_SINGLE_CHANNEL_CENTERED:
+		cbIniValue = eCSR_INI_SINGLE_CHANNEL_CENTERED;
+		break;
+	/* secondary LOW */
+	case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
+		cbIniValue = eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY;
+		break;
+	/* secondary HIGH */
+	case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
+		cbIniValue = eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY;
+		break;
+#ifdef WLAN_FEATURE_11AC
+	case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED:
+		cbIniValue =
+			eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED;
+		break;
+	case PHY_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED:
+		cbIniValue =
+			eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED;
+		break;
+	case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED:
+		cbIniValue =
+			eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED;
+		break;
+	case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW:
+		cbIniValue = eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW;
+		break;
+	case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW:
+		cbIniValue = eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW;
+		break;
+	case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH:
+		cbIniValue = eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH;
+		break;
+	case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH:
+		cbIniValue = eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH;
+		break;
+#endif
+	default:
+		/* return some invalid value */
+		cbIniValue = eCSR_INI_CHANNEL_BONDING_STATE_MAX;
+		break;
+	}
+	return cbIniValue;
+}
+
+CDF_STATUS csr_change_default_config_param(tpAniSirGlobal pMac,
+					   tCsrConfigParam *pParam)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+
+	if (pParam) {
+		pMac->roam.configParam.WMMSupportMode = pParam->WMMSupportMode;
+		cfg_set_int(pMac, WNI_CFG_WME_ENABLED,
+			(pParam->WMMSupportMode == eCsrRoamWmmNoQos) ? 0 : 1);
+		pMac->roam.configParam.Is11eSupportEnabled =
+			pParam->Is11eSupportEnabled;
+		pMac->roam.configParam.FragmentationThreshold =
+			pParam->FragmentationThreshold;
+		pMac->roam.configParam.Is11dSupportEnabled =
+			pParam->Is11dSupportEnabled;
+		pMac->roam.configParam.Is11dSupportEnabledOriginal =
+			pParam->Is11dSupportEnabled;
+		pMac->roam.configParam.Is11hSupportEnabled =
+			pParam->Is11hSupportEnabled;
+
+		pMac->roam.configParam.fenableMCCMode = pParam->fEnableMCCMode;
+		pMac->roam.configParam.mcc_rts_cts_prot_enable =
+						pParam->mcc_rts_cts_prot_enable;
+		pMac->roam.configParam.mcc_bcast_prob_resp_enable =
+					pParam->mcc_bcast_prob_resp_enable;
+		pMac->roam.configParam.fAllowMCCGODiffBI =
+			pParam->fAllowMCCGODiffBI;
+
+		/* channelBondingMode5GHz plays a dual role right now
+		 * INFRA STA will use this non zero value as CB enabled and SOFTAP will use this non-zero value to determine the secondary channel offset
+		 * This is how channelBondingMode5GHz works now and this is kept intact to avoid any cfg.ini change
+		 */
+		if (pParam->channelBondingMode24GHz > MAX_CB_VALUE_IN_INI) {
+			sms_log(pMac, LOGW,
+				"Invalid CB value from ini in 2.4GHz band %d, CB DISABLED",
+				pParam->channelBondingMode24GHz);
+		}
+		pMac->roam.configParam.channelBondingMode24GHz =
+			csr_convert_cb_ini_value_to_phy_cb_state(pParam->
+								 channelBondingMode24GHz);
+		if (pParam->channelBondingMode5GHz > MAX_CB_VALUE_IN_INI) {
+			sms_log(pMac, LOGW,
+				"Invalid CB value from ini in 5GHz band %d, CB DISABLED",
+				pParam->channelBondingMode5GHz);
+		}
+		pMac->roam.configParam.channelBondingMode5GHz =
+			csr_convert_cb_ini_value_to_phy_cb_state(pParam->
+								 channelBondingMode5GHz);
+		pMac->roam.configParam.RTSThreshold = pParam->RTSThreshold;
+		pMac->roam.configParam.phyMode = pParam->phyMode;
+		pMac->roam.configParam.shortSlotTime = pParam->shortSlotTime;
+		pMac->roam.configParam.HeartbeatThresh24 =
+			pParam->HeartbeatThresh24;
+		pMac->roam.configParam.HeartbeatThresh50 =
+			pParam->HeartbeatThresh50;
+		pMac->roam.configParam.ProprietaryRatesEnabled =
+			pParam->ProprietaryRatesEnabled;
+		pMac->roam.configParam.TxRate = pParam->TxRate;
+		pMac->roam.configParam.AdHocChannel24 = pParam->AdHocChannel24;
+		pMac->roam.configParam.AdHocChannel5G = pParam->AdHocChannel5G;
+		pMac->roam.configParam.bandCapability = pParam->bandCapability;
+		pMac->roam.configParam.cbChoice = pParam->cbChoice;
+		pMac->roam.configParam.neighborRoamConfig.
+			delay_before_vdev_stop =
+			pParam->neighborRoamConfig.delay_before_vdev_stop;
+
+		/* if HDD passed down non zero values then only update, */
+		/* otherwise keep using the defaults */
+		if (pParam->initial_scan_no_dfs_chnl) {
+			pMac->roam.configParam.initial_scan_no_dfs_chnl =
+				pParam->initial_scan_no_dfs_chnl;
+		}
+		if (pParam->nInitialDwellTime) {
+			pMac->roam.configParam.nInitialDwellTime =
+				pParam->nInitialDwellTime;
+		}
+		if (pParam->nActiveMaxChnTime) {
+			pMac->roam.configParam.nActiveMaxChnTime =
+				pParam->nActiveMaxChnTime;
+			cfg_set_int(pMac, WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME,
+				    pParam->nActiveMaxChnTime);
+		}
+		if (pParam->nActiveMinChnTime) {
+			pMac->roam.configParam.nActiveMinChnTime =
+				pParam->nActiveMinChnTime;
+			cfg_set_int(pMac, WNI_CFG_ACTIVE_MINIMUM_CHANNEL_TIME,
+				    pParam->nActiveMinChnTime);
+		}
+		if (pParam->nPassiveMaxChnTime) {
+			pMac->roam.configParam.nPassiveMaxChnTime =
+				pParam->nPassiveMaxChnTime;
+			cfg_set_int(pMac, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME,
+				    pParam->nPassiveMaxChnTime);
+		}
+		if (pParam->nPassiveMinChnTime) {
+			pMac->roam.configParam.nPassiveMinChnTime =
+				pParam->nPassiveMinChnTime;
+			cfg_set_int(pMac, WNI_CFG_PASSIVE_MINIMUM_CHANNEL_TIME,
+				    pParam->nPassiveMinChnTime);
+		}
+#ifdef WLAN_AP_STA_CONCURRENCY
+		if (pParam->nActiveMaxChnTimeConc) {
+			pMac->roam.configParam.nActiveMaxChnTimeConc =
+				pParam->nActiveMaxChnTimeConc;
+		}
+		if (pParam->nActiveMinChnTimeConc) {
+			pMac->roam.configParam.nActiveMinChnTimeConc =
+				pParam->nActiveMinChnTimeConc;
+		}
+		if (pParam->nPassiveMaxChnTimeConc) {
+			pMac->roam.configParam.nPassiveMaxChnTimeConc =
+				pParam->nPassiveMaxChnTimeConc;
+		}
+		if (pParam->nPassiveMinChnTimeConc) {
+			pMac->roam.configParam.nPassiveMinChnTimeConc =
+				pParam->nPassiveMinChnTimeConc;
+		}
+		if (pParam->nRestTimeConc) {
+			pMac->roam.configParam.nRestTimeConc =
+				pParam->nRestTimeConc;
+		}
+		if (pParam->nNumStaChanCombinedConc) {
+			pMac->roam.configParam.nNumStaChanCombinedConc =
+				pParam->nNumStaChanCombinedConc;
+		}
+		if (pParam->nNumP2PChanCombinedConc) {
+			pMac->roam.configParam.nNumP2PChanCombinedConc =
+				pParam->nNumP2PChanCombinedConc;
+		}
+#endif
+		pMac->roam.configParam.eBand = pParam->eBand;
+		pMac->roam.configParam.uCfgDot11Mode =
+			csr_get_cfg_dot11_mode_from_csr_phy_mode(NULL,
+								 pMac->roam.configParam.
+								 phyMode,
+								 pMac->roam.configParam.
+								 ProprietaryRatesEnabled);
+		/* if HDD passed down non zero values for age params, then only update, */
+		/* otherwise keep using the defaults */
+		if (pParam->nScanResultAgeCount) {
+			pMac->roam.configParam.agingCount =
+				pParam->nScanResultAgeCount;
+		}
+		if (pParam->scanAgeTimeNCNPS) {
+			pMac->roam.configParam.scanAgeTimeNCNPS =
+				pParam->scanAgeTimeNCNPS;
+		}
+		if (pParam->scanAgeTimeNCPS) {
+			pMac->roam.configParam.scanAgeTimeNCPS =
+				pParam->scanAgeTimeNCPS;
+		}
+		if (pParam->scanAgeTimeCNPS) {
+			pMac->roam.configParam.scanAgeTimeCNPS =
+				pParam->scanAgeTimeCNPS;
+		}
+		if (pParam->scanAgeTimeCPS) {
+			pMac->roam.configParam.scanAgeTimeCPS =
+				pParam->scanAgeTimeCPS;
+		}
+
+		csr_assign_rssi_for_category(pMac, CSR_BEST_RSSI_VALUE,
+					     pParam->bCatRssiOffset);
+		pMac->roam.configParam.nRoamingTime = pParam->nRoamingTime;
+		pMac->roam.configParam.fSupplicantCountryCodeHasPriority =
+			pParam->fSupplicantCountryCodeHasPriority;
+		pMac->roam.configParam.vccRssiThreshold =
+			pParam->vccRssiThreshold;
+		pMac->roam.configParam.vccUlMacLossThreshold =
+			pParam->vccUlMacLossThreshold;
+		pMac->roam.configParam.statsReqPeriodicity =
+			pParam->statsReqPeriodicity;
+		pMac->roam.configParam.statsReqPeriodicityInPS =
+			pParam->statsReqPeriodicityInPS;
+		/* Assign this before calling csr_init11d_info */
+		pMac->roam.configParam.nTxPowerCap = pParam->nTxPowerCap;
+		if (csr_is11d_supported(pMac)) {
+			status = csr_init11d_info(pMac, &pParam->Csr11dinfo);
+		} else {
+			pMac->scan.curScanType = eSIR_ACTIVE_SCAN;
+		}
+
+		/* Initialize the power + channel information if 11h is enabled.
+		   If 11d is enabled this information has already been initialized */
+		if (csr_is11h_supported(pMac) && !csr_is11d_supported(pMac)) {
+			csr_init_channel_power_list(pMac, &pParam->Csr11dinfo);
+		}
+
+#ifdef WLAN_FEATURE_VOWIFI_11R
+		cdf_mem_copy(&pMac->roam.configParam.csr11rConfig,
+			     &pParam->csr11rConfig,
+			     sizeof(tCsr11rConfigParams));
+		sms_log(pMac, LOG1, "IsFTResourceReqSupp = %d",
+			pMac->roam.configParam.csr11rConfig.
+			IsFTResourceReqSupported);
+#endif
+#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
+		pMac->roam.configParam.isFastTransitionEnabled =
+			pParam->isFastTransitionEnabled;
+		pMac->roam.configParam.RoamRssiDiff = pParam->RoamRssiDiff;
+		pMac->roam.configParam.nRoamPrefer5GHz =
+			pParam->nRoamPrefer5GHz;
+		pMac->roam.configParam.nRoamIntraBand = pParam->nRoamIntraBand;
+		pMac->roam.configParam.isWESModeEnabled =
+			pParam->isWESModeEnabled;
+		pMac->roam.configParam.nProbes = pParam->nProbes;
+		pMac->roam.configParam.nRoamScanHomeAwayTime =
+			pParam->nRoamScanHomeAwayTime;
+#endif
+		pMac->roam.configParam.isRoamOffloadScanEnabled =
+			pParam->isRoamOffloadScanEnabled;
+		pMac->roam.configParam.bFastRoamInConIniFeatureEnabled =
+			pParam->bFastRoamInConIniFeatureEnabled;
+#ifdef FEATURE_WLAN_LFR
+		pMac->roam.configParam.isFastRoamIniFeatureEnabled =
+			pParam->isFastRoamIniFeatureEnabled;
+		pMac->roam.configParam.MAWCEnabled = pParam->MAWCEnabled;
+#endif
+
+#ifdef FEATURE_WLAN_ESE
+		pMac->roam.configParam.isEseIniFeatureEnabled =
+			pParam->isEseIniFeatureEnabled;
+#endif
+#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
+		cdf_mem_copy(&pMac->roam.configParam.neighborRoamConfig,
+			     &pParam->neighborRoamConfig,
+			     sizeof(tCsrNeighborRoamConfigParams));
+		sms_log(pMac, LOG1, "nNeighborScanTimerPerioid = %d",
+			pMac->roam.configParam.neighborRoamConfig.
+			nNeighborScanTimerPeriod);
+		sms_log(pMac, LOG1, "nNeighborLookupRssiThreshold = %d",
+			pMac->roam.configParam.neighborRoamConfig.
+			nNeighborLookupRssiThreshold);
+		sms_log(pMac, LOG1, "nOpportunisticThresholdDiff = %d",
+			pMac->roam.configParam.neighborRoamConfig.
+			nOpportunisticThresholdDiff);
+		sms_log(pMac, LOG1, "nRoamRescanRssiDiff = %d",
+			pMac->roam.configParam.neighborRoamConfig.
+			nRoamRescanRssiDiff);
+		sms_log(pMac, LOG1, "nNeighborScanMinChanTime = %d",
+			pMac->roam.configParam.neighborRoamConfig.
+			nNeighborScanMinChanTime);
+		sms_log(pMac, LOG1, "nNeighborScanMaxChanTime = %d",
+			pMac->roam.configParam.neighborRoamConfig.
+			nNeighborScanMaxChanTime);
+		sms_log(pMac, LOG1, "nMaxNeighborRetries = %d",
+			pMac->roam.configParam.neighborRoamConfig.
+			nMaxNeighborRetries);
+		sms_log(pMac, LOG1, "nNeighborResultsRefreshPeriod = %d",
+			pMac->roam.configParam.neighborRoamConfig.
+			nNeighborResultsRefreshPeriod);
+		sms_log(pMac, LOG1, "nEmptyScanRefreshPeriod = %d",
+			pMac->roam.configParam.neighborRoamConfig.
+			nEmptyScanRefreshPeriod);
+		{
+			int i;
+			sms_log(pMac, LOG1,
+				FL("Num of Channels in CFG Channel List: %d"),
+				pMac->roam.configParam.neighborRoamConfig.
+				neighborScanChanList.numChannels);
+			for (i = 0;
+			     i <
+			     pMac->roam.configParam.neighborRoamConfig.
+			     neighborScanChanList.numChannels; i++) {
+				sms_log(pMac, LOG1, "%d ",
+					pMac->roam.configParam.
+					neighborRoamConfig.neighborScanChanList.
+					channelList[i]);
+			}
+		}
+		sms_log(pMac, LOG1, "nRoamBmissFirstBcnt = %d",
+			pMac->roam.configParam.neighborRoamConfig.
+			nRoamBmissFirstBcnt);
+		sms_log(pMac, LOG1, "nRoamBmissFinalBcnt = %d",
+			pMac->roam.configParam.neighborRoamConfig.
+			nRoamBmissFinalBcnt);
+		sms_log(pMac, LOG1, "nRoamBeaconRssiWeight = %d",
+			pMac->roam.configParam.neighborRoamConfig.
+			nRoamBeaconRssiWeight);
+#endif
+		pMac->roam.configParam.addTSWhenACMIsOff =
+			pParam->addTSWhenACMIsOff;
+		pMac->scan.fValidateList = pParam->fValidateList;
+		pMac->scan.fEnableBypass11d = pParam->fEnableBypass11d;
+		pMac->scan.fEnableDFSChnlScan = pParam->fEnableDFSChnlScan;
+		pMac->scan.scanResultCfgAgingTime = pParam->scanCfgAgingTime;
+		pMac->roam.configParam.fScanTwice = pParam->fScanTwice;
+		pMac->scan.fFirstScanOnly2GChnl = pParam->fFirstScanOnly2GChnl;
+		pMac->scan.max_scan_count = pParam->max_scan_count;
+		/* This parameter is not available in cfg and not passed from upper layers. Instead it is initialized here
+		 * This paramtere is used in concurrency to determine if there are concurrent active sessions.
+		 * Is used as a temporary fix to disconnect all active sessions when BMPS enabled so the active session if Infra STA
+		 * will automatically connect back and resume BMPS since resume BMPS is not working when moving from concurrent to
+		 * single session
+		 */
+		/* Remove this code once SLM_Sessionization is supported */
+		/* BMPS_WORKAROUND_NOT_NEEDED */
+		pMac->roam.configParam.doBMPSWorkaround = 0;
+
+#ifdef WLAN_FEATURE_11AC
+		pMac->roam.configParam.nVhtChannelWidth =
+			pParam->nVhtChannelWidth;
+		pMac->roam.configParam.txBFEnable = pParam->enableTxBF;
+		pMac->roam.configParam.txBFCsnValue = pParam->txBFCsnValue;
+		pMac->roam.configParam.enable2x2 = pParam->enable2x2;
+		pMac->roam.configParam.enableVhtFor24GHz =
+			pParam->enableVhtFor24GHz;
+		pMac->roam.configParam.txMuBformee = pParam->enableMuBformee;
+		pMac->roam.configParam.enableVhtpAid = pParam->enableVhtpAid;
+		pMac->roam.configParam.enableVhtGid = pParam->enableVhtGid;
+#endif
+		pMac->roam.configParam.enableAmpduPs = pParam->enableAmpduPs;
+		pMac->roam.configParam.enableHtSmps = pParam->enableHtSmps;
+		pMac->roam.configParam.htSmps = pParam->htSmps;
+		pMac->roam.configParam.txLdpcEnable = pParam->enableTxLdpc;
+		pMac->roam.configParam.ignore_peer_erp_info =
+			pParam->ignore_peer_erp_info;
+		pMac->roam.configParam.isAmsduSupportInAMPDU =
+			pParam->isAmsduSupportInAMPDU;
+		pMac->roam.configParam.nSelect5GHzMargin =
+			pParam->nSelect5GHzMargin;
+		pMac->roam.configParam.isCoalesingInIBSSAllowed =
+			pParam->isCoalesingInIBSSAllowed;
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+		pMac->roam.configParam.cc_switch_mode = pParam->cc_switch_mode;
+#endif
+		pMac->roam.configParam.allowDFSChannelRoam =
+			pParam->allowDFSChannelRoam;
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+		pMac->roam.configParam.isRoamOffloadEnabled =
+			pParam->isRoamOffloadEnabled;
+#endif
+		pMac->roam.configParam.obssEnabled = pParam->obssEnabled;
+		pMac->roam.configParam.conc_custom_rule1 =
+			pParam->conc_custom_rule1;
+		pMac->roam.configParam.conc_custom_rule2 =
+			pParam->conc_custom_rule2;
+		pMac->roam.configParam.is_sta_connection_in_5gz_enabled =
+			pParam->is_sta_connection_in_5gz_enabled;
+		pMac->roam.configParam.sendDeauthBeforeCon =
+			pParam->sendDeauthBeforeCon;
+
+		pMac->enable_dot11p = pParam->enable_dot11p;
+	}
+
+	return status;
+}
+
+CDF_STATUS csr_get_config_param(tpAniSirGlobal pMac, tCsrConfigParam *pParam)
+{
+	int i;
+	tCsrConfig *cfg_params = &pMac->roam.configParam;
+
+	if (!pParam)
+		return CDF_STATUS_E_INVAL;
+
+	pParam->WMMSupportMode = cfg_params->WMMSupportMode;
+	pParam->Is11eSupportEnabled = cfg_params->Is11eSupportEnabled;
+	pParam->FragmentationThreshold = cfg_params->FragmentationThreshold;
+	pParam->Is11dSupportEnabled = cfg_params->Is11dSupportEnabled;
+	pParam->Is11dSupportEnabledOriginal =
+		cfg_params->Is11dSupportEnabledOriginal;
+	pParam->Is11hSupportEnabled = cfg_params->Is11hSupportEnabled;
+	pParam->channelBondingMode24GHz = csr_convert_phy_cb_state_to_ini_value(
+					cfg_params->channelBondingMode24GHz);
+	pParam->channelBondingMode5GHz = csr_convert_phy_cb_state_to_ini_value(
+					cfg_params->channelBondingMode5GHz);
+	pParam->RTSThreshold = cfg_params->RTSThreshold;
+	pParam->phyMode = cfg_params->phyMode;
+	pParam->shortSlotTime = cfg_params->shortSlotTime;
+	pParam->HeartbeatThresh24 = cfg_params->HeartbeatThresh24;
+	pParam->HeartbeatThresh50 = cfg_params->HeartbeatThresh50;
+	pParam->ProprietaryRatesEnabled = cfg_params->ProprietaryRatesEnabled;
+	pParam->TxRate = cfg_params->TxRate;
+	pParam->AdHocChannel24 = cfg_params->AdHocChannel24;
+	pParam->AdHocChannel5G = cfg_params->AdHocChannel5G;
+	pParam->bandCapability = cfg_params->bandCapability;
+	pParam->cbChoice = cfg_params->cbChoice;
+	pParam->nActiveMaxChnTime = cfg_params->nActiveMaxChnTime;
+	pParam->nActiveMinChnTime = cfg_params->nActiveMinChnTime;
+	pParam->nPassiveMaxChnTime = cfg_params->nPassiveMaxChnTime;
+	pParam->nPassiveMinChnTime = cfg_params->nPassiveMinChnTime;
+#ifdef WLAN_AP_STA_CONCURRENCY
+	pParam->nActiveMaxChnTimeConc = cfg_params->nActiveMaxChnTimeConc;
+	pParam->nActiveMinChnTimeConc = cfg_params->nActiveMinChnTimeConc;
+	pParam->nPassiveMaxChnTimeConc = cfg_params->nPassiveMaxChnTimeConc;
+	pParam->nPassiveMinChnTimeConc = cfg_params->nPassiveMinChnTimeConc;
+	pParam->nRestTimeConc = cfg_params->nRestTimeConc;
+	pParam->nNumStaChanCombinedConc = cfg_params->nNumStaChanCombinedConc;
+	pParam->nNumP2PChanCombinedConc = cfg_params->nNumP2PChanCombinedConc;
+#endif
+	pParam->eBand = cfg_params->eBand;
+	pParam->nScanResultAgeCount = cfg_params->agingCount;
+	pParam->scanAgeTimeNCNPS = cfg_params->scanAgeTimeNCNPS;
+	pParam->scanAgeTimeNCPS = cfg_params->scanAgeTimeNCPS;
+	pParam->scanAgeTimeCNPS = cfg_params->scanAgeTimeCNPS;
+	pParam->scanAgeTimeCPS = cfg_params->scanAgeTimeCPS;
+	pParam->bCatRssiOffset = cfg_params->bCatRssiOffset;
+	pParam->nRoamingTime = cfg_params->nRoamingTime;
+	pParam->fSupplicantCountryCodeHasPriority =
+		cfg_params->fSupplicantCountryCodeHasPriority;
+	pParam->vccRssiThreshold = cfg_params->vccRssiThreshold;
+	pParam->vccUlMacLossThreshold = cfg_params->vccUlMacLossThreshold;
+	pParam->nTxPowerCap = cfg_params->nTxPowerCap;
+	pParam->statsReqPeriodicity = cfg_params->statsReqPeriodicity;
+	pParam->statsReqPeriodicityInPS = cfg_params->statsReqPeriodicityInPS;
+	pParam->addTSWhenACMIsOff = cfg_params->addTSWhenACMIsOff;
+	pParam->fValidateList = cfg_params->fValidateList;
+	pParam->fEnableBypass11d = pMac->scan.fEnableBypass11d;
+	pParam->fEnableDFSChnlScan = pMac->scan.fEnableDFSChnlScan;
+	pParam->fScanTwice = cfg_params->fScanTwice;
+	pParam->fFirstScanOnly2GChnl = pMac->scan.fFirstScanOnly2GChnl;
+	pParam->fEnableMCCMode = cfg_params->fenableMCCMode;
+	pParam->fAllowMCCGODiffBI = cfg_params->fAllowMCCGODiffBI;
+	pParam->scanCfgAgingTime = pMac->scan.scanResultCfgAgingTime;
+#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
+	cdf_mem_copy(&pParam->neighborRoamConfig,
+		     &cfg_params->neighborRoamConfig,
+		     sizeof(tCsrNeighborRoamConfigParams));
+#endif
+#ifdef WLAN_FEATURE_11AC
+	pParam->nVhtChannelWidth = cfg_params->nVhtChannelWidth;
+	pParam->enableTxBF = cfg_params->txBFEnable;
+	pParam->txBFCsnValue = cfg_params->txBFCsnValue;
+	pParam->enableMuBformee = cfg_params->txMuBformee;
+	pParam->enableVhtFor24GHz = cfg_params->enableVhtFor24GHz;
+	pParam->ignore_peer_erp_info = cfg_params->ignore_peer_erp_info;
+	pParam->enable2x2 = cfg_params->enable2x2;
+#endif
+#ifdef WLAN_FEATURE_VOWIFI_11R
+	cdf_mem_copy(&cfg_params->csr11rConfig, &pParam->csr11rConfig,
+		     sizeof(tCsr11rConfigParams));
+#endif
+#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
+	pParam->isFastTransitionEnabled = cfg_params->isFastTransitionEnabled;
+	pParam->RoamRssiDiff = cfg_params->RoamRssiDiff;
+	pParam->nRoamPrefer5GHz = cfg_params->nRoamPrefer5GHz;
+	pParam->nRoamIntraBand = cfg_params->nRoamIntraBand;
+	pParam->isWESModeEnabled = cfg_params->isWESModeEnabled;
+	pParam->nProbes = cfg_params->nProbes;
+	pParam->nRoamScanHomeAwayTime = cfg_params->nRoamScanHomeAwayTime;
+#endif
+	pParam->isRoamOffloadScanEnabled = cfg_params->isRoamOffloadScanEnabled;
+	pParam->bFastRoamInConIniFeatureEnabled =
+		cfg_params->bFastRoamInConIniFeatureEnabled;
+#ifdef FEATURE_WLAN_LFR
+	pParam->isFastRoamIniFeatureEnabled =
+		cfg_params->isFastRoamIniFeatureEnabled;
+#endif
+#ifdef FEATURE_WLAN_ESE
+	pParam->isEseIniFeatureEnabled = cfg_params->isEseIniFeatureEnabled;
+#endif
+#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
+	cdf_mem_copy(&pParam->neighborRoamConfig,
+		     &cfg_params->neighborRoamConfig,
+		     sizeof(tCsrNeighborRoamConfigParams));
+	sms_log(pMac, LOG1,
+		FL("Num of Channels in CFG Channel List: %d"),
+		cfg_params->neighborRoamConfig.
+		neighborScanChanList.numChannels);
+	for (i = 0; i < cfg_params->neighborRoamConfig.
+	     neighborScanChanList.numChannels; i++) {
+		sms_log(pMac, LOG1, "%d ",
+			cfg_params->neighborRoamConfig.
+			neighborScanChanList.channelList[i]);
+	}
+#endif
+
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+	pParam->cc_switch_mode = cfg_params->cc_switch_mode;
+#endif
+	pParam->enableTxLdpc = cfg_params->txLdpcEnable;
+	pParam->isAmsduSupportInAMPDU = cfg_params->isAmsduSupportInAMPDU;
+	pParam->nSelect5GHzMargin = cfg_params->nSelect5GHzMargin;
+	pParam->isCoalesingInIBSSAllowed = cfg_params->isCoalesingInIBSSAllowed;
+	pParam->allowDFSChannelRoam = cfg_params->allowDFSChannelRoam;
+	pParam->nInitialDwellTime = cfg_params->nInitialDwellTime;
+	pParam->initial_scan_no_dfs_chnl = cfg_params->initial_scan_no_dfs_chnl;
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	pParam->isRoamOffloadEnabled = cfg_params->isRoamOffloadEnabled;
+#endif
+	pParam->enable_dot11p = pMac->enable_dot11p;
+	csr_set_channels(pMac, pParam);
+	pParam->obssEnabled = cfg_params->obssEnabled;
+	pParam->conc_custom_rule1 = cfg_params->conc_custom_rule1;
+	pParam->conc_custom_rule2 = cfg_params->conc_custom_rule2;
+	pParam->is_sta_connection_in_5gz_enabled =
+		cfg_params->is_sta_connection_in_5gz_enabled;
+	pParam->sendDeauthBeforeCon =
+		cfg_params->sendDeauthBeforeCon;
+	pParam->max_scan_count = pMac->scan.max_scan_count;
+	return CDF_STATUS_SUCCESS;
+}
+
+CDF_STATUS csr_set_phy_mode(tHalHandle hHal, uint32_t phyMode, eCsrBand eBand,
+			    bool *pfRestartNeeded)
+{
+	CDF_STATUS status = CDF_STATUS_E_INVAL;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	bool fRestartNeeded = false;
+	eCsrPhyMode newPhyMode = eCSR_DOT11_MODE_AUTO;
+	if (eCSR_BAND_24 == eBand) {
+		if (CSR_IS_RADIO_A_ONLY(pMac))
+			goto end;
+		if (eCSR_DOT11_MODE_11a & phyMode)
+			goto end;
+	}
+	if (eCSR_BAND_5G == eBand) {
+		if (CSR_IS_RADIO_BG_ONLY(pMac))
+			goto end;
+		if ((eCSR_DOT11_MODE_11b & phyMode)
+			|| (eCSR_DOT11_MODE_11b_ONLY & phyMode)
+			|| (eCSR_DOT11_MODE_11g & phyMode)
+			|| (eCSR_DOT11_MODE_11g_ONLY & phyMode))
+			goto end;
+	}
+	if (eCSR_DOT11_MODE_AUTO & phyMode)
+		newPhyMode = eCSR_DOT11_MODE_AUTO;
+	else {
+		/* Check for dual band and higher capability first */
+		if (eCSR_DOT11_MODE_11n_ONLY & phyMode) {
+			if (eCSR_DOT11_MODE_11n_ONLY != phyMode)
+				goto end;
+			newPhyMode = eCSR_DOT11_MODE_11n_ONLY;
+		} else if (eCSR_DOT11_MODE_11g_ONLY & phyMode) {
+			if (eCSR_DOT11_MODE_11g_ONLY != phyMode)
+				goto end;
+			if (eCSR_BAND_5G == eBand)
+				goto end;
+			newPhyMode = eCSR_DOT11_MODE_11g_ONLY;
+			eBand = eCSR_BAND_24;
+		} else if (eCSR_DOT11_MODE_11b_ONLY & phyMode) {
+			if (eCSR_DOT11_MODE_11b_ONLY != phyMode)
+				goto end;
+			if (eCSR_BAND_5G == eBand)
+				goto end;
+			newPhyMode = eCSR_DOT11_MODE_11b_ONLY;
+			eBand = eCSR_BAND_24;
+		} else if (eCSR_DOT11_MODE_11n & phyMode) {
+			newPhyMode = eCSR_DOT11_MODE_11n;
+		} else if (eCSR_DOT11_MODE_abg & phyMode) {
+			newPhyMode = eCSR_DOT11_MODE_abg;
+		} else if (eCSR_DOT11_MODE_11a & phyMode) {
+			if ((eCSR_DOT11_MODE_11g & phyMode)
+				|| (eCSR_DOT11_MODE_11b & phyMode)) {
+				if (eCSR_BAND_ALL == eBand)
+					newPhyMode = eCSR_DOT11_MODE_abg;
+				else
+					goto end;
+			} else {
+				newPhyMode = eCSR_DOT11_MODE_11a;
+				eBand = eCSR_BAND_5G;
+			}
+		} else if (eCSR_DOT11_MODE_11g & phyMode) {
+			newPhyMode = eCSR_DOT11_MODE_11g;
+			eBand = eCSR_BAND_24;
+		} else if (eCSR_DOT11_MODE_11b & phyMode) {
+			newPhyMode = eCSR_DOT11_MODE_11b;
+			eBand = eCSR_BAND_24;
+		} else {
+			/* We will never be here */
+			sms_log(pMac, LOGE,
+					FL("can't recognize phymode 0x%08X"),
+					phyMode);
+			newPhyMode = eCSR_DOT11_MODE_AUTO;
+		}
+	}
+	/* Done validating */
+	status = CDF_STATUS_SUCCESS;
+	/* Now we need to check whether a restart is needed. */
+	if (eBand != pMac->roam.configParam.eBand) {
+		fRestartNeeded = true;
+		goto end;
+	}
+	if (newPhyMode != pMac->roam.configParam.phyMode) {
+		fRestartNeeded = true;
+		goto end;
+	}
+end:
+	if (CDF_IS_STATUS_SUCCESS(status)) {
+		pMac->roam.configParam.eBand = eBand;
+		pMac->roam.configParam.phyMode = newPhyMode;
+		if (pfRestartNeeded)
+			*pfRestartNeeded = fRestartNeeded;
+	}
+	return status;
+}
+
+/**
+ * csr_prune_ch_list() - prunes the channel list to keep only a type of channels
+ * @ch_lst:        existing channel list
+ * @is_24_GHz:     indicates if 2.5 GHz or 5 GHz channels are required
+ *
+ * Return: void
+ */
+void csr_prune_ch_list(tCsrChannel *ch_lst, bool is_24_GHz)
+{
+	uint8_t idx = 0, num_channels = 0;
+	for ( ; idx < ch_lst->numChannels; idx++) {
+		if (is_24_GHz) {
+			if (CDS_IS_CHANNEL_24GHZ(ch_lst->channelList[idx])) {
+				ch_lst->channelList[num_channels] =
+					ch_lst->channelList[idx];
+				num_channels++;
+			}
+		} else {
+			if (CDS_IS_CHANNEL_5GHZ(ch_lst->channelList[idx])) {
+				ch_lst->channelList[num_channels] =
+					ch_lst->channelList[idx];
+				num_channels++;
+			}
+		}
+	}
+	/*
+	 * Cleanup the rest of channels. Note we only need to clean up the
+	 * channels if we had to trim the list. Calling cdf_mem_set() with a 0
+	 * size is going to throw asserts on the debug builds so let's be a bit
+	 * smarter about that. Zero out the reset of the channels only if we
+	 * need to. The amount of memory to clear is the number of channesl that
+	 * we trimmed (ch_lst->numChannels - num_channels) times the size of a
+	 * channel in the structure.
+	 */
+	if (ch_lst->numChannels > num_channels) {
+		cdf_mem_set(&ch_lst->channelList[num_channels],
+			    sizeof(ch_lst->channelList[0]) *
+			    (ch_lst->numChannels - num_channels), 0);
+	}
+	ch_lst->numChannels = num_channels;
+}
+
+/**
+ * csr_prune_channel_list_for_mode() - prunes the channel list
+ * @mac_ctx:       global mac context
+ * @ch_lst:        existing channel list
+ *
+ * Prunes the channel list according to band stored in mac_ctx
+ *
+ * Return: void
+ */
+void csr_prune_channel_list_for_mode(tpAniSirGlobal mac_ctx,
+				     tCsrChannel *ch_lst)
+{
+	/* for dual band NICs, don't need to trim the channel list.... */
+	if (CSR_IS_OPEARTING_DUAL_BAND(mac_ctx))
+		return;
+	/*
+	 * 2.4 GHz band operation requires the channel list to be trimmed to
+	 * the 2.4 GHz channels only
+	 */
+	if (CSR_IS_24_BAND_ONLY(mac_ctx))
+		csr_prune_ch_list(ch_lst, true);
+	else if (CSR_IS_5G_BAND_ONLY(mac_ctx))
+		csr_prune_ch_list(ch_lst, false);
+}
+
+#define INFRA_AP_DEFAULT_CHANNEL 6
+CDF_STATUS csr_is_valid_channel(tpAniSirGlobal pMac, uint8_t chnNum)
+{
+	uint8_t index = 0;
+	CDF_STATUS status = CDF_STATUS_E_NOSUPPORT;
+
+	/* regulatory check */
+	for (index = 0; index < pMac->scan.base_channels.numChannels;
+	     index++) {
+		if (pMac->scan.base_channels.channelList[index] == chnNum) {
+			status = CDF_STATUS_SUCCESS;
+			break;
+		}
+	}
+
+	if (status == CDF_STATUS_SUCCESS) {
+		/* dfs nol */
+		for (index = 0;
+		     index <
+		     pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels;
+		     index++) {
+			tSapDfsNolInfo *dfsChan =
+				&pMac->sap.SapDfsInfo.sapDfsChannelNolList[index];
+			if ((dfsChan->dfs_channel_number == chnNum)
+			    && (dfsChan->radar_status_flag ==
+				eSAP_DFS_CHANNEL_UNAVAILABLE)) {
+				CDF_TRACE(CDF_MODULE_ID_SME,
+					  CDF_TRACE_LEVEL_ERROR,
+					  FL("channel %d is in dfs nol"),
+					  chnNum);
+				status = CDF_STATUS_E_FAILURE;
+				break;
+			}
+		}
+	}
+
+	if (CDF_STATUS_SUCCESS != status) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+			  FL("channel %d is not available"), chnNum);
+	}
+
+	return status;
+}
+
+CDF_STATUS csr_get_channel_and_power_list(tpAniSirGlobal pMac)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	uint8_t num20MHzChannelsFound = 0;
+	CDF_STATUS cdf_status;
+	uint8_t Index = 0;
+	uint8_t num40MHzChannelsFound = 0;
+
+	/* TODO: this interface changed to include the 40MHz channel list */
+	/* this needs to be tied into the adapter structure somehow and referenced appropriately for CB operation */
+	/* Read the scan channel list (including the power limit) from EEPROM */
+	cdf_status =
+		cds_get_channel_list_with_power(pMac->scan.defaultPowerTable,
+						   &num20MHzChannelsFound,
+						   pMac->scan.defaultPowerTable40MHz,
+						   &num40MHzChannelsFound);
+	if ((CDF_STATUS_SUCCESS != cdf_status) || (num20MHzChannelsFound == 0)) {
+		sms_log(pMac, LOGE, FL("failed to get channels "));
+		status = CDF_STATUS_E_FAILURE;
+	} else {
+		if (num20MHzChannelsFound > WNI_CFG_VALID_CHANNEL_LIST_LEN) {
+			num20MHzChannelsFound = WNI_CFG_VALID_CHANNEL_LIST_LEN;
+		}
+		pMac->scan.numChannelsDefault = num20MHzChannelsFound;
+		/* Move the channel list to the global data */
+		/* structure -- this will be used as the scan list */
+		for (Index = 0; Index < num20MHzChannelsFound; Index++) {
+			pMac->scan.base_channels.channelList[Index] =
+				pMac->scan.defaultPowerTable[Index].chanId;
+		}
+		pMac->scan.base_channels.numChannels =
+			num20MHzChannelsFound;
+		if (num40MHzChannelsFound > WNI_CFG_VALID_CHANNEL_LIST_LEN) {
+			num40MHzChannelsFound = WNI_CFG_VALID_CHANNEL_LIST_LEN;
+		}
+		for (Index = 0; Index < num40MHzChannelsFound; Index++) {
+			pMac->scan.base40MHzChannels.channelList[Index] =
+				pMac->scan.defaultPowerTable40MHz[Index].chanId;
+		}
+		pMac->scan.base40MHzChannels.numChannels =
+			num40MHzChannelsFound;
+	}
+	return status;
+}
+
+CDF_STATUS csr_apply_channel_and_power_list(tpAniSirGlobal pMac)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+
+	csr_prune_channel_list_for_mode(pMac, &pMac->scan.base_channels);
+	csr_save_channel_power_for_band(pMac, false);
+	csr_save_channel_power_for_band(pMac, true);
+	/* Apply the base channel list, power info, and set the Country code... */
+	csr_apply_channel_power_info_to_fw(pMac,
+					   &pMac->scan.base_channels,
+					   pMac->scan.countryCodeCurrent);
+
+	csr_init_operating_classes((tHalHandle) pMac);
+	return status;
+}
+
+CDF_STATUS csr_change_config_params(tpAniSirGlobal pMac,
+				    tCsrUpdateConfigParam *pUpdateConfigParam)
+{
+	CDF_STATUS status = CDF_STATUS_E_FAILURE;
+	tCsr11dinfo *ps11dinfo = NULL;
+	ps11dinfo = &pUpdateConfigParam->Csr11dinfo;
+	status = csr_init11d_info(pMac, ps11dinfo);
+	return status;
+}
+
+static CDF_STATUS csr_init11d_info(tpAniSirGlobal pMac, tCsr11dinfo *ps11dinfo)
+{
+	CDF_STATUS status = CDF_STATUS_E_FAILURE;
+	uint8_t index;
+	uint32_t count = 0;
+	tSirMacChanInfo *pChanInfo;
+	tSirMacChanInfo *pChanInfoStart;
+	bool applyConfig = true;
+
+	pMac->scan.currentCountryRSSI = -128;
+	if (!ps11dinfo) {
+		return status;
+	}
+	if (ps11dinfo->Channels.numChannels
+	    && (WNI_CFG_VALID_CHANNEL_LIST_LEN >=
+		ps11dinfo->Channels.numChannels)) {
+		pMac->scan.base_channels.numChannels =
+			ps11dinfo->Channels.numChannels;
+		cdf_mem_copy(pMac->scan.base_channels.channelList,
+			     ps11dinfo->Channels.channelList,
+			     ps11dinfo->Channels.numChannels);
+	} else {
+		/* No change */
+		return CDF_STATUS_SUCCESS;
+	}
+	/* legacy maintenance */
+
+	cdf_mem_copy(pMac->scan.countryCodeDefault, ps11dinfo->countryCode,
+		     WNI_CFG_COUNTRY_CODE_LEN);
+
+	/* Tush: at csropen get this initialized with default, during csr reset if this */
+	/* already set with some value no need initilaize with default again */
+	if (0 == pMac->scan.countryCodeCurrent[0]) {
+		cdf_mem_copy(pMac->scan.countryCodeCurrent,
+			     ps11dinfo->countryCode, WNI_CFG_COUNTRY_CODE_LEN);
+	}
+	/* need to add the max power channel list */
+	pChanInfo =
+		cdf_mem_malloc(sizeof(tSirMacChanInfo) *
+			       WNI_CFG_VALID_CHANNEL_LIST_LEN);
+	if (pChanInfo != NULL) {
+		cdf_mem_set(pChanInfo,
+			    sizeof(tSirMacChanInfo) *
+			    WNI_CFG_VALID_CHANNEL_LIST_LEN, 0);
+
+		pChanInfoStart = pChanInfo;
+		for (index = 0; index < ps11dinfo->Channels.numChannels;
+		     index++) {
+			pChanInfo->firstChanNum =
+				ps11dinfo->ChnPower[index].firstChannel;
+			pChanInfo->numChannels =
+				ps11dinfo->ChnPower[index].numChannels;
+			pChanInfo->maxTxPower =
+				CDF_MIN(ps11dinfo->ChnPower[index].maxtxPower,
+					pMac->roam.configParam.nTxPowerCap);
+			pChanInfo++;
+			count++;
+		}
+		if (count) {
+			csr_save_to_channel_power2_g_5_g(pMac,
+							 count *
+							 sizeof(tSirMacChanInfo),
+							 pChanInfoStart);
+		}
+		cdf_mem_free(pChanInfoStart);
+	}
+	/* Only apply them to CFG when not in STOP state. Otherwise they will be applied later */
+	if (CDF_IS_STATUS_SUCCESS(status)) {
+		for (index = 0; index < CSR_ROAM_SESSION_MAX; index++) {
+			if ((CSR_IS_SESSION_VALID(pMac, index))
+			    && CSR_IS_ROAM_STOP(pMac, index)) {
+				applyConfig = false;
+			}
+		}
+
+		if (true == applyConfig) {
+			/* Apply the base channel list, power info, and set the Country code... */
+			csr_apply_channel_power_info_to_fw(pMac,
+							   &pMac->scan.
+							   base_channels,
+							   pMac->scan.
+							   countryCodeCurrent);
+		}
+	}
+	return status;
+}
+
+/* Initialize the Channel + Power List in the local cache and in the CFG */
+CDF_STATUS csr_init_channel_power_list(tpAniSirGlobal pMac, tCsr11dinfo *ps11dinfo)
+{
+	uint8_t index;
+	uint32_t count = 0;
+	tSirMacChanInfo *pChanInfo;
+	tSirMacChanInfo *pChanInfoStart;
+
+	if (!ps11dinfo || !pMac) {
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	pChanInfo =
+		cdf_mem_malloc(sizeof(tSirMacChanInfo) *
+			       WNI_CFG_VALID_CHANNEL_LIST_LEN);
+	if (pChanInfo != NULL) {
+		cdf_mem_set(pChanInfo,
+			    sizeof(tSirMacChanInfo) *
+			    WNI_CFG_VALID_CHANNEL_LIST_LEN, 0);
+		pChanInfoStart = pChanInfo;
+
+		for (index = 0; index < ps11dinfo->Channels.numChannels;
+		     index++) {
+			pChanInfo->firstChanNum =
+				ps11dinfo->ChnPower[index].firstChannel;
+			pChanInfo->numChannels =
+				ps11dinfo->ChnPower[index].numChannels;
+			pChanInfo->maxTxPower =
+				CDF_MIN(ps11dinfo->ChnPower[index].maxtxPower,
+					pMac->roam.configParam.nTxPowerCap);
+			pChanInfo++;
+			count++;
+		}
+		if (count) {
+			csr_save_to_channel_power2_g_5_g(pMac,
+							 count *
+							 sizeof(tSirMacChanInfo),
+							 pChanInfoStart);
+		}
+		cdf_mem_free(pChanInfoStart);
+	}
+
+	return CDF_STATUS_SUCCESS;
+}
+
+/* pCommand may be NULL */
+/* Pass in sessionId in case pCommand is NULL. sessionId is not used in case pCommand is not NULL. */
+void csr_roam_remove_duplicate_command(tpAniSirGlobal pMac, uint32_t sessionId,
+				       tSmeCmd *pCommand,
+				       eCsrRoamReason eRoamReason)
+{
+	tListElem *pEntry, *pNextEntry;
+	tSmeCmd *pDupCommand;
+	tDblLinkList localList;
+
+	cdf_mem_zero(&localList, sizeof(tDblLinkList));
+	if (!CDF_IS_STATUS_SUCCESS(csr_ll_open(pMac->hHdd, &localList))) {
+		sms_log(pMac, LOGE, FL(" failed to open list"));
+		return;
+	}
+	csr_ll_lock(&pMac->sme.smeCmdPendingList);
+	pEntry = csr_ll_peek_head(&pMac->sme.smeCmdPendingList, LL_ACCESS_NOLOCK);
+	while (pEntry) {
+		pNextEntry =
+			csr_ll_next(&pMac->sme.smeCmdPendingList, pEntry,
+				    LL_ACCESS_NOLOCK);
+		pDupCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
+		/* Remove the previous command if.. */
+		/* - the new roam command is for the same RoamReason... */
+		/* - the new roam command is a NewProfileList. */
+		/* - the new roam command is a Forced Dissoc */
+		/* - the new roam command is from an 802.11 OID (OID_SSID or OID_BSSID). */
+		if ((pCommand && (pCommand->sessionId == pDupCommand->sessionId)
+		     && ((pCommand->command == pDupCommand->command) &&
+			/*
+			 * This peermac check is requried for Softap/GO
+			 * scenarios. For STA scenario below OR check will
+			 * suffice as pCommand will always be NULL for STA
+			 * scenarios
+			 */
+			 (cdf_mem_compare
+				  (pDupCommand->u.roamCmd.peerMac,
+				  pCommand->u.roamCmd.peerMac,
+				  CDF_MAC_ADDR_SIZE))
+			 && (pCommand->u.roamCmd.roamReason ==
+			     pDupCommand->u.roamCmd.roamReason
+			     || eCsrForcedDisassoc ==
+			     pCommand->u.roamCmd.roamReason
+			     || eCsrHddIssued ==
+			     pCommand->u.roamCmd.roamReason)))
+		    ||
+		    /* below the pCommand is NULL */
+		    ((sessionId == pDupCommand->sessionId) &&
+		     (eSmeCommandRoam == pDupCommand->command) &&
+		     ((eCsrForcedDisassoc == eRoamReason) ||
+		      (eCsrHddIssued == eRoamReason))
+		    )
+		    ) {
+			sms_log(pMac, LOGW, FL("   roamReason = %d"),
+				pDupCommand->u.roamCmd.roamReason);
+			/* Remove the 'stale' roam command from the pending list... */
+			if (csr_ll_remove_entry
+				    (&pMac->sme.smeCmdPendingList, pEntry,
+				    LL_ACCESS_NOLOCK)) {
+				csr_ll_insert_tail(&localList, pEntry,
+						   LL_ACCESS_NOLOCK);
+			}
+		}
+		pEntry = pNextEntry;
+	}
+	csr_ll_unlock(&pMac->sme.smeCmdPendingList);
+
+	while ((pEntry = csr_ll_remove_head(&localList, LL_ACCESS_NOLOCK))) {
+		pDupCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
+		/* Tell caller that the command is cancelled */
+		csr_roam_call_callback(pMac, pDupCommand->sessionId, NULL,
+				       pDupCommand->u.roamCmd.roamId,
+				       eCSR_ROAM_CANCELLED, eCSR_ROAM_RESULT_NONE);
+		csr_release_command_roam(pMac, pDupCommand);
+	}
+	csr_ll_close(&localList);
+}
+
+/**
+ * csr_roam_populate_channels() - Helper function to populate channels
+ * @beacon_ies: pointer to beacon ie
+ * @roam_info: Roaming related information
+ * @chan1: center freq 1
+ * @chan2: center freq2
+ *
+ * This function will issue populate chan1 and chan2 based on beacon ie
+ *
+ * Return: none.
+ */
+static void csr_roam_populate_channels(tDot11fBeaconIEs *beacon_ies,
+			tCsrRoamInfo *roam_info,
+			uint8_t *chan1, uint8_t *chan2)
+{
+	ePhyChanBondState phy_state;
+	if (beacon_ies->VHTOperation.present) {
+		*chan1 = beacon_ies->VHTOperation.chanCenterFreqSeg1;
+		*chan2 = beacon_ies->VHTOperation.chanCenterFreqSeg2;
+		roam_info->chan_info.info = MODE_11AC_VHT80;
+	} else if (beacon_ies->HTInfo.present) {
+		if (beacon_ies->HTInfo.recommendedTxWidthSet ==
+			eHT_CHANNEL_WIDTH_40MHZ) {
+			phy_state = beacon_ies->HTInfo.secondaryChannelOffset;
+			if (phy_state == PHY_DOUBLE_CHANNEL_LOW_PRIMARY)
+				*chan1 = beacon_ies->HTInfo.primaryChannel +
+						CSR_CB_CENTER_CHANNEL_OFFSET;
+			else if (phy_state == PHY_DOUBLE_CHANNEL_HIGH_PRIMARY)
+				*chan1 = beacon_ies->HTInfo.primaryChannel -
+						CSR_CB_CENTER_CHANNEL_OFFSET;
+			else
+				*chan1 = beacon_ies->HTInfo.primaryChannel;
+
+			roam_info->chan_info.info = MODE_11NA_HT40;
+		} else {
+			*chan1 = beacon_ies->HTInfo.primaryChannel;
+			roam_info->chan_info.info = MODE_11NA_HT20;
+		}
+		*chan2 = 0;
+	} else {
+		*chan1 = 0;
+		*chan2 = 0;
+		roam_info->chan_info.info = MODE_11A;
+	}
+}
+
+CDF_STATUS csr_roam_call_callback(tpAniSirGlobal pMac, uint32_t sessionId,
+				  tCsrRoamInfo *pRoamInfo, uint32_t roamId,
+				  eRoamCmdStatus u1, eCsrRoamResult u2)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+	uint32_t rssi = 0;
+	WLAN_HOST_DIAG_EVENT_DEF(connectionStatus,
+			host_event_wlan_status_payload_type);
+#endif
+	tCsrRoamSession *pSession;
+	tDot11fBeaconIEs *beacon_ies = NULL;
+	uint8_t chan1, chan2;
+
+	if (!CSR_IS_SESSION_VALID(pMac, sessionId)) {
+		sms_log(pMac, LOGE, "Session ID:%d is not valid", sessionId);
+		CDF_ASSERT(0);
+		return CDF_STATUS_E_FAILURE;
+	}
+	pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (false == pSession->sessionActive) {
+		sms_log(pMac, LOG1, "%s Session is not Active", __func__);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	sms_log(pMac, LOG4, "Received RoamCmdStatus %d with Roam Result %d", u1,
+		u2);
+
+	if (eCSR_ROAM_ASSOCIATION_COMPLETION == u1 &&
+			eCSR_ROAM_RESULT_ASSOCIATED == u2 && pRoamInfo) {
+		sms_log(pMac, LOGW,
+			FL("Assoc complete result=%d status=%d reason=%d"),
+			u2, pRoamInfo->statusCode, pRoamInfo->reasonCode);
+		beacon_ies = cdf_mem_malloc(sizeof(tDot11fBeaconIEs));
+		if ((NULL != beacon_ies) && (NULL != pRoamInfo->pBssDesc)) {
+			status = csr_parse_bss_description_ies(
+					(tHalHandle) pMac, pRoamInfo->pBssDesc,
+					beacon_ies);
+			csr_roam_populate_channels(beacon_ies, pRoamInfo,
+					&chan1, &chan2);
+			if (0 != chan1)
+				pRoamInfo->chan_info.band_center_freq1 =
+					cds_chan_to_freq(chan1);
+			else
+				pRoamInfo->chan_info.band_center_freq1 = 0;
+			if (0 != chan2)
+				pRoamInfo->chan_info.band_center_freq2 =
+					cds_chan_to_freq(chan2);
+			else
+				pRoamInfo->chan_info.band_center_freq2 = 0;
+		} else {
+			pRoamInfo->chan_info.band_center_freq1 = 0;
+			pRoamInfo->chan_info.band_center_freq2 = 0;
+			pRoamInfo->chan_info.info = 0;
+		}
+		pRoamInfo->chan_info.chan_id =
+			pRoamInfo->u.pConnectedProfile->operationChannel;
+		pRoamInfo->chan_info.mhz =
+			cds_chan_to_freq(pRoamInfo->chan_info.chan_id);
+		pRoamInfo->chan_info.reg_info_1 =
+			(csr_get_cfg_max_tx_power(pMac,
+				pRoamInfo->chan_info.chan_id) << 16);
+		pRoamInfo->chan_info.reg_info_2 =
+			(csr_get_cfg_max_tx_power(pMac,
+				pRoamInfo->chan_info.chan_id) << 8);
+		cdf_mem_free(beacon_ies);
+	} else if ((u1 == eCSR_ROAM_FT_REASSOC_FAILED)
+			&& (pSession->bRefAssocStartCnt)) {
+		/*
+		 * Decrement bRefAssocStartCnt for FT reassoc failure.
+		 * Reason: For FT reassoc failures, we first call
+		 * csr_roam_call_callback before notifying a failed roam
+		 * completion through csr_roam_complete. The latter in
+		 * turn calls csr_roam_process_results which tries to
+		 * once again call csr_roam_call_callback if bRefAssocStartCnt
+		 * is non-zero. Since this is redundant for FT reassoc
+		 * failure, decrement bRefAssocStartCnt.
+		 */
+		pSession->bRefAssocStartCnt--;
+	} else if (u1 == eCSR_ROAM_SET_CHANNEL_RSP && u2 ==
+				eCSR_ROAM_RESULT_CHANNEL_CHANGE_SUCCESS)
+		pSession->connectedProfile.operationChannel =
+			pRoamInfo->channelChangeRespEvent->newChannelNumber;
+
+	if (NULL != pSession->callback) {
+		if (pRoamInfo) {
+			pRoamInfo->sessionId = (uint8_t) sessionId;
+			/*
+			 * the reasonCode will be passed to supplicant by
+			 * cfg80211_disconnected. Based on the document,
+			 * the reason code passed to supplicant needs to set
+			 * to 0 if unknow. eSIR_BEACON_MISSED reason code is not
+			 * recognizable so that we set to 0 instead.
+			 */
+			pRoamInfo->reasonCode =
+				(pRoamInfo->reasonCode == eSIR_BEACON_MISSED) ?
+				0 : pRoamInfo->reasonCode;
+		}
+		status = pSession->callback(pSession->pContext, pRoamInfo,
+					roamId, u1, u2);
+	}
+	/*
+	 * EVENT_WLAN_STATUS: eCSR_ROAM_ASSOCIATION_COMPLETION,
+	 *                    eCSR_ROAM_LOSTLINK,
+	 *                    eCSR_ROAM_DISASSOCIATED,
+	 */
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+	cdf_mem_set(&connectionStatus,
+			sizeof(host_event_wlan_status_payload_type), 0);
+
+	if ((eCSR_ROAM_ASSOCIATION_COMPLETION == u1)
+			&& (eCSR_ROAM_RESULT_ASSOCIATED == u2) && pRoamInfo) {
+		connectionStatus.eventId = eCSR_WLAN_STATUS_CONNECT;
+		connectionStatus.bssType =
+			pRoamInfo->u.pConnectedProfile->BSSType;
+
+		if (NULL != pRoamInfo->pBssDesc) {
+			connectionStatus.rssi =
+				pRoamInfo->pBssDesc->rssi * (-1);
+			connectionStatus.channel =
+				pRoamInfo->pBssDesc->channelId;
+		}
+		if (cfg_set_int(pMac, WNI_CFG_CURRENT_RSSI,
+				connectionStatus.rssi) == eSIR_FAILURE)
+			sms_log(pMac, LOGE,
+				FL("Can't pass WNI_CFG_CURRENT_RSSI to cfg"));
+
+		connectionStatus.qosCapability =
+			pRoamInfo->u.pConnectedProfile->qosConnection;
+		connectionStatus.authType =
+			(uint8_t) diag_auth_type_from_csr_type(
+				pRoamInfo->u.pConnectedProfile->AuthType);
+		connectionStatus.encryptionType =
+			(uint8_t) diag_enc_type_from_csr_type(
+				pRoamInfo->u.pConnectedProfile->EncryptionType);
+		cdf_mem_copy(connectionStatus.ssid,
+				pRoamInfo->u.pConnectedProfile->SSID.ssId, 6);
+
+		connectionStatus.reason = eCSR_REASON_UNSPECIFIED;
+		cdf_mem_copy(&pMac->sme.eventPayload, &connectionStatus,
+				sizeof(host_event_wlan_status_payload_type));
+		WLAN_HOST_DIAG_EVENT_REPORT(&connectionStatus,
+				EVENT_WLAN_STATUS);
+	}
+	if ((eCSR_ROAM_MIC_ERROR_IND == u1)
+			|| (eCSR_ROAM_RESULT_MIC_FAILURE == u2)) {
+		cdf_mem_copy(&connectionStatus, &pMac->sme.eventPayload,
+				sizeof(host_event_wlan_status_payload_type));
+		if (IS_SIR_STATUS_SUCCESS(wlan_cfg_get_int(pMac,
+				WNI_CFG_CURRENT_RSSI, &rssi)))
+			connectionStatus.rssi = rssi;
+
+		connectionStatus.eventId = eCSR_WLAN_STATUS_DISCONNECT;
+		connectionStatus.reason = eCSR_REASON_MIC_ERROR;
+		WLAN_HOST_DIAG_EVENT_REPORT(&connectionStatus,
+				EVENT_WLAN_STATUS);
+	}
+	if (eCSR_ROAM_RESULT_FORCED == u2) {
+		cdf_mem_copy(&connectionStatus, &pMac->sme.eventPayload,
+				sizeof(host_event_wlan_status_payload_type));
+		if (IS_SIR_STATUS_SUCCESS(wlan_cfg_get_int(pMac,
+				WNI_CFG_CURRENT_RSSI, &rssi)))
+			connectionStatus.rssi = rssi;
+
+		connectionStatus.eventId = eCSR_WLAN_STATUS_DISCONNECT;
+		connectionStatus.reason = eCSR_REASON_USER_REQUESTED;
+		WLAN_HOST_DIAG_EVENT_REPORT(&connectionStatus,
+				EVENT_WLAN_STATUS);
+	}
+	if (eCSR_ROAM_RESULT_DISASSOC_IND == u2) {
+		cdf_mem_copy(&connectionStatus, &pMac->sme.eventPayload,
+				sizeof(host_event_wlan_status_payload_type));
+		if (IS_SIR_STATUS_SUCCESS(wlan_cfg_get_int(pMac,
+				WNI_CFG_CURRENT_RSSI, &rssi)))
+			connectionStatus.rssi = rssi;
+
+		connectionStatus.eventId = eCSR_WLAN_STATUS_DISCONNECT;
+		connectionStatus.reason = eCSR_REASON_DISASSOC;
+		if (pRoamInfo)
+			connectionStatus.reasonDisconnect =
+				pRoamInfo->reasonCode;
+
+		WLAN_HOST_DIAG_EVENT_REPORT(&connectionStatus,
+				EVENT_WLAN_STATUS);
+	}
+	if (eCSR_ROAM_RESULT_DEAUTH_IND == u2) {
+		cdf_mem_copy(&connectionStatus, &pMac->sme.eventPayload,
+				sizeof(host_event_wlan_status_payload_type));
+		if (IS_SIR_STATUS_SUCCESS(wlan_cfg_get_int(pMac,
+				WNI_CFG_CURRENT_RSSI, &rssi)))
+			connectionStatus.rssi = rssi;
+
+		connectionStatus.eventId = eCSR_WLAN_STATUS_DISCONNECT;
+		connectionStatus.reason = eCSR_REASON_DEAUTH;
+		if (pRoamInfo)
+			connectionStatus.reasonDisconnect =
+				pRoamInfo->reasonCode;
+		WLAN_HOST_DIAG_EVENT_REPORT(&connectionStatus,
+				EVENT_WLAN_STATUS);
+	}
+#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
+	return status;
+}
+
+/* Returns whether handoff is currently in progress or not */
+bool csr_roam_is_handoff_in_progress(tpAniSirGlobal pMac, uint8_t sessionId)
+{
+#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
+	return csr_neighbor_roam_is_handoff_in_progress(pMac, sessionId);
+#else
+	return false;
+#endif
+}
+
+CDF_STATUS csr_roam_issue_disassociate(tpAniSirGlobal pMac, uint32_t sessionId,
+				       eCsrRoamSubState NewSubstate,
+				       bool fMICFailure)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	struct cdf_mac_addr bssId = CDF_MAC_ADDR_BROADCAST_INITIALIZER;
+	uint16_t reasonCode;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("  session %d not found "), sessionId);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	if (fMICFailure) {
+		reasonCode = eSIR_MAC_MIC_FAILURE_REASON;
+	} else if (NewSubstate == eCSR_ROAM_SUBSTATE_DISASSOC_HANDOFF) {
+		reasonCode = eSIR_MAC_DISASSOC_DUE_TO_FTHANDOFF_REASON;
+	} else if (eCSR_ROAM_SUBSTATE_DISASSOC_STA_HAS_LEFT == NewSubstate) {
+		reasonCode = eSIR_MAC_DISASSOC_LEAVING_BSS_REASON;
+		NewSubstate = eCSR_ROAM_SUBSTATE_DISASSOC_FORCED;
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
+			  FL
+				  ("set to reason code eSIR_MAC_DISASSOC_LEAVING_BSS_REASON"
+				  " and set back NewSubstate"));
+	} else {
+		reasonCode = eSIR_MAC_UNSPEC_FAILURE_REASON;
+	}
+#ifdef WLAN_FEATURE_VOWIFI_11R
+	if ((csr_roam_is_handoff_in_progress(pMac, sessionId)) &&
+	    (NewSubstate != eCSR_ROAM_SUBSTATE_DISASSOC_HANDOFF)) {
+		tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+			&pMac->roam.neighborRoamInfo[sessionId];
+		cdf_copy_macaddr(&bssId,
+			      pNeighborRoamInfo->csrNeighborRoamProfile.BSSIDs.
+			      bssid);
+	} else
+#endif
+	if (pSession->pConnectBssDesc) {
+		cdf_mem_copy(&bssId.bytes, pSession->pConnectBssDesc->bssId,
+			     sizeof(struct cdf_mac_addr));
+	}
+
+	sms_log(pMac, LOG2,
+		FL("CSR Attempting to Disassociate Bssid=" MAC_ADDRESS_STR
+		   " subState = %s reason=%d"), MAC_ADDR_ARRAY(bssId.bytes),
+		mac_trace_getcsr_roam_sub_state(NewSubstate), reasonCode);
+
+	csr_roam_substate_change(pMac, NewSubstate, sessionId);
+
+	status = csr_send_mb_disassoc_req_msg(pMac, sessionId, bssId.bytes,
+						reasonCode);
+
+	if (CDF_IS_STATUS_SUCCESS(status)) {
+		csr_roam_link_down(pMac, sessionId);
+#ifndef WLAN_MDM_CODE_REDUCTION_OPT
+		/* no need to tell QoS that we are disassociating, it will be taken care off in assoc req for HO */
+		if (eCSR_ROAM_SUBSTATE_DISASSOC_HANDOFF != NewSubstate) {
+			/* notify QoS module that disassoc happening */
+			sme_qos_csr_event_ind(pMac, (uint8_t) sessionId,
+					      SME_QOS_CSR_DISCONNECT_REQ, NULL);
+		}
+#endif
+	} else {
+		sms_log(pMac, LOGW,
+			FL("csr_send_mb_disassoc_req_msg failed with status %d"),
+			status);
+	}
+
+	return status;
+}
+
+/* ---------------------------------------------------------------------------
+    \fn csr_roam_issue_disassociate_sta_cmd
+    \brief csr function that HDD calls to disassociate a associated station
+    \param sessionId    - session Id for Soft AP
+    \param pPeerMacAddr - MAC of associated station to delete
+    \param reason - reason code, be one of the tSirMacReasonCodes
+    \return CDF_STATUS
+   ---------------------------------------------------------------------------*/
+CDF_STATUS csr_roam_issue_disassociate_sta_cmd(tpAniSirGlobal pMac,
+					       uint32_t sessionId,
+					       const uint8_t *pPeerMacAddr,
+					       uint32_t reason)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tSmeCmd *pCommand;
+
+	do {
+		pCommand = csr_get_command_buffer(pMac);
+		if (!pCommand) {
+			sms_log(pMac, LOGE, FL(" fail to get command buffer"));
+			status = CDF_STATUS_E_RESOURCES;
+			break;
+		}
+		pCommand->command = eSmeCommandRoam;
+		pCommand->sessionId = (uint8_t) sessionId;
+		pCommand->u.roamCmd.roamReason = eCsrForcedDisassocSta;
+		cdf_mem_copy(pCommand->u.roamCmd.peerMac, pPeerMacAddr, 6);
+		pCommand->u.roamCmd.reason = (tSirMacReasonCodes) reason;
+		status = csr_queue_sme_command(pMac, pCommand, false);
+		if (!CDF_IS_STATUS_SUCCESS(status)) {
+			sms_log(pMac, LOGE,
+				FL(" fail to send message status = %d"), status);
+			csr_release_command_roam(pMac, pCommand);
+		}
+	} while (0);
+
+	return status;
+}
+
+/**
+ * csr_roam_issue_deauthSta() - delete a associated station
+ * @sessionId:     Session Id for Soft AP
+ * @pDelStaParams: Pointer to parameters of the station to deauthenticate
+ *
+ * CSR function that HDD calls to delete a associated station
+ *
+ * Return: CDF_STATUS_SUCCESS on success or another CDF_STATUS_* on error
+ */
+CDF_STATUS csr_roam_issue_deauth_sta_cmd(tpAniSirGlobal pMac,
+		uint32_t sessionId,
+		struct tagCsrDelStaParams *pDelStaParams)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tSmeCmd *pCommand;
+
+	do {
+		pCommand = csr_get_command_buffer(pMac);
+		if (!pCommand) {
+			sms_log(pMac, LOGE, FL(" fail to get command buffer"));
+			status = CDF_STATUS_E_RESOURCES;
+			break;
+		}
+		pCommand->command = eSmeCommandRoam;
+		pCommand->sessionId = (uint8_t) sessionId;
+		pCommand->u.roamCmd.roamReason = eCsrForcedDeauthSta;
+		cdf_mem_copy(pCommand->u.roamCmd.peerMac,
+			     pDelStaParams->peerMacAddr.bytes,
+			     sizeof(tSirMacAddr));
+		pCommand->u.roamCmd.reason =
+			(tSirMacReasonCodes)pDelStaParams->reason_code;
+		status = csr_queue_sme_command(pMac, pCommand, false);
+		if (!CDF_IS_STATUS_SUCCESS(status)) {
+			sms_log(pMac, LOGE,
+				FL(" fail to send message status = %d"), status);
+			csr_release_command_roam(pMac, pCommand);
+		}
+	} while (0);
+
+	return status;
+}
+
+CDF_STATUS
+csr_roam_issue_tkip_counter_measures(tpAniSirGlobal pMac, uint32_t sessionId,
+				     bool bEnable)
+{
+	CDF_STATUS status = CDF_STATUS_E_FAILURE;
+	struct cdf_mac_addr bssId = CDF_MAC_ADDR_BROADCAST_INITIALIZER;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+	if (!pSession) {
+		sms_log(pMac, LOGE,
+			"csr_roam_issue_tkip_counter_measures:CSR Session not found");
+		return status;
+	}
+	if (pSession->pConnectBssDesc) {
+		cdf_mem_copy(bssId.bytes, pSession->pConnectBssDesc->bssId,
+			     sizeof(struct cdf_mac_addr));
+	} else {
+		sms_log(pMac, LOGE,
+			"csr_roam_issue_tkip_counter_measures:Connected BSS Description in CSR Session not found");
+		return status;
+	}
+	sms_log(pMac, LOG2,
+		"CSR issuing tkip counter measures for Bssid = " MAC_ADDRESS_STR
+		", Enable = %d", MAC_ADDR_ARRAY(bssId.bytes), bEnable);
+	status =
+		csr_send_mb_tkip_counter_measures_req_msg(pMac, sessionId,
+							bEnable, bssId.bytes);
+	return status;
+}
+
+CDF_STATUS
+csr_roam_get_associated_stas(tpAniSirGlobal pMac, uint32_t sessionId,
+			     CDF_MODULE_ID modId, void *pUsrContext,
+			     void *pfnSapEventCallback, uint8_t *pAssocStasBuf)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	struct cdf_mac_addr bssId = CDF_MAC_ADDR_BROADCAST_INITIALIZER;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+	if (!pSession) {
+		sms_log(pMac, LOGE,
+			"csr_roam_get_associated_stas:CSR Session not found");
+		return status;
+	}
+	if (pSession->pConnectBssDesc) {
+		cdf_mem_copy(bssId.bytes, pSession->pConnectBssDesc->bssId,
+			     sizeof(struct cdf_mac_addr));
+	} else {
+		sms_log(pMac, LOGE,
+			"csr_roam_get_associated_stas:Connected BSS Description in CSR Session not found");
+		return status;
+	}
+	sms_log(pMac, LOG2,
+		"CSR getting associated stations for Bssid = " MAC_ADDRESS_STR,
+		MAC_ADDR_ARRAY(bssId.bytes));
+	status =
+		csr_send_mb_get_associated_stas_req_msg(pMac, sessionId, modId,
+							bssId.bytes,
+							pUsrContext,
+							pfnSapEventCallback,
+							pAssocStasBuf);
+	return status;
+}
+
+CDF_STATUS
+csr_roam_get_wps_session_overlap(tpAniSirGlobal pMac, uint32_t sessionId,
+				 void *pUsrContext, void *pfnSapEventCallback,
+				 struct cdf_mac_addr pRemoveMac)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	struct cdf_mac_addr bssId = CDF_MAC_ADDR_BROADCAST_INITIALIZER;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sms_log(pMac, LOGE,
+			"csr_roam_get_wps_session_overlap:CSR Session not found");
+		return status;
+	}
+	if (pSession->pConnectBssDesc) {
+		cdf_mem_copy(bssId.bytes, pSession->pConnectBssDesc->bssId,
+			     sizeof(struct cdf_mac_addr));
+	} else {
+		sms_log(pMac, LOGE,
+			"csr_roam_get_wps_session_overlap:Connected BSS Description in CSR Session not found");
+		return status;
+	}
+	sms_log(pMac, LOG2,
+		"CSR getting WPS Session Overlap for Bssid = " MAC_ADDRESS_STR,
+		MAC_ADDR_ARRAY(bssId.bytes));
+
+	status =
+		csr_send_mb_get_wpspbc_sessions(pMac, sessionId, bssId.bytes, pUsrContext,
+						pfnSapEventCallback, pRemoveMac);
+
+	return status;
+}
+
+CDF_STATUS csr_roam_issue_deauth(tpAniSirGlobal pMac, uint32_t sessionId,
+				 eCsrRoamSubState NewSubstate)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	struct cdf_mac_addr bssId = CDF_MAC_ADDR_BROADCAST_INITIALIZER;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("  session %d not found "), sessionId);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	if (pSession->pConnectBssDesc) {
+		cdf_mem_copy(bssId.bytes, pSession->pConnectBssDesc->bssId,
+			     sizeof(struct cdf_mac_addr));
+	}
+	sms_log(pMac, LOG2, "CSR Attempting to Deauth Bssid= " MAC_ADDRESS_STR,
+		MAC_ADDR_ARRAY(bssId.bytes));
+	csr_roam_substate_change(pMac, NewSubstate, sessionId);
+
+	status =
+		csr_send_mb_deauth_req_msg(pMac, sessionId, bssId.bytes,
+					   eSIR_MAC_DEAUTH_LEAVING_BSS_REASON);
+	if (CDF_IS_STATUS_SUCCESS(status))
+		csr_roam_link_down(pMac, sessionId);
+	else {
+		sms_log(pMac, LOGE,
+			FL
+				("csr_send_mb_deauth_req_msg failed with status %d Session ID: %d"
+				MAC_ADDRESS_STR), status, sessionId,
+			MAC_ADDR_ARRAY(bssId.bytes));
+	}
+
+	return status;
+}
+
+CDF_STATUS csr_roam_save_connected_bss_desc(tpAniSirGlobal pMac, uint32_t sessionId,
+					    tSirBssDescription *pBssDesc)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+	uint32_t size;
+
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("  session %d not found "), sessionId);
+		return CDF_STATUS_E_FAILURE;
+	}
+	/* If no BSS description was found in this connection (happens with start IBSS), then */
+	/* nix the BSS description that we keep around for the connected BSS) and get out... */
+	if (NULL == pBssDesc) {
+		csr_free_connect_bss_desc(pMac, sessionId);
+	} else {
+		size = pBssDesc->length + sizeof(pBssDesc->length);
+		if (NULL != pSession->pConnectBssDesc) {
+			if (((pSession->pConnectBssDesc->length) +
+			     sizeof(pSession->pConnectBssDesc->length)) <
+			    size) {
+				/* not enough room for the new BSS, pMac->roam.pConnectBssDesc is freed inside */
+				csr_free_connect_bss_desc(pMac, sessionId);
+			}
+		}
+		if (NULL == pSession->pConnectBssDesc) {
+			pSession->pConnectBssDesc = cdf_mem_malloc(size);
+		}
+		if (NULL == pSession->pConnectBssDesc)
+			status = CDF_STATUS_E_NOMEM;
+		else
+			cdf_mem_copy(pSession->pConnectBssDesc, pBssDesc, size);
+	}
+	return status;
+}
+
+CDF_STATUS csr_roam_prepare_bss_config(tpAniSirGlobal pMac,
+				       tCsrRoamProfile *pProfile,
+				       tSirBssDescription *pBssDesc,
+				       tBssConfigParam *pBssConfig,
+				       tDot11fBeaconIEs *pIes)
+{
+	eCsrCfgDot11Mode cfgDot11Mode;
+	CDF_ASSERT(pIes != NULL);
+	if (pIes == NULL)
+		return CDF_STATUS_E_FAILURE;
+
+	cdf_mem_copy(&pBssConfig->BssCap, &pBssDesc->capabilityInfo,
+		     sizeof(tSirMacCapabilityInfo));
+	/* get qos */
+	pBssConfig->qosType = csr_get_qo_s_from_bss_desc(pMac, pBssDesc, pIes);
+	/* get SSID */
+	if (pIes->SSID.present) {
+		cdf_mem_copy(&pBssConfig->SSID.ssId, pIes->SSID.ssid,
+			     pIes->SSID.num_ssid);
+		pBssConfig->SSID.length = pIes->SSID.num_ssid;
+	} else
+		pBssConfig->SSID.length = 0;
+	if (csr_is_nullssid(pBssConfig->SSID.ssId, pBssConfig->SSID.length)) {
+		sms_log(pMac, LOGW, FL("BSS desc SSID is a wild card"));
+		/* Return failed if profile doesn't have an SSID either. */
+		if (pProfile->SSIDs.numOfSSIDs == 0) {
+			sms_log(pMac, LOGW,
+				FL("BSS desc and profile doesn't have SSID"));
+			return CDF_STATUS_E_FAILURE;
+		}
+	}
+	if (CDS_IS_CHANNEL_5GHZ(pBssDesc->channelId))
+		pBssConfig->eBand = eCSR_BAND_5G;
+	else
+		pBssConfig->eBand = eCSR_BAND_24;
+		/* phymode */
+	if (csr_is_phy_mode_match(pMac, pProfile->phyMode, pBssDesc,
+				  pProfile, &cfgDot11Mode, pIes)) {
+		pBssConfig->uCfgDot11Mode = cfgDot11Mode;
+	} else {
+		sms_log(pMac, LOGW, "Can not find match phy mode");
+		/* force it */
+		if (eCSR_BAND_24 == pBssConfig->eBand)
+			pBssConfig->uCfgDot11Mode = eCSR_CFG_DOT11_MODE_11G;
+		else
+			pBssConfig->uCfgDot11Mode = eCSR_CFG_DOT11_MODE_11A;
+	}
+	/* Qos */
+	if ((pBssConfig->uCfgDot11Mode != eCSR_CFG_DOT11_MODE_11N) &&
+	    (pMac->roam.configParam.WMMSupportMode == eCsrRoamWmmNoQos)) {
+		/*
+		 * Joining BSS is not 11n capable and WMM is disabled on client.
+		 * Disable QoS and WMM
+		 */
+		pBssConfig->qosType = eCSR_MEDIUM_ACCESS_DCF;
+	}
+
+	if (((pBssConfig->uCfgDot11Mode == eCSR_CFG_DOT11_MODE_11N)
+	    || (pBssConfig->uCfgDot11Mode == eCSR_CFG_DOT11_MODE_11AC))
+		&& ((pBssConfig->qosType != eCSR_MEDIUM_ACCESS_WMM_eDCF_DSCP)
+		    || (pBssConfig->qosType != eCSR_MEDIUM_ACCESS_11e_HCF)
+		    || (pBssConfig->qosType != eCSR_MEDIUM_ACCESS_11e_eDCF))) {
+		/* Joining BSS is 11n capable and WMM is disabled on AP. */
+		/* Assume all HT AP's are QOS AP's and enable WMM */
+		pBssConfig->qosType = eCSR_MEDIUM_ACCESS_WMM_eDCF_DSCP;
+	}
+	/* auth type */
+	switch (pProfile->negotiatedAuthType) {
+	default:
+	case eCSR_AUTH_TYPE_WPA:
+	case eCSR_AUTH_TYPE_WPA_PSK:
+	case eCSR_AUTH_TYPE_WPA_NONE:
+	case eCSR_AUTH_TYPE_OPEN_SYSTEM:
+		pBssConfig->authType = eSIR_OPEN_SYSTEM;
+		break;
+	case eCSR_AUTH_TYPE_SHARED_KEY:
+		pBssConfig->authType = eSIR_SHARED_KEY;
+		break;
+	case eCSR_AUTH_TYPE_AUTOSWITCH:
+		pBssConfig->authType = eSIR_AUTO_SWITCH;
+		break;
+	}
+	/* short slot time */
+	if (eCSR_CFG_DOT11_MODE_11B != cfgDot11Mode)
+		pBssConfig->uShortSlotTime =
+			pMac->roam.configParam.shortSlotTime;
+	else
+		pBssConfig->uShortSlotTime = 0;
+
+	if (pBssConfig->BssCap.ibss)
+		/* We don't support 11h on IBSS */
+		pBssConfig->f11hSupport = false;
+	else
+		pBssConfig->f11hSupport =
+			pMac->roam.configParam.Is11hSupportEnabled;
+	/* power constraint */
+	pBssConfig->uPowerLimit =
+		csr_get11h_power_constraint(pMac, &pIes->PowerConstraints);
+	/* heartbeat */
+	if (CSR_IS_11A_BSS(pBssDesc))
+		pBssConfig->uHeartBeatThresh =
+			pMac->roam.configParam.HeartbeatThresh50;
+	else
+		pBssConfig->uHeartBeatThresh =
+			pMac->roam.configParam.HeartbeatThresh24;
+
+	/*
+	 * Join timeout: if we find a BeaconInterval in the BssDescription,
+	 * then set the Join Timeout to be 10 x the BeaconInterval.
+	 */
+	if (pBssDesc->beaconInterval)
+		/* Make sure it is bigger than the minimal */
+		pBssConfig->uJoinTimeOut =
+			CDF_MAX(10 * pBssDesc->beaconInterval,
+				CSR_JOIN_FAILURE_TIMEOUT_MIN);
+	else
+		pBssConfig->uJoinTimeOut =
+			CSR_JOIN_FAILURE_TIMEOUT_DEFAULT;
+	/* validate CB */
+	pBssConfig->cbMode = csr_get_cb_mode_from_ies(pMac, pBssDesc->channelId,
+						      pIes);
+
+	return CDF_STATUS_SUCCESS;
+}
+
+static CDF_STATUS csr_roam_prepare_bss_config_from_profile(tpAniSirGlobal pMac,
+							   tCsrRoamProfile *pProfile,
+							   tBssConfigParam *
+							   pBssConfig,
+							   tSirBssDescription *
+							   pBssDesc)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	uint8_t operationChannel = 0;
+	uint8_t qAPisEnabled = false;
+	/* SSID */
+	pBssConfig->SSID.length = 0;
+	if (pProfile->SSIDs.numOfSSIDs) {
+		/* only use the first one */
+		cdf_mem_copy(&pBssConfig->SSID,
+			     &pProfile->SSIDs.SSIDList[0].SSID,
+			     sizeof(tSirMacSSid));
+	} else {
+		/* SSID must present */
+		return CDF_STATUS_E_FAILURE;
+	}
+	/* Settomg up the capabilities */
+	if (csr_is_bss_type_ibss(pProfile->BSSType)) {
+		pBssConfig->BssCap.ibss = 1;
+	} else {
+		pBssConfig->BssCap.ess = 1;
+	}
+	if (eCSR_ENCRYPT_TYPE_NONE !=
+	    pProfile->EncryptionType.encryptionType[0]) {
+		pBssConfig->BssCap.privacy = 1;
+	}
+	pBssConfig->eBand = pMac->roam.configParam.eBand;
+	/* phymode */
+	if (pProfile->ChannelInfo.ChannelList) {
+		operationChannel = pProfile->ChannelInfo.ChannelList[0];
+	}
+	pBssConfig->uCfgDot11Mode =
+		csr_roam_get_phy_mode_band_for_bss(pMac, pProfile, operationChannel,
+						   &pBssConfig->eBand);
+	/* QOS */
+	/* Is this correct to always set to this // *** */
+	if (pBssConfig->BssCap.ess == 1) {
+		/*For Softap case enable WMM */
+		if (CSR_IS_INFRA_AP(pProfile)
+		    && (eCsrRoamWmmNoQos !=
+			pMac->roam.configParam.WMMSupportMode)) {
+			qAPisEnabled = true;
+		} else
+		if (csr_roam_get_qos_info_from_bss(pMac, pBssDesc) ==
+		    CDF_STATUS_SUCCESS) {
+			qAPisEnabled = true;
+		} else {
+			qAPisEnabled = false;
+		}
+	} else {
+		qAPisEnabled = true;
+	}
+	if ((eCsrRoamWmmNoQos != pMac->roam.configParam.WMMSupportMode &&
+	     qAPisEnabled) ||
+	    ((eCSR_CFG_DOT11_MODE_11N == pBssConfig->uCfgDot11Mode &&
+	      qAPisEnabled))) {
+		pBssConfig->qosType = eCSR_MEDIUM_ACCESS_WMM_eDCF_DSCP;
+	} else {
+		pBssConfig->qosType = eCSR_MEDIUM_ACCESS_DCF;
+	}
+
+	/* auth type */
+	/* Take the preferred Auth type. */
+	switch (pProfile->AuthType.authType[0]) {
+	default:
+	case eCSR_AUTH_TYPE_WPA:
+	case eCSR_AUTH_TYPE_WPA_PSK:
+	case eCSR_AUTH_TYPE_WPA_NONE:
+	case eCSR_AUTH_TYPE_OPEN_SYSTEM:
+		pBssConfig->authType = eSIR_OPEN_SYSTEM;
+		break;
+	case eCSR_AUTH_TYPE_SHARED_KEY:
+		pBssConfig->authType = eSIR_SHARED_KEY;
+		break;
+	case eCSR_AUTH_TYPE_AUTOSWITCH:
+		pBssConfig->authType = eSIR_AUTO_SWITCH;
+		break;
+	}
+	/* short slot time */
+	if (WNI_CFG_PHY_MODE_11B != pBssConfig->uCfgDot11Mode) {
+		pBssConfig->uShortSlotTime =
+			pMac->roam.configParam.shortSlotTime;
+	} else {
+		pBssConfig->uShortSlotTime = 0;
+	}
+	/* power constraint. We don't support 11h on IBSS */
+	pBssConfig->f11hSupport = false;
+	pBssConfig->uPowerLimit = 0;
+	/* heartbeat */
+	if (eCSR_BAND_5G == pBssConfig->eBand) {
+		pBssConfig->uHeartBeatThresh =
+			pMac->roam.configParam.HeartbeatThresh50;
+	} else {
+		pBssConfig->uHeartBeatThresh =
+			pMac->roam.configParam.HeartbeatThresh24;
+	}
+	/* Join timeout */
+	pBssConfig->uJoinTimeOut = CSR_JOIN_FAILURE_TIMEOUT_DEFAULT;
+
+	return status;
+}
+
+static CDF_STATUS csr_roam_get_qos_info_from_bss(tpAniSirGlobal pMac,
+						 tSirBssDescription *pBssDesc)
+{
+	CDF_STATUS status = CDF_STATUS_E_FAILURE;
+	tDot11fBeaconIEs *pIes = NULL;
+
+	do {
+		if (!CDF_IS_STATUS_SUCCESS(
+			csr_get_parsed_bss_description_ies(
+				pMac, pBssDesc, &pIes))) {
+			/* err msg */
+			CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+				  "csr_roam_get_qos_info_from_bss() failed");
+			break;
+		}
+		/* check if the AP is QAP & it supports APSD */
+		if (CSR_IS_QOS_BSS(pIes)) {
+			status = CDF_STATUS_SUCCESS;
+		}
+	} while (0);
+
+	if (NULL != pIes) {
+		cdf_mem_free(pIes);
+	}
+
+	return status;
+}
+
+void csr_set_cfg_privacy(tpAniSirGlobal pMac, tCsrRoamProfile *pProfile,
+			 bool fPrivacy)
+{
+	/*
+	 * the only difference between this function and
+	 * the csr_set_cfg_privacyFromProfile() is the setting of the privacy
+	 * CFG based on the advertised privacy setting from the AP for WPA
+	 * associations. See note below in this function...
+	 */
+	uint32_t PrivacyEnabled = 0, RsnEnabled = 0, WepDefaultKeyId = 0;
+	uint32_t WepKeyLength = WNI_CFG_WEP_KEY_LENGTH_5;
+	uint32_t Key0Length = 0, Key1Length = 0, Key2Length = 0, Key3Length = 0;
+
+	/* Reserve for the biggest key */
+	uint8_t Key0[WNI_CFG_WEP_DEFAULT_KEY_1_LEN];
+	uint8_t Key1[WNI_CFG_WEP_DEFAULT_KEY_2_LEN];
+	uint8_t Key2[WNI_CFG_WEP_DEFAULT_KEY_3_LEN];
+	uint8_t Key3[WNI_CFG_WEP_DEFAULT_KEY_4_LEN];
+
+	switch (pProfile->negotiatedUCEncryptionType) {
+	case eCSR_ENCRYPT_TYPE_NONE:
+		/* for NO encryption, turn off Privacy and Rsn. */
+		PrivacyEnabled = 0;
+		RsnEnabled = 0;
+		/* clear out the WEP keys that may be hanging around. */
+		Key0Length = 0;
+		Key1Length = 0;
+		Key2Length = 0;
+		Key3Length = 0;
+		break;
+
+	case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
+	case eCSR_ENCRYPT_TYPE_WEP40:
+
+		/* Privacy is ON.  NO RSN for Wep40 static key. */
+		PrivacyEnabled = 1;
+		RsnEnabled = 0;
+		/* Set the Wep default key ID. */
+		WepDefaultKeyId = pProfile->Keys.defaultIndex;
+		/* Wep key size if 5 bytes (40 bits). */
+		WepKeyLength = WNI_CFG_WEP_KEY_LENGTH_5;
+		/*
+		 * set encryption keys in the CFG database or
+		 * clear those that are not present in this profile.
+		 */
+		if (pProfile->Keys.KeyLength[0]) {
+			cdf_mem_copy(Key0,
+				pProfile->Keys.KeyMaterial[0],
+				WNI_CFG_WEP_KEY_LENGTH_5);
+			Key0Length = WNI_CFG_WEP_KEY_LENGTH_5;
+		} else {
+			Key0Length = 0;
+		}
+
+		if (pProfile->Keys.KeyLength[1]) {
+			cdf_mem_copy(Key1,
+				pProfile->Keys.KeyMaterial[1],
+				WNI_CFG_WEP_KEY_LENGTH_5);
+			Key1Length = WNI_CFG_WEP_KEY_LENGTH_5;
+		} else {
+			Key1Length = 0;
+		}
+
+		if (pProfile->Keys.KeyLength[2]) {
+			cdf_mem_copy(Key2,
+				pProfile->Keys.KeyMaterial[2],
+				WNI_CFG_WEP_KEY_LENGTH_5);
+			Key2Length = WNI_CFG_WEP_KEY_LENGTH_5;
+		} else {
+			Key2Length = 0;
+		}
+
+		if (pProfile->Keys.KeyLength[3]) {
+			cdf_mem_copy(Key3,
+				pProfile->Keys.KeyMaterial[3],
+				WNI_CFG_WEP_KEY_LENGTH_5);
+			Key3Length = WNI_CFG_WEP_KEY_LENGTH_5;
+		} else {
+			Key3Length = 0;
+		}
+		break;
+
+	case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
+	case eCSR_ENCRYPT_TYPE_WEP104:
+
+		/* Privacy is ON.  NO RSN for Wep40 static key. */
+		PrivacyEnabled = 1;
+		RsnEnabled = 0;
+		/* Set the Wep default key ID. */
+		WepDefaultKeyId = pProfile->Keys.defaultIndex;
+		/* Wep key size if 13 bytes (104 bits). */
+		WepKeyLength = WNI_CFG_WEP_KEY_LENGTH_13;
+		/*
+		 * set encryption keys in the CFG database or clear
+		 * those that are not present in this profile.
+		 */
+		if (pProfile->Keys.KeyLength[0]) {
+			cdf_mem_copy(Key0,
+				pProfile->Keys.KeyMaterial[0],
+				WNI_CFG_WEP_KEY_LENGTH_13);
+			Key0Length = WNI_CFG_WEP_KEY_LENGTH_13;
+		} else {
+			Key0Length = 0;
+		}
+
+		if (pProfile->Keys.KeyLength[1]) {
+			cdf_mem_copy(Key1,
+				pProfile->Keys.KeyMaterial[1],
+				WNI_CFG_WEP_KEY_LENGTH_13);
+			Key1Length = WNI_CFG_WEP_KEY_LENGTH_13;
+		} else {
+			Key1Length = 0;
+		}
+
+		if (pProfile->Keys.KeyLength[2]) {
+			cdf_mem_copy(Key2,
+				pProfile->Keys.KeyMaterial[2],
+				WNI_CFG_WEP_KEY_LENGTH_13);
+			Key2Length = WNI_CFG_WEP_KEY_LENGTH_13;
+		} else {
+			Key2Length = 0;
+		}
+
+		if (pProfile->Keys.KeyLength[3]) {
+			cdf_mem_copy(Key3,
+				pProfile->Keys.KeyMaterial[3],
+				WNI_CFG_WEP_KEY_LENGTH_13);
+			Key3Length = WNI_CFG_WEP_KEY_LENGTH_13;
+		} else {
+			Key3Length = 0;
+		}
+		break;
+
+	case eCSR_ENCRYPT_TYPE_TKIP:
+	case eCSR_ENCRYPT_TYPE_AES:
+#ifdef FEATURE_WLAN_WAPI
+	case eCSR_ENCRYPT_TYPE_WPI:
+#endif /* FEATURE_WLAN_WAPI */
+		/*
+		 * this is the only difference between this function and
+		 * the csr_set_cfg_privacyFromProfile().
+		 * (setting of the privacy CFG based on the advertised
+		 *  privacy setting from AP for WPA/WAPI associations).
+		 */
+		PrivacyEnabled = (0 != fPrivacy);
+		/* turn on RSN enabled for WPA associations */
+		RsnEnabled = 1;
+		/* clear static WEP keys that may be hanging around. */
+		Key0Length = 0;
+		Key1Length = 0;
+		Key2Length = 0;
+		Key3Length = 0;
+		break;
+	default:
+		PrivacyEnabled = 0;
+		RsnEnabled = 0;
+		break;
+	}
+
+	cfg_set_int(pMac, WNI_CFG_PRIVACY_ENABLED, PrivacyEnabled);
+	cfg_set_int(pMac, WNI_CFG_RSN_ENABLED, RsnEnabled);
+	cfg_set_str(pMac, WNI_CFG_WEP_DEFAULT_KEY_1, Key0, Key0Length);
+	cfg_set_str(pMac, WNI_CFG_WEP_DEFAULT_KEY_2, Key1, Key1Length);
+	cfg_set_str(pMac, WNI_CFG_WEP_DEFAULT_KEY_3, Key2, Key2Length);
+	cfg_set_str(pMac, WNI_CFG_WEP_DEFAULT_KEY_4, Key3, Key3Length);
+	cfg_set_int(pMac, WNI_CFG_WEP_KEY_LENGTH, WepKeyLength);
+	cfg_set_int(pMac, WNI_CFG_WEP_DEFAULT_KEYID, WepDefaultKeyId);
+}
+
+static void csr_set_cfg_ssid(tpAniSirGlobal pMac, tSirMacSSid *pSSID)
+{
+	uint32_t len = 0;
+	if (pSSID->length <= WNI_CFG_SSID_LEN) {
+		len = pSSID->length;
+	}
+	cfg_set_str(pMac, WNI_CFG_SSID, (uint8_t *) pSSID->ssId, len);
+}
+
+CDF_STATUS csr_set_qos_to_cfg(tpAniSirGlobal pMac, uint32_t sessionId,
+			      eCsrMediaAccessType qosType)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	uint32_t QoSEnabled;
+	uint32_t WmeEnabled;
+	/* set the CFG enable/disable variables based on the qosType being configured... */
+	switch (qosType) {
+	case eCSR_MEDIUM_ACCESS_WMM_eDCF_802dot1p:
+		QoSEnabled = false;
+		WmeEnabled = true;
+		break;
+	case eCSR_MEDIUM_ACCESS_WMM_eDCF_DSCP:
+		QoSEnabled = false;
+		WmeEnabled = true;
+		break;
+	case eCSR_MEDIUM_ACCESS_WMM_eDCF_NoClassify:
+		QoSEnabled = false;
+		WmeEnabled = true;
+		break;
+	case eCSR_MEDIUM_ACCESS_11e_eDCF:
+		QoSEnabled = true;
+		WmeEnabled = false;
+		break;
+	case eCSR_MEDIUM_ACCESS_11e_HCF:
+		QoSEnabled = true;
+		WmeEnabled = false;
+		break;
+	default:
+	case eCSR_MEDIUM_ACCESS_DCF:
+		QoSEnabled = false;
+		WmeEnabled = false;
+		break;
+	}
+	/* save the WMM setting for later use */
+	pMac->roam.roamSession[sessionId].fWMMConnection = (bool) WmeEnabled;
+	pMac->roam.roamSession[sessionId].fQOSConnection = (bool) QoSEnabled;
+	return status;
+}
+
+static CDF_STATUS csr_get_rate_set(tpAniSirGlobal pMac,
+				tCsrRoamProfile *pProfile, eCsrPhyMode phyMode,
+				tSirBssDescription *pBssDesc,
+				tDot11fBeaconIEs *pIes,
+				tSirMacRateSet *pOpRateSet,
+				tSirMacRateSet *pExRateSet)
+{
+	CDF_STATUS status = CDF_STATUS_E_FAILURE;
+	int i;
+	eCsrCfgDot11Mode cfgDot11Mode;
+	uint8_t *pDstRate;
+	uint16_t rateBitmap = 0;
+	cdf_mem_set(pOpRateSet, sizeof(tSirMacRateSet), 0);
+	cdf_mem_set(pExRateSet, sizeof(tSirMacRateSet), 0);
+	CDF_ASSERT(pIes != NULL);
+
+	if (NULL == pIes) {
+		sms_log(pMac, LOGE, FL("failed to parse BssDesc"));
+		return status;
+	}
+
+	csr_is_phy_mode_match(pMac, phyMode, pBssDesc, pProfile,
+			      &cfgDot11Mode, pIes);
+	/*
+	 * Originally, we thought that for 11a networks, the 11a rates
+	 * are always in the Operational Rate set & for 11b and 11g
+	 * networks, the 11b rates appear in the Operational Rate set.
+	 * Consequently, in either case, we would blindly put the rates
+	 * we support into our Operational Rate set.
+	 * (including the basic rates, which we've already verified are
+	 * supported earlier in the roaming decision).
+	 * However, it turns out that this is not always the case.
+	 * Some AP's (e.g. D-Link DI-784) ram 11g rates into the
+	 * Operational Rate set too.  Now, we're a little more careful.
+	 */
+	pDstRate = pOpRateSet->rate;
+	if (pIes->SuppRates.present) {
+		for (i = 0; i < pIes->SuppRates.num_rates; i++) {
+			if (csr_rates_is_dot11_rate_supported(pMac,
+				pIes->SuppRates.rates[i]) &&
+				!csr_check_rate_bitmap(
+					pIes->SuppRates.rates[i],
+					rateBitmap)) {
+				csr_add_rate_bitmap(pIes->SuppRates.
+						    rates[i], &rateBitmap);
+				*pDstRate++ = pIes->SuppRates.rates[i];
+				pOpRateSet->numRates++;
+			}
+		}
+	}
+	if ((eCSR_CFG_DOT11_MODE_11G == cfgDot11Mode ||
+	    eCSR_CFG_DOT11_MODE_11N == cfgDot11Mode ||
+	    eCSR_CFG_DOT11_MODE_ABG == cfgDot11Mode
+#ifdef WLAN_FEATURE_11AC
+	    || eCSR_CFG_DOT11_MODE_11AC == cfgDot11Mode
+#endif
+	    ) && pIes->ExtSuppRates.present) {
+		/*
+		 * If there are extended rates in the beacon,
+		 * we will reflect those extended rates that we support in our
+		 * extended operational rate
+		 */
+		pDstRate = pExRateSet->rate;
+		for (i = 0; i < pIes->ExtSuppRates.num_rates; i++) {
+			if (csr_rates_is_dot11_rate_supported(pMac,
+				pIes->ExtSuppRates.rates[i]) &&
+				!csr_check_rate_bitmap(
+					pIes->ExtSuppRates.rates[i],
+					rateBitmap)) {
+				*pDstRate++ = pIes->ExtSuppRates.rates[i];
+				pExRateSet->numRates++;
+			}
+		}
+	}
+	if (pOpRateSet->numRates > 0 || pExRateSet->numRates > 0)
+		status = CDF_STATUS_SUCCESS;
+	return status;
+}
+
+static void csr_set_cfg_rate_set(tpAniSirGlobal pMac, eCsrPhyMode phyMode,
+				 tCsrRoamProfile *pProfile,
+				 tSirBssDescription *pBssDesc,
+				 tDot11fBeaconIEs *pIes)
+{
+	int i;
+	uint8_t *pDstRate;
+	eCsrCfgDot11Mode cfgDot11Mode;
+	uint8_t OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];        /* leave enough room for the max number of rates */
+	uint32_t OperationalRatesLength = 0;
+	uint8_t ExtendedOperationalRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];       /* leave enough room for the max number of rates */
+	uint32_t ExtendedOperationalRatesLength = 0;
+	uint8_t MCSRateIdxSet[SIZE_OF_SUPPORTED_MCS_SET];
+	uint32_t MCSRateLength = 0;
+	CDF_ASSERT(pIes != NULL);
+	if (NULL != pIes) {
+		csr_is_phy_mode_match(pMac, phyMode, pBssDesc, pProfile,
+				      &cfgDot11Mode, pIes);
+		/* Originally, we thought that for 11a networks, the 11a rates are always */
+		/* in the Operational Rate set & for 11b and 11g networks, the 11b rates */
+		/* appear in the Operational Rate set.  Consequently, in either case, we */
+		/* would blindly put the rates we support into our Operational Rate set */
+		/* (including the basic rates, which we have already verified are */
+		/* supported earlier in the roaming decision). */
+		/* However, it turns out that this is not always the case.  Some AP's */
+		/* (e.g. D-Link DI-784) ram 11g rates into the Operational Rate set, */
+		/* too.  Now, we're a little more careful: */
+		pDstRate = OperationalRates;
+		if (pIes->SuppRates.present) {
+			for (i = 0; i < pIes->SuppRates.num_rates; i++) {
+				if (csr_rates_is_dot11_rate_supported
+					    (pMac, pIes->SuppRates.rates[i])
+				    && (OperationalRatesLength <
+					CSR_DOT11_SUPPORTED_RATES_MAX)) {
+					*pDstRate++ = pIes->SuppRates.rates[i];
+					OperationalRatesLength++;
+				}
+			}
+		}
+		if (eCSR_CFG_DOT11_MODE_11G == cfgDot11Mode ||
+		    eCSR_CFG_DOT11_MODE_11N == cfgDot11Mode ||
+		    eCSR_CFG_DOT11_MODE_ABG == cfgDot11Mode) {
+			/* If there are Extended Rates in the beacon, we will reflect those */
+			/* extended rates that we support in out Extended Operational Rate */
+			/* set: */
+			pDstRate = ExtendedOperationalRates;
+			if (pIes->ExtSuppRates.present) {
+				for (i = 0; i < pIes->ExtSuppRates.num_rates;
+				     i++) {
+					if (csr_rates_is_dot11_rate_supported
+						    (pMac, pIes->ExtSuppRates.rates[i])
+					    && (ExtendedOperationalRatesLength <
+						CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX)) {
+						*pDstRate++ =
+							pIes->ExtSuppRates.rates[i];
+						ExtendedOperationalRatesLength++;
+					}
+				}
+			}
+		}
+		/* Enable proprietary MAC features if peer node is Airgo node and STA */
+		/* user wants to use them */
+		/* For ANI network companions, we need to populate the proprietary rate */
+		/* set with any proprietary rates we found in the beacon, only if user */
+		/* allows them... */
+			/* No proprietary modes... */
+		/* Get MCS Rate */
+		pDstRate = MCSRateIdxSet;
+		if (pIes->HTCaps.present) {
+			for (i = 0; i < VALID_MAX_MCS_INDEX; i++) {
+				if ((unsigned int)pIes->HTCaps.
+				    supportedMCSSet[0] & (1 << i)) {
+					MCSRateLength++;
+					*pDstRate++ = i;
+				}
+			}
+		}
+		/* Set the operational rate set CFG variables... */
+		cfg_set_str(pMac, WNI_CFG_OPERATIONAL_RATE_SET,
+				OperationalRates, OperationalRatesLength);
+		cfg_set_str(pMac, WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
+				ExtendedOperationalRates,
+				ExtendedOperationalRatesLength);
+		cfg_set_str(pMac, WNI_CFG_CURRENT_MCS_SET, MCSRateIdxSet,
+				MCSRateLength);
+	} /* Parsing BSSDesc */
+	else {
+		sms_log(pMac, LOGE, FL("failed to parse BssDesc"));
+	}
+}
+
+static void csr_set_cfg_rate_set_from_profile(tpAniSirGlobal pMac,
+					      tCsrRoamProfile *pProfile)
+{
+	tSirMacRateSetIE DefaultSupportedRates11a = { SIR_MAC_RATESET_EID,
+						      {8,
+						       {SIR_MAC_RATE_6,
+							SIR_MAC_RATE_9,
+							SIR_MAC_RATE_12,
+							SIR_MAC_RATE_18,
+							SIR_MAC_RATE_24,
+							SIR_MAC_RATE_36,
+							SIR_MAC_RATE_48,
+							SIR_MAC_RATE_54} } };
+	tSirMacRateSetIE DefaultSupportedRates11b = { SIR_MAC_RATESET_EID,
+						      {4,
+						       {SIR_MAC_RATE_1,
+							SIR_MAC_RATE_2,
+							SIR_MAC_RATE_5_5,
+							SIR_MAC_RATE_11} } };
+
+	tSirMacPropRateSet DefaultSupportedPropRates = { 3,
+							 {SIR_MAC_RATE_72,
+							  SIR_MAC_RATE_96,
+							  SIR_MAC_RATE_108} };
+	eCsrCfgDot11Mode cfgDot11Mode;
+	eCsrBand eBand;
+	/* leave enough room for the max number of rates */
+	uint8_t OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
+	uint32_t OperationalRatesLength = 0;
+	/* leave enough room for the max number of rates */
+	uint8_t ExtendedOperationalRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
+	uint32_t ExtendedOperationalRatesLength = 0;
+	/* leave enough room for the max number of proprietary rates */
+	uint8_t ProprietaryOperationalRates[4];
+	uint32_t ProprietaryOperationalRatesLength = 0;
+	uint32_t PropRatesEnable = 0;
+	uint8_t operationChannel = 0;
+	if (pProfile->ChannelInfo.ChannelList) {
+		operationChannel = pProfile->ChannelInfo.ChannelList[0];
+	}
+	cfgDot11Mode =
+		csr_roam_get_phy_mode_band_for_bss(pMac, pProfile, operationChannel,
+						   &eBand);
+	/* For 11a networks, the 11a rates go into the Operational Rate set.  For 11b and 11g */
+	/* networks, the 11b rates appear in the Operational Rate set.  In either case, */
+	/* we can blindly put the rates we support into our Operational Rate set */
+	/* (including the basic rates, which we have already verified are supported */
+	/* earlier in the roaming decision). */
+	if (eCSR_BAND_5G == eBand) {
+		/* 11a rates into the Operational Rate Set. */
+		OperationalRatesLength =
+			DefaultSupportedRates11a.supportedRateSet.numRates *
+			sizeof(*DefaultSupportedRates11a.supportedRateSet.rate);
+		cdf_mem_copy(OperationalRates,
+			     DefaultSupportedRates11a.supportedRateSet.rate,
+			     OperationalRatesLength);
+
+		/* Nothing in the Extended rate set. */
+		ExtendedOperationalRatesLength = 0;
+		/* populate proprietary rates if user allows them */
+		if (pMac->roam.configParam.ProprietaryRatesEnabled) {
+			ProprietaryOperationalRatesLength =
+				DefaultSupportedPropRates.numPropRates *
+				sizeof(*DefaultSupportedPropRates.propRate);
+			cdf_mem_copy(ProprietaryOperationalRates,
+				     DefaultSupportedPropRates.propRate,
+				     ProprietaryOperationalRatesLength);
+		} else {
+			/* No proprietary modes */
+			ProprietaryOperationalRatesLength = 0;
+		}
+	} else if (eCSR_CFG_DOT11_MODE_11B == cfgDot11Mode) {
+		/* 11b rates into the Operational Rate Set. */
+		OperationalRatesLength =
+			DefaultSupportedRates11b.supportedRateSet.numRates *
+			sizeof(*DefaultSupportedRates11b.supportedRateSet.rate);
+		cdf_mem_copy(OperationalRates,
+			     DefaultSupportedRates11b.supportedRateSet.rate,
+			     OperationalRatesLength);
+		/* Nothing in the Extended rate set. */
+		ExtendedOperationalRatesLength = 0;
+		/* No proprietary modes */
+		ProprietaryOperationalRatesLength = 0;
+	} else {
+		/* 11G */
+
+		/* 11b rates into the Operational Rate Set. */
+		OperationalRatesLength =
+			DefaultSupportedRates11b.supportedRateSet.numRates *
+			sizeof(*DefaultSupportedRates11b.supportedRateSet.rate);
+		cdf_mem_copy(OperationalRates,
+			     DefaultSupportedRates11b.supportedRateSet.rate,
+			     OperationalRatesLength);
+
+		/* 11a rates go in the Extended rate set. */
+		ExtendedOperationalRatesLength =
+			DefaultSupportedRates11a.supportedRateSet.numRates *
+			sizeof(*DefaultSupportedRates11a.supportedRateSet.rate);
+		cdf_mem_copy(ExtendedOperationalRates,
+			     DefaultSupportedRates11a.supportedRateSet.rate,
+			     ExtendedOperationalRatesLength);
+
+		/* populate proprietary rates if user allows them */
+		if (pMac->roam.configParam.ProprietaryRatesEnabled) {
+			ProprietaryOperationalRatesLength =
+				DefaultSupportedPropRates.numPropRates *
+				sizeof(*DefaultSupportedPropRates.propRate);
+			cdf_mem_copy(ProprietaryOperationalRates,
+				     DefaultSupportedPropRates.propRate,
+				     ProprietaryOperationalRatesLength);
+		} else {
+			/* No proprietary modes */
+			ProprietaryOperationalRatesLength = 0;
+		}
+	}
+	/* set this to 1 if prop. rates need to be advertised in to the IBSS beacon and user wants to use them */
+	if (ProprietaryOperationalRatesLength
+	    && pMac->roam.configParam.ProprietaryRatesEnabled) {
+		PropRatesEnable = 1;
+	} else {
+		PropRatesEnable = 0;
+	}
+
+	/* Set the operational rate set CFG variables... */
+	cfg_set_str(pMac, WNI_CFG_OPERATIONAL_RATE_SET, OperationalRates,
+			OperationalRatesLength);
+	cfg_set_str(pMac, WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
+			ExtendedOperationalRates, ExtendedOperationalRatesLength);
+	cfg_set_str(pMac, WNI_CFG_PROPRIETARY_OPERATIONAL_RATE_SET,
+			ProprietaryOperationalRates,
+			ProprietaryOperationalRatesLength);
+}
+
+void csr_roam_ccm_cfg_set_callback(tpAniSirGlobal pMac, int32_t result)
+{
+	tListElem *pEntry =
+		csr_ll_peek_head(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK);
+	uint32_t sessionId;
+	tSmeCmd *pCommand = NULL;
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	tCsrRoamSession *pSession = NULL;
+#endif
+	if (NULL == pEntry) {
+		sms_log(pMac, LOGW, "CFG_CNF with active list empty");
+		return;
+	}
+	pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
+	sessionId = pCommand->sessionId;
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	pSession = &pMac->roam.roamSession[sessionId];
+	if (pSession->roamOffloadSynchParams.bRoamSynchInProgress) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
+			  "LFR3:csr_roam_cfg_set_callback");
+	}
+#endif
+
+	if (CSR_IS_ROAM_JOINING(pMac, sessionId)
+	    && CSR_IS_ROAM_SUBSTATE_CONFIG(pMac, sessionId)) {
+		csr_roaming_state_config_cnf_processor(pMac, (uint32_t) result);
+	}
+}
+
+/* This function is very dump. It is here because PE still need WNI_CFG_PHY_MODE */
+uint32_t csr_roam_get_phy_mode_from_dot11_mode(eCsrCfgDot11Mode dot11Mode,
+					       eCsrBand band)
+{
+	if (eCSR_CFG_DOT11_MODE_11B == dot11Mode) {
+		return WNI_CFG_PHY_MODE_11B;
+	} else {
+		if (eCSR_BAND_24 == band)
+			return WNI_CFG_PHY_MODE_11G;
+	}
+	return WNI_CFG_PHY_MODE_11A;
+}
+
+#ifdef WLAN_FEATURE_11AC
+ePhyChanBondState csr_get_htcb_state_from_vhtcb_state(ePhyChanBondState aniCBMode)
+{
+	switch (aniCBMode) {
+	case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW:
+	case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED:
+	case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH:
+		return PHY_DOUBLE_CHANNEL_HIGH_PRIMARY;
+	case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW:
+	case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED:
+	case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH:
+		return PHY_DOUBLE_CHANNEL_LOW_PRIMARY;
+	case PHY_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED:
+	default:
+		return PHY_SINGLE_CHANNEL_CENTERED;
+	}
+}
+#endif
+
+/* pIes may be NULL */
+CDF_STATUS csr_roam_set_bss_config_cfg(tpAniSirGlobal pMac, uint32_t sessionId,
+				       tCsrRoamProfile *pProfile,
+				       tSirBssDescription *pBssDesc,
+				       tBssConfigParam *pBssConfig,
+				       tDot11fBeaconIEs *pIes, bool resetCountry)
+{
+	tSirRetStatus status;
+	uint32_t cfgCb = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
+	uint8_t channel = 0;
+	/* Make sure we have the domain info for the BSS we try to connect to. */
+	/* Do we need to worry about sequence for OSs that are not Windows?? */
+	if (pBssDesc) {
+		if (csr_learn_11dcountry_information(pMac, pBssDesc, pIes, true)) {
+				csr_apply_country_information(pMac);
+		}
+		if ((csr_is11d_supported(pMac)) && pIes) {
+			if (!pIes->Country.present) {
+				csr_apply_channel_power_info_wrapper(pMac);
+			} else {
+				/* Let's also update the below to make sure we don't update CC while */
+				/* connected to an AP which is advertising some CC */
+				cdf_mem_copy(pMac->scan.currentCountryBssid.bytes,
+					     pBssDesc->bssId,
+					     sizeof(tSirMacAddr));
+			}
+		}
+	}
+	/* Qos */
+	csr_set_qos_to_cfg(pMac, sessionId, pBssConfig->qosType);
+	/* SSID */
+	csr_set_cfg_ssid(pMac, &pBssConfig->SSID);
+
+	/* Auth type */
+	cfg_set_int(pMac, WNI_CFG_AUTHENTICATION_TYPE, pBssConfig->authType);
+	/* encryption type */
+	csr_set_cfg_privacy(pMac, pProfile, (bool) pBssConfig->BssCap.privacy);
+	/* short slot time */
+	cfg_set_int(pMac, WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED,
+			pBssConfig->uShortSlotTime);
+	/* 11d */
+	cfg_set_int(pMac, WNI_CFG_11D_ENABLED,
+			((pBssConfig->f11hSupport) ? pBssConfig->f11hSupport :
+			 pProfile->ieee80211d));
+	cfg_set_int(pMac, WNI_CFG_LOCAL_POWER_CONSTRAINT,
+			pBssConfig->uPowerLimit);
+	/* CB */
+
+	if (CSR_IS_INFRA_AP(pProfile) || CSR_IS_WDS_AP(pProfile)
+	    || CSR_IS_IBSS(pProfile)) {
+		channel = pProfile->operationChannel;
+	} else {
+		if (pBssDesc) {
+			channel = pBssDesc->channelId;
+		}
+	}
+	if (0 != channel) {
+		if (CDS_IS_CHANNEL_24GHZ(channel)) {    /* for now if we are on 2.4 Ghz, CB will be always disabled */
+			cfgCb = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
+		} else {
+			cfgCb = pBssConfig->cbMode;
+		}
+	}
+	/* Rate */
+	/* Fixed Rate */
+	if (pBssDesc) {
+		csr_set_cfg_rate_set(pMac, (eCsrPhyMode) pProfile->phyMode,
+				     pProfile, pBssDesc, pIes);
+	} else {
+		csr_set_cfg_rate_set_from_profile(pMac, pProfile);
+	}
+	/* Make this the last CFG to set. The callback will trigger a join_req */
+	/* Join time out */
+	csr_roam_substate_change(pMac, eCSR_ROAM_SUBSTATE_CONFIG, sessionId);
+
+	status = cfg_set_int(pMac, WNI_CFG_JOIN_FAILURE_TIMEOUT,
+			pBssConfig->uJoinTimeOut);
+	csr_roam_ccm_cfg_set_callback(pMac, status);
+	return CDF_STATUS_SUCCESS;
+}
+
+CDF_STATUS csr_roam_stop_network(tpAniSirGlobal pMac, uint32_t sessionId,
+				 tCsrRoamProfile *pProfile,
+				 tSirBssDescription *pBssDesc,
+				 tDot11fBeaconIEs *pIes)
+{
+	CDF_STATUS status;
+	tBssConfigParam *pBssConfig;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("  session %d not found "), sessionId);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	pBssConfig = cdf_mem_malloc(sizeof(tBssConfigParam));
+	if (NULL == pBssConfig)
+		return CDF_STATUS_E_NOMEM;
+
+	cdf_mem_set(pBssConfig, sizeof(tBssConfigParam), 0);
+	status = csr_roam_prepare_bss_config(pMac, pProfile, pBssDesc,
+			pBssConfig, pIes);
+	if (CDF_IS_STATUS_SUCCESS(status)) {
+		eCsrRoamSubState substate;
+		substate = eCSR_ROAM_SUBSTATE_DISCONNECT_CONTINUE_ROAMING;
+		pSession->bssParams.uCfgDot11Mode = pBssConfig->uCfgDot11Mode;
+		/* This will allow to pass cbMode during join req */
+		pSession->bssParams.cbMode = pBssConfig->cbMode;
+		/* For IBSS, we need to prepare some more information */
+		if (csr_is_bss_type_ibss(pProfile->BSSType) ||
+				CSR_IS_WDS(pProfile) ||
+				CSR_IS_INFRA_AP(pProfile))
+			csr_roam_prepare_bss_params(pMac, sessionId, pProfile,
+				pBssDesc, pBssConfig, pIes);
+
+		/*
+		 * If we are in an IBSS, then stop the IBSS...
+		 * Not worry about WDS connection for now
+		 */
+		if (csr_is_conn_state_ibss(pMac, sessionId)) {
+			status = csr_roam_issue_stop_bss(pMac, sessionId,
+					substate);
+		} else if (csr_is_conn_state_infra(pMac, sessionId)) {
+			/*
+			 * the new Bss is an Ibss OR we are roaming from
+			 * Infra to Infra across SSIDs
+			 * (roaming to a new SSID)...
+			 * Not worry about WDS connection for now
+			 */
+			if (pBssDesc && (csr_is_ibss_bss_desc(pBssDesc) ||
+				!csr_is_ssid_equal(pMac,
+					pSession->pConnectBssDesc,
+					pBssDesc, pIes)))
+				status = csr_roam_issue_disassociate(pMac,
+						sessionId, substate, false);
+			else if (pBssDesc)
+				/*
+				 * In an infra & going to an infra network with
+				 * the same SSID.  This calls for a reassoc seq.
+				 * So issue the CFG sets for this new AP. Set
+				 * parameters for this Bss.
+				 */
+				status = csr_roam_set_bss_config_cfg(pMac,
+						sessionId, pProfile, pBssDesc,
+						pBssConfig, pIes, false);
+		} else if (pBssDesc || CSR_IS_WDS_AP(pProfile) ||
+					CSR_IS_INFRA_AP(pProfile)) {
+			/*
+			 * Neither in IBSS nor in Infra. We can go ahead and set
+			 * the cfg for tne new network... nothing to stop.
+			 */
+			bool is11rRoamingFlag = false;
+			is11rRoamingFlag = csr_roam_is11r_assoc(pMac,
+							sessionId);
+			/* Set parameters for this Bss. */
+			status = csr_roam_set_bss_config_cfg(pMac, sessionId,
+					pProfile, pBssDesc, pBssConfig, pIes,
+					is11rRoamingFlag);
+		}
+	} /* Success getting BSS config info */
+	cdf_mem_free(pBssConfig);
+	return status;
+}
+
+/**
+ * csr_roam_state_for_same_profile() - Determine roam state for same profile
+ * @mac_ctx: pointer to mac context
+ * @profile: Roam profile
+ * @session: Roam session
+ * @session_id: session id
+ * @ies_local: local ies
+ * @bss_descr: bss description
+ *
+ * This function will determine the roam state for same profile
+ *
+ * Return: Roaming state.
+ */
+static eCsrJoinState csr_roam_state_for_same_profile(tpAniSirGlobal mac_ctx,
+			tCsrRoamProfile *profile, tCsrRoamSession *session,
+			uint32_t session_id, tDot11fBeaconIEs *ies_local,
+			tSirBssDescription *bss_descr)
+{
+	CDF_STATUS status;
+	tBssConfigParam bssConfig;
+	if (csr_roam_is_same_profile_keys(mac_ctx, &session->connectedProfile,
+				profile))
+		return eCsrReassocToSelfNoCapChange;
+	/* The key changes */
+	cdf_mem_set(&bssConfig, sizeof(bssConfig), 0);
+	status = csr_roam_prepare_bss_config(mac_ctx, profile, bss_descr,
+				&bssConfig, ies_local);
+	if (CDF_IS_STATUS_SUCCESS(status)) {
+		session->bssParams.uCfgDot11Mode =
+				bssConfig.uCfgDot11Mode;
+		session->bssParams.cbMode =
+				bssConfig.cbMode;
+		/* reapply the cfg including keys so reassoc happens. */
+		status = csr_roam_set_bss_config_cfg(mac_ctx, session_id,
+				profile, bss_descr, &bssConfig,
+				ies_local, false);
+		if (CDF_IS_STATUS_SUCCESS(status))
+			return eCsrContinueRoaming;
+	}
+
+	return eCsrStopRoaming;
+
+}
+
+eCsrJoinState csr_roam_join(tpAniSirGlobal pMac, uint32_t sessionId,
+			    tCsrScanResultInfo *pScanResult,
+			    tCsrRoamProfile *pProfile)
+{
+	eCsrJoinState eRoamState = eCsrContinueRoaming;
+	tSirBssDescription *pBssDesc = &pScanResult->BssDescriptor;
+	tDot11fBeaconIEs *pIesLocal = (tDot11fBeaconIEs *) (pScanResult->pvIes);
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("session %d not found"), sessionId);
+		return eCsrStopRoaming;
+	}
+
+	if (CSR_IS_WDS_STA(pProfile) &&
+		!CDF_IS_STATUS_SUCCESS(csr_roam_start_wds(pMac, sessionId,
+				pProfile, pBssDesc)))
+		return eCsrStopRoaming;
+	if (!pIesLocal &&
+		!CDF_IS_STATUS_SUCCESS(csr_get_parsed_bss_description_ies(pMac,
+				pBssDesc, &pIesLocal))) {
+		sms_log(pMac, LOGE, FL("fail to parse IEs"));
+		return eCsrStopRoaming;
+	}
+	if (csr_is_infra_bss_desc(pBssDesc)) {
+		/*
+		 * If we are connected in infra mode and the join bss descr is
+		 * for the same BssID, then we are attempting to join the AP we
+		 * are already connected with.  In that case, see if the Bss or
+		 * sta capabilities have changed and handle the changes
+		 * without disturbing the current association
+		 */
+
+		if (csr_is_conn_state_connected_infra(pMac, sessionId) &&
+			csr_is_bss_id_equal(pMac,
+				pBssDesc, pSession->pConnectBssDesc) &&
+			csr_is_ssid_equal(pMac, pSession->pConnectBssDesc,
+				pBssDesc, pIesLocal)) {
+			/*
+			 * Check to see if the Auth type has changed in the
+			 * profile.  If so, we don't want to reassociate with
+			 * authenticating first.  To force this, stop the
+			 * current association (Disassociate) and then re 'Join'
+			 * the AP, wihch will force an Authentication (with the
+			 * new Auth type) followed by a new Association.
+			 */
+			if (csr_is_same_profile(pMac,
+				&pSession->connectedProfile, pProfile)) {
+				sms_log(pMac, LOGW,
+					FL("detect same profile"));
+				eRoamState =
+					csr_roam_state_for_same_profile(pMac,
+						pProfile, pSession, sessionId,
+						pIesLocal, pBssDesc);
+			} else if (!CDF_IS_STATUS_SUCCESS(
+					csr_roam_issue_disassociate(pMac,
+						sessionId,
+						eCSR_ROAM_SUBSTATE_DISASSOC_REQ,
+						false))) {
+					sms_log(pMac, LOGE,
+						FL("fail disassoc session %d"),
+						sessionId);
+					eRoamState = eCsrStopRoaming;
+			}
+		} else if (!CDF_IS_STATUS_SUCCESS(csr_roam_stop_network(pMac,
+				sessionId, pProfile, pBssDesc, pIesLocal))) {
+				/* we used to pre-auth here with open auth
+				 * networks but that wasn't working so well.
+				 * stop the existing network before attempting
+				 * to join the new network... */
+				eRoamState = eCsrStopRoaming;
+		}
+	} else if (!CDF_IS_STATUS_SUCCESS(csr_roam_stop_network(pMac, sessionId,
+						pProfile, pBssDesc,
+						pIesLocal))) {
+			eRoamState = eCsrStopRoaming;
+	}
+
+	if (pIesLocal && !pScanResult->pvIes)
+		cdf_mem_free(pIesLocal);
+	return eRoamState;
+}
+
+CDF_STATUS csr_roam_should_roam(tpAniSirGlobal pMac, uint32_t sessionId,
+				tSirBssDescription *pBssDesc, uint32_t roamId)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tCsrRoamInfo roamInfo;
+	cdf_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0);
+	roamInfo.pBssDesc = pBssDesc;
+	status =
+		csr_roam_call_callback(pMac, sessionId, &roamInfo, roamId,
+				       eCSR_ROAM_SHOULD_ROAM, eCSR_ROAM_RESULT_NONE);
+	return status;
+}
+
+/* In case no matching BSS is found, use whatever default we can find */
+static void csr_roam_assign_default_param(tpAniSirGlobal pMac, tSmeCmd *pCommand)
+{
+	/* Need to get all negotiated types in place first */
+	/* auth type */
+	/* Take the preferred Auth type. */
+	switch (pCommand->u.roamCmd.roamProfile.AuthType.authType[0]) {
+	default:
+	case eCSR_AUTH_TYPE_WPA:
+	case eCSR_AUTH_TYPE_WPA_PSK:
+	case eCSR_AUTH_TYPE_WPA_NONE:
+	case eCSR_AUTH_TYPE_OPEN_SYSTEM:
+		pCommand->u.roamCmd.roamProfile.negotiatedAuthType =
+			eCSR_AUTH_TYPE_OPEN_SYSTEM;
+		break;
+
+	case eCSR_AUTH_TYPE_SHARED_KEY:
+		pCommand->u.roamCmd.roamProfile.negotiatedAuthType =
+			eCSR_AUTH_TYPE_SHARED_KEY;
+		break;
+
+	case eCSR_AUTH_TYPE_AUTOSWITCH:
+		pCommand->u.roamCmd.roamProfile.negotiatedAuthType =
+			eCSR_AUTH_TYPE_AUTOSWITCH;
+		break;
+	}
+	pCommand->u.roamCmd.roamProfile.negotiatedUCEncryptionType =
+		pCommand->u.roamCmd.roamProfile.EncryptionType.encryptionType[0];
+	/* In this case, the multicast encryption needs to follow the uncast ones. */
+	pCommand->u.roamCmd.roamProfile.negotiatedMCEncryptionType =
+		pCommand->u.roamCmd.roamProfile.EncryptionType.encryptionType[0];
+}
+
+static void csr_set_abort_roaming_command(tpAniSirGlobal pMac, tSmeCmd *pCommand)
+{
+	switch (pCommand->u.roamCmd.roamReason) {
+	case eCsrLostLink1:
+		pCommand->u.roamCmd.roamReason = eCsrLostLink1Abort;
+		break;
+	case eCsrLostLink2:
+		pCommand->u.roamCmd.roamReason = eCsrLostLink2Abort;
+		break;
+	case eCsrLostLink3:
+		pCommand->u.roamCmd.roamReason = eCsrLostLink3Abort;
+		break;
+	default:
+		sms_log(pMac, LOGE,
+			FL(" aborting roaming reason %d not recognized"),
+			pCommand->u.roamCmd.roamReason);
+		break;
+	}
+}
+
+/**
+ * csr_roam_select_bss() - Handle join scenario based on profile
+ * @mac_ctx:             Global MAC Context
+ * @roam_bss_entry:      The next BSS to join
+ * @csr_result_info:     Result of join
+ * @csr_scan_result:     Global scan result
+ * @session_id:          SME Session ID
+ * @roam_id:             Roaming ID
+ * @roam_state:          Current roaming state
+ * @bss_list:            BSS List
+ *
+ * Return: true if the entire BSS list is done, false otherwise.
+ */
+static bool csr_roam_select_bss(tpAniSirGlobal mac_ctx,
+		tListElem *roam_bss_entry, tCsrScanResultInfo **csr_result_info,
+		tCsrScanResult **csr_scan_result, uint32_t session_id,
+		uint32_t roam_id, eCsrJoinState *roam_state,
+		tScanResultList *bss_list)
+{
+	uint8_t conc_channel = 0;
+	bool status = false;
+	tCsrScanResult *scan_result = NULL;
+	tCsrScanResultInfo *result = NULL;
+
+	while (roam_bss_entry) {
+		scan_result = GET_BASE_ADDR(roam_bss_entry, tCsrScanResult,
+				Link);
+		/*
+		 * If concurrency enabled take the
+		 * concurrent connected channel first.
+		 * Valid multichannel concurrent
+		 * sessions exempted
+		 */
+		result = &scan_result->Result;
+		if (cds_concurrent_open_sessions_running() &&
+			!csr_is_valid_mc_concurrent_session(mac_ctx,
+					session_id, &result->BssDescriptor)) {
+			conc_channel = csr_get_concurrent_operation_channel(
+					mac_ctx);
+			sms_log(mac_ctx, LOG1, FL("csr Conc Channel = %d"),
+				conc_channel);
+			if ((conc_channel) && (conc_channel ==
+				result->BssDescriptor.channelId)) {
+				/*
+				 * make this 0 because we do not want the below
+				 * check to pass as we don't want to connect on
+				 * other channel
+				 */
+				sms_log(mac_ctx, LOG1, FL("Conc chnl match=%d"),
+					conc_channel);
+				conc_channel = 0;
+			}
+		}
+
+		/* Ok to roam this */
+		if (!conc_channel &&
+			CDF_IS_STATUS_SUCCESS(csr_roam_should_roam(mac_ctx,
+				session_id, &result->BssDescriptor, roam_id))) {
+			status = false;
+			break;
+		} else {
+			*roam_state = eCsrStopRoamingDueToConcurrency;
+			status = true;
+		}
+		roam_bss_entry = csr_ll_next(&bss_list->List, roam_bss_entry,
+					LL_ACCESS_LOCK);
+	}
+	*csr_result_info = result;
+	*csr_scan_result = scan_result;
+	return status;
+}
+
+/**
+ * csr_roam_join_handle_profile() - Handle join scenario based on profile
+ * @mac_ctx:             Global MAC Context
+ * @session_id:          SME Session ID
+ * @cmd:                 Command
+ * @roam_info_ptr:       Pointed to the roaming info for join
+ * @roam_state:          Current roaming state
+ * @result:              Result of join
+ * @scan_result:         Global scan result
+ *
+ * Return: None
+ */
+static void csr_roam_join_handle_profile(tpAniSirGlobal mac_ctx,
+		uint32_t session_id, tSmeCmd *cmd, tCsrRoamInfo *roam_info_ptr,
+		eCsrJoinState *roam_state, tCsrScanResultInfo *result,
+		tCsrScanResult *scan_result)
+{
+#ifndef WLAN_MDM_CODE_REDUCTION_OPT
+	uint8_t acm_mask = 0;
+#endif
+	CDF_STATUS status;
+	tCsrRoamSession *session = CSR_GET_SESSION(mac_ctx, session_id);
+	tCsrRoamProfile *profile = &cmd->u.roamCmd.roamProfile;
+	tDot11fBeaconIEs *ies_local = NULL;
+	/*
+	 * We have something to roam, tell HDD when it is infra.
+	 * For IBSS, the indication goes back to HDD via eCSR_ROAM_IBSS_IND
+	 * For WDS, the indication is eCSR_ROAM_WDS_IND
+	 */
+	if (CSR_IS_INFRASTRUCTURE(profile)) {
+		if (roam_info_ptr && session->bRefAssocStartCnt) {
+			session->bRefAssocStartCnt--;
+			roam_info_ptr->pProfile = profile;
+			/*
+			 * Complete the last assoc attempt as a
+			 * new one is about to be tried
+			 */
+			csr_roam_call_callback(mac_ctx, session_id,
+				roam_info_ptr, cmd->u.roamCmd.roamId,
+				eCSR_ROAM_ASSOCIATION_COMPLETION,
+				eCSR_ROAM_RESULT_NOT_ASSOCIATED);
+		}
+		/* If roaming has stopped, don't continue the roaming command */
+		if (!CSR_IS_ROAMING(session) && CSR_IS_ROAMING_COMMAND(cmd)) {
+			/* No need to complete roaming as it already complete */
+			sms_log(mac_ctx, LOGW,
+				FL(
+				"Roam cmd(reason %d)aborted as roam complete"),
+				cmd->u.roamCmd.roamReason);
+			*roam_state = eCsrStopRoaming;
+			csr_set_abort_roaming_command(mac_ctx, cmd);
+			return;
+		}
+		cdf_mem_set(roam_info_ptr, sizeof(tCsrRoamInfo), 0);
+		if (!scan_result)
+			cmd->u.roamCmd.roamProfile.uapsd_mask = 0;
+		else
+			ies_local = scan_result->Result.pvIes;
+
+		if (scan_result && !ies_local &&
+			(!CDF_IS_STATUS_SUCCESS(
+					csr_get_parsed_bss_description_ies(
+						mac_ctx,
+						&result->BssDescriptor,
+						&ies_local)))) {
+			sms_log(mac_ctx, LOGE, FL(" cannot parse IEs"));
+			*roam_state = eCsrStopRoaming;
+			return;
+		}
+		roam_info_ptr->pBssDesc = &result->BssDescriptor;
+		cmd->u.roamCmd.pLastRoamBss = roam_info_ptr->pBssDesc;
+		/* dont put uapsd_mask if BSS doesn't support uAPSD */
+		if (scan_result && cmd->u.roamCmd.roamProfile.uapsd_mask
+				&& CSR_IS_QOS_BSS(ies_local)
+				&& CSR_IS_UAPSD_BSS(ies_local)) {
+#ifndef WLAN_MDM_CODE_REDUCTION_OPT
+			acm_mask = sme_qos_get_acm_mask(mac_ctx,
+					&result->BssDescriptor, ies_local);
+#endif /* WLAN_MDM_CODE_REDUCTION_OPT */
+		} else {
+			cmd->u.roamCmd.roamProfile.uapsd_mask = 0;
+		}
+		if (ies_local && !result->pvIes)
+			cdf_mem_free(ies_local);
+		roam_info_ptr->pProfile = profile;
+		session->bRefAssocStartCnt++;
+		csr_roam_call_callback(mac_ctx, session_id, roam_info_ptr,
+			cmd->u.roamCmd.roamId, eCSR_ROAM_ASSOCIATION_START,
+			eCSR_ROAM_RESULT_NONE);
+	}
+	if (NULL != cmd->u.roamCmd.pRoamBssEntry) {
+		/*
+		 * We have BSS
+		 * Need to assign these value because
+		 * they are used in csr_is_same_profile
+		 */
+		scan_result = GET_BASE_ADDR(cmd->u.roamCmd.pRoamBssEntry,
+				tCsrScanResult, Link);
+		/*
+		 * The OSEN IE doesn't provide the cipher suite.Therefore set
+		 * to constant value of AES
+		 */
+		if (cmd->u.roamCmd.roamProfile.bOSENAssociation) {
+			cmd->u.roamCmd.roamProfile.negotiatedUCEncryptionType =
+				eCSR_ENCRYPT_TYPE_AES;
+			cmd->u.roamCmd.roamProfile.negotiatedMCEncryptionType =
+				eCSR_ENCRYPT_TYPE_AES;
+		} else {
+			/* Negotiated while building scan result. */
+			cmd->u.roamCmd.roamProfile.negotiatedUCEncryptionType =
+				scan_result->ucEncryptionType;
+			cmd->u.roamCmd.roamProfile.negotiatedMCEncryptionType =
+				scan_result->mcEncryptionType;
+		}
+		cmd->u.roamCmd.roamProfile.negotiatedAuthType =
+			scan_result->authType;
+		if (CSR_IS_START_IBSS(&cmd->u.roamCmd.roamProfile)) {
+			if (csr_is_same_profile(mac_ctx,
+				&session->connectedProfile, profile)) {
+				*roam_state = eCsrStartIbssSameIbss;
+				return;
+			}
+		}
+		if (cmd->u.roamCmd.fReassocToSelfNoCapChange) {
+			/* trying to connect to the one already connected */
+			cmd->u.roamCmd.fReassocToSelfNoCapChange = false;
+			*roam_state = eCsrReassocToSelfNoCapChange;
+			return;
+		}
+		/* Attempt to Join this Bss... */
+		*roam_state = csr_roam_join(mac_ctx, session_id,
+				&scan_result->Result, profile);
+		return;
+	}
+
+	/* For an IBSS profile, then we need to start the IBSS. */
+	if (CSR_IS_START_IBSS(profile)) {
+		bool same_ibss = false;
+		/* Attempt to start this IBSS... */
+		csr_roam_assign_default_param(mac_ctx, cmd);
+		status = csr_roam_start_ibss(mac_ctx, session_id,
+				profile, &same_ibss);
+		if (CDF_IS_STATUS_SUCCESS(status)) {
+			if (same_ibss)
+				*roam_state = eCsrStartIbssSameIbss;
+			else
+				*roam_state = eCsrContinueRoaming;
+		} else {
+			/* it somehow fail need to stop */
+			*roam_state = eCsrStopRoaming;
+		}
+		return;
+	} else if ((CSR_IS_WDS_AP(profile)) ||
+			(CSR_IS_INFRA_AP(profile))) {
+		/* Attempt to start this WDS... */
+		csr_roam_assign_default_param(mac_ctx, cmd);
+		/* For AP WDS, we dont have any BSSDescription */
+		status = csr_roam_start_wds(mac_ctx, session_id, profile, NULL);
+		if (CDF_IS_STATUS_SUCCESS(status))
+			*roam_state = eCsrContinueRoaming;
+		else
+			*roam_state = eCsrStopRoaming;
+	} else {
+		/* Nothing we can do */
+		sms_log(mac_ctx, LOGW, FL("cannot continue without BSS list"));
+		*roam_state = eCsrStopRoaming;
+		return;
+	}
+
+}
+/**
+ * csr_roam_join_next_bss() - Pick the next BSS for join
+ * @mac_ctx:             Global MAC Context
+ * @cmd:                 Command
+ * @use_same_bss:        Use Same BSS to Join
+ *
+ * Return: The Join State
+ */
+static eCsrJoinState csr_roam_join_next_bss(tpAniSirGlobal mac_ctx,
+		tSmeCmd *cmd, bool use_same_bss)
+{
+	tCsrScanResult *scan_result = NULL;
+	eCsrJoinState roam_state = eCsrStopRoaming;
+	tScanResultList *bss_list =
+		(tScanResultList *) cmd->u.roamCmd.hBSSList;
+	bool done = false;
+	tCsrRoamInfo roam_info, *roam_info_ptr = NULL;
+	uint32_t session_id = cmd->sessionId;
+	tCsrRoamSession *session = CSR_GET_SESSION(mac_ctx, session_id);
+	tCsrRoamProfile *profile = &cmd->u.roamCmd.roamProfile;
+	tCsrRoamJoinStatus *join_status;
+	tCsrScanResultInfo *result = NULL;
+
+	if (!session) {
+		sms_log(mac_ctx, LOGE, FL("session %d not found"), session_id);
+		return eCsrStopRoaming;
+	}
+
+	cdf_mem_set(&roam_info, sizeof(roam_info), 0);
+	cdf_mem_copy(&roam_info.bssid, &session->joinFailStatusCode.bssId,
+			sizeof(tSirMacAddr));
+	/*
+	 * When handling AP's capability change, continue to associate
+	 * to same BSS and make sure pRoamBssEntry is not Null.
+	 */
+	if ((NULL != bss_list) &&
+		((false == use_same_bss) ||
+		 (cmd->u.roamCmd.pRoamBssEntry == NULL))) {
+		if (cmd->u.roamCmd.pRoamBssEntry == NULL) {
+			/* Try the first BSS */
+			cmd->u.roamCmd.pLastRoamBss = NULL;
+			cmd->u.roamCmd.pRoamBssEntry =
+				csr_ll_peek_head(&bss_list->List,
+					LL_ACCESS_LOCK);
+		} else {
+			cmd->u.roamCmd.pRoamBssEntry =
+				csr_ll_next(&bss_list->List,
+					cmd->u.roamCmd.pRoamBssEntry,
+					LL_ACCESS_LOCK);
+			/*
+			 * Done with all the BSSs.
+			 * In this case, will tell HDD the
+			 * completion
+			 */
+			if (NULL == cmd->u.roamCmd.pRoamBssEntry)
+				goto end;
+			/*
+			 * We need to indicate to HDD that we
+			 * are done with this one.
+			 */
+			roam_info.pBssDesc = cmd->u.roamCmd.pLastRoamBss;
+			join_status = &session->joinFailStatusCode;
+			roam_info.statusCode = join_status->statusCode;
+			roam_info.reasonCode = join_status->reasonCode;
+			roam_info_ptr = &roam_info;
+		}
+		done = csr_roam_select_bss(mac_ctx,
+				cmd->u.roamCmd.pRoamBssEntry, &result,
+				&scan_result, session_id, cmd->u.roamCmd.roamId,
+				&roam_state, bss_list);
+		if (done)
+			goto end;
+	}
+	if (!roam_info_ptr)
+		roam_info_ptr = &roam_info;
+	roam_info_ptr->u.pConnectedProfile = &session->connectedProfile;
+	csr_roam_join_handle_profile(mac_ctx, session_id, cmd, roam_info_ptr,
+		&roam_state, result, scan_result);
+end:
+	if ((eCsrStopRoaming == roam_state) && CSR_IS_INFRASTRUCTURE(profile) &&
+		(session->bRefAssocStartCnt > 0)) {
+		/*
+		 * Need to indicate association_completion if association_start
+		 * has been done
+		 */
+		session->bRefAssocStartCnt--;
+		/*
+		 * Complete the last assoc attempte as a
+		 * new one is about to be tried
+		 */
+		roam_info_ptr = &roam_info;
+		roam_info_ptr->pProfile = profile;
+		csr_roam_call_callback(mac_ctx, session_id,
+			roam_info_ptr, cmd->u.roamCmd.roamId,
+			eCSR_ROAM_ASSOCIATION_COMPLETION,
+			eCSR_ROAM_RESULT_NOT_ASSOCIATED);
+	}
+
+	return roam_state;
+}
+
+static CDF_STATUS csr_roam(tpAniSirGlobal pMac, tSmeCmd *pCommand)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	eCsrJoinState RoamState;
+	eCsrRoamSubState substate;
+	uint32_t sessionId = pCommand->sessionId;
+
+	/* Attept to join a Bss... */
+	RoamState = csr_roam_join_next_bss(pMac, pCommand, false);
+
+	/* if nothing to join.. */
+	if ((eCsrStopRoaming == RoamState) ||
+		(eCsrStopRoamingDueToConcurrency == RoamState)) {
+		bool fComplete = false;
+		/* and if connected in Infrastructure mode... */
+		if (csr_is_conn_state_infra(pMac, sessionId)) {
+			/* ... then we need to issue a disassociation */
+			substate = eCSR_ROAM_SUBSTATE_DISASSOC_NOTHING_TO_JOIN;
+			status = csr_roam_issue_disassociate(pMac, sessionId,
+					substate, false);
+			if (!CDF_IS_STATUS_SUCCESS(status)) {
+				sms_log(pMac, LOGW,
+					FL("fail issuing disassoc status = %d"),
+					status);
+				/*
+				 * roam command is completed by caller in the
+				 * failed case
+				 */
+				fComplete = true;
+			}
+		} else if (csr_is_conn_state_ibss(pMac, sessionId)) {
+			status = csr_roam_issue_stop_bss(pMac, sessionId,
+					eCSR_ROAM_SUBSTATE_STOP_BSS_REQ);
+			if (!CDF_IS_STATUS_SUCCESS(status)) {
+				sms_log(pMac, LOGW,
+					FL("fail issuing stop bss status = %d"),
+					status);
+				/*
+				 * roam command is completed by caller in the
+				 * failed case
+				 */
+				fComplete = true;
+			}
+		} else if (csr_is_conn_state_connected_infra_ap(pMac,
+					sessionId)) {
+			substate = eCSR_ROAM_SUBSTATE_STOP_BSS_REQ;
+			status = csr_roam_issue_stop_bss(pMac, sessionId,
+						substate);
+			if (!CDF_IS_STATUS_SUCCESS(status)) {
+				sms_log(pMac, LOGW,
+					FL("fail issuing stop bss status = %d"),
+					status);
+				/*
+				 * roam command is completed by caller in the
+				 * failed case
+				 */
+				fComplete = true;
+			}
+		} else {
+			fComplete = true;
+		}
+
+		if (fComplete) {
+			/* otherwise, we can complete the Roam command here. */
+			if (eCsrStopRoamingDueToConcurrency == RoamState)
+				csr_roam_complete(pMac,
+					eCsrJoinFailureDueToConcurrency, NULL);
+			else
+				csr_roam_complete(pMac,
+					eCsrNothingToJoin, NULL);
+		}
+	} else if (eCsrReassocToSelfNoCapChange == RoamState) {
+		csr_roam_complete(pMac, eCsrSilentlyStopRoamingSaveState,
+				NULL);
+	} else if (eCsrStartIbssSameIbss == RoamState) {
+		csr_roam_complete(pMac, eCsrSilentlyStopRoaming, NULL);
+	}
+
+	return status;
+}
+
+CDF_STATUS csr_process_ft_reassoc_roam_command(tpAniSirGlobal pMac,
+					       tSmeCmd *pCommand)
+{
+	uint32_t sessionId;
+	tCsrRoamSession *pSession;
+	tCsrScanResult *pScanResult = NULL;
+	tSirBssDescription *pBssDesc = NULL;
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	sessionId = pCommand->sessionId;
+	pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("  session %d not found "), sessionId);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	if (CSR_IS_ROAMING(pSession) && pSession->fCancelRoaming) {
+		/* the roaming is cancelled. Simply complete the command */
+		sms_log(pMac, LOG1, FL("Roam command canceled"));
+		csr_roam_complete(pMac, eCsrNothingToJoin, NULL);
+		return CDF_STATUS_E_FAILURE;
+	}
+	if (pCommand->u.roamCmd.pRoamBssEntry) {
+		pScanResult =
+			GET_BASE_ADDR(pCommand->u.roamCmd.pRoamBssEntry,
+				      tCsrScanResult, Link);
+		pBssDesc = &pScanResult->Result.BssDescriptor;
+	} else {
+		/* the roaming is cancelled. Simply complete the command */
+		sms_log(pMac, LOG1, FL("Roam command canceled"));
+		csr_roam_complete(pMac, eCsrNothingToJoin, NULL);
+		return CDF_STATUS_E_FAILURE;
+	}
+	status = csr_roam_issue_reassociate(pMac, sessionId, pBssDesc,
+					    (tDot11fBeaconIEs *) (pScanResult->
+								  Result.pvIes),
+					    &pCommand->u.roamCmd.roamProfile);
+	return status;
+}
+
+/**
+ * csr_roam_trigger_reassociate() - Helper function to trigger reassociate
+ * @mac_ctx: pointer to mac context
+ * @cmd: sme command
+ * @roam_info: Roaming infor structure
+ * @session_ptr: session pointer
+ * @session_id: session id
+ *
+ * This function will trigger reassociate.
+ *
+ * Return: CDF_STATUS for success or failure.
+ */
+static CDF_STATUS csr_roam_trigger_reassociate(tpAniSirGlobal mac_ctx,
+			tSmeCmd *cmd, tCsrRoamInfo *roam_info,
+			tCsrRoamSession *session_ptr, uint32_t session_id)
+{
+	tDot11fBeaconIEs *pIes = NULL;
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+
+	if (session_ptr->pConnectBssDesc) {
+		status = csr_get_parsed_bss_description_ies(mac_ctx,
+				session_ptr->pConnectBssDesc, &pIes);
+		if (!CDF_IS_STATUS_SUCCESS(status)) {
+			sms_log(mac_ctx, LOGE, FL("fail to parse IEs"));
+		} else {
+			roam_info->reasonCode =
+					eCsrRoamReasonStaCapabilityChanged;
+			csr_roam_call_callback(mac_ctx, session_ptr->sessionId,
+					roam_info, 0, eCSR_ROAM_ROAMING_START,
+					eCSR_ROAM_RESULT_NONE);
+			session_ptr->roamingReason = eCsrReassocRoaming;
+			roam_info->pBssDesc = session_ptr->pConnectBssDesc;
+			roam_info->pProfile = &cmd->u.roamCmd.roamProfile;
+			session_ptr->bRefAssocStartCnt++;
+			csr_roam_call_callback(mac_ctx, session_id, roam_info,
+				cmd->u.roamCmd.roamId,
+				eCSR_ROAM_ASSOCIATION_START,
+				eCSR_ROAM_RESULT_NONE);
+
+			sms_log(mac_ctx, LOG1,
+				FL("calling csr_roam_issue_reassociate"));
+			status = csr_roam_issue_reassociate(mac_ctx, session_id,
+					session_ptr->pConnectBssDesc, pIes,
+					&cmd->u.roamCmd.roamProfile);
+			if (!CDF_IS_STATUS_SUCCESS(status)) {
+				sms_log(mac_ctx, LOGE, FL("failed status %d"),
+					status);
+				csr_release_command_roam(mac_ctx, cmd);
+			}
+
+			cdf_mem_free(pIes);
+			pIes = NULL;
+		}
+	} else {
+		sms_log(mac_ctx, LOGE, FL
+			("reassoc to same AP failed as connected BSS is NULL"));
+		status = CDF_STATUS_E_FAILURE;
+	}
+	return status;
+}
+
+CDF_STATUS csr_roam_process_command(tpAniSirGlobal pMac, tSmeCmd *pCommand)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tCsrRoamInfo roamInfo;
+	uint32_t sessionId = pCommand->sessionId;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("session %d not found"), sessionId);
+		return CDF_STATUS_E_FAILURE;
+	}
+	sms_log(pMac, LOG1, FL("Roam Reason : %d, sessionId: %d"),
+		pCommand->u.roamCmd.roamReason, sessionId);
+
+	switch (pCommand->u.roamCmd.roamReason) {
+	case eCsrForcedDisassoc:
+		if (eCSR_ROAMING_STATE_IDLE == pMac->roam.curState[sessionId]) {
+			sms_log(pMac, LOGE,
+				FL("Ignore eCsrForcedDisassoc cmd on roam state"
+				   " %d"), eCSR_ROAMING_STATE_IDLE);
+			return CDF_STATUS_E_FAILURE;
+		}
+
+		status = csr_roam_process_disassoc_deauth(pMac, pCommand,
+				true, false);
+		csr_free_roam_profile(pMac, sessionId);
+		break;
+	case eCsrSmeIssuedDisassocForHandoff:
+		/* Not to free pMac->roam.pCurRoamProfile (via
+		 * csr_free_roam_profile) because its needed after disconnect */
+		status = csr_roam_process_disassoc_deauth(pMac, pCommand,
+				true, false);
+
+		break;
+	case eCsrForcedDisassocMICFailure:
+		status = csr_roam_process_disassoc_deauth(pMac, pCommand,
+				true, true);
+		csr_free_roam_profile(pMac, sessionId);
+		break;
+	case eCsrForcedDeauth:
+		status = csr_roam_process_disassoc_deauth(pMac, pCommand,
+				false, false);
+		csr_free_roam_profile(pMac, sessionId);
+		break;
+	case eCsrHddIssuedReassocToSameAP:
+	case eCsrSmeIssuedReassocToSameAP:
+		status = csr_roam_trigger_reassociate(pMac, pCommand, &roamInfo,
+				pSession, sessionId);
+		break;
+	case eCsrCapsChange:
+		sms_log(pMac, LOGE, FL("received eCsrCapsChange "));
+		csr_roam_state_change(pMac, eCSR_ROAMING_STATE_JOINING,
+				sessionId);
+		status = csr_roam_issue_disassociate(pMac, sessionId,
+				eCSR_ROAM_SUBSTATE_DISCONNECT_CONTINUE_ROAMING,
+				false);
+		break;
+	case eCsrSmeIssuedFTReassoc:
+		sms_log(pMac, LOG1, FL("received FT Reassoc Req "));
+		status = csr_process_ft_reassoc_roam_command(pMac, pCommand);
+		break;
+
+	case eCsrStopBss:
+		csr_roam_state_change(pMac, eCSR_ROAMING_STATE_JOINING,
+				sessionId);
+		status = csr_roam_issue_stop_bss(pMac, sessionId,
+				eCSR_ROAM_SUBSTATE_STOP_BSS_REQ);
+		break;
+
+	case eCsrForcedDisassocSta:
+		csr_roam_state_change(pMac, eCSR_ROAMING_STATE_JOINING,
+				sessionId);
+		csr_roam_substate_change(pMac, eCSR_ROAM_SUBSTATE_DISASSOC_REQ,
+				sessionId);
+		status = csr_send_mb_disassoc_req_msg(pMac, sessionId,
+				pCommand->u.roamCmd.peerMac,
+				pCommand->u.roamCmd.reason);
+		break;
+
+	case eCsrForcedDeauthSta:
+		csr_roam_state_change(pMac, eCSR_ROAMING_STATE_JOINING,
+				sessionId);
+		csr_roam_substate_change(pMac, eCSR_ROAM_SUBSTATE_DEAUTH_REQ,
+				sessionId);
+		status = csr_send_mb_deauth_req_msg(pMac, sessionId,
+				pCommand->u.roamCmd.peerMac,
+				pCommand->u.roamCmd.reason);
+		break;
+
+	case eCsrPerformPreauth:
+		sms_log(pMac, LOG1, FL("Attempting FT PreAuth Req"));
+		status = csr_roam_issue_ft_preauth_req(pMac, sessionId,
+				pCommand->u.roamCmd.pLastRoamBss);
+		break;
+	default:
+		csr_roam_state_change(pMac, eCSR_ROAMING_STATE_JOINING,
+				sessionId);
+
+		if (pCommand->u.roamCmd.fUpdateCurRoamProfile) {
+			/* Remember the roaming profile */
+			csr_free_roam_profile(pMac, sessionId);
+			pSession->pCurRoamProfile =
+					cdf_mem_malloc(sizeof(tCsrRoamProfile));
+			if (NULL != pSession->pCurRoamProfile) {
+				cdf_mem_set(pSession->pCurRoamProfile,
+					sizeof(tCsrRoamProfile), 0);
+				csr_roam_copy_profile(pMac,
+					pSession->pCurRoamProfile,
+					&pCommand->u.roamCmd.roamProfile);
+			}
+		}
+		/*
+		 * At this point original uapsd_mask is saved in
+		 * pCurRoamProfile. uapsd_mask in the pCommand may change from
+		 * this point on. Attempt to roam with the new scan results
+		 * (if we need to..)
+		 */
+		status = csr_roam(pMac, pCommand);
+		if (!CDF_IS_STATUS_SUCCESS(status))
+			sms_log(pMac, LOGW,
+				FL("csr_roam() failed with status = 0x%08X"),
+				status);
+		break;
+	}
+	return status;
+}
+
+void csr_reinit_preauth_cmd(tpAniSirGlobal pMac, tSmeCmd *pCommand)
+{
+	pCommand->u.roamCmd.pLastRoamBss = NULL;
+	pCommand->u.roamCmd.pRoamBssEntry = NULL;
+	/* Because u.roamCmd is union and share with scanCmd and StatusChange */
+	cdf_mem_set(&pCommand->u.roamCmd, sizeof(tRoamCmd), 0);
+}
+
+void csr_reinit_roam_cmd(tpAniSirGlobal pMac, tSmeCmd *pCommand)
+{
+	if (pCommand->u.roamCmd.fReleaseBssList) {
+		csr_scan_result_purge(pMac, pCommand->u.roamCmd.hBSSList);
+		pCommand->u.roamCmd.fReleaseBssList = false;
+		pCommand->u.roamCmd.hBSSList = CSR_INVALID_SCANRESULT_HANDLE;
+	}
+	if (pCommand->u.roamCmd.fReleaseProfile) {
+		csr_release_profile(pMac, &pCommand->u.roamCmd.roamProfile);
+		pCommand->u.roamCmd.fReleaseProfile = false;
+	}
+	pCommand->u.roamCmd.pRoamBssEntry = NULL;
+	/* Because u.roamCmd is union and share with scanCmd and StatusChange */
+	cdf_mem_set(&pCommand->u.roamCmd, sizeof(tRoamCmd), 0);
+}
+
+void csr_reinit_wm_status_change_cmd(tpAniSirGlobal pMac, tSmeCmd *pCommand)
+{
+	cdf_mem_set(&pCommand->u.wmStatusChangeCmd, sizeof(tWmStatusChangeCmd),
+		    0);
+}
+
+void csr_roam_complete(tpAniSirGlobal pMac, eCsrRoamCompleteResult Result,
+		       void *Context)
+{
+	tListElem *pEntry;
+	tSmeCmd *pCommand;
+	bool fReleaseCommand = true;
+	CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
+		  "%s: Roam Completion ...", __func__);
+	pEntry = csr_ll_peek_head(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK);
+	if (pEntry) {
+		pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
+		/* If the head of the queue is Active and it is a ROAM command, remove */
+		/* and put this on the Free queue. */
+		if (eSmeCommandRoam == pCommand->command) {
+			/* we need to process the result first before removing it from active list because state changes */
+			/* still happening insides roamQProcessRoamResults so no other roam command should be issued */
+			fReleaseCommand =
+				csr_roam_process_results(pMac, pCommand, Result,
+							 Context);
+			if (fReleaseCommand) {
+				if (csr_ll_remove_entry
+					    (&pMac->sme.smeCmdActiveList, pEntry,
+					    LL_ACCESS_LOCK)) {
+					csr_release_command_roam(pMac, pCommand);
+				} else {
+					sms_log(pMac, LOGE,
+						" **********csr_roam_complete fail to release command reason %d",
+						pCommand->u.roamCmd.roamReason);
+				}
+			} else {
+				sms_log(pMac, LOGE,
+					" **********csr_roam_complete fail to release command reason %d",
+					pCommand->u.roamCmd.roamReason);
+			}
+		} else {
+			sms_log(pMac, LOGW,
+				"CSR: Roam Completion called but ROAM command is not ACTIVE ...");
+		}
+	} else {
+		sms_log(pMac, LOGW,
+			"CSR: Roam Completion called but NO commands are ACTIVE ...");
+	}
+	if (fReleaseCommand) {
+		sme_process_pending_queue(pMac);
+	}
+}
+
+void csr_reset_pmkid_candidate_list(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("  session %d not found "), sessionId);
+		return;
+	}
+	cdf_mem_set(&(pSession->PmkidCandidateInfo[0]),
+		    sizeof(tPmkidCandidateInfo) * CSR_MAX_PMKID_ALLOWED, 0);
+	pSession->NumPmkidCandidate = 0;
+}
+
+#ifdef FEATURE_WLAN_WAPI
+void csr_reset_bkid_candidate_list(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("  session %d not found "), sessionId);
+		return;
+	}
+	cdf_mem_set(&(pSession->BkidCandidateInfo[0]),
+		    sizeof(tBkidCandidateInfo) * CSR_MAX_BKID_ALLOWED, 0);
+	pSession->NumBkidCandidate = 0;
+}
+#endif /* FEATURE_WLAN_WAPI */
+extern uint8_t csr_wpa_oui[][CSR_WPA_OUI_SIZE];
+
+/**
+ * csr_roam_save_params() - Helper function to save params
+ * @mac_ctx: pointer to mac context
+ * @session_ptr: Session pointer
+ * @auth_type: auth type
+ * @ie_ptr: pointer to ie
+ * @ie_local: pointr to local ie
+ *
+ * This function will save params to session
+ *
+ * Return: none.
+ */
+static CDF_STATUS csr_roam_save_params(tpAniSirGlobal mac_ctx,
+				tCsrRoamSession *session_ptr,
+				eCsrAuthType auth_type,
+				tDot11fBeaconIEs *ie_ptr,
+				tDot11fBeaconIEs *ie_local)
+{
+	uint32_t nIeLen;
+	uint8_t *pIeBuf;
+
+	if ((eCSR_AUTH_TYPE_RSN == auth_type) ||
+#if defined WLAN_FEATURE_VOWIFI_11R
+		(eCSR_AUTH_TYPE_FT_RSN == auth_type) ||
+		(eCSR_AUTH_TYPE_FT_RSN_PSK == auth_type) ||
+#endif /* WLAN_FEATURE_VOWIFI_11R */
+#if defined WLAN_FEATURE_11W
+		(eCSR_AUTH_TYPE_RSN_PSK_SHA256 == auth_type) ||
+		(eCSR_AUTH_TYPE_RSN_8021X_SHA256 == auth_type) ||
+#endif
+		(eCSR_AUTH_TYPE_RSN_PSK == auth_type)) {
+		if (ie_local->RSN.present) {
+			tDot11fIERSN *rsnie = &ie_local->RSN;
+			/*
+			 * Calculate the actual length
+			 * version + gp_cipher_suite + pwise_cipher_suite_count
+			 * + akm_suite_count + reserved + pwise_cipher_suites
+			 */
+			nIeLen = 8 + 2 + 2
+				+ (rsnie->pwise_cipher_suite_count * 4)
+				+ (rsnie->akm_suite_count * 4);
+			if (rsnie->pmkid_count)
+				/* pmkid */
+				nIeLen += 2 + rsnie->pmkid_count * 4;
+
+			/* nIeLen doesn't count EID and length fields */
+			session_ptr->pWpaRsnRspIE = cdf_mem_malloc(nIeLen + 2);
+			if (NULL == session_ptr->pWpaRsnRspIE)
+				return CDF_STATUS_E_NOMEM;
+
+			cdf_mem_set(session_ptr->pWpaRsnRspIE,
+					nIeLen + 2, 0);
+			session_ptr->pWpaRsnRspIE[0] = DOT11F_EID_RSN;
+			session_ptr->pWpaRsnRspIE[1] = (uint8_t) nIeLen;
+			/* copy upto akm_suites */
+			pIeBuf = session_ptr->pWpaRsnRspIE + 2;
+			cdf_mem_copy(pIeBuf, &rsnie->version,
+					sizeof(rsnie->version));
+			pIeBuf += sizeof(rsnie->version);
+			cdf_mem_copy(pIeBuf, &rsnie->gp_cipher_suite,
+				sizeof(rsnie->gp_cipher_suite));
+			pIeBuf += sizeof(rsnie->gp_cipher_suite);
+			cdf_mem_copy(pIeBuf, &rsnie->pwise_cipher_suite_count,
+				sizeof(rsnie->pwise_cipher_suite_count));
+			pIeBuf += sizeof(rsnie->pwise_cipher_suite_count);
+			if (rsnie->pwise_cipher_suite_count) {
+				/* copy pwise_cipher_suites */
+				cdf_mem_copy(pIeBuf, rsnie->pwise_cipher_suites,
+					rsnie->pwise_cipher_suite_count * 4);
+				pIeBuf += rsnie->pwise_cipher_suite_count * 4;
+			}
+			cdf_mem_copy(pIeBuf, &rsnie->akm_suite_count, 2);
+			pIeBuf += 2;
+			if (rsnie->akm_suite_count) {
+				/* copy akm_suites */
+				cdf_mem_copy(pIeBuf, rsnie->akm_suites,
+					rsnie->akm_suite_count * 4);
+				pIeBuf += rsnie->akm_suite_count * 4;
+			}
+			/* copy the rest */
+			cdf_mem_copy(pIeBuf, rsnie->akm_suites +
+				rsnie->akm_suite_count * 4,
+				2 + rsnie->pmkid_count * 4);
+			session_ptr->nWpaRsnRspIeLength = nIeLen + 2;
+		}
+	} else if ((eCSR_AUTH_TYPE_WPA == auth_type) ||
+			(eCSR_AUTH_TYPE_WPA_PSK == auth_type)) {
+		if (ie_local->WPA.present) {
+			tDot11fIEWPA *wpaie = &ie_local->WPA;
+			/* Calculate the actual length wpaie */
+			nIeLen = 12 + 2 /* auth_suite_count */
+				+ wpaie->unicast_cipher_count * 4
+				+ wpaie->auth_suite_count * 4;
+
+			/* The WPA capabilities follows the Auth Suite
+			 * (two octects)-- this field is optional, and
+			 * we always "send" zero, so just remove it.  This is
+			 * consistent with our assumptions in the frames
+			 * compiler; nIeLen doesn't count EID & length fields */
+			session_ptr->pWpaRsnRspIE = cdf_mem_malloc(nIeLen + 2);
+			if (NULL == session_ptr->pWpaRsnRspIE)
+				return CDF_STATUS_E_NOMEM;
+			session_ptr->pWpaRsnRspIE[0] = DOT11F_EID_WPA;
+			session_ptr->pWpaRsnRspIE[1] = (uint8_t) nIeLen;
+			pIeBuf = session_ptr->pWpaRsnRspIE + 2;
+			/* Copy WPA OUI */
+			cdf_mem_copy(pIeBuf, &csr_wpa_oui[1], 4);
+			pIeBuf += 4;
+			cdf_mem_copy(pIeBuf, &wpaie->version,
+				8 + wpaie->unicast_cipher_count * 4);
+			pIeBuf += 8 + wpaie->unicast_cipher_count * 4;
+			cdf_mem_copy(pIeBuf, &wpaie->auth_suite_count,
+				2 + wpaie->auth_suite_count * 4);
+			pIeBuf += wpaie->auth_suite_count * 4;
+			session_ptr->nWpaRsnRspIeLength = nIeLen + 2;
+		}
+	}
+#ifdef FEATURE_WLAN_WAPI
+	else if ((eCSR_AUTH_TYPE_WAPI_WAI_PSK == auth_type) ||
+			(eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE ==
+			 auth_type)) {
+		if (ie_local->WAPI.present) {
+			tDot11fIEWAPI *wapi_ie = &ie_local->WAPI;
+			/* Calculate the actual length of wapi ie*/
+			nIeLen = 4 + 2 /* pwise_cipher_suite_count */
+				+ wapi_ie->akm_suite_count * 4
+				+ wapi_ie->unicast_cipher_suite_count * 4
+				+ 6;  /* gp_cipher_suite + preauth + reserved */
+
+			if (wapi_ie->bkid_count)
+				nIeLen += 2 + wapi_ie->bkid_count * 4;
+
+			/* nIeLen doesn't count EID and length fields */
+			session_ptr->pWapiRspIE =
+				cdf_mem_malloc(nIeLen + 2);
+			if (NULL == session_ptr->pWapiRspIE)
+				return CDF_STATUS_E_NOMEM;
+			session_ptr->pWapiRspIE[0] = DOT11F_EID_WAPI;
+			session_ptr->pWapiRspIE[1] = (uint8_t) nIeLen;
+			pIeBuf = session_ptr->pWapiRspIE + 2;
+			/* copy upto akm_suite_count */
+			cdf_mem_copy(pIeBuf, &wapi_ie->version, 2);
+			pIeBuf += 4;
+			if (wapi_ie->akm_suite_count) {
+				/* copy akm_suites */
+				cdf_mem_copy(pIeBuf,
+					wapi_ie->akm_suites,
+					wapi_ie->akm_suite_count * 4);
+				pIeBuf += wapi_ie->akm_suite_count * 4;
+			}
+			cdf_mem_copy(pIeBuf,
+				&wapi_ie->unicast_cipher_suite_count, 2);
+			pIeBuf += 2;
+			if (wapi_ie->unicast_cipher_suite_count) {
+				uint16_t suite_size =
+					wapi_ie->unicast_cipher_suite_count * 4;
+				/* copy pwise_cipher_suites */
+				cdf_mem_copy(pIeBuf,
+					wapi_ie->unicast_cipher_suites,
+					suite_size);
+				pIeBuf += suite_size;
+			}
+			/* gp_cipher_suite */
+			cdf_mem_copy(pIeBuf,
+				wapi_ie->multicast_cipher_suite, 4);
+			pIeBuf += 4;
+			/* preauth + reserved */
+			cdf_mem_copy(pIeBuf,
+				wapi_ie->multicast_cipher_suite + 4, 2);
+			pIeBuf += 2;
+			if (wapi_ie->bkid_count) {
+				/* bkid_count */
+				cdf_mem_copy(pIeBuf, &wapi_ie->bkid_count, 2);
+				pIeBuf += 2;
+				/* copy akm_suites */
+				cdf_mem_copy(pIeBuf, wapi_ie->bkid,
+					wapi_ie->bkid_count * 4);
+				pIeBuf += wapi_ie->bkid_count * 4;
+			}
+			session_ptr->nWapiRspIeLength = nIeLen + 2;
+		}
+	}
+#endif /* FEATURE_WLAN_WAPI */
+	return CDF_STATUS_SUCCESS;
+}
+
+static CDF_STATUS csr_roam_save_security_rsp_ie(tpAniSirGlobal pMac,
+						uint32_t sessionId,
+						eCsrAuthType authType,
+						tSirBssDescription *pSirBssDesc,
+						tDot11fBeaconIEs *pIes)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+	tDot11fBeaconIEs *pIesLocal = pIes;
+
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("session %d not found"), sessionId);
+		return CDF_STATUS_E_FAILURE;
+	}
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	if (pSession->roamOffloadSynchParams.bRoamSynchInProgress) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
+				FL("LFR3:csr_roam_save_security_rsp_ie"));
+	}
+#endif
+
+	if ((eCSR_AUTH_TYPE_WPA == authType) ||
+		(eCSR_AUTH_TYPE_WPA_PSK == authType) ||
+		(eCSR_AUTH_TYPE_RSN == authType) ||
+		(eCSR_AUTH_TYPE_RSN_PSK == authType)
+#if defined WLAN_FEATURE_VOWIFI_11R
+		|| (eCSR_AUTH_TYPE_FT_RSN == authType) ||
+		(eCSR_AUTH_TYPE_FT_RSN_PSK == authType)
+#endif /* FEATURE_WLAN_WAPI */
+#ifdef FEATURE_WLAN_WAPI
+		|| (eCSR_AUTH_TYPE_WAPI_WAI_PSK == authType) ||
+		(eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE == authType)
+#endif /* FEATURE_WLAN_WAPI */
+#ifdef WLAN_FEATURE_11W
+		|| (eCSR_AUTH_TYPE_RSN_PSK_SHA256 == authType) ||
+		(eCSR_AUTH_TYPE_RSN_8021X_SHA256 == authType)
+#endif /* FEATURE_WLAN_WAPI */
+	) {
+		if (!pIesLocal && !CDF_IS_STATUS_SUCCESS
+				(csr_get_parsed_bss_description_ies(pMac,
+				pSirBssDesc, &pIesLocal)))
+			sms_log(pMac, LOGE, FL(" cannot parse IEs"));
+		if (pIesLocal) {
+			status = csr_roam_save_params(pMac, pSession, authType,
+					pIes, pIesLocal);
+			if (!pIes)
+				/* locally allocated */
+				cdf_mem_free(pIesLocal);
+		}
+	}
+	return status;
+}
+
+#ifdef WLAN_FEATURE_VOWIFI_11R
+/* Returns whether the current association is a 11r assoc or not */
+bool csr_roam_is11r_assoc(tpAniSirGlobal pMac, uint8_t sessionId)
+{
+#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
+	return csr_neighbor_roam_is11r_assoc(pMac, sessionId);
+#else
+	return false;
+#endif
+}
+#endif
+#ifdef FEATURE_WLAN_ESE
+/* Returns whether the current association is a ESE assoc or not */
+bool csr_roam_is_ese_assoc(tpAniSirGlobal pMac, uint8_t sessionId)
+{
+#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
+	return csr_neighbor_roam_is_ese_assoc(pMac, sessionId);
+#else
+	return false;
+#endif
+}
+#endif
+#ifdef FEATURE_WLAN_LFR
+/* Returns whether "Legacy Fast Roaming" is currently enabled...or not */
+bool csr_roam_is_fast_roam_enabled(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	tCsrRoamSession *pSession = NULL;
+
+	if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
+		pSession = CSR_GET_SESSION(pMac, sessionId);
+		if (NULL != pSession->pCurRoamProfile) {
+			if (pSession->pCurRoamProfile->csrPersona !=
+			    CDF_STA_MODE) {
+				return false;
+			}
+		}
+	}
+	if (true == CSR_IS_FASTROAM_IN_CONCURRENCY_INI_FEATURE_ENABLED(pMac)) {
+		return pMac->roam.configParam.isFastRoamIniFeatureEnabled;
+	} else {
+		return pMac->roam.configParam.isFastRoamIniFeatureEnabled &&
+			(!csr_is_concurrent_session_running(pMac));
+	}
+}
+
+#ifdef FEATURE_WLAN_ESE
+/**
+ * csr_neighbor_roam_is_ese_assoc() - Check the Association type
+ * @mac_ctx: Global MAC Context
+ * @session_id: Session ID on which the check should be done
+ *
+ * This function returns whether the current association
+ * is a ESE assoc or not
+ *
+ * Return: True if ESE association, false otherwise.
+ **/
+bool csr_neighbor_roam_is_ese_assoc(tpAniSirGlobal mac_ctx, uint8_t session_id)
+{
+	return mac_ctx->roam.neighborRoamInfo[session_id].isESEAssoc;
+}
+#endif /* FEATURE_WLAN_ESE */
+
+/* Returns whether "FW based BG scan" is currently enabled...or not */
+bool csr_roam_is_roam_offload_scan_enabled(tpAniSirGlobal pMac)
+{
+	return pMac->roam.configParam.isRoamOffloadScanEnabled;
+}
+#endif
+
+#if defined(FEATURE_WLAN_ESE)
+bool csr_roam_is_ese_ini_feature_enabled(tpAniSirGlobal pMac)
+{
+	return pMac->roam.configParam.isEseIniFeatureEnabled;
+}
+#endif /*FEATURE_WLAN_ESE */
+
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+eCsrPhyMode csr_roamdot11mode_to_phymode(uint8_t dot11mode)
+{
+	eCsrPhyMode phymode = eCSR_DOT11_MODE_abg;
+
+	switch (dot11mode) {
+	case WNI_CFG_DOT11_MODE_ALL:
+		phymode = eCSR_DOT11_MODE_abg;
+		break;
+	case WNI_CFG_DOT11_MODE_11A:
+		phymode = eCSR_DOT11_MODE_11a;
+		break;
+	case WNI_CFG_DOT11_MODE_11B:
+		phymode = eCSR_DOT11_MODE_11b;
+		break;
+	case WNI_CFG_DOT11_MODE_11G:
+		phymode = eCSR_DOT11_MODE_11g;
+		break;
+	case WNI_CFG_DOT11_MODE_11N:
+		phymode = eCSR_DOT11_MODE_11n;
+		break;
+	case WNI_CFG_DOT11_MODE_11G_ONLY:
+		phymode = eCSR_DOT11_MODE_11g_ONLY;
+		break;
+	case WNI_CFG_DOT11_MODE_11N_ONLY:
+		phymode = eCSR_DOT11_MODE_11n_ONLY;
+		break;
+	case WNI_CFG_DOT11_MODE_11AC:
+		phymode = eCSR_DOT11_MODE_11ac;
+		break;
+	case WNI_CFG_DOT11_MODE_11AC_ONLY:
+		phymode = eCSR_DOT11_MODE_11ac_ONLY;
+		break;
+	default:
+		break;
+	}
+
+	return phymode;
+}
+#endif
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+CDF_STATUS csr_roam_offload_send_synch_cnf(tpAniSirGlobal pMac, uint8_t sessionId)
+{
+	tpSirSmeRoamOffloadSynchCnf pRoamOffloadSynchCnf;
+	cds_msg_t msg;
+	tCsrRoamSession *pSession = &pMac->roam.roamSession[sessionId];
+	pRoamOffloadSynchCnf =
+		cdf_mem_malloc(sizeof(tSirSmeRoamOffloadSynchCnf));
+	if (NULL == pRoamOffloadSynchCnf) {
+		CDF_TRACE(CDF_MODULE_ID_SME,
+			  CDF_TRACE_LEVEL_ERROR,
+			  "%s: not able to allocate memory for roam"
+			  "offload synch confirmation data", __func__);
+		pSession->roamOffloadSynchParams.bRoamSynchInProgress =
+			false;
+		return CDF_STATUS_E_NOMEM;
+	}
+	pRoamOffloadSynchCnf->sessionId = sessionId;
+	msg.type = WMA_ROAM_OFFLOAD_SYNCH_CNF;
+	msg.reserved = 0;
+	msg.bodyptr = pRoamOffloadSynchCnf;
+	CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+		  "LFR3: Posting WMA_ROAM_OFFLOAD_SYNCH_CNF");
+	if (!CDF_IS_STATUS_SUCCESS
+		    (cds_mq_post_message(CDF_MODULE_ID_WMA, &msg))) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
+			  "%s: Not able to post WMA_ROAM_OFFLOAD_SYNCH_CNF message to WMA",
+			  __func__);
+		cdf_mem_free(pRoamOffloadSynchCnf);
+		pSession->roamOffloadSynchParams.bRoamSynchInProgress =
+			false;
+		return CDF_STATUS_E_FAILURE;
+	}
+	pSession->roamOffloadSynchParams.bRoamSynchInProgress = false;
+	return CDF_STATUS_SUCCESS;
+}
+
+void csr_roam_synch_clean_up (tpAniSirGlobal mac, uint8_t session_id)
+{
+	cds_msg_t msg;
+	struct roam_offload_synch_fail *roam_offload_failed = NULL;
+	tCsrRoamSession *session = &mac->roam.roamSession[session_id];
+
+	/* Clean up the roam synch in progress for LFR3 */
+	CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+		  "%s: Roam Synch Failed, Clean Up", __func__);
+	session->roamOffloadSynchParams.bRoamSynchInProgress = false;
+
+	roam_offload_failed = cdf_mem_malloc(
+				sizeof(struct roam_offload_synch_fail));
+	if (NULL == roam_offload_failed) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+			  "%s: unable to allocate memory for roam synch fail" ,
+			  __func__);
+		return;
+	}
+
+	roam_offload_failed->session_id = session_id;
+	msg.type     = WMA_ROAM_OFFLOAD_SYNCH_FAIL;
+	msg.reserved = 0;
+	msg.bodyptr  = roam_offload_failed;
+	if (!CDF_IS_STATUS_SUCCESS(cds_mq_post_message(CDF_MODULE_ID_WMA,
+						       &msg))) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
+			"%s: Unable to post WMA_ROAM_OFFLOAD_SYNCH_FAIL to WMA",
+			__func__);
+		cdf_mem_free(roam_offload_failed);
+	}
+}
+#endif
+
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+/**
+ * csr_roam_copy_ht_profile() - Copy from src to dst
+ * @dst_profile:          Destination HT profile
+ * @src_profile:          Source HT profile
+ *
+ * Copy the HT profile from the given source to destination
+ *
+ * Return: None
+ */
+static void csr_roam_copy_ht_profile(tCsrRoamHTProfile *dst_profile,
+		tSirSmeHTProfile *src_profile)
+{
+	dst_profile->phymode =
+		csr_roamdot11mode_to_phymode(src_profile->dot11mode);
+	dst_profile->htCapability = src_profile->htCapability;
+	dst_profile->htSupportedChannelWidthSet =
+		src_profile->htSupportedChannelWidthSet;
+	dst_profile->htRecommendedTxWidthSet =
+		src_profile->htRecommendedTxWidthSet;
+	dst_profile->htSecondaryChannelOffset =
+		src_profile->htSecondaryChannelOffset;
+#ifdef WLAN_FEATURE_11AC
+	dst_profile->vhtCapability = src_profile->vhtCapability;
+	dst_profile->vhtTxChannelWidthSet = src_profile->vhtTxChannelWidthSet;
+	dst_profile->apCenterChan = src_profile->apCenterChan;
+	dst_profile->apChanWidth = src_profile->apChanWidth;
+#endif
+}
+#endif
+
+/**
+ * csr_roam_process_results_default() - Process the result for start bss
+ * @mac_ctx:          Global MAC Context
+ * @cmd:              Command to be processed
+ * @context:          Additional data in context of the cmd
+ *
+ * Return: None
+ */
+static void csr_roam_process_results_default(tpAniSirGlobal mac_ctx,
+		     tSmeCmd *cmd, void *context, eCsrRoamCompleteResult res)
+{
+	uint32_t session_id = cmd->sessionId;
+	tCsrRoamSession *session = CSR_GET_SESSION(mac_ctx, session_id);
+	tCsrRoamInfo roam_info;
+	CDF_STATUS status;
+
+	sms_log(mac_ctx, LOGW, FL("receives no association indication"));
+	sms_log(mac_ctx, LOG1, FL("Assoc ref count %d"),
+			session->bRefAssocStartCnt);
+	if (CSR_IS_INFRASTRUCTURE(&session->connectedProfile)
+		|| CSR_IS_ROAM_SUBSTATE_STOP_BSS_REQ(mac_ctx, session_id)) {
+		/*
+		 * do not free for the other profiles as we need
+		 * to send down stop BSS later
+		 */
+		csr_free_connect_bss_desc(mac_ctx, session_id);
+		csr_roam_free_connect_profile(mac_ctx,
+			&session->connectedProfile);
+		csr_roam_free_connected_info(mac_ctx, &session->connectedInfo);
+		csr_set_default_dot11_mode(mac_ctx);
+	}
+
+	switch (cmd->u.roamCmd.roamReason) {
+	/*
+	 * If this transition is because of an 802.11 OID, then we
+	 * transition back to INIT state so we sit waiting for more
+	 * OIDs to be issued and we don't start the IDLE timer.
+	 */
+	case eCsrSmeIssuedFTReassoc:
+	case eCsrSmeIssuedAssocToSimilarAP:
+	case eCsrHddIssued:
+	case eCsrSmeIssuedDisassocForHandoff:
+		csr_roam_state_change(mac_ctx, eCSR_ROAMING_STATE_IDLE,
+			session_id);
+		cdf_mem_set(&roam_info, sizeof(tCsrRoamInfo), 0);
+		roam_info.pBssDesc = cmd->u.roamCmd.pLastRoamBss;
+		roam_info.pProfile = &cmd->u.roamCmd.roamProfile;
+		roam_info.statusCode = session->joinFailStatusCode.statusCode;
+		roam_info.reasonCode = session->joinFailStatusCode.reasonCode;
+		cdf_mem_copy(&roam_info.bssid,
+			&session->joinFailStatusCode.bssId,
+			sizeof(struct cdf_mac_addr));
+
+#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
+		/*
+		 * If Join fails while Handoff is in progress, indicate
+		 * disassociated event to supplicant to reconnect
+		 */
+		if (csr_roam_is_handoff_in_progress(mac_ctx, session_id)) {
+			csr_neighbor_roam_indicate_connect(mac_ctx,
+				(uint8_t)session_id, CDF_STATUS_E_FAILURE);
+		}
+#endif
+		if (session->bRefAssocStartCnt > 0) {
+			session->bRefAssocStartCnt--;
+			if (eCsrJoinFailureDueToConcurrency == res)
+				csr_roam_call_callback(mac_ctx, session_id,
+					&roam_info, cmd->u.roamCmd.roamId,
+					eCSR_ROAM_ASSOCIATION_COMPLETION,
+					eCSR_ROAM_RESULT_ASSOC_FAIL_CON_CHANNEL);
+			else
+				csr_roam_call_callback(mac_ctx, session_id,
+					&roam_info, cmd->u.roamCmd.roamId,
+					eCSR_ROAM_ASSOCIATION_COMPLETION,
+					eCSR_ROAM_RESULT_FAILURE);
+		} else {
+			/*
+			 * bRefAssocStartCnt is not incremented when
+			 * eRoamState == eCsrStopRoamingDueToConcurrency
+			 * in csr_roam_join_next_bss API. so handle this in
+			 * else case by sending assoc failure
+			 */
+			csr_roam_call_callback(mac_ctx, session_id,
+				&roam_info, cmd->u.scanCmd.roamId,
+				eCSR_ROAM_ASSOCIATION_FAILURE,
+				eCSR_ROAM_RESULT_FAILURE);
+		}
+		sms_log(mac_ctx, LOG1, FL("roam(reason %d) failed"),
+			cmd->u.roamCmd.roamReason);
+#ifndef WLAN_MDM_CODE_REDUCTION_OPT
+		sme_qos_update_hand_off((uint8_t) session_id, false);
+		sme_qos_csr_event_ind(mac_ctx, (uint8_t) session_id,
+			SME_QOS_CSR_DISCONNECT_IND, NULL);
+#endif
+		csr_roam_completion(mac_ctx, session_id, NULL, cmd,
+			eCSR_ROAM_RESULT_FAILURE, false);
+#ifdef FEATURE_WLAN_BTAMP_UT_RF
+		/*
+		 * For WDS STA. To fix the issue where the WDS AP side may
+		 * be too busy by BT activity and not able to receive
+		 * WLAN traffic. Retry the join
+		 */
+		if (CSR_IS_WDS_STA(profile))
+			csr_roam_start_join_retry_timer(mac_ctx, session_id,
+				CSR_JOIN_RETRY_TIMEOUT_PERIOD);
+#endif
+		break;
+	case eCsrHddIssuedReassocToSameAP:
+	case eCsrSmeIssuedReassocToSameAP:
+		csr_roam_state_change(mac_ctx, eCSR_ROAMING_STATE_IDLE,
+			session_id);
+
+		csr_roam_call_callback(mac_ctx, session_id, NULL,
+			cmd->u.roamCmd.roamId, eCSR_ROAM_DISASSOCIATED,
+			eCSR_ROAM_RESULT_FORCED);
+#ifndef WLAN_MDM_CODE_REDUCTION_OPT
+		sme_qos_csr_event_ind(mac_ctx, (uint8_t) session_id,
+			SME_QOS_CSR_DISCONNECT_IND, NULL);
+#endif
+		csr_roam_completion(mac_ctx, session_id, NULL, cmd,
+			eCSR_ROAM_RESULT_FAILURE, false);
+		break;
+	case eCsrForcedDisassoc:
+	case eCsrForcedDeauth:
+	case eCsrSmeIssuedIbssJoinFailure:
+		csr_roam_state_change(mac_ctx, eCSR_ROAMING_STATE_IDLE,
+			session_id);
+
+		if (eCsrSmeIssuedIbssJoinFailure == cmd->u.roamCmd.roamReason)
+			/* notify HDD that IBSS join failed */
+			csr_roam_call_callback(mac_ctx, session_id, NULL, 0,
+				eCSR_ROAM_IBSS_IND,
+				eCSR_ROAM_RESULT_IBSS_JOIN_FAILED);
+		else
+			csr_roam_call_callback(mac_ctx, session_id, NULL,
+				cmd->u.roamCmd.roamId, eCSR_ROAM_DISASSOCIATED,
+				eCSR_ROAM_RESULT_FORCED);
+#ifndef WLAN_MDM_CODE_REDUCTION_OPT
+		sme_qos_csr_event_ind(mac_ctx, (uint8_t) session_id,
+				SME_QOS_CSR_DISCONNECT_IND,
+				NULL);
+#endif
+		csr_roam_link_down(mac_ctx, session_id);
+
+		if (mac_ctx->roam.deauthRspStatus == eSIR_SME_DEAUTH_STATUS) {
+			sms_log(mac_ctx, LOGW,
+				FL("FW still in connected state"));
+			break;
+		}
+		break;
+	case eCsrForcedIbssLeave:
+		csr_roam_call_callback(mac_ctx, session_id, NULL,
+			cmd->u.roamCmd.roamId, eCSR_ROAM_IBSS_LEAVE,
+			eCSR_ROAM_RESULT_IBSS_STOP);
+		break;
+	case eCsrForcedDisassocMICFailure:
+		csr_roam_state_change(mac_ctx, eCSR_ROAMING_STATE_IDLE,
+			session_id);
+
+		csr_roam_call_callback(mac_ctx, session_id, NULL,
+			cmd->u.roamCmd.roamId, eCSR_ROAM_DISASSOCIATED,
+			eCSR_ROAM_RESULT_MIC_FAILURE);
+#ifndef WLAN_MDM_CODE_REDUCTION_OPT
+		sme_qos_csr_event_ind(mac_ctx, (uint8_t) session_id,
+			SME_QOS_CSR_DISCONNECT_REQ, NULL);
+#endif
+		break;
+	case eCsrStopBss:
+		csr_roam_call_callback(mac_ctx, session_id, NULL,
+			cmd->u.roamCmd.roamId, eCSR_ROAM_INFRA_IND,
+			eCSR_ROAM_RESULT_INFRA_STOPPED);
+		break;
+	case eCsrForcedDisassocSta:
+	case eCsrForcedDeauthSta:
+		csr_roam_state_change(mac_ctx, eCSR_ROAMING_STATE_JOINED,
+			session_id);
+		session = CSR_GET_SESSION(mac_ctx, session_id);
+		if (CSR_IS_SESSION_VALID(mac_ctx, session_id) &&
+			CSR_IS_INFRA_AP(&session->connectedProfile)) {
+			roam_info.u.pConnectedProfile =
+				&session->connectedProfile;
+			cdf_mem_copy(roam_info.peerMac.bytes,
+					cmd->u.roamCmd.peerMac,
+					sizeof(tSirMacAddr));
+			roam_info.reasonCode = eCSR_ROAM_RESULT_FORCED;
+			roam_info.statusCode = eSIR_SME_SUCCESS;
+			status = csr_roam_call_callback(mac_ctx, session_id,
+					&roam_info, cmd->u.roamCmd.roamId,
+					eCSR_ROAM_LOSTLINK,
+					eCSR_ROAM_RESULT_FORCED);
+		}
+		break;
+	case eCsrLostLink1:
+		/* if lost link roam1 failed, then issue lost link Scan2 ... */
+		csr_scan_request_lost_link2(mac_ctx, session_id);
+		break;
+	case eCsrLostLink2:
+		/* if lost link roam2 failed, then issue lost link scan3 ... */
+		csr_scan_request_lost_link3(mac_ctx, session_id);
+		break;
+	case eCsrLostLink3:
+	default:
+		csr_roam_state_change(mac_ctx,
+			eCSR_ROAMING_STATE_IDLE, session_id);
+
+		/* We are done with one round of lostlink roaming here */
+		csr_scan_handle_failed_lostlink3(mac_ctx, session_id);
+		break;
+	}
+}
+
+/**
+ * csr_roam_process_start_bss_success() - Process the result for start bss
+ * @mac_ctx:          Global MAC Context
+ * @cmd:              Command to be processed
+ * @context:          Additional data in context of the cmd
+ *
+ * Return: None
+ */
+static void csr_roam_process_start_bss_success(tpAniSirGlobal mac_ctx,
+		     tSmeCmd *cmd, void *context)
+{
+	uint32_t session_id = cmd->sessionId;
+	tCsrRoamProfile *profile = &cmd->u.roamCmd.roamProfile;
+	tCsrRoamSession *session = CSR_GET_SESSION(mac_ctx, session_id);
+	tSirBssDescription *bss_desc = NULL;
+	tCsrRoamInfo roam_info;
+	tSirSmeStartBssRsp *start_bss_rsp = NULL;
+	tCsrScanResult *scan_res = NULL;
+	eRoamCmdStatus roam_status;
+	eCsrRoamResult roam_result;
+	tDot11fBeaconIEs *ies_ptr = NULL;
+	tSirMacAddr bcast_mac = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+	CDF_STATUS status;
+	host_log_ibss_pkt_type *ibss_log;
+	uint32_t bi;
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+	tSirSmeHTProfile *src_profile = NULL;
+	tCsrRoamHTProfile *dst_profile = NULL;
+#endif
+
+	/*
+	 * on the StartBss Response, LIM is returning the Bss Description that
+	 * we are beaconing.  Add this Bss Description to our scan results and
+	 * chain the Profile to this Bss Description.  On a Start BSS, there was
+	 * no detected Bss description (no partner) so we issued the Start Bss
+	 * to start the Ibss without any Bss description.  Lim was kind enough
+	 * to return the Bss Description that we start beaconing for the newly
+	 * started Ibss.
+	 */
+	sms_log(mac_ctx, LOG2, FL("receives start BSS ok indication"));
+	status = CDF_STATUS_E_FAILURE;
+	start_bss_rsp = (tSirSmeStartBssRsp *) context;
+	cdf_mem_set(&roam_info, sizeof(tCsrRoamInfo), 0);
+	if (CSR_IS_IBSS(profile))
+		session->connectState = eCSR_ASSOC_STATE_TYPE_IBSS_DISCONNECTED;
+	else if (CSR_IS_INFRA_AP(profile))
+		session->connectState =
+			eCSR_ASSOC_STATE_TYPE_INFRA_DISCONNECTED;
+	else
+		session->connectState = eCSR_ASSOC_STATE_TYPE_WDS_DISCONNECTED;
+	if (!CSR_IS_WDS_STA(profile)) {
+		csr_roam_state_change(mac_ctx, eCSR_ROAMING_STATE_JOINED,
+			session_id);
+		bss_desc = &start_bss_rsp->bssDescription;
+		if (!CDF_IS_STATUS_SUCCESS
+			(csr_get_parsed_bss_description_ies(mac_ctx, bss_desc,
+							    &ies_ptr))) {
+			sms_log(mac_ctx, LOGW, FL("cannot parse IBSS IEs"));
+			roam_info.pBssDesc = bss_desc;
+			csr_roam_call_callback(mac_ctx, session_id, &roam_info,
+				cmd->u.roamCmd.roamId, eCSR_ROAM_IBSS_IND,
+				eCSR_ROAM_RESULT_IBSS_START_FAILED);
+			return;
+		}
+		if (!CSR_IS_INFRA_AP(profile)) {
+			scan_res =
+				csr_scan_append_bss_description(mac_ctx,
+						bss_desc, ies_ptr, false,
+						session_id);
+		}
+		csr_roam_save_connected_bss_desc(mac_ctx, session_id, bss_desc);
+		csr_roam_free_connect_profile(mac_ctx,
+				&session->connectedProfile);
+		csr_roam_free_connected_info(mac_ctx,
+				&session->connectedInfo);
+		if (bss_desc) {
+			csr_roam_save_connected_infomation(mac_ctx, session_id,
+					profile, bss_desc, ies_ptr);
+			cdf_mem_copy(&roam_info.bssid, &bss_desc->bssId,
+				sizeof(struct cdf_mac_addr));
+		}
+		/* We are done with the IEs so free it */
+		cdf_mem_free(ies_ptr);
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+		WLAN_HOST_DIAG_LOG_ALLOC(ibss_log,
+			host_log_ibss_pkt_type, LOG_WLAN_IBSS_C);
+		if (ibss_log) {
+			if (CSR_INVALID_SCANRESULT_HANDLE ==
+					cmd->u.roamCmd.hBSSList) {
+				/*
+				 * We start the IBSS (didn't find any
+				 * matched IBSS out there)
+				 */
+				ibss_log->eventId =
+					WLAN_IBSS_EVENT_START_IBSS_RSP;
+			} else {
+				ibss_log->eventId =
+					WLAN_IBSS_EVENT_JOIN_IBSS_RSP;
+			}
+			if (bss_desc) {
+				cdf_mem_copy(ibss_log->bssid,
+					bss_desc->bssId, 6);
+				ibss_log->operatingChannel =
+					bss_desc->channelId;
+			}
+			if (IS_SIR_STATUS_SUCCESS(wlan_cfg_get_int(
+						mac_ctx,
+						WNI_CFG_BEACON_INTERVAL,
+						&bi)))
+				/* U8 is not enough for BI */
+				ibss_log->beaconInterval = (uint8_t) bi;
+			WLAN_HOST_DIAG_LOG_REPORT(ibss_log);
+		}
+#endif
+		/*
+		 * Only set context for non-WDS_STA. We don't even need it for
+		 * WDS_AP. But since the encryption.
+		 * is WPA2-PSK so it won't matter.
+		 */
+		if (CSR_IS_ENC_TYPE_STATIC(profile->negotiatedUCEncryptionType)
+				&& session->pCurRoamProfile
+				&& !CSR_IS_INFRA_AP(session->pCurRoamProfile)) {
+			/*
+			 * Issue the set Context request to LIM to establish
+			 * the Broadcast STA context for the Ibss. In Rome IBSS
+			 * case, dummy key installation will break proper BSS
+			 * key installation, so skip it.
+			 */
+			if (!CSR_IS_IBSS(session->pCurRoamProfile)) {
+				/* NO keys. these key parameters don't matter */
+				csr_roam_issue_set_context_req(mac_ctx,
+					session_id,
+					profile->negotiatedMCEncryptionType,
+					bss_desc, &bcast_mac, false,
+					false, eSIR_TX_RX, 0, 0, NULL, 0);
+			}
+
+		}
+	} else {
+		/*
+		 * Keep the state to eCSR_ROAMING_STATE_JOINING.
+		 * Need to send join_req.
+		 */
+		if (cmd->u.roamCmd.pRoamBssEntry) {
+			scan_res = GET_BASE_ADDR(cmd->u.roamCmd.
+					pRoamBssEntry, tCsrScanResult, Link);
+			if (scan_res) {
+				bss_desc = &scan_res->Result.BssDescriptor;
+				ies_ptr = (tDot11fBeaconIEs *)
+					(scan_res->Result.pvIes);
+				/* Set the roaming substate to join attempt */
+				csr_roam_substate_change(mac_ctx,
+					eCSR_ROAM_SUBSTATE_JOIN_REQ,
+					session_id);
+				status = csr_send_join_req_msg(mac_ctx,
+						session_id, bss_desc,
+						profile, ies_ptr,
+						eWNI_SME_JOIN_REQ);
+			}
+		} else {
+			sms_log(mac_ctx, LOGE,
+				"StartBSS for WDS station with no BssDesc");
+			CDF_ASSERT(0);
+		}
+	}
+	/*
+	 * Only tell upper layer is we start the BSS because Vista doesn't like
+	 * multiple connection indications. If we don't start the BSS ourself,
+	 * handler of eSIR_SME_JOINED_NEW_BSS will trigger the connection start
+	 * indication in Vista
+	 */
+	if (!CSR_IS_JOIN_TO_IBSS(profile)) {
+		roam_status = eCSR_ROAM_IBSS_IND;
+		roam_result = eCSR_ROAM_RESULT_IBSS_STARTED;
+		if (CSR_IS_WDS(profile)) {
+			roam_status = eCSR_ROAM_WDS_IND;
+			roam_result = eCSR_ROAM_RESULT_WDS_STARTED;
+		}
+		if (CSR_IS_INFRA_AP(profile)) {
+			roam_status = eCSR_ROAM_INFRA_IND;
+			roam_result = eCSR_ROAM_RESULT_INFRA_STARTED;
+		}
+		/*
+		 * Only tell upper layer is we start the BSS because Vista
+		 * doesn't like multiple connection indications. If we don't
+		 * start the BSS ourself, handler of eSIR_SME_JOINED_NEW_BSS
+		 * will trigger the connection start indication in Vista
+		 */
+		cdf_mem_set(&roam_info, sizeof(tCsrRoamInfo), 0);
+		roam_info.statusCode = session->joinFailStatusCode.statusCode;
+		roam_info.reasonCode = session->joinFailStatusCode.reasonCode;
+		/* We start the IBSS (didn't find any matched IBSS out there) */
+		roam_info.pBssDesc = bss_desc;
+		roam_info.staId = (uint8_t) start_bss_rsp->staId;
+		cdf_mem_copy(roam_info.bssid.bytes, bss_desc->bssId,
+				sizeof(struct cdf_mac_addr));
+		if (!IS_FEATURE_SUPPORTED_BY_FW(SLM_SESSIONIZATION) &&
+				(csr_is_concurrent_session_running(mac_ctx))) {
+			mac_ctx->roam.configParam.doBMPSWorkaround = 1;
+		}
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+		dst_profile = &session->connectedProfile.HTProfile;
+		src_profile = &start_bss_rsp->HTProfile;
+		if (mac_ctx->roam.configParam.cc_switch_mode
+				!= CDF_MCC_TO_SCC_SWITCH_DISABLE)
+			csr_roam_copy_ht_profile(dst_profile, src_profile);
+#endif
+		csr_roam_call_callback(mac_ctx, session_id, &roam_info,
+				cmd->u.roamCmd.roamId,
+				roam_status, roam_result);
+	}
+
+
+	if (CSR_IS_WDS_STA(profile)) {
+		/* need to send stop BSS because we fail to send join_req */
+		csr_roam_issue_disassociate_cmd(mac_ctx, session_id,
+				eCSR_DISCONNECT_REASON_UNSPECIFIED);
+		csr_roam_call_callback(mac_ctx, session_id, &roam_info,
+				cmd->u.roamCmd.roamId,
+				eCSR_ROAM_WDS_IND,
+				eCSR_ROAM_RESULT_WDS_STOPPED);
+	}
+}
+
+/**
+ * csr_roam_process_join_res() - Process the Join results
+ * @mac_ctx:          Global MAC Context
+ * @result:           Result after the command was processed
+ * @cmd:              Command to be processed
+ * @context:          Additional data in context of the cmd
+ *
+ * Process the join results which are obtained in a succesful join
+ *
+ * Return: None
+ */
+static void csr_roam_process_join_res(tpAniSirGlobal mac_ctx,
+	eCsrRoamCompleteResult res, tSmeCmd *cmd, void *context)
+{
+	tSirMacAddr bcast_mac = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+	sme_QosAssocInfo assoc_info;
+	uint32_t key_timeout_interval = 0;
+	uint8_t acm_mask = 0;   /* HDD needs ACM mask in assoc rsp callback */
+	uint32_t session_id = cmd->sessionId;
+	tCsrRoamProfile *profile = &cmd->u.roamCmd.roamProfile;
+	tCsrRoamSession *session = CSR_GET_SESSION(mac_ctx, session_id);
+	tSirBssDescription *bss_desc = NULL;
+	tCsrScanResult *scan_res = NULL;
+	sme_qos_csr_event_indType ind_qos;
+	csr_roam_offload_synch_params *roam_offload_params = NULL;
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+	tSirSmeHTProfile *src_profile = NULL;
+	tCsrRoamHTProfile *dst_profile = NULL;
+#endif
+	tCsrRoamConnectedProfile *conn_profile = NULL;
+	tDot11fBeaconIEs *ies_ptr = NULL;
+	tCsrRoamInfo roam_info;
+	struct ps_global_info *ps_global_info = &mac_ctx->sme.ps_global_info;
+	tSirSmeJoinRsp *join_rsp = (tSirSmeJoinRsp *) context;
+	uint32_t len;
+
+	roam_offload_params = &session->roamOffloadSynchParams;
+	conn_profile = &session->connectedProfile;
+	if (eCsrReassocSuccess == res)
+		ind_qos = SME_QOS_CSR_REASSOC_COMPLETE;
+	else
+		ind_qos = SME_QOS_CSR_ASSOC_COMPLETE;
+	sms_log(mac_ctx, LOGW, FL("receives association indication"));
+	cdf_mem_set(&roam_info, sizeof(roam_info), 0);
+	/* always free the memory here */
+	if (session->pWpaRsnRspIE) {
+		session->nWpaRsnRspIeLength = 0;
+		cdf_mem_free(session->pWpaRsnRspIE);
+		session->pWpaRsnRspIE = NULL;
+	}
+#ifdef FEATURE_WLAN_WAPI
+	if (session->pWapiRspIE) {
+		session->nWapiRspIeLength = 0;
+		cdf_mem_free(session->pWapiRspIE);
+		session->pWapiRspIE = NULL;
+	}
+#endif /* FEATURE_WLAN_WAPI */
+#ifdef FEATURE_WLAN_BTAMP_UT_RF
+	session->maxRetryCount = 0;
+	csr_roam_stop_join_retry_timer(mac_ctx, session_id);
+#endif
+	/*
+	 * Reset remain_in_power_active_till_dhcp as
+	 * it might have been set by last failed secured connection.
+	 * It should be set only for secured connection.
+	 */
+	ps_global_info->remain_in_power_active_till_dhcp = false;
+	if (CSR_IS_INFRASTRUCTURE(profile))
+		session->connectState = eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED;
+	else
+		session->connectState = eCSR_ASSOC_STATE_TYPE_WDS_CONNECTED;
+	/*
+	 * Use the last connected bssdesc for reassoc-ing to the same AP.
+	 * NOTE: What to do when reassoc to a different AP???
+	 */
+	if ((eCsrHddIssuedReassocToSameAP == cmd->u.roamCmd.roamReason)
+		|| (eCsrSmeIssuedReassocToSameAP ==
+			cmd->u.roamCmd.roamReason)) {
+		bss_desc = session->pConnectBssDesc;
+		if (bss_desc)
+			cdf_mem_copy(&roam_info.bssid, &bss_desc->bssId,
+					sizeof(struct cdf_mac_addr));
+	} else {
+		if (cmd->u.roamCmd.pRoamBssEntry) {
+			scan_res = GET_BASE_ADDR(cmd->u.roamCmd.pRoamBssEntry,
+					tCsrScanResult, Link);
+			if (scan_res != NULL) {
+				bss_desc = &scan_res->Result.BssDescriptor;
+				ies_ptr = (tDot11fBeaconIEs *)
+					(scan_res->Result.pvIes);
+				cdf_mem_copy(&roam_info.bssid, &bss_desc->bssId,
+					sizeof(struct cdf_mac_addr));
+			}
+		}
+	}
+	if (bss_desc) {
+		roam_info.staId = STA_INVALID_IDX;
+		csr_roam_save_connected_infomation(mac_ctx, session_id,
+			profile, bss_desc, ies_ptr);
+		/* Save WPA/RSN IE */
+		csr_roam_save_security_rsp_ie(mac_ctx, session_id,
+			profile->negotiatedAuthType, bss_desc, ies_ptr);
+#ifdef FEATURE_WLAN_ESE
+		roam_info.isESEAssoc = conn_profile->isESEAssoc;
+#endif
+
+		/*
+		 * csr_roam_state_change also affects sub-state.
+		 * Hence, csr_roam_state_change happens first and then
+		 * substate change.
+		 * Moving even save profile above so that below
+		 * mentioned conditon is also met.
+		 * JEZ100225: Moved to after saving the profile.
+		 * Fix needed in main/latest
+		 */
+		csr_roam_state_change(mac_ctx,
+			eCSR_ROAMING_STATE_JOINED, session_id);
+
+		/*
+		 * Make sure the Set Context is issued before link
+		 * indication to NDIS.  After link indication is
+		 * made to NDIS, frames could start flowing.
+		 * If we have not set context with LIM, the frames
+		 * will be dropped for the security context may not
+		 * be set properly.
+		 *
+		 * this was causing issues in the 2c_wlan_wep WHQL test
+		 * when the SetContext was issued after the link
+		 * indication. (Link Indication happens in the
+		 * profFSMSetConnectedInfra call).
+		 *
+		 * this reordering was done on titan_prod_usb branch
+		 * and is being replicated here.
+		 */
+
+		if (CSR_IS_ENC_TYPE_STATIC
+			(profile->negotiatedUCEncryptionType) &&
+			!profile->bWPSAssociation) {
+			/*
+			 * Issue the set Context request to LIM to establish
+			 * the Unicast STA context
+			 */
+			if (!CDF_IS_STATUS_SUCCESS(
+				csr_roam_issue_set_context_req(mac_ctx,
+					session_id,
+					profile->negotiatedUCEncryptionType,
+					bss_desc, &(bss_desc->bssId),
+					false, true,
+					eSIR_TX_RX, 0, 0, NULL, 0))) {
+				/* NO keys. these key parameters don't matter */
+				sms_log(mac_ctx, LOGE,
+					FL("Set context for unicast fail"));
+				csr_roam_substate_change(mac_ctx,
+					eCSR_ROAM_SUBSTATE_NONE, session_id);
+			}
+			/*
+			 * Issue the set Context request to LIM
+			 * to establish the Broadcast STA context
+			 * NO keys. these key parameters don't matter
+			 */
+			csr_roam_issue_set_context_req(mac_ctx, session_id,
+				profile->negotiatedMCEncryptionType,
+				bss_desc, &bcast_mac, false, false,
+				eSIR_TX_RX, 0, 0, NULL, 0);
+		} else {
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+			if (roam_offload_params->bRoamSynchInProgress
+				&& (roam_offload_params->authStatus
+				== CSR_ROAM_AUTH_STATUS_AUTHENTICATED)) {
+				CDF_TRACE(CDF_MODULE_ID_SME,
+					CDF_TRACE_LEVEL_DEBUG,
+					FL("LFR3:Don't start waitforkey timer"));
+				csr_roam_substate_change(mac_ctx,
+					eCSR_ROAM_SUBSTATE_NONE, session_id);
+			} else {
+#endif
+				/* Need to wait for supplicant authtication */
+				roam_info.fAuthRequired = true;
+				/*
+				 * Set the substate to WaitForKey in case
+				 * authentiation is needed
+				 */
+				csr_roam_substate_change(mac_ctx,
+					eCSR_ROAM_SUBSTATE_WAIT_FOR_KEY,
+					session_id);
+
+				/*
+				 * Set remain_in_power_active_till_dhcp to make
+				 * sure we wait for until keys are set before
+				 * going into BMPS.
+				 */
+				ps_global_info->remain_in_power_active_till_dhcp
+					= true;
+
+				if (profile->bWPSAssociation)
+					key_timeout_interval =
+						CSR_WAIT_FOR_WPS_KEY_TIMEOUT_PERIOD;
+				else
+					key_timeout_interval =
+						CSR_WAIT_FOR_KEY_TIMEOUT_PERIOD;
+
+				/* Save session_id in case of timeout */
+				mac_ctx->roam.WaitForKeyTimerInfo.sessionId =
+					(uint8_t) session_id;
+				/*
+				 * This time should be long enough for the rest
+				 * of the process plus setting key
+				 */
+				if (!CDF_IS_STATUS_SUCCESS
+					(csr_roam_start_wait_for_key_timer(
+						mac_ctx, key_timeout_interval))
+					) {
+					/* Reset state so nothing is blocked. */
+					sms_log(mac_ctx, LOGE, FL
+						("Failed preauth timer start"));
+					csr_roam_substate_change(mac_ctx,
+						eCSR_ROAM_SUBSTATE_NONE,
+						session_id);
+				}
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+			}
+#endif
+		}
+
+		assoc_info.pBssDesc = bss_desc;       /* could be NULL */
+		assoc_info.pProfile = profile;
+		if (context) {
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+			if (roam_offload_params->bRoamSynchInProgress)
+				CDF_TRACE(CDF_MODULE_ID_SME,
+					CDF_TRACE_LEVEL_DEBUG,
+					FL("LFR3:Clear Connected info"));
+#endif
+			csr_roam_free_connected_info(mac_ctx,
+				&session->connectedInfo);
+			len = join_rsp->assocReqLength +
+				join_rsp->assocRspLength +
+				join_rsp->beaconLength;
+#ifdef WLAN_FEATURE_VOWIFI_11R
+			len += join_rsp->parsedRicRspLen;
+#endif /* WLAN_FEATURE_VOWIFI_11R */
+#ifdef FEATURE_WLAN_ESE
+			len += join_rsp->tspecIeLen;
+#endif
+			if (len) {
+				session->connectedInfo.pbFrames =
+					cdf_mem_malloc(len);
+				if (session->connectedInfo.pbFrames !=
+						NULL) {
+					cdf_mem_copy(
+						session->connectedInfo.pbFrames,
+						join_rsp->frames, len);
+					session->connectedInfo.nAssocReqLength =
+						join_rsp->assocReqLength;
+					session->connectedInfo.nAssocRspLength =
+						join_rsp->assocRspLength;
+					session->connectedInfo.nBeaconLength =
+						join_rsp->beaconLength;
+#ifdef WLAN_FEATURE_VOWIFI_11R
+					session->connectedInfo.nRICRspLength =
+						join_rsp->parsedRicRspLen;
+#endif /* WLAN_FEATURE_VOWIFI_11R */
+#ifdef FEATURE_WLAN_ESE
+					session->connectedInfo.nTspecIeLength =
+						join_rsp->tspecIeLen;
+#endif
+					roam_info.nAssocReqLength =
+						join_rsp->assocReqLength;
+					roam_info.nAssocRspLength =
+						join_rsp->assocRspLength;
+					roam_info.nBeaconLength =
+						join_rsp->beaconLength;
+					roam_info.pbFrames =
+						session->connectedInfo.pbFrames;
+				}
+			}
+			if (cmd->u.roamCmd.fReassoc)
+				roam_info.fReassocReq =
+					roam_info.fReassocRsp = true;
+			conn_profile->vht_channel_width =
+				join_rsp->vht_channel_width;
+			session->connectedInfo.staId =
+				(uint8_t) join_rsp->staId;
+			roam_info.staId = (uint8_t) join_rsp->staId;
+			roam_info.ucastSig = (uint8_t) join_rsp->ucastSig;
+			roam_info.bcastSig = (uint8_t) join_rsp->bcastSig;
+			roam_info.timingMeasCap = join_rsp->timingMeasCap;
+#ifdef FEATURE_WLAN_TDLS
+			roam_info.tdls_prohibited = join_rsp->tdls_prohibited;
+			roam_info.tdls_chan_swit_prohibited =
+				join_rsp->tdls_chan_swit_prohibited;
+			sms_log(mac_ctx, LOG1,
+				FL("tdls:prohibit: %d, chan_swit_prohibit: %d"),
+				roam_info.tdls_prohibited,
+				roam_info.tdls_chan_swit_prohibited);
+#endif
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+			src_profile = &join_rsp->HTProfile;
+			dst_profile = &conn_profile->HTProfile;
+			if (mac_ctx->roam.configParam.cc_switch_mode
+				!= CDF_MCC_TO_SCC_SWITCH_DISABLE)
+				csr_roam_copy_ht_profile(dst_profile,
+						src_profile);
+#endif
+		} else {
+			if (cmd->u.roamCmd.fReassoc) {
+				roam_info.fReassocReq =
+					roam_info.fReassocRsp = true;
+				roam_info.nAssocReqLength =
+					session->connectedInfo.nAssocReqLength;
+				roam_info.nAssocRspLength =
+					session->connectedInfo.nAssocRspLength;
+				roam_info.nBeaconLength =
+					session->connectedInfo.nBeaconLength;
+				roam_info.pbFrames =
+					session->connectedInfo.pbFrames;
+			}
+		}
+
+		/*
+		 * Update the staId from the previous connected profile info
+		 * as the reassociation is triggred at SME/HDD
+		 */
+
+		if ((eCsrHddIssuedReassocToSameAP ==
+				cmd->u.roamCmd.roamReason) ||
+			(eCsrSmeIssuedReassocToSameAP ==
+				cmd->u.roamCmd.roamReason))
+			roam_info.staId = session->connectedInfo.staId;
+
+#ifndef WLAN_MDM_CODE_REDUCTION_OPT
+		/*
+		 * Indicate SME-QOS with reassoc success event,
+		 * only after copying the frames
+		 */
+		sme_qos_csr_event_ind(mac_ctx, (uint8_t) session_id, ind_qos,
+				&assoc_info);
+#endif
+		roam_info.pBssDesc = bss_desc;
+		roam_info.statusCode =
+			session->joinFailStatusCode.statusCode;
+		roam_info.reasonCode =
+			session->joinFailStatusCode.reasonCode;
+#ifndef WLAN_MDM_CODE_REDUCTION_OPT
+		acm_mask = sme_qos_get_acm_mask(mac_ctx, bss_desc, NULL);
+#endif
+		conn_profile->acm_mask = acm_mask;
+		/*
+		 * start UAPSD if uapsd_mask is not 0 because HDD will
+		 * configure for trigger frame It may be better to let QoS do
+		 * this????
+		 */
+		if (conn_profile->modifyProfileFields.uapsd_mask) {
+			sms_log(mac_ctx, LOGE,
+				" uapsd_mask (0x%X) set, request UAPSD now",
+				conn_profile->modifyProfileFields.uapsd_mask);
+			sme_ps_start_uapsd(mac_ctx, session_id,
+				NULL, NULL);
+		}
+		conn_profile->dot11Mode = session->bssParams.uCfgDot11Mode;
+		roam_info.u.pConnectedProfile = conn_profile;
+
+		if (session->bRefAssocStartCnt > 0) {
+			session->bRefAssocStartCnt--;
+			if (!IS_FEATURE_SUPPORTED_BY_FW
+				(SLM_SESSIONIZATION) &&
+				(csr_is_concurrent_session_running(mac_ctx))) {
+				mac_ctx->roam.configParam.doBMPSWorkaround = 1;
+			}
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+			if (roam_offload_params->bRoamSynchInProgress) {
+				roam_info.roamSynchInProgress = 1;
+				roam_info.synchAuthStatus =
+					roam_offload_params->authStatus;
+				cdf_mem_copy(roam_info.kck,
+					roam_offload_params->kck,
+					SIR_KCK_KEY_LEN);
+				cdf_mem_copy(roam_info.kek,
+					roam_offload_params->kek,
+					SIR_KEK_KEY_LEN);
+				cdf_mem_copy(roam_info.replay_ctr,
+					roam_offload_params->replay_ctr,
+					SIR_REPLAY_CTR_LEN);
+				CDF_TRACE(CDF_MODULE_ID_SME,
+					CDF_TRACE_LEVEL_DEBUG,
+					FL
+					("LFR3: Copy KCK, KEK and Replay Ctr"));
+			}
+#endif
+			csr_roam_call_callback(mac_ctx, session_id, &roam_info,
+				cmd->u.roamCmd.roamId,
+				eCSR_ROAM_ASSOCIATION_COMPLETION,
+				eCSR_ROAM_RESULT_ASSOCIATED);
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+			if (roam_offload_params->bRoamSynchInProgress
+				&& (roam_offload_params->authStatus
+				    == CSR_ROAM_AUTH_STATUS_CONNECTED)) {
+				CDF_TRACE(CDF_MODULE_ID_SME,
+					CDF_TRACE_LEVEL_DEBUG,
+					FL("LFR3:Send Synch Cnf for Auth status connected"));
+				csr_roam_offload_send_synch_cnf(mac_ctx,
+					session_id);
+			}
+#endif
+		}
+
+		csr_roam_completion(mac_ctx, session_id, NULL, cmd,
+				eCSR_ROAM_RESULT_NONE, true);
+		csr_reset_pmkid_candidate_list(mac_ctx, session_id);
+#ifdef FEATURE_WLAN_WAPI
+		csr_reset_bkid_candidate_list(mac_ctx, session_id);
+#endif
+	} else {
+		sms_log(mac_ctx, LOGW,
+			"Roam command doesn't have a BSS desc");
+	}
+	/* Not to signal link up because keys are yet to be set.
+	 * The linkup function will overwrite the sub-state that
+	 * we need to keep at this point.
+	 */
+	if (!CSR_IS_WAIT_FOR_KEY(mac_ctx, session_id)) {
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+		if (roam_offload_params->bRoamSynchInProgress) {
+			CDF_TRACE(CDF_MODULE_ID_SME,
+				CDF_TRACE_LEVEL_DEBUG,
+				FL
+				("NO CSR_IS_WAIT_FOR_KEY -> csr_roam_link_up"));
+		}
+#endif
+		csr_roam_link_up(mac_ctx, conn_profile->bssid);
+	}
+}
+
+/**
+ * csr_roam_process_results() - Process the Roam Results
+ * @mac_ctx:      Global MAC Context
+ * @cmd:          Command that has been processed
+ * @res:          Results available after processing the command
+ * @context:      Context
+ *
+ * Process the available results and make an appropriate decision
+ *
+ * Return: true if the command can be released, else not.
+ */
+static bool csr_roam_process_results(tpAniSirGlobal mac_ctx, tSmeCmd *cmd,
+				     eCsrRoamCompleteResult res, void *context)
+{
+	bool release_cmd = true;
+	tSirBssDescription *bss_desc = NULL;
+	tCsrRoamInfo roam_info;
+	uint32_t session_id = cmd->sessionId;
+	tCsrRoamSession *session = CSR_GET_SESSION(mac_ctx, session_id);
+	tCsrRoamProfile *profile = &cmd->u.roamCmd.roamProfile;
+	eRoamCmdStatus roam_status;
+	eCsrRoamResult roam_result;
+	host_log_ibss_pkt_type *ibss_log;
+
+	if (!session) {
+		sms_log(mac_ctx, LOGE, FL("session %d not found "), session_id);
+		return false;
+	}
+	sms_log(mac_ctx, LOG1, FL("Processing ROAM results..."));
+	switch (res) {
+	case eCsrJoinSuccess:
+	case eCsrReassocSuccess:
+		csr_roam_process_join_res(mac_ctx, res, cmd, context);
+		break;
+	case eCsrStartBssSuccess:
+		csr_roam_process_start_bss_success(mac_ctx, cmd, context);
+		break;
+	case eCsrStartBssFailure:
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+		WLAN_HOST_DIAG_LOG_ALLOC(ibss_log,
+			host_log_ibss_pkt_type, LOG_WLAN_IBSS_C);
+		if (ibss_log) {
+			ibss_log->status = WLAN_IBSS_STATUS_FAILURE;
+			WLAN_HOST_DIAG_LOG_REPORT(ibss_log);
+		}
+#endif
+		roam_status = eCSR_ROAM_IBSS_IND;
+		roam_result = eCSR_ROAM_RESULT_IBSS_STARTED;
+		if (CSR_IS_WDS(profile)) {
+			roam_status = eCSR_ROAM_WDS_IND;
+			roam_result = eCSR_ROAM_RESULT_WDS_STARTED;
+		}
+		if (CSR_IS_INFRA_AP(profile)) {
+			roam_status = eCSR_ROAM_INFRA_IND;
+			roam_result = eCSR_ROAM_RESULT_INFRA_START_FAILED;
+		}
+		if (context) {
+			bss_desc = (tSirBssDescription *) context;
+		} else {
+			bss_desc = NULL;
+		}
+		cdf_mem_set(&roam_info, sizeof(tCsrRoamInfo), 0);
+		roam_info.pBssDesc = bss_desc;
+		csr_roam_call_callback(mac_ctx, session_id, &roam_info,
+				cmd->u.roamCmd.roamId, roam_status,
+				roam_result);
+		csr_set_default_dot11_mode(mac_ctx);
+		break;
+	case eCsrSilentlyStopRoaming:
+		/*
+		 * We are here because we try to start the same IBSS.
+		 * No message to PE. return the roaming state to Joined.
+		 */
+		sms_log(mac_ctx, LOGW, FL("receives silently stop roam ind"));
+		csr_roam_state_change(mac_ctx, eCSR_ROAMING_STATE_JOINED,
+			session_id);
+		csr_roam_substate_change(mac_ctx, eCSR_ROAM_SUBSTATE_NONE,
+			session_id);
+		cdf_mem_set(&roam_info, sizeof(tCsrRoamInfo), 0);
+		roam_info.pBssDesc = session->pConnectBssDesc;
+		if (roam_info.pBssDesc)
+			cdf_mem_copy(&roam_info.bssid,
+				&roam_info.pBssDesc->bssId,
+				sizeof(struct cdf_mac_addr));
+		/*
+		 * Since there is no change in the current state, simply pass
+		 * back no result otherwise HDD may be mistakenly mark to
+		 * disconnected state.
+		 */
+		csr_roam_call_callback(mac_ctx, session_id, &roam_info,
+				cmd->u.roamCmd.roamId,
+				eCSR_ROAM_IBSS_IND, eCSR_ROAM_RESULT_NONE);
+		break;
+	case eCsrSilentlyStopRoamingSaveState:
+		/* We are here because we try to connect to the same AP */
+		/* No message to PE */
+		sms_log(mac_ctx, LOGW,
+			FL("receives silently stop roaming indication"));
+		cdf_mem_set(&roam_info, sizeof(roam_info), 0);
+
+		/* to aviod resetting the substate to NONE */
+		mac_ctx->roam.curState[session_id] = eCSR_ROAMING_STATE_JOINED;
+		/*
+		 * No need to change substate to wai_for_key because there
+		 * is no state change
+		 */
+		roam_info.pBssDesc = session->pConnectBssDesc;
+		if (roam_info.pBssDesc)
+			cdf_mem_copy(&roam_info.bssid,
+				&roam_info.pBssDesc->bssId,
+				sizeof(struct cdf_mac_addr));
+		roam_info.statusCode = session->joinFailStatusCode.statusCode;
+		roam_info.reasonCode = session->joinFailStatusCode.reasonCode;
+		roam_info.nBeaconLength = session->connectedInfo.nBeaconLength;
+		roam_info.nAssocReqLength =
+			session->connectedInfo.nAssocReqLength;
+		roam_info.nAssocRspLength =
+			session->connectedInfo.nAssocRspLength;
+		roam_info.pbFrames = session->connectedInfo.pbFrames;
+		roam_info.staId = session->connectedInfo.staId;
+		roam_info.u.pConnectedProfile = &session->connectedProfile;
+		if (0 == roam_info.staId) {
+			CDF_ASSERT(0);
+			return false;
+		}
+		session->bRefAssocStartCnt--;
+		csr_roam_call_callback(mac_ctx, session_id, &roam_info,
+				cmd->u.roamCmd.roamId,
+				eCSR_ROAM_ASSOCIATION_COMPLETION,
+				eCSR_ROAM_RESULT_ASSOCIATED);
+		csr_roam_completion(mac_ctx, session_id, NULL, cmd,
+				eCSR_ROAM_RESULT_ASSOCIATED, true);
+		break;
+	case eCsrReassocFailure:
+#ifndef WLAN_MDM_CODE_REDUCTION_OPT
+		sme_qos_csr_event_ind(mac_ctx, (uint8_t) session_id,
+				SME_QOS_CSR_REASSOC_FAILURE, NULL);
+#endif
+	case eCsrJoinWdsFailure:
+		sms_log(mac_ctx, LOGW, FL("failed to join WDS"));
+		csr_free_connect_bss_desc(mac_ctx, session_id);
+		csr_roam_free_connect_profile(mac_ctx,
+			&session->connectedProfile);
+		csr_roam_free_connected_info(mac_ctx, &session->connectedInfo);
+		cdf_mem_set(&roam_info, sizeof(tCsrRoamInfo), 0);
+		roam_info.pBssDesc = cmd->u.roamCmd.pLastRoamBss;
+		roam_info.statusCode = session->joinFailStatusCode.statusCode;
+		roam_info.reasonCode = session->joinFailStatusCode.reasonCode;
+		csr_roam_call_callback(mac_ctx, session_id, &roam_info,
+			cmd->u.roamCmd.roamId, eCSR_ROAM_WDS_IND,
+			eCSR_ROAM_RESULT_WDS_NOT_ASSOCIATED);
+		/* Need to issue stop_bss */
+		break;
+	case eCsrJoinFailure:
+	case eCsrNothingToJoin:
+	case eCsrJoinFailureDueToConcurrency:
+	default:
+		csr_roam_process_results_default(mac_ctx, cmd, context, res);
+		break;
+	}
+	return release_cmd;
+}
+
+CDF_STATUS csr_roam_copy_profile(tpAniSirGlobal pMac,
+				 tCsrRoamProfile *pDstProfile,
+				 tCsrRoamProfile *pSrcProfile)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	uint32_t size = 0;
+
+	cdf_mem_set(pDstProfile, sizeof(tCsrRoamProfile), 0);
+	if (pSrcProfile->BSSIDs.numOfBSSIDs) {
+		size = sizeof(struct cdf_mac_addr) * pSrcProfile->BSSIDs.numOfBSSIDs;
+		pDstProfile->BSSIDs.bssid = cdf_mem_malloc(size);
+		if (NULL == pDstProfile->BSSIDs.bssid) {
+			status = CDF_STATUS_E_NOMEM;
+			goto end;
+		}
+		pDstProfile->BSSIDs.numOfBSSIDs =
+			pSrcProfile->BSSIDs.numOfBSSIDs;
+		cdf_mem_copy(pDstProfile->BSSIDs.bssid,
+			pSrcProfile->BSSIDs.bssid, size);
+	}
+	if (pSrcProfile->SSIDs.numOfSSIDs) {
+		size = sizeof(tCsrSSIDInfo) * pSrcProfile->SSIDs.numOfSSIDs;
+		pDstProfile->SSIDs.SSIDList = cdf_mem_malloc(size);
+		if (NULL == pDstProfile->SSIDs.SSIDList) {
+			status = CDF_STATUS_E_NOMEM;
+			goto end;
+		}
+		pDstProfile->SSIDs.numOfSSIDs =
+			pSrcProfile->SSIDs.numOfSSIDs;
+		cdf_mem_copy(pDstProfile->SSIDs.SSIDList,
+			pSrcProfile->SSIDs.SSIDList, size);
+	}
+	if (pSrcProfile->nWPAReqIELength) {
+		pDstProfile->pWPAReqIE =
+			cdf_mem_malloc(pSrcProfile->nWPAReqIELength);
+		if (NULL == pDstProfile->pWPAReqIE) {
+			status = CDF_STATUS_E_NOMEM;
+			goto end;
+		}
+		pDstProfile->nWPAReqIELength =
+			pSrcProfile->nWPAReqIELength;
+		cdf_mem_copy(pDstProfile->pWPAReqIE, pSrcProfile->pWPAReqIE,
+			pSrcProfile->nWPAReqIELength);
+	}
+	if (pSrcProfile->nRSNReqIELength) {
+		pDstProfile->pRSNReqIE =
+			cdf_mem_malloc(pSrcProfile->nRSNReqIELength);
+		if (NULL == pDstProfile->pRSNReqIE) {
+			status = CDF_STATUS_E_NOMEM;
+			goto end;
+		}
+		pDstProfile->nRSNReqIELength =
+			pSrcProfile->nRSNReqIELength;
+		cdf_mem_copy(pDstProfile->pRSNReqIE, pSrcProfile->pRSNReqIE,
+			pSrcProfile->nRSNReqIELength);
+	}
+#ifdef FEATURE_WLAN_WAPI
+	if (pSrcProfile->nWAPIReqIELength) {
+		pDstProfile->pWAPIReqIE =
+			cdf_mem_malloc(pSrcProfile->nWAPIReqIELength);
+		if (NULL == pDstProfile->pWAPIReqIE) {
+			status = CDF_STATUS_E_NOMEM;
+			goto end;
+		}
+		pDstProfile->nWAPIReqIELength =
+			pSrcProfile->nWAPIReqIELength;
+		cdf_mem_copy(pDstProfile->pWAPIReqIE, pSrcProfile->pWAPIReqIE,
+			pSrcProfile->nWAPIReqIELength);
+	}
+#endif /* FEATURE_WLAN_WAPI */
+	if (pSrcProfile->nAddIEScanLength) {
+		pDstProfile->pAddIEScan =
+			cdf_mem_malloc(pSrcProfile->nAddIEScanLength);
+		if (NULL == pDstProfile->pAddIEScan) {
+			status = CDF_STATUS_E_NOMEM;
+			goto end;
+		}
+		pDstProfile->nAddIEScanLength =
+			pSrcProfile->nAddIEScanLength;
+		cdf_mem_copy(pDstProfile->pAddIEScan, pSrcProfile->pAddIEScan,
+			pSrcProfile->nAddIEScanLength);
+	}
+	if (pSrcProfile->nAddIEAssocLength) {
+		pDstProfile->pAddIEAssoc =
+			cdf_mem_malloc(pSrcProfile->nAddIEAssocLength);
+		if (NULL == pDstProfile->pAddIEAssoc) {
+			status = CDF_STATUS_E_NOMEM;
+			goto end;
+		}
+		pDstProfile->nAddIEAssocLength =
+			pSrcProfile->nAddIEAssocLength;
+		cdf_mem_copy(pDstProfile->pAddIEAssoc, pSrcProfile->pAddIEAssoc,
+			pSrcProfile->nAddIEAssocLength);
+	}
+	if (pSrcProfile->ChannelInfo.ChannelList) {
+		pDstProfile->ChannelInfo.ChannelList =
+			cdf_mem_malloc(pSrcProfile->ChannelInfo.
+					numOfChannels);
+		if (NULL == pDstProfile->ChannelInfo.ChannelList) {
+			status = CDF_STATUS_E_NOMEM;
+			goto end;
+		}
+		pDstProfile->ChannelInfo.numOfChannels =
+			pSrcProfile->ChannelInfo.numOfChannels;
+		cdf_mem_copy(pDstProfile->ChannelInfo.ChannelList,
+			pSrcProfile->ChannelInfo.ChannelList,
+			pSrcProfile->ChannelInfo.numOfChannels);
+	}
+	pDstProfile->AuthType = pSrcProfile->AuthType;
+	pDstProfile->EncryptionType = pSrcProfile->EncryptionType;
+	pDstProfile->mcEncryptionType = pSrcProfile->mcEncryptionType;
+	pDstProfile->negotiatedUCEncryptionType =
+		pSrcProfile->negotiatedUCEncryptionType;
+	pDstProfile->negotiatedMCEncryptionType =
+		pSrcProfile->negotiatedMCEncryptionType;
+	pDstProfile->negotiatedAuthType = pSrcProfile->negotiatedAuthType;
+#ifdef WLAN_FEATURE_11W
+	pDstProfile->MFPEnabled = pSrcProfile->MFPEnabled;
+	pDstProfile->MFPRequired = pSrcProfile->MFPRequired;
+	pDstProfile->MFPCapable = pSrcProfile->MFPCapable;
+#endif
+	pDstProfile->BSSType = pSrcProfile->BSSType;
+	pDstProfile->phyMode = pSrcProfile->phyMode;
+	pDstProfile->csrPersona = pSrcProfile->csrPersona;
+
+#ifdef FEATURE_WLAN_WAPI
+	if (csr_is_profile_wapi(pSrcProfile))
+		if (pDstProfile->phyMode & eCSR_DOT11_MODE_11n)
+			pDstProfile->phyMode &= ~eCSR_DOT11_MODE_11n;
+#endif /* FEATURE_WLAN_WAPI */
+	pDstProfile->CBMode = pSrcProfile->CBMode;
+	pDstProfile->ch_params.ch_width = pSrcProfile->ch_params.ch_width;
+	pDstProfile->ch_params.center_freq_seg0 =
+		pSrcProfile->ch_params.center_freq_seg0;
+	pDstProfile->ch_params.center_freq_seg1 =
+		pSrcProfile->ch_params.center_freq_seg1;
+	pDstProfile->ch_params.sec_ch_offset =
+		pSrcProfile->ch_params.sec_ch_offset;
+	/*Save the WPS info */
+	pDstProfile->bWPSAssociation = pSrcProfile->bWPSAssociation;
+	pDstProfile->bOSENAssociation = pSrcProfile->bOSENAssociation;
+	pDstProfile->uapsd_mask = pSrcProfile->uapsd_mask;
+	pDstProfile->beaconInterval = pSrcProfile->beaconInterval;
+	pDstProfile->privacy = pSrcProfile->privacy;
+	pDstProfile->fwdWPSPBCProbeReq = pSrcProfile->fwdWPSPBCProbeReq;
+	pDstProfile->csr80211AuthType = pSrcProfile->csr80211AuthType;
+	pDstProfile->dtimPeriod = pSrcProfile->dtimPeriod;
+	pDstProfile->ApUapsdEnable = pSrcProfile->ApUapsdEnable;
+	pDstProfile->SSIDs.SSIDList[0].ssidHidden =
+		pSrcProfile->SSIDs.SSIDList[0].ssidHidden;
+	pDstProfile->protEnabled = pSrcProfile->protEnabled;
+	pDstProfile->obssProtEnabled = pSrcProfile->obssProtEnabled;
+	pDstProfile->cfg_protection = pSrcProfile->cfg_protection;
+	pDstProfile->wps_state = pSrcProfile->wps_state;
+	pDstProfile->ieee80211d = pSrcProfile->ieee80211d;
+	pDstProfile->sap_dot11mc = pSrcProfile->sap_dot11mc;
+	cdf_mem_copy(&pDstProfile->Keys, &pSrcProfile->Keys,
+		sizeof(pDstProfile->Keys));
+#ifdef WLAN_FEATURE_11W
+	pDstProfile->MFPEnabled = pSrcProfile->MFPEnabled;
+	pDstProfile->MFPRequired = pSrcProfile->MFPRequired;
+	pDstProfile->MFPCapable = pSrcProfile->MFPCapable;
+#endif
+#ifdef WLAN_FEATURE_VOWIFI_11R
+	if (pSrcProfile->MDID.mdiePresent) {
+		pDstProfile->MDID.mdiePresent = 1;
+		pDstProfile->MDID.mobilityDomain =
+			pSrcProfile->MDID.mobilityDomain;
+	}
+#endif
+	cdf_mem_copy(&pDstProfile->addIeParams, &pSrcProfile->addIeParams,
+			sizeof(tSirAddIeParams));
+end:
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		csr_release_profile(pMac, pDstProfile);
+		pDstProfile = NULL;
+	}
+
+	return status;
+}
+
+CDF_STATUS csr_roam_copy_connected_profile(tpAniSirGlobal pMac,
+			uint32_t sessionId, tCsrRoamProfile *pDstProfile)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tCsrRoamConnectedProfile *pSrcProfile =
+		&pMac->roam.roamSession[sessionId].connectedProfile;
+
+	cdf_mem_set(pDstProfile, sizeof(tCsrRoamProfile), 0);
+
+	pDstProfile->BSSIDs.bssid = cdf_mem_malloc(sizeof(struct cdf_mac_addr));
+	if (NULL == pDstProfile->BSSIDs.bssid) {
+		status = CDF_STATUS_E_NOMEM;
+		sms_log(pMac, LOGE,
+			FL("failed to allocate memory for BSSID "
+			MAC_ADDRESS_STR),
+			MAC_ADDR_ARRAY(pSrcProfile->bssid.bytes));
+		goto end;
+	}
+	pDstProfile->BSSIDs.numOfBSSIDs = 1;
+	cdf_copy_macaddr(pDstProfile->BSSIDs.bssid, &pSrcProfile->bssid);
+
+	if (pSrcProfile->SSID.ssId) {
+		pDstProfile->SSIDs.SSIDList =
+			cdf_mem_malloc(sizeof(tCsrSSIDInfo));
+		if (NULL == pDstProfile->SSIDs.SSIDList) {
+			status = CDF_STATUS_E_NOMEM;
+			sms_log(pMac, LOGE,
+				FL("failed to allocate memory for SSID "
+				MAC_ADDRESS_STR),
+				MAC_ADDR_ARRAY(pSrcProfile->bssid.bytes));
+			goto end;
+		}
+		pDstProfile->SSIDs.numOfSSIDs = 1;
+		pDstProfile->SSIDs.SSIDList[0].handoffPermitted =
+			pSrcProfile->handoffPermitted;
+		pDstProfile->SSIDs.SSIDList[0].ssidHidden =
+			pSrcProfile->ssidHidden;
+		cdf_mem_copy(&pDstProfile->SSIDs.SSIDList[0].SSID,
+			&pSrcProfile->SSID, sizeof(tSirMacSSid));
+	}
+	if (pSrcProfile->nAddIEAssocLength) {
+		pDstProfile->pAddIEAssoc =
+			cdf_mem_malloc(pSrcProfile->nAddIEAssocLength);
+		if (NULL == pDstProfile->pAddIEAssoc) {
+			status = CDF_STATUS_E_NOMEM;
+			sms_log(pMac, LOGE,
+				FL("failed to allocate mem for additional ie"));
+			goto end;
+		}
+		pDstProfile->nAddIEAssocLength = pSrcProfile->nAddIEAssocLength;
+		cdf_mem_copy(pDstProfile->pAddIEAssoc, pSrcProfile->pAddIEAssoc,
+			pSrcProfile->nAddIEAssocLength);
+	}
+	pDstProfile->ChannelInfo.ChannelList = cdf_mem_malloc(1);
+	if (NULL == pDstProfile->ChannelInfo.ChannelList) {
+		status = CDF_STATUS_E_NOMEM;
+		goto end;
+	}
+	pDstProfile->ChannelInfo.numOfChannels = 1;
+	pDstProfile->ChannelInfo.ChannelList[0] = pSrcProfile->operationChannel;
+	pDstProfile->AuthType.numEntries = 1;
+	pDstProfile->AuthType.authType[0] = pSrcProfile->AuthType;
+	pDstProfile->negotiatedAuthType = pSrcProfile->AuthType;
+	pDstProfile->EncryptionType.numEntries = 1;
+	pDstProfile->EncryptionType.encryptionType[0] =
+		pSrcProfile->EncryptionType;
+	pDstProfile->negotiatedUCEncryptionType =
+		pSrcProfile->EncryptionType;
+	pDstProfile->mcEncryptionType.numEntries = 1;
+	pDstProfile->mcEncryptionType.encryptionType[0] =
+		pSrcProfile->mcEncryptionType;
+	pDstProfile->negotiatedMCEncryptionType =
+		pSrcProfile->mcEncryptionType;
+	pDstProfile->BSSType = pSrcProfile->BSSType;
+	pDstProfile->CBMode = pSrcProfile->CBMode;
+	cdf_mem_copy(&pDstProfile->Keys, &pSrcProfile->Keys,
+		sizeof(pDstProfile->Keys));
+#ifdef WLAN_FEATURE_VOWIFI_11R
+	if (pSrcProfile->MDID.mdiePresent) {
+		pDstProfile->MDID.mdiePresent = 1;
+		pDstProfile->MDID.mobilityDomain =
+			pSrcProfile->MDID.mobilityDomain;
+	}
+#endif
+
+end:
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		csr_release_profile(pMac, pDstProfile);
+		pDstProfile = NULL;
+	}
+
+	return status;
+}
+
+CDF_STATUS csr_roam_issue_connect(tpAniSirGlobal pMac, uint32_t sessionId,
+				  tCsrRoamProfile *pProfile,
+				  tScanResultHandle hBSSList,
+				  eCsrRoamReason reason, uint32_t roamId,
+				  bool fImediate, bool fClearScan)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tSmeCmd *pCommand;
+
+	pCommand = csr_get_command_buffer(pMac);
+	if (NULL == pCommand) {
+		sms_log(pMac, LOGE, FL(" fail to get command buffer"));
+		status = CDF_STATUS_E_RESOURCES;
+	} else {
+		if (fClearScan) {
+			csr_scan_abort_mac_scan_not_for_connect(pMac, sessionId);
+		}
+		pCommand->u.roamCmd.fReleaseProfile = false;
+		if (NULL == pProfile) {
+			/* We can roam now */
+			/* Since pProfile is NULL, we need to build our own profile, set everything to default */
+			/* We can only support open and no encryption */
+			pCommand->u.roamCmd.roamProfile.AuthType.numEntries = 1;
+			pCommand->u.roamCmd.roamProfile.AuthType.authType[0] =
+				eCSR_AUTH_TYPE_OPEN_SYSTEM;
+			pCommand->u.roamCmd.roamProfile.EncryptionType.
+			numEntries = 1;
+			pCommand->u.roamCmd.roamProfile.EncryptionType.
+			encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;
+			pCommand->u.roamCmd.roamProfile.csrPersona =
+				CDF_STA_MODE;
+		} else {
+			/* make a copy of the profile */
+			status =
+				csr_roam_copy_profile(pMac,
+						      &pCommand->u.roamCmd.roamProfile,
+						      pProfile);
+			if (CDF_IS_STATUS_SUCCESS(status)) {
+				pCommand->u.roamCmd.fReleaseProfile = true;
+			}
+		}
+
+		pCommand->command = eSmeCommandRoam;
+		pCommand->sessionId = (uint8_t) sessionId;
+		pCommand->u.roamCmd.hBSSList = hBSSList;
+		pCommand->u.roamCmd.roamId = roamId;
+		pCommand->u.roamCmd.roamReason = reason;
+		/* We need to free the BssList when the command is done */
+		pCommand->u.roamCmd.fReleaseBssList = true;
+		pCommand->u.roamCmd.fUpdateCurRoamProfile = true;
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
+			  FL("CSR PERSONA=%d"),
+			  pCommand->u.roamCmd.roamProfile.csrPersona);
+		status = csr_queue_sme_command(pMac, pCommand, fImediate);
+		if (!CDF_IS_STATUS_SUCCESS(status)) {
+			sms_log(pMac, LOGE,
+				FL(" fail to send message status = %d"), status);
+			csr_release_command_roam(pMac, pCommand);
+		}
+	}
+
+	return status;
+}
+
+CDF_STATUS csr_roam_issue_reassoc(tpAniSirGlobal pMac, uint32_t sessionId,
+				  tCsrRoamProfile *pProfile,
+				  tCsrRoamModifyProfileFields *pMmodProfileFields,
+				  eCsrRoamReason reason, uint32_t roamId,
+				  bool fImediate)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tSmeCmd *pCommand;
+
+	pCommand = csr_get_command_buffer(pMac);
+	if (NULL == pCommand) {
+		sms_log(pMac, LOGE, FL(" fail to get command buffer"));
+		status = CDF_STATUS_E_RESOURCES;
+	} else {
+		csr_scan_abort_mac_scan_not_for_connect(pMac, sessionId);
+		if (pProfile) {
+			/* This is likely trying to reassoc to different profile */
+			pCommand->u.roamCmd.fReleaseProfile = false;
+			/* make a copy of the profile */
+			status =
+				csr_roam_copy_profile(pMac,
+						      &pCommand->u.roamCmd.roamProfile,
+						      pProfile);
+			pCommand->u.roamCmd.fUpdateCurRoamProfile = true;
+		} else {
+			status =
+				csr_roam_copy_connected_profile(pMac, sessionId,
+								&pCommand->u.roamCmd.
+								roamProfile);
+			/* how to update WPA/WPA2 info in roamProfile?? */
+			pCommand->u.roamCmd.roamProfile.uapsd_mask =
+				pMmodProfileFields->uapsd_mask;
+		}
+		if (CDF_IS_STATUS_SUCCESS(status)) {
+			pCommand->u.roamCmd.fReleaseProfile = true;
+		}
+		pCommand->command = eSmeCommandRoam;
+		pCommand->sessionId = (uint8_t) sessionId;
+		pCommand->u.roamCmd.roamId = roamId;
+		pCommand->u.roamCmd.roamReason = reason;
+		/* We need to free the BssList when the command is done */
+		/* For reassoc there is no BSS list, so the bool set to false */
+		pCommand->u.roamCmd.hBSSList = CSR_INVALID_SCANRESULT_HANDLE;
+		pCommand->u.roamCmd.fReleaseBssList = false;
+		pCommand->u.roamCmd.fReassoc = true;
+		csr_roam_remove_duplicate_command(pMac, sessionId, pCommand,
+						  reason);
+		status = csr_queue_sme_command(pMac, pCommand, fImediate);
+		if (!CDF_IS_STATUS_SUCCESS(status)) {
+			sms_log(pMac, LOGE,
+				FL(" fail to send message status = %d"), status);
+			csr_roam_completion(pMac, sessionId, NULL, pCommand,
+					    eCSR_ROAM_RESULT_FAILURE, false);
+			csr_release_command_roam(pMac, pCommand);
+		}
+	}
+	return status;
+}
+
+CDF_STATUS csr_roam_enqueue_preauth(tpAniSirGlobal pMac, uint32_t sessionId,
+				    tpSirBssDescription pBssDescription,
+				    eCsrRoamReason reason, bool fImmediate)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tSmeCmd *pCommand;
+
+	pCommand = csr_get_command_buffer(pMac);
+	if (NULL == pCommand) {
+		sms_log(pMac, LOGE, FL(" fail to get command buffer"));
+		status = CDF_STATUS_E_RESOURCES;
+	} else {
+		if (pBssDescription) {
+			/* copy over the parameters we need later */
+			pCommand->command = eSmeCommandRoam;
+			pCommand->sessionId = (uint8_t) sessionId;
+			pCommand->u.roamCmd.roamReason = reason;
+			/* this is the important parameter */
+			/* in this case we are using this field for the "next" BSS */
+			pCommand->u.roamCmd.pLastRoamBss = pBssDescription;
+			status = csr_queue_sme_command(pMac, pCommand, fImmediate);
+			if (!CDF_IS_STATUS_SUCCESS(status)) {
+				sms_log(pMac, LOGE,
+					FL
+						(" fail to enqueue preauth command, status = %d"),
+					status);
+				csr_release_command_preauth(pMac, pCommand);
+			}
+		} else {
+			/* Return failure */
+			status = CDF_STATUS_E_RESOURCES;
+		}
+	}
+	return status;
+}
+
+CDF_STATUS csr_dequeue_roam_command(tpAniSirGlobal pMac, eCsrRoamReason reason)
+{
+	tListElem *pEntry;
+	tSmeCmd *pCommand;
+	pEntry = csr_ll_peek_head(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK);
+	if (pEntry) {
+		pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
+		if ((eSmeCommandRoam == pCommand->command) &&
+		    (eCsrPerformPreauth == reason)) {
+			sms_log(pMac, LOG1, FL("DQ-Command = %d, Reason = %d"),
+				pCommand->command,
+				pCommand->u.roamCmd.roamReason);
+			if (csr_ll_remove_entry
+				    (&pMac->sme.smeCmdActiveList, pEntry,
+				    LL_ACCESS_LOCK)) {
+				csr_release_command_preauth(pMac, pCommand);
+			}
+		} else if ((eSmeCommandRoam == pCommand->command) &&
+			   (eCsrSmeIssuedFTReassoc == reason)) {
+			sms_log(pMac, LOG1, FL("DQ-Command = %d, Reason = %d"),
+				pCommand->command,
+				pCommand->u.roamCmd.roamReason);
+			if (csr_ll_remove_entry
+				    (&pMac->sme.smeCmdActiveList, pEntry,
+				    LL_ACCESS_LOCK)) {
+				csr_release_command_roam(pMac, pCommand);
+			}
+		} else {
+			sms_log(pMac, LOGE, FL("Command = %d, Reason = %d "),
+				pCommand->command,
+				pCommand->u.roamCmd.roamReason);
+		}
+	} else {
+		sms_log(pMac, LOGE,
+			FL("pEntry NULL for eWNI_SME_FT_PRE_AUTH_RSP"));
+	}
+	sme_process_pending_queue(pMac);
+	return CDF_STATUS_SUCCESS;
+}
+
+CDF_STATUS csr_roam_connect(tpAniSirGlobal pMac, uint32_t sessionId,
+		tCsrRoamProfile *pProfile,
+		uint32_t *pRoamId)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tScanResultHandle hBSSList;
+	tCsrScanResultFilter *pScanFilter;
+	uint32_t roamId = 0;
+	bool fCallCallback = false;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+	tSirBssDescription first_ap_profile;
+
+	if (NULL == pSession) {
+		sms_log(pMac, LOGE,
+			FL("session does not exist for given sessionId:%d"),
+			sessionId);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	if (NULL == pProfile) {
+		sms_log(pMac, LOGP, FL("No profile specified"));
+		return CDF_STATUS_E_FAILURE;
+	}
+	/* Initialize the count before proceeding with the Join requests */
+	pSession->join_bssid_count = 0;
+	sms_log(pMac, LOG1,
+		FL("called  BSSType = %d authtype = %d  encryType = %d"),
+		pProfile->BSSType, pProfile->AuthType.authType[0],
+		pProfile->EncryptionType.encryptionType[0]);
+	csr_roam_cancel_roaming(pMac, sessionId);
+	csr_scan_remove_fresh_scan_command(pMac, sessionId);
+	/* Only abort the scan if its not used for other roam/connect purpose */
+	csr_scan_abort_mac_scan(pMac, sessionId, eCSR_SCAN_ABORT_DEFAULT);
+	csr_roam_remove_duplicate_command(pMac, sessionId, NULL, eCsrHddIssued);
+	/* Check whether ssid changes */
+	if (csr_is_conn_state_connected(pMac, sessionId) &&
+		pProfile->SSIDs.numOfSSIDs && !csr_is_ssid_in_list(pMac,
+			&pSession->connectedProfile.SSID, &pProfile->SSIDs))
+			csr_roam_issue_disassociate_cmd(pMac, sessionId,
+					eCSR_DISCONNECT_REASON_UNSPECIFIED);
+#ifdef FEATURE_WLAN_BTAMP_UT_RF
+	pSession->maxRetryCount = CSR_JOIN_MAX_RETRY_COUNT;
+#endif
+	pScanFilter = cdf_mem_malloc(sizeof(tCsrScanResultFilter));
+	if (NULL == pScanFilter) {
+		status = CDF_STATUS_E_NOMEM;
+		goto end;
+	}
+
+	cdf_mem_set(pScanFilter, sizeof(tCsrScanResultFilter),
+			0);
+	/* Try to connect to any BSS */
+	if (NULL == pProfile) {
+		/* No encryption */
+		pScanFilter->EncryptionType.numEntries = 1;
+		pScanFilter->EncryptionType.encryptionType[0] =
+			eCSR_ENCRYPT_TYPE_NONE;
+	} else {
+		/* Here is the profile we need to connect to */
+		status = csr_roam_prepare_filter_from_profile(pMac,
+				pProfile, pScanFilter);
+	}
+	roamId = GET_NEXT_ROAM_ID(&pMac->roam);
+	if (pRoamId)
+		*pRoamId = roamId;
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		cdf_mem_free(pScanFilter);
+		goto end;
+	}
+
+	/*Save the WPS info */
+	if (NULL != pProfile) {
+		pScanFilter->bWPSAssociation =
+			pProfile->bWPSAssociation;
+		pScanFilter->bOSENAssociation =
+			pProfile->bOSENAssociation;
+	} else {
+		pScanFilter->bWPSAssociation = 0;
+		pScanFilter->bOSENAssociation = 0;
+	}
+	if ((pProfile && CSR_IS_WDS_AP(pProfile)) || (pProfile
+				&& CSR_IS_INFRA_AP(pProfile))) {
+		/* This can be started right away */
+		status = csr_roam_issue_connect(pMac, sessionId, pProfile, NULL,
+				 eCsrHddIssued, roamId, false, false);
+		if (!CDF_IS_STATUS_SUCCESS(status)) {
+			sms_log(pMac, LOGE,
+				FL("CSR failed to issue start BSS cmd with status = 0x%08X"),
+				status);
+			fCallCallback = true;
+		} else {
+			sms_log(pMac, LOG1,
+				FL("Connect request to proceed for sap mode"));
+		}
+
+		csr_free_scan_filter(pMac, pScanFilter);
+		cdf_mem_free(pScanFilter);
+		goto end;
+	}
+	status = csr_scan_get_result(pMac, pScanFilter, &hBSSList);
+	sms_log(pMac, LOG1,
+		FL("******* csr_scan_get_result Status ****** %d"), status);
+	if (CDF_IS_STATUS_SUCCESS(status)) {
+		/* check if set hw mode needs to be done */
+		if ((pMac->policy_manager_enabled) &&
+			(pScanFilter->csrPersona == CDF_STA_MODE)) {
+			csr_get_bssdescr_from_scan_handle(hBSSList,
+					&first_ap_profile);
+			if (!cds_handle_conc_multiport(sessionId,
+						first_ap_profile.channelId)) {
+				sms_log(pMac, LOG1, FL("conc multiport error"));
+				csr_scan_result_purge(pMac, hBSSList);
+				fCallCallback = true;
+				goto error;
+			}
+		}
+
+		status = csr_roam_issue_connect(pMac, sessionId, pProfile,
+				hBSSList, eCsrHddIssued, roamId, false, false);
+		if (!CDF_IS_STATUS_SUCCESS(status)) {
+			sms_log(pMac, LOGE,
+				FL("CSR failed to issue connect cmd with status = 0x%08X"),
+				status);
+			csr_scan_result_purge(pMac, hBSSList);
+			fCallCallback = true;
+		}
+	} else if (NULL != pProfile) {
+		/* Check whether it is for start ibss */
+		if (CSR_IS_START_IBSS(pProfile)) {
+			status = csr_roam_issue_connect(pMac, sessionId,
+					pProfile, NULL, eCsrHddIssued,
+					roamId, false, false);
+			if (!CDF_IS_STATUS_SUCCESS(status)) {
+				sms_log(pMac, LOGE,
+					FL("CSR failed to issue startIBSS cmd with status = 0x%08X"),
+					status);
+				fCallCallback = true;
+			}
+		} else {
+			/* scan for this SSID */
+			status = csr_scan_for_ssid(pMac, sessionId, pProfile,
+						roamId, true);
+			if (!CDF_IS_STATUS_SUCCESS(status)) {
+				sms_log(pMac, LOGE,
+					FL("CSR failed to issue SSID scan cmd with status = 0x%08X"),
+					status);
+				fCallCallback = true;
+			} else {
+				sms_log(pMac, LOG1,
+					FL("SSID scan requested"));
+			}
+		}
+	} else {
+		fCallCallback = true;
+	}
+
+error:
+	if (NULL != pProfile)
+		/*
+		 * we need to free memory for filter
+		 * if profile exists
+		 */
+		csr_free_scan_filter(pMac, pScanFilter);
+
+	cdf_mem_free(pScanFilter);
+end:
+	/* tell the caller if we fail to trigger a join request */
+	if (fCallCallback) {
+		csr_roam_call_callback(pMac, sessionId, NULL, roamId,
+				eCSR_ROAM_FAILED, eCSR_ROAM_RESULT_FAILURE);
+	}
+	return status;
+}
+
+/**
+ * csr_roam_reassoc() - process reassoc command
+ * @mac_ctx:       mac global context
+ * @session_id:    session id
+ * @profile:       roam profile
+ * @mod_fields:    AC info being modified in reassoc
+ * @roam_id:       roam id to be populated
+ *
+ * Return: status of operation
+ */
+CDF_STATUS
+csr_roam_reassoc(tpAniSirGlobal mac_ctx, uint32_t session_id,
+		 tCsrRoamProfile *profile,
+		 tCsrRoamModifyProfileFields mod_fields,
+		 uint32_t *roam_id)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	bool fCallCallback = true;
+	uint32_t roamId = 0;
+
+	tCsrRoamSession *session = CSR_GET_SESSION(mac_ctx, session_id);
+	if (NULL == profile) {
+		sms_log(mac_ctx, LOGP, FL("No profile specified"));
+		return CDF_STATUS_E_FAILURE;
+	}
+	sms_log(mac_ctx, LOG1,
+		FL("called  BSSType = %d authtype = %d  encryType = %d"),
+		profile->BSSType, profile->AuthType.authType[0],
+		profile->EncryptionType.encryptionType[0]);
+	csr_roam_cancel_roaming(mac_ctx, session_id);
+	csr_scan_remove_fresh_scan_command(mac_ctx, session_id);
+	csr_scan_abort_mac_scan_not_for_connect(mac_ctx, session_id);
+	csr_roam_remove_duplicate_command(mac_ctx, session_id, NULL,
+					  eCsrHddIssuedReassocToSameAP);
+	if (csr_is_conn_state_connected(mac_ctx, session_id)) {
+		if (profile) {
+			if (profile->SSIDs.numOfSSIDs &&
+			    csr_is_ssid_in_list(mac_ctx,
+						&session->connectedProfile.SSID,
+						&profile->SSIDs)) {
+				fCallCallback = false;
+			} else {
+				/*
+				 * Connected SSID did not match with what is
+				 * asked in profile
+				 */
+				sms_log(mac_ctx, LOG1, FL("SSID mismatch"));
+			}
+		} else if (!cdf_mem_compare(&mod_fields,
+				&session->connectedProfile.modifyProfileFields,
+				sizeof(tCsrRoamModifyProfileFields))) {
+			fCallCallback = false;
+		} else {
+			sms_log(mac_ctx, LOG1,
+				/*
+				 * Either the profile is NULL or none of the
+				 * fields in tCsrRoamModifyProfileFields got
+				 * modified
+				 */
+				FL("Profile NULL or nothing to modify."));
+		}
+	} else {
+		sms_log(mac_ctx, LOG1, FL("Not connected! No need to reassoc"));
+	}
+	if (!fCallCallback) {
+		roamId = GET_NEXT_ROAM_ID(&mac_ctx->roam);
+		if (roam_id)
+			*roam_id = roamId;
+		status = csr_roam_issue_reassoc(mac_ctx, session_id, profile,
+				&mod_fields, eCsrHddIssuedReassocToSameAP,
+				roamId, false);
+	} else {
+		status = csr_roam_call_callback(mac_ctx, session_id, NULL,
+						roamId, eCSR_ROAM_FAILED,
+						eCSR_ROAM_RESULT_FAILURE);
+	}
+	return status;
+}
+
+CDF_STATUS csr_roam_join_last_profile(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	CDF_STATUS status = CDF_STATUS_E_FAILURE;
+	tScanResultHandle hBSSList = NULL;
+	tCsrScanResultFilter *pScanFilter = NULL;
+	uint32_t roamId;
+	tCsrRoamProfile *pProfile = NULL;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("  session %d not found "), sessionId);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	if (pSession->pCurRoamProfile) {
+		csr_scan_abort_mac_scan_not_for_connect(pMac, sessionId);
+		/* We have to make a copy of pCurRoamProfile because it
+		 * will be free inside csr_roam_issue_connect */
+		pProfile = cdf_mem_malloc(sizeof(tCsrRoamProfile));
+		if (NULL == pProfile) {
+			status = CDF_STATUS_E_NOMEM;
+			goto end;
+		}
+		cdf_mem_set(pProfile, sizeof(tCsrRoamProfile), 0);
+		status = csr_roam_copy_profile(pMac, pProfile,
+			pSession->pCurRoamProfile);
+		if (!CDF_IS_STATUS_SUCCESS(status))
+			goto end;
+		pScanFilter = cdf_mem_malloc(sizeof(tCsrScanResultFilter));
+		if (NULL == pScanFilter) {
+			status = CDF_STATUS_E_NOMEM;
+			goto end;
+		}
+		cdf_mem_set(pScanFilter, sizeof(tCsrScanResultFilter), 0);
+		status = csr_roam_prepare_filter_from_profile(pMac, pProfile,
+					pScanFilter);
+		if (!CDF_IS_STATUS_SUCCESS(status))
+			goto end;
+		roamId = GET_NEXT_ROAM_ID(&pMac->roam);
+		status = csr_scan_get_result(pMac, pScanFilter, &hBSSList);
+		if (CDF_IS_STATUS_SUCCESS(status)) {
+			/* we want to put the last connected BSS to the
+			 * very beginning, if possible */
+			csr_move_bss_to_head_from_bssid(pMac,
+				&pSession->connectedProfile.bssid, hBSSList);
+			status = csr_roam_issue_connect(pMac, sessionId,
+					pProfile, hBSSList, eCsrHddIssued,
+					roamId, false, false);
+			if (!CDF_IS_STATUS_SUCCESS(status)) {
+				csr_scan_result_purge(pMac, hBSSList);
+				goto end;
+			}
+		} else {
+			/* scan for this SSID only incase AP suppresses SSID */
+			status = csr_scan_for_ssid(pMac, sessionId, pProfile,
+					roamId, true);
+			if (!CDF_IS_STATUS_SUCCESS(status))
+				goto end;
+		}
+	} /* We have a profile */
+	else {
+		sms_log(pMac, LOGW, FL("cannot find a roaming profile"));
+		goto end;
+	}
+end:
+	if (pScanFilter) {
+		csr_free_scan_filter(pMac, pScanFilter);
+		cdf_mem_free(pScanFilter);
+	}
+	if (NULL != pProfile) {
+		csr_release_profile(pMac, pProfile);
+		cdf_mem_free(pProfile);
+	}
+	return status;
+}
+
+CDF_STATUS csr_roam_reconnect(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	CDF_STATUS status = CDF_STATUS_E_FAILURE;
+	if (csr_is_conn_state_connected(pMac, sessionId)) {
+		status =
+			csr_roam_issue_disassociate_cmd(pMac, sessionId,
+							eCSR_DISCONNECT_REASON_UNSPECIFIED);
+		if (CDF_IS_STATUS_SUCCESS(status)) {
+			status = csr_roam_join_last_profile(pMac, sessionId);
+		}
+	}
+	return status;
+}
+
+CDF_STATUS csr_roam_connect_to_last_profile(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	CDF_STATUS status = CDF_STATUS_E_FAILURE;
+	sms_log(pMac, LOGW, FL("is called"));
+	csr_roam_cancel_roaming(pMac, sessionId);
+	csr_roam_remove_duplicate_command(pMac, sessionId, NULL, eCsrHddIssued);
+	if (csr_is_conn_state_disconnected(pMac, sessionId)) {
+		status = csr_roam_join_last_profile(pMac, sessionId);
+	}
+	return status;
+}
+
+CDF_STATUS csr_roam_process_disassoc_deauth(tpAniSirGlobal pMac, tSmeCmd *pCommand,
+					    bool fDisassoc, bool fMICFailure)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	bool fComplete = false;
+	eCsrRoamSubState NewSubstate;
+	uint32_t sessionId = pCommand->sessionId;
+
+	if (CSR_IS_WAIT_FOR_KEY(pMac, sessionId)) {
+		sms_log(pMac, LOG1,
+			FL(" Stop Wait for key timer and change substate to"
+			   " eCSR_ROAM_SUBSTATE_NONE"));
+		csr_roam_stop_wait_for_key_timer(pMac);
+		csr_roam_substate_change(pMac, eCSR_ROAM_SUBSTATE_NONE, sessionId);
+	}
+	/* change state to 'Roaming'... */
+	csr_roam_state_change(pMac, eCSR_ROAMING_STATE_JOINING, sessionId);
+
+	if (csr_is_conn_state_ibss(pMac, sessionId)) {
+		/* If we are in an IBSS, then stop the IBSS... */
+		status =
+			csr_roam_issue_stop_bss(pMac, sessionId,
+						eCSR_ROAM_SUBSTATE_STOP_BSS_REQ);
+		fComplete = (!CDF_IS_STATUS_SUCCESS(status));
+	} else if (csr_is_conn_state_infra(pMac, sessionId)) {
+		/*
+		 * in Infrastructure, we need to disassociate from the
+		 * Infrastructure network...
+		 */
+		NewSubstate = eCSR_ROAM_SUBSTATE_DISASSOC_FORCED;
+		if (eCsrSmeIssuedDisassocForHandoff ==
+		    pCommand->u.roamCmd.roamReason) {
+			NewSubstate = eCSR_ROAM_SUBSTATE_DISASSOC_HANDOFF;
+		} else
+		if ((eCsrForcedDisassoc == pCommand->u.roamCmd.roamReason)
+		    && (eSIR_MAC_DISASSOC_LEAVING_BSS_REASON ==
+			pCommand->u.roamCmd.reason)) {
+			NewSubstate = eCSR_ROAM_SUBSTATE_DISASSOC_STA_HAS_LEFT;
+			CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
+				  FL
+					  ("set to substate eCSR_ROAM_SUBSTATE_DISASSOC_STA_HAS_LEFT"));
+		}
+		if (fDisassoc) {
+			status =
+				csr_roam_issue_disassociate(pMac, sessionId,
+							    NewSubstate, fMICFailure);
+		} else {
+			status =
+				csr_roam_issue_deauth(pMac, sessionId,
+						      eCSR_ROAM_SUBSTATE_DEAUTH_REQ);
+		}
+		fComplete = (!CDF_IS_STATUS_SUCCESS(status));
+	} else if (csr_is_conn_state_wds(pMac, sessionId)) {
+		if (CSR_IS_WDS_AP
+			    (&pMac->roam.roamSession[sessionId].connectedProfile)) {
+			status =
+				csr_roam_issue_stop_bss(pMac, sessionId,
+							eCSR_ROAM_SUBSTATE_STOP_BSS_REQ);
+			fComplete = (!CDF_IS_STATUS_SUCCESS(status));
+		}
+		/* This has to be WDS station */
+		else if (csr_is_conn_state_connected_wds(pMac, sessionId)) {
+			/* This has to be WDS station */
+			pCommand->u.roamCmd.fStopWds = true;
+			if (fDisassoc) {
+				status =
+					csr_roam_issue_disassociate(pMac, sessionId,
+								    eCSR_ROAM_SUBSTATE_DISCONNECT_CONTINUE_ROAMING,
+								    fMICFailure);
+				fComplete = (!CDF_IS_STATUS_SUCCESS(status));
+			}
+		}
+	} else {
+		/* we got a dis-assoc request while not connected to any peer */
+		/* just complete the command */
+		fComplete = true;
+		status = CDF_STATUS_E_FAILURE;
+	}
+	if (fComplete) {
+		csr_roam_complete(pMac, eCsrNothingToJoin, NULL);
+	}
+
+	if (CDF_IS_STATUS_SUCCESS(status)) {
+		if (csr_is_conn_state_infra(pMac, sessionId)) {
+			/* Set the state to disconnect here */
+			pMac->roam.roamSession[sessionId].connectState =
+				eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED;
+		}
+	} else {
+		sms_log(pMac, LOGW, FL(" failed with status %d"), status);
+	}
+	return status;
+}
+
+/**
+ * csr_prepare_disconnect_command() - function to prepare disconnect command
+ * @mac: pointer to global mac structure
+ * @session_id: sme session index
+ * @sme_cmd: pointer to sme command being prepared
+ *
+ * Function to prepare internal sme disconnect command
+ * Return: CDF_STATUS_SUCCESS on success else CDF_STATUS_E_RESOURCES on failure
+ */
+
+CDF_STATUS csr_prepare_disconnect_command(tpAniSirGlobal mac,
+			uint32_t session_id, tSmeCmd **sme_cmd)
+{
+	tSmeCmd *command;
+
+	command = csr_get_command_buffer(mac);
+	if (!command) {
+		sms_log(mac, LOGE, FL("fail to get command buffer"));
+		return CDF_STATUS_E_RESOURCES;
+	}
+
+	command->command = eSmeCommandRoam;
+	command->sessionId = (uint8_t)session_id;
+	command->u.roamCmd.roamReason = eCsrForcedDisassoc;
+
+	*sme_cmd = command;
+	return CDF_STATUS_SUCCESS;
+}
+
+CDF_STATUS csr_roam_issue_disassociate_cmd(tpAniSirGlobal pMac, uint32_t sessionId,
+					   eCsrRoamDisconnectReason reason)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tSmeCmd *pCommand;
+	bool fHighPriority = false;
+	do {
+		pCommand = csr_get_command_buffer(pMac);
+		if (!pCommand) {
+			sms_log(pMac, LOGE, FL(" fail to get command buffer"));
+			status = CDF_STATUS_E_RESOURCES;
+			break;
+		}
+		/* Change the substate in case it is wait-for-key */
+		if (CSR_IS_WAIT_FOR_KEY(pMac, sessionId)) {
+			csr_roam_stop_wait_for_key_timer(pMac);
+			csr_roam_substate_change(pMac, eCSR_ROAM_SUBSTATE_NONE,
+						 sessionId);
+		}
+		pCommand->command = eSmeCommandRoam;
+		pCommand->sessionId = (uint8_t) sessionId;
+		sms_log(pMac, LOG1,
+			FL("Disassociate reason: %d, sessionId: %d"),
+			reason, sessionId);
+		switch (reason) {
+		case eCSR_DISCONNECT_REASON_MIC_ERROR:
+			pCommand->u.roamCmd.roamReason =
+				eCsrForcedDisassocMICFailure;
+			break;
+		case eCSR_DISCONNECT_REASON_DEAUTH:
+			pCommand->u.roamCmd.roamReason = eCsrForcedDeauth;
+			break;
+		case eCSR_DISCONNECT_REASON_HANDOFF:
+			fHighPriority = true;
+			pCommand->u.roamCmd.roamReason =
+				eCsrSmeIssuedDisassocForHandoff;
+			break;
+		case eCSR_DISCONNECT_REASON_UNSPECIFIED:
+		case eCSR_DISCONNECT_REASON_DISASSOC:
+			pCommand->u.roamCmd.roamReason = eCsrForcedDisassoc;
+			break;
+		case eCSR_DISCONNECT_REASON_IBSS_JOIN_FAILURE:
+			pCommand->u.roamCmd.roamReason =
+				eCsrSmeIssuedIbssJoinFailure;
+			break;
+		case eCSR_DISCONNECT_REASON_IBSS_LEAVE:
+			pCommand->u.roamCmd.roamReason = eCsrForcedIbssLeave;
+			break;
+		case eCSR_DISCONNECT_REASON_STA_HAS_LEFT:
+			pCommand->u.roamCmd.roamReason = eCsrForcedDisassoc;
+			pCommand->u.roamCmd.reason =
+				eSIR_MAC_DISASSOC_LEAVING_BSS_REASON;
+			CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
+				  FL
+					  ("SME convert to internal reason code eCsrStaHasLeft"));
+			break;
+		default:
+			break;
+		}
+		status = csr_queue_sme_command(pMac, pCommand, fHighPriority);
+		if (!CDF_IS_STATUS_SUCCESS(status)) {
+			sms_log(pMac, LOGE,
+				FL(" fail to send message status = %d"), status);
+			csr_release_command_roam(pMac, pCommand);
+		}
+	} while (0);
+	return status;
+}
+
+CDF_STATUS csr_roam_issue_stop_bss_cmd(tpAniSirGlobal pMac, uint32_t sessionId,
+				       bool fHighPriority)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tSmeCmd *pCommand;
+	pCommand = csr_get_command_buffer(pMac);
+	if (NULL != pCommand) {
+		/* Change the substate in case it is wait-for-key */
+		if (CSR_IS_WAIT_FOR_KEY(pMac, sessionId)) {
+			csr_roam_stop_wait_for_key_timer(pMac);
+			csr_roam_substate_change(pMac, eCSR_ROAM_SUBSTATE_NONE,
+						 sessionId);
+		}
+		pCommand->command = eSmeCommandRoam;
+		pCommand->sessionId = (uint8_t) sessionId;
+		pCommand->u.roamCmd.roamReason = eCsrStopBss;
+		status = csr_queue_sme_command(pMac, pCommand, fHighPriority);
+		if (!CDF_IS_STATUS_SUCCESS(status)) {
+			sms_log(pMac, LOGE,
+				FL(" fail to send message status = %d"), status);
+			csr_release_command_roam(pMac, pCommand);
+		}
+	} else {
+		sms_log(pMac, LOGE, FL(" fail to get command buffer"));
+		status = CDF_STATUS_E_RESOURCES;
+	}
+	return status;
+}
+
+CDF_STATUS csr_roam_disconnect_internal(tpAniSirGlobal pMac, uint32_t sessionId,
+					eCsrRoamDisconnectReason reason)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("  session %d not found "), sessionId);
+		return CDF_STATUS_E_FAILURE;
+	}
+#ifdef FEATURE_WLAN_BTAMP_UT_RF
+	/* Stop the retry */
+	pSession->maxRetryCount = 0;
+	csr_roam_stop_join_retry_timer(pMac, sessionId);
+#endif
+	/* Not to call cancel roaming here */
+	/* Only issue disconnect when necessary */
+	if (csr_is_conn_state_connected(pMac, sessionId)
+	    || csr_is_bss_type_ibss(pSession->connectedProfile.BSSType)
+	    || csr_is_bss_type_wds(pSession->connectedProfile.BSSType)
+	    || csr_is_roam_command_waiting_for_session(pMac, sessionId)) {
+		sms_log(pMac, LOG2, FL("called"));
+		status = csr_roam_issue_disassociate_cmd(pMac, sessionId,
+							 reason);
+	} else {
+		csr_scan_abort_scan_for_ssid(pMac, sessionId);
+		status = CDF_STATUS_CMD_NOT_QUEUED;
+		sms_log(pMac, LOG1,
+			FL
+			(" Disconnect cmd not queued, Roam command is not present"
+			" return with status %d"), status);
+	}
+	return status;
+}
+
+CDF_STATUS csr_roam_disconnect(tpAniSirGlobal pMac, uint32_t sessionId,
+			       eCsrRoamDisconnectReason reason)
+{
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("  session %d not found "), sessionId);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	csr_roam_cancel_roaming(pMac, sessionId);
+	csr_roam_remove_duplicate_command(pMac, sessionId, NULL,
+					  eCsrForcedDisassoc);
+
+	return csr_roam_disconnect_internal(pMac, sessionId, reason);
+}
+
+CDF_STATUS csr_roam_save_connected_infomation(tpAniSirGlobal pMac,
+					      uint32_t sessionId,
+					      tCsrRoamProfile *pProfile,
+					      tSirBssDescription *pSirBssDesc,
+					      tDot11fBeaconIEs *pIes)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tDot11fBeaconIEs *pIesTemp = pIes;
+	uint8_t index;
+	tCsrRoamSession *pSession = NULL;
+	tCsrRoamConnectedProfile *pConnectProfile = NULL;
+
+	pSession = CSR_GET_SESSION(pMac, sessionId);
+	if (NULL == pSession) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+			  FL("session %d not found"), sessionId);
+		return CDF_STATUS_E_FAILURE;
+	}
+	pConnectProfile = &pSession->connectedProfile;
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	if (pSession->roamOffloadSynchParams.bRoamSynchInProgress) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
+			  FL("csr_roam_save_connected_infomation"));
+	}
+#endif
+	if (pConnectProfile->pAddIEAssoc) {
+		cdf_mem_free(pConnectProfile->pAddIEAssoc);
+		pConnectProfile->pAddIEAssoc = NULL;
+	}
+	cdf_mem_set(&pSession->connectedProfile,
+		    sizeof(tCsrRoamConnectedProfile), 0);
+	pConnectProfile->AuthType = pProfile->negotiatedAuthType;
+	pConnectProfile->AuthInfo = pProfile->AuthType;
+	pConnectProfile->CBMode = pProfile->CBMode;     /* *** this may not be valid */
+	pConnectProfile->EncryptionType = pProfile->negotiatedUCEncryptionType;
+	pConnectProfile->EncryptionInfo = pProfile->EncryptionType;
+	pConnectProfile->mcEncryptionType =
+		pProfile->negotiatedMCEncryptionType;
+	pConnectProfile->mcEncryptionInfo = pProfile->mcEncryptionType;
+	pConnectProfile->BSSType = pProfile->BSSType;
+	pConnectProfile->modifyProfileFields.uapsd_mask = pProfile->uapsd_mask;
+	pConnectProfile->operationChannel = pSirBssDesc->channelId;
+	pConnectProfile->beaconInterval = pSirBssDesc->beaconInterval;
+	if (!pConnectProfile->beaconInterval) {
+		sms_log(pMac, LOGW, FL("ERROR: Beacon interval is ZERO"));
+	}
+	cdf_mem_copy(&pConnectProfile->Keys, &pProfile->Keys, sizeof(tCsrKeys));
+	/* saving the addional IE`s like Hot spot indication element and extended capabilities */
+	if (pProfile->nAddIEAssocLength) {
+		pConnectProfile->pAddIEAssoc =
+			cdf_mem_malloc(pProfile->nAddIEAssocLength);
+		if (NULL == pConnectProfile->pAddIEAssoc)
+			status = CDF_STATUS_E_NOMEM;
+		else
+			status = CDF_STATUS_SUCCESS;
+		if (!CDF_IS_STATUS_SUCCESS(status)) {
+			sms_log(pMac, LOGE,
+				FL
+					("Failed to allocate memory for additional IEs"));
+			return CDF_STATUS_E_FAILURE;
+		}
+		pConnectProfile->nAddIEAssocLength =
+			pProfile->nAddIEAssocLength;
+		cdf_mem_copy(pConnectProfile->pAddIEAssoc,
+			     pProfile->pAddIEAssoc,
+			     pProfile->nAddIEAssocLength);
+	}
+#ifdef WLAN_FEATURE_11W
+	pConnectProfile->MFPEnabled = pProfile->MFPEnabled;
+	pConnectProfile->MFPRequired = pProfile->MFPRequired;
+	pConnectProfile->MFPCapable = pProfile->MFPCapable;
+#endif
+	/* Save bssid */
+	csr_get_bss_id_bss_desc(pMac, pSirBssDesc, &pConnectProfile->bssid);
+#ifdef WLAN_FEATURE_VOWIFI_11R
+	if (pSirBssDesc->mdiePresent) {
+		pConnectProfile->MDID.mdiePresent = 1;
+		pConnectProfile->MDID.mobilityDomain =
+			(pSirBssDesc->mdie[1] << 8) | (pSirBssDesc->mdie[0]);
+	}
+#endif
+	if (NULL == pIesTemp) {
+		status =
+			csr_get_parsed_bss_description_ies(pMac, pSirBssDesc,
+							   &pIesTemp);
+	}
+#ifdef FEATURE_WLAN_ESE
+	if ((csr_is_profile_ese(pProfile) ||
+	     (CDF_IS_STATUS_SUCCESS(status) && (pIesTemp->ESEVersion.present)
+	      && (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_OPEN_SYSTEM)))
+	    && (pMac->roam.configParam.isEseIniFeatureEnabled)) {
+		pConnectProfile->isESEAssoc = 1;
+	}
+#endif
+	/* save ssid */
+	if (CDF_IS_STATUS_SUCCESS(status)) {
+		if (pIesTemp->SSID.present) {
+			pConnectProfile->SSID.length = pIesTemp->SSID.num_ssid;
+			cdf_mem_copy(pConnectProfile->SSID.ssId,
+				     pIesTemp->SSID.ssid,
+				     pIesTemp->SSID.num_ssid);
+		}
+		/* Save the bss desc */
+		status =
+			csr_roam_save_connected_bss_desc(pMac, sessionId, pSirBssDesc);
+
+		if (CSR_IS_QOS_BSS(pIesTemp) || pIesTemp->HTCaps.present) {
+			/* Some HT AP's dont send WMM IE so in that case we assume all HT Ap's are Qos Enabled AP's */
+			pConnectProfile->qap = true;
+		} else {
+			pConnectProfile->qap = false;
+		}
+
+		if (pIesTemp->ExtCap.present) {
+			struct s_ext_cap *p_ext_cap = (struct s_ext_cap *)
+							pIesTemp->ExtCap.bytes;
+			pConnectProfile->proxyARPService = p_ext_cap->
+							    proxy_arp_service;
+		}
+
+		if (NULL == pIes) {
+			/* Free memory if it allocated locally */
+			cdf_mem_free(pIesTemp);
+		}
+	}
+	/* Save Qos connection */
+	pConnectProfile->qosConnection =
+		pMac->roam.roamSession[sessionId].fWMMConnection;
+
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		csr_free_connect_bss_desc(pMac, sessionId);
+	}
+	for (index = 0; index < pProfile->SSIDs.numOfSSIDs; index++) {
+		if ((pProfile->SSIDs.SSIDList[index].SSID.length ==
+		     pConnectProfile->SSID.length)
+		    && cdf_mem_compare(pProfile->SSIDs.SSIDList[index].SSID.
+				       ssId, pConnectProfile->SSID.ssId,
+				       pConnectProfile->SSID.length)) {
+			pConnectProfile->handoffPermitted =
+				pProfile->SSIDs.SSIDList[index].handoffPermitted;
+			break;
+		}
+		pConnectProfile->handoffPermitted = false;
+	}
+
+	return status;
+}
+
+
+static bool is_disconnect_pending(tpAniSirGlobal pmac,
+				uint8_t sessionid)
+{
+	tListElem *entry = NULL;
+	tListElem *next_entry = NULL;
+	tSmeCmd *command = NULL;
+	bool disconnect_cmd_exist = false;
+
+	csr_ll_lock(&pmac->sme.smeCmdPendingList);
+	entry = csr_ll_peek_head(&pmac->sme.smeCmdPendingList, LL_ACCESS_NOLOCK);
+	while (entry) {
+		next_entry = csr_ll_next(&pmac->sme.smeCmdPendingList,
+					entry, LL_ACCESS_NOLOCK);
+
+		command = GET_BASE_ADDR(entry, tSmeCmd, Link);
+		if (command && CSR_IS_DISCONNECT_COMMAND(command) &&
+				command->sessionId == sessionid){
+			disconnect_cmd_exist = true;
+			break;
+		}
+		entry = next_entry;
+	}
+	csr_ll_unlock(&pmac->sme.smeCmdPendingList);
+	return disconnect_cmd_exist;
+}
+
+static void csr_roam_join_rsp_processor(tpAniSirGlobal pMac,
+					tSirSmeJoinRsp *pSmeJoinRsp)
+{
+	tListElem *pEntry = NULL;
+	tSmeCmd *pCommand = NULL;
+	tCsrRoamSession *session_ptr;
+
+	if (pSmeJoinRsp) {
+		session_ptr = CSR_GET_SESSION(pMac, pSmeJoinRsp->sessionId);
+	} else {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+				FL("Sme Join Response is NULL"));
+		return;
+	}
+	if (!session_ptr) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+			FL("session %d not found"), pSmeJoinRsp->sessionId);
+		return;
+	}
+	/* The head of the active list is the request we sent */
+	pEntry = csr_ll_peek_head(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK);
+	if (pEntry) {
+		pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
+	}
+	if (eSIR_SME_SUCCESS == pSmeJoinRsp->statusCode) {
+		if (pCommand
+		    && eCsrSmeIssuedAssocToSimilarAP ==
+		    pCommand->u.roamCmd.roamReason) {
+#ifndef WLAN_MDM_CODE_REDUCTION_OPT
+			sme_qos_csr_event_ind(pMac, pSmeJoinRsp->sessionId,
+					      SME_QOS_CSR_HANDOFF_COMPLETE, NULL);
+#endif
+		}
+		/* *
+		 * The join bssid count can be reset as soon as
+		 * we are done with the join requests and returning
+		 * the response to upper layers
+		 * */
+		session_ptr->join_bssid_count = 0;
+		csr_roam_complete(pMac, eCsrJoinSuccess, (void *)pSmeJoinRsp);
+	} else {
+		uint32_t roamId = 0;
+		bool is_dis_pending;
+
+		/* The head of the active list is the request we sent */
+		/* Try to get back the same profile and roam again */
+		if (pCommand) {
+			roamId = pCommand->u.roamCmd.roamId;
+		}
+		session_ptr->joinFailStatusCode.statusCode =
+			pSmeJoinRsp->statusCode;
+		session_ptr->joinFailStatusCode.reasonCode =
+			pSmeJoinRsp->protStatusCode;
+		sms_log(pMac, LOGW,
+			"SmeJoinReq failed with statusCode= 0x%08X [%d]",
+			pSmeJoinRsp->statusCode, pSmeJoinRsp->statusCode);
+#if   defined WLAN_FEATURE_NEIGHBOR_ROAMING
+		/* If Join fails while Handoff is in progress, indicate disassociated event to supplicant to reconnect */
+		if (csr_roam_is_handoff_in_progress(pMac, pSmeJoinRsp->sessionId)) {
+			csr_roam_call_callback(pMac, pSmeJoinRsp->sessionId, NULL,
+					       roamId, eCSR_ROAM_DISASSOCIATED,
+					       eCSR_ROAM_RESULT_FORCED);
+			/* Should indicate neighbor roam algorithm about the connect failure here */
+			csr_neighbor_roam_indicate_connect(pMac,
+							   pSmeJoinRsp->sessionId,
+							   CDF_STATUS_E_FAILURE);
+		}
+#endif
+		/*
+		 * if userspace has issued disconnection,
+		 * driver should not continue connecting
+		 */
+		is_dis_pending = is_disconnect_pending(pMac, session_ptr->sessionId);
+		if (pCommand && (session_ptr->join_bssid_count <
+				CSR_MAX_BSSID_COUNT) && !is_dis_pending) {
+			if (CSR_IS_WDS_STA(&pCommand->u.roamCmd.roamProfile)) {
+				pCommand->u.roamCmd.fStopWds = true;
+				session_ptr->connectedProfile.BSSType =
+					eCSR_BSS_TYPE_WDS_STA;
+				csr_roam_reissue_roam_command(pMac);
+			} else if (CSR_IS_WDS(&pCommand->u.roamCmd.roamProfile)) {
+				session_ptr->join_bssid_count = 0;
+				csr_roam_complete(pMac, eCsrNothingToJoin, NULL);
+			} else {
+				csr_roam(pMac, pCommand);
+			}
+		} else {
+			/* ****************************************************
+			 * When the upper layers issue a connect command, there
+			 * is a roam command with reason eCsrHddIssued that
+			 * gets enqueued and an associated timer for the SME
+			 * command timeout is started which is currently 120
+			 * seconds. This command would be dequeued only upon
+			 * succesfull connections. In case of join failures, if
+			 * there are too many BSS in the cache, and if we fail
+			 * Join requests with all of them, there is a chance of
+			 * timing out the above timer.
+			 * ***************************************************/
+			if (session_ptr->join_bssid_count >=
+					CSR_MAX_BSSID_COUNT)
+				CDF_TRACE(CDF_MODULE_ID_SME,
+					  CDF_TRACE_LEVEL_ERROR,
+					  FL("Excessive Join Req Failures"));
+
+			if (is_dis_pending)
+				CDF_TRACE(CDF_MODULE_ID_SME,
+					CDF_TRACE_LEVEL_ERROR,
+					FL("disconnect is pending, complete roam"));
+
+			session_ptr->join_bssid_count = 0;
+			csr_roam_complete(pMac, eCsrNothingToJoin, NULL);
+		}
+	} /*else: ( eSIR_SME_SUCCESS == pSmeJoinRsp->statusCode ) */
+}
+
+CDF_STATUS csr_roam_issue_join(tpAniSirGlobal pMac, uint32_t sessionId,
+			       tSirBssDescription *pSirBssDesc,
+			       tDot11fBeaconIEs *pIes, tCsrRoamProfile *pProfile,
+			       uint32_t roamId)
+{
+	CDF_STATUS status;
+	sms_log(pMac, LOG1, "Attempting to Join Bssid= " MAC_ADDRESS_STR,
+		MAC_ADDR_ARRAY(pSirBssDesc->bssId));
+
+	/* Set the roaming substate to 'join attempt'... */
+	csr_roam_substate_change(pMac, eCSR_ROAM_SUBSTATE_JOIN_REQ, sessionId);
+	/* attempt to Join this BSS... */
+	status =
+		csr_send_join_req_msg(pMac, sessionId, pSirBssDesc, pProfile, pIes,
+				      eWNI_SME_JOIN_REQ);
+	return status;
+}
+
+static CDF_STATUS csr_roam_issue_reassociate(tpAniSirGlobal pMac,
+					     uint32_t sessionId,
+					     tSirBssDescription *pSirBssDesc,
+					     tDot11fBeaconIEs *pIes,
+					     tCsrRoamProfile *pProfile)
+{
+	csr_roam_state_change(pMac, eCSR_ROAMING_STATE_JOINING, sessionId);
+	/* Set the roaming substate to 'join attempt'... */
+	csr_roam_substate_change(pMac, eCSR_ROAM_SUBSTATE_REASSOC_REQ, sessionId);
+	CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
+		  FL(" calling csr_send_join_req_msg (eWNI_SME_REASSOC_REQ)"));
+	/* attempt to Join this BSS... */
+	return csr_send_join_req_msg(pMac, sessionId, pSirBssDesc, pProfile, pIes,
+				     eWNI_SME_REASSOC_REQ);
+}
+
+void csr_roam_reissue_roam_command(tpAniSirGlobal pMac)
+{
+	tListElem *pEntry;
+	tSmeCmd *pCommand;
+	tCsrRoamInfo roamInfo;
+	uint32_t sessionId;
+	tCsrRoamSession *pSession;
+
+	pEntry = csr_ll_peek_head(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK);
+	if (NULL == pEntry) {
+		sms_log(pMac, LOGE,
+			FL("Disassoc rsp can't continue, no active CMD"));
+		return;
+	}
+	pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
+	if (eSmeCommandRoam != pCommand->command) {
+		sms_log(pMac, LOGW, FL("Active cmd, is not a roaming CMD"));
+		return;
+	}
+	sessionId = pCommand->sessionId;
+	pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("session %d not found"), sessionId);
+		return;
+	}
+
+	if (!pCommand->u.roamCmd.fStopWds) {
+		if (pSession->bRefAssocStartCnt > 0) {
+			/*
+			 * bRefAssocStartCnt was incremented in
+			 * csr_roam_join_next_bss when the roam command issued
+			 * previously. As part of reissuing the roam command
+			 * again csr_roam_join_next_bss is going increment
+			 * RefAssocStartCnt. So make sure to decrement the
+			 * bRefAssocStartCnt
+			 */
+			pSession->bRefAssocStartCnt--;
+		}
+		if (eCsrStopRoaming == csr_roam_join_next_bss(pMac, pCommand,
+							      true)) {
+			sms_log(pMac, LOGW,
+				FL("Failed to reissue join command"));
+			csr_roam_complete(pMac, eCsrNothingToJoin, NULL);
+		}
+		return;
+	}
+	cdf_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0);
+	roamInfo.pBssDesc = pCommand->u.roamCmd.pLastRoamBss;
+	roamInfo.statusCode = pSession->joinFailStatusCode.statusCode;
+	roamInfo.reasonCode = pSession->joinFailStatusCode.reasonCode;
+	if (CSR_IS_WDS(&pSession->connectedProfile)) {
+		pSession->connectState = eCSR_ASSOC_STATE_TYPE_WDS_DISCONNECTED;
+		csr_roam_call_callback(pMac, sessionId, &roamInfo,
+				       pCommand->u.roamCmd.roamId,
+				       eCSR_ROAM_WDS_IND,
+				       eCSR_ROAM_RESULT_WDS_DISASSOCIATED);
+	} else if (CSR_IS_INFRA_AP(&pSession->connectedProfile)) {
+		pSession->connectState =
+			eCSR_ASSOC_STATE_TYPE_INFRA_DISCONNECTED;
+		csr_roam_call_callback(pMac, sessionId, &roamInfo,
+				       pCommand->u.roamCmd.roamId,
+				       eCSR_ROAM_INFRA_IND,
+				       eCSR_ROAM_RESULT_INFRA_DISASSOCIATED);
+	}
+
+	if (!CDF_IS_STATUS_SUCCESS(csr_roam_issue_stop_bss(pMac, sessionId,
+					eCSR_ROAM_SUBSTATE_STOP_BSS_REQ))) {
+		sms_log(pMac, LOGE,
+			FL("Failed to reissue stop_bss command for WDS"));
+		csr_roam_complete(pMac, eCsrNothingToJoin, NULL);
+	}
+}
+
+bool csr_is_roam_command_waiting_for_session(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	bool fRet = false;
+	tListElem *pEntry;
+	tSmeCmd *pCommand = NULL;
+	/* alwasy lock active list before locking pending list */
+	csr_ll_lock(&pMac->sme.smeCmdActiveList);
+	pEntry = csr_ll_peek_head(&pMac->sme.smeCmdActiveList, LL_ACCESS_NOLOCK);
+	if (pEntry) {
+		pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
+		if ((eSmeCommandRoam == pCommand->command)
+		    && (sessionId == pCommand->sessionId)) {
+			fRet = true;
+		}
+	}
+	if (false == fRet) {
+		csr_ll_lock(&pMac->sme.smeCmdPendingList);
+		pEntry =
+			csr_ll_peek_head(&pMac->sme.smeCmdPendingList,
+					 LL_ACCESS_NOLOCK);
+		while (pEntry) {
+			pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
+			if ((eSmeCommandRoam == pCommand->command)
+			    && (sessionId == pCommand->sessionId)) {
+				fRet = true;
+				break;
+			}
+			pEntry =
+				csr_ll_next(&pMac->sme.smeCmdPendingList, pEntry,
+					    LL_ACCESS_NOLOCK);
+		}
+		csr_ll_unlock(&pMac->sme.smeCmdPendingList);
+	}
+	if (false == fRet) {
+		csr_ll_lock(&pMac->roam.roamCmdPendingList);
+		pEntry =
+			csr_ll_peek_head(&pMac->roam.roamCmdPendingList,
+					 LL_ACCESS_NOLOCK);
+		while (pEntry) {
+			pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
+			if ((eSmeCommandRoam == pCommand->command)
+			    && (sessionId == pCommand->sessionId)) {
+				fRet = true;
+				break;
+			}
+			pEntry =
+				csr_ll_next(&pMac->roam.roamCmdPendingList, pEntry,
+					    LL_ACCESS_NOLOCK);
+		}
+		csr_ll_unlock(&pMac->roam.roamCmdPendingList);
+	}
+	csr_ll_unlock(&pMac->sme.smeCmdActiveList);
+	return fRet;
+}
+
+bool csr_is_roam_command_waiting(tpAniSirGlobal pMac)
+{
+	bool fRet = false;
+	uint32_t i;
+	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
+		fRet = csr_is_roam_command_waiting_for_session(pMac, i);
+		if (CSR_IS_SESSION_VALID(pMac, i)
+		    && (fRet)) {
+			break;
+		}
+	}
+	return fRet;
+}
+
+bool csr_is_command_waiting(tpAniSirGlobal pMac)
+{
+	bool fRet = false;
+	/* alwasy lock active list before locking pending list */
+	csr_ll_lock(&pMac->sme.smeCmdActiveList);
+	fRet = csr_ll_is_list_empty(&pMac->sme.smeCmdActiveList, LL_ACCESS_NOLOCK);
+	if (false == fRet) {
+		fRet =
+			csr_ll_is_list_empty(&pMac->sme.smeCmdPendingList,
+					     LL_ACCESS_LOCK);
+	}
+	csr_ll_unlock(&pMac->sme.smeCmdActiveList);
+	return fRet;
+}
+
+bool csr_is_scan_for_roam_command_active(tpAniSirGlobal pMac)
+{
+	bool fRet = false;
+	tListElem *pEntry;
+	tCsrCmd *pCommand;
+	/* alwasy lock active list before locking pending list */
+	csr_ll_lock(&pMac->sme.smeCmdActiveList);
+	pEntry = csr_ll_peek_head(&pMac->sme.smeCmdActiveList, LL_ACCESS_NOLOCK);
+	if (pEntry) {
+		pCommand = GET_BASE_ADDR(pEntry, tCsrCmd, Link);
+		if ((eCsrRoamCommandScan == pCommand->command) &&
+		    ((eCsrScanForSsid == pCommand->u.scanCmd.reason) ||
+		     (eCsrScanP2PFindPeer == pCommand->u.scanCmd.reason))) {
+			fRet = true;
+		}
+	}
+	csr_ll_unlock(&pMac->sme.smeCmdActiveList);
+	return fRet;
+}
+
+CDF_STATUS csr_roam_issue_reassociate_cmd(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tSmeCmd *pCommand = NULL;
+	bool fHighPriority = true;
+	bool fRemoveCmd = false;
+	tListElem *pEntry;
+	/* Delete the old assoc command. All is setup for reassoc to be serialized */
+	pEntry = csr_ll_peek_head(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK);
+	if (pEntry) {
+		pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
+		if (!pCommand) {
+			sms_log(pMac, LOGE, FL(" fail to get command buffer"));
+			return CDF_STATUS_E_RESOURCES;
+		}
+		if (eSmeCommandRoam == pCommand->command) {
+			if (pCommand->u.roamCmd.roamReason ==
+			    eCsrSmeIssuedAssocToSimilarAP) {
+				fRemoveCmd =
+					csr_ll_remove_entry(&pMac->sme.
+							    smeCmdActiveList, pEntry,
+							    LL_ACCESS_LOCK);
+			} else {
+				sms_log(pMac, LOGE,
+					FL
+						(" Unexpected active roam command present "));
+			}
+			if (fRemoveCmd == false) {
+				/* Implies we did not get the serialized assoc command we */
+				/* were expecting */
+				pCommand = NULL;
+			}
+		}
+	}
+	if (NULL == pCommand) {
+		sms_log(pMac, LOGE,
+			FL
+				(" fail to get command buffer as expected based on previous connect roam command"));
+		return CDF_STATUS_E_RESOURCES;
+	}
+	do {
+		/* Change the substate in case it is wait-for-key */
+		if (CSR_IS_WAIT_FOR_KEY(pMac, sessionId)) {
+			csr_roam_stop_wait_for_key_timer(pMac);
+			csr_roam_substate_change(pMac, eCSR_ROAM_SUBSTATE_NONE,
+						 sessionId);
+		}
+		pCommand->command = eSmeCommandRoam;
+		pCommand->sessionId = (uint8_t) sessionId;
+		pCommand->u.roamCmd.roamReason = eCsrSmeIssuedFTReassoc;
+		status = csr_queue_sme_command(pMac, pCommand, fHighPriority);
+		if (!CDF_IS_STATUS_SUCCESS(status)) {
+			sms_log(pMac, LOGE,
+				FL(" fail to send message status = %d"), status);
+			csr_release_command_roam(pMac, pCommand);
+		}
+	} while (0);
+
+	return status;
+}
+
+static void
+csr_roaming_state_config_cnf_processor(tpAniSirGlobal mac_ctx,
+				       uint32_t result)
+{
+	tListElem *entry = csr_ll_peek_head(&mac_ctx->sme.smeCmdActiveList,
+					     LL_ACCESS_LOCK);
+	tCsrScanResult *scan_result = NULL;
+	tSirBssDescription *bss_desc = NULL;
+	tSmeCmd *cmd = NULL;
+	uint32_t session_id;
+	tCsrRoamSession *session;
+	tDot11fBeaconIEs *local_ies = NULL;
+	CDF_STATUS status = CDF_STATUS_E_FAILURE;
+
+	if (NULL == entry) {
+		sms_log(mac_ctx, LOGE, FL("CFG_CNF with active list empty"));
+		return;
+	}
+	cmd = GET_BASE_ADDR(entry, tSmeCmd, Link);
+	session_id = cmd->sessionId;
+	session = CSR_GET_SESSION(mac_ctx, session_id);
+
+	if (!session) {
+		sms_log(mac_ctx, LOGE, FL("session %d not found"), session_id);
+		return;
+	}
+
+	if (CSR_IS_ROAMING(session) && session->fCancelRoaming) {
+		/* the roaming is cancelled. Simply complete the command */
+		sms_log(mac_ctx, LOGW, FL("Roam command canceled"));
+		csr_roam_complete(mac_ctx, eCsrNothingToJoin, NULL);
+		return;
+	}
+
+	/* If the roaming has stopped, not to continue the roaming command */
+	if (!CSR_IS_ROAMING(session) && CSR_IS_ROAMING_COMMAND(cmd)) {
+		/* No need to complete roaming here as it already completes */
+		sms_log(mac_ctx, LOGW,
+			FL("Roam cmd (reason %d) aborted(roaming completed)"),
+			cmd->u.roamCmd.roamReason);
+		csr_set_abort_roaming_command(mac_ctx, cmd);
+		csr_roam_complete(mac_ctx, eCsrNothingToJoin, NULL);
+		return;
+	}
+
+	if (!IS_SIR_STATUS_SUCCESS(result)) {
+		/*
+		 * In the event the configuration failed, for infra let the roam
+		 * processor attempt to join something else...
+		 */
+		if (cmd->u.roamCmd.pRoamBssEntry
+		    && CSR_IS_INFRASTRUCTURE(&cmd->u.roamCmd.roamProfile)) {
+			csr_roam(mac_ctx, cmd);
+		} else {
+			/* We need to complete the command */
+			if (csr_is_bss_type_ibss
+				    (cmd->u.roamCmd.roamProfile.BSSType)) {
+				csr_roam_complete(mac_ctx, eCsrStartBssFailure,
+						  NULL);
+			} else {
+				csr_roam_complete(mac_ctx, eCsrNothingToJoin,
+						  NULL);
+			}
+		}
+		return;
+	}
+
+	/* we have active entry */
+	sms_log(mac_ctx, LOG2, "Cfg sequence complete");
+	/*
+	 * Successfully set the configuration parameters for the new Bss.
+	 * Attempt to join the roaming Bss
+	 */
+	if (cmd->u.roamCmd.pRoamBssEntry) {
+		scan_result = GET_BASE_ADDR(cmd->u.roamCmd.pRoamBssEntry,
+					    tCsrScanResult,
+					    Link);
+		bss_desc = &scan_result->Result.BssDescriptor;
+	}
+	if (csr_is_bss_type_ibss(cmd->u.roamCmd.roamProfile.BSSType)
+	    || CSR_IS_WDS(&cmd->u.roamCmd.roamProfile)
+	    || CSR_IS_INFRA_AP(&cmd->u.roamCmd.roamProfile)) {
+		if (!CDF_IS_STATUS_SUCCESS(csr_roam_issue_start_bss(mac_ctx,
+						session_id, &session->bssParams,
+						&cmd->u.roamCmd.roamProfile,
+						bss_desc,
+						cmd->u.roamCmd.roamId))) {
+			sms_log(mac_ctx, LOGE, FL("CSR start BSS failed"));
+			/* We need to complete the command */
+			csr_roam_complete(mac_ctx, eCsrStartBssFailure, NULL);
+		}
+		return;
+	}
+
+	if (!cmd->u.roamCmd.pRoamBssEntry) {
+		sms_log(mac_ctx, LOGE, FL("pRoamBssEntry is NULL"));
+		/* We need to complete the command */
+		csr_roam_complete(mac_ctx, eCsrJoinFailure, NULL);
+		return;
+	}
+
+	if (NULL == scan_result) {
+		/* If we are roaming TO an Infrastructure BSS... */
+		CDF_ASSERT(scan_result != NULL);
+		return;
+	}
+
+	if (!csr_is_infra_bss_desc(bss_desc)) {
+		sms_log(mac_ctx, LOGW,
+			FL("found BSSType mismatching the one in BSS descp"));
+		return;
+	}
+
+	local_ies = (tDot11fBeaconIEs *) scan_result->Result.pvIes;
+	if (!local_ies) {
+		status = csr_get_parsed_bss_description_ies(mac_ctx, bss_desc,
+							    &local_ies);
+		if (!CDF_IS_STATUS_SUCCESS(status))
+			return;
+	}
+
+	if (csr_is_conn_state_connected_infra(mac_ctx, session_id)) {
+		if (csr_is_ssid_equal(mac_ctx, session->pConnectBssDesc,
+				      bss_desc, local_ies)) {
+			cmd->u.roamCmd.fReassoc = true;
+			csr_roam_issue_reassociate(mac_ctx, session_id,
+						   bss_desc, local_ies,
+						   &cmd->u.roamCmd.roamProfile);
+		} else {
+			/*
+			 * otherwise, we have to issue a new Join request to LIM
+			 * because we disassociated from the previously
+			 * associated AP.
+			 */
+			status = csr_roam_issue_join(mac_ctx, session_id,
+					bss_desc, local_ies,
+					&cmd->u.roamCmd.roamProfile,
+					cmd->u.roamCmd.roamId);
+			if (!CDF_IS_STATUS_SUCCESS(status)) {
+				/* try something else */
+				csr_roam(mac_ctx, cmd);
+			}
+		}
+	} else {
+		status = CDF_STATUS_SUCCESS;
+		/*
+		 * We need to come with other way to figure out that this is
+		 * because of HO in BMP The below API will be only available for
+		 * Android as it uses a different HO algorithm. Reassoc request
+		 * will be used only for ESE and 11r handoff whereas other
+		 * legacy roaming should use join request
+		 */
+#ifdef WLAN_FEATURE_VOWIFI_11R
+		if (csr_roam_is_handoff_in_progress(mac_ctx, session_id)
+		    && csr_roam_is11r_assoc(mac_ctx, session_id)) {
+			status = csr_roam_issue_reassociate(mac_ctx,
+					session_id, bss_desc,
+					(tDot11fBeaconIEs *)
+					(scan_result->Result.pvIes),
+					&cmd->u.roamCmd.roamProfile);
+		} else
+#endif
+#ifdef FEATURE_WLAN_ESE
+		if (csr_roam_is_handoff_in_progress(mac_ctx, session_id)
+		   && csr_roam_is_ese_assoc(mac_ctx, session_id)) {
+			/* Now serialize the reassoc command. */
+			status = csr_roam_issue_reassociate_cmd(mac_ctx,
+								session_id);
+		} else
+#endif
+#ifdef FEATURE_WLAN_LFR
+		if (csr_roam_is_handoff_in_progress(mac_ctx, session_id)
+		   && csr_roam_is_fast_roam_enabled(mac_ctx, session_id)) {
+			/* Now serialize the reassoc command. */
+			status = csr_roam_issue_reassociate_cmd(mac_ctx,
+								session_id);
+		} else
+#endif
+		{
+		/*
+		 * else we are not connected and attempting to Join. Issue the
+		 * Join request.
+		 */
+			status = csr_roam_issue_join(mac_ctx, session_id,
+						    bss_desc,
+						    (tDot11fBeaconIEs *)
+						    (scan_result->Result.pvIes),
+						    &cmd->u.roamCmd.roamProfile,
+						    cmd->u.roamCmd.roamId);
+		}
+		if (!CDF_IS_STATUS_SUCCESS(status)) {
+			/* try something else */
+			csr_roam(mac_ctx, cmd);
+		}
+	}
+	if (!scan_result->Result.pvIes) {
+		/* Locally allocated */
+		cdf_mem_free(local_ies);
+	}
+}
+
+static void csr_roam_roaming_state_reassoc_rsp_processor(tpAniSirGlobal pMac,
+							 tpSirSmeJoinRsp pSmeJoinRsp)
+{
+	eCsrRoamCompleteResult result;
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+		&pMac->roam.neighborRoamInfo[pSmeJoinRsp->sessionId];
+	tCsrRoamInfo roamInfo;
+	uint32_t roamId = 0;
+
+	if (eSIR_SME_SUCCESS == pSmeJoinRsp->statusCode) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
+			  FL("CSR SmeReassocReq Successful"));
+		result = eCsrReassocSuccess;
+		/* Defeaturize this part later if needed */
+#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
+		/* Since the neighbor roam algorithm uses reassoc req for handoff instead of join,
+		 * we need the response contents while processing the result in csr_roam_process_results() */
+		if (csr_roam_is_handoff_in_progress(pMac, pSmeJoinRsp->sessionId)) {
+			/* Need to dig more on indicating events to SME QoS module */
+			sme_qos_csr_event_ind(pMac, pSmeJoinRsp->sessionId,
+					      SME_QOS_CSR_HANDOFF_COMPLETE, NULL);
+			csr_roam_complete(pMac, result, pSmeJoinRsp);
+		} else
+#endif
+		{
+			csr_roam_complete(pMac, result, NULL);
+		}
+	}
+	/* Should we handle this similar to handling the join failure? Is it ok
+	 * to call csr_roam_complete() with state as CsrJoinFailure */
+	else {
+		sms_log(pMac, LOGW,
+			"CSR SmeReassocReq failed with statusCode= 0x%08X [%d]",
+			pSmeJoinRsp->statusCode, pSmeJoinRsp->statusCode);
+		result = eCsrReassocFailure;
+#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || \
+		defined(FEATURE_WLAN_LFR)
+		if ((eSIR_SME_FT_REASSOC_TIMEOUT_FAILURE ==
+		     pSmeJoinRsp->statusCode)
+		    || (eSIR_SME_FT_REASSOC_FAILURE ==
+			pSmeJoinRsp->statusCode)
+		    || (eSIR_SME_INVALID_PARAMETERS ==
+			pSmeJoinRsp->statusCode)) {
+			/* Inform HDD to turn off FT flag in HDD */
+			if (pNeighborRoamInfo) {
+				cdf_mem_zero(&roamInfo, sizeof(tCsrRoamInfo));
+				csr_roam_call_callback(pMac,
+						       pSmeJoinRsp->sessionId,
+						       &roamInfo, roamId,
+						       eCSR_ROAM_FT_REASSOC_FAILED,
+						       eSIR_SME_SUCCESS);
+				/*
+				 * Since the above callback sends a disconnect
+				 * to HDD, we should clean-up our state
+				 * machine as well to be in sync with the upper
+				 * layers. There is no need to send a disassoc
+				 * since: 1) we will never reassoc to the current
+				 * AP in LFR, and 2) there is no need to issue a
+				 * disassoc to the AP with which we were trying
+				 * to reassoc.
+				 */
+				csr_roam_complete(pMac, eCsrJoinFailure, NULL);
+				return;
+			}
+		}
+#endif
+		/* In the event that the Reassociation fails, then we need to Disassociate the current association and keep */
+		/* roaming.  Note that we will attempt to Join the AP instead of a Reassoc since we may have attempted a */
+		/* 'Reassoc to self', which AP's that don't support Reassoc will force a Disassoc. */
+		/* The disassoc rsp message will remove the command from active list */
+		if (!CDF_IS_STATUS_SUCCESS
+			    (csr_roam_issue_disassociate
+				    (pMac, pSmeJoinRsp->sessionId,
+				    eCSR_ROAM_SUBSTATE_DISASSOC_REASSOC_FAILURE, false))) {
+			csr_roam_complete(pMac, eCsrJoinFailure, NULL);
+		}
+	}
+}
+
+static void csr_roam_roaming_state_stop_bss_rsp_processor(tpAniSirGlobal pMac,
+							  tSirSmeRsp *pSmeRsp)
+{
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+	{
+		host_log_ibss_pkt_type *pIbssLog;
+		WLAN_HOST_DIAG_LOG_ALLOC(pIbssLog, host_log_ibss_pkt_type,
+					 LOG_WLAN_IBSS_C);
+		if (pIbssLog) {
+			pIbssLog->eventId = WLAN_IBSS_EVENT_STOP_RSP;
+			if (eSIR_SME_SUCCESS != pSmeRsp->statusCode) {
+				pIbssLog->status = WLAN_IBSS_STATUS_FAILURE;
+			}
+			WLAN_HOST_DIAG_LOG_REPORT(pIbssLog);
+		}
+	}
+#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
+	pMac->roam.roamSession[pSmeRsp->sessionId].connectState =
+		eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED;
+	if (CSR_IS_ROAM_SUBSTATE_STOP_BSS_REQ(pMac, pSmeRsp->sessionId)) {
+		csr_roam_complete(pMac, eCsrNothingToJoin, NULL);
+	} else
+	if (CSR_IS_ROAM_SUBSTATE_DISCONNECT_CONTINUE
+		    (pMac, pSmeRsp->sessionId)) {
+		csr_roam_reissue_roam_command(pMac);
+	}
+}
+
+/**
+ * csr_dequeue_command() - removes a command from active cmd list
+ * @pMac:          mac global context
+ *
+ * Return: void
+ */
+static void
+csr_dequeue_command(tpAniSirGlobal mac_ctx)
+{
+	bool fRemoveCmd;
+	tSmeCmd *cmd = NULL;
+	tListElem *entry = csr_ll_peek_head(&mac_ctx->sme.smeCmdActiveList,
+					    LL_ACCESS_LOCK);
+	if (!entry) {
+		sms_log(mac_ctx, LOGE, FL("NO commands are active"));
+		return;
+	}
+
+	cmd = GET_BASE_ADDR(entry, tSmeCmd, Link);
+	/*
+	 * If the head of the queue is Active and it is a given cmd type, remove
+	 * and put this on the Free queue.
+	 */
+	if (eSmeCommandRoam != cmd->command) {
+		sms_log(mac_ctx, LOGE, FL("Roam command not active"));
+		return;
+	}
+	/*
+	 * we need to process the result first before removing it from active
+	 * list because state changes still happening insides
+	 * roamQProcessRoamResults so no other roam command should be issued.
+	 */
+	fRemoveCmd = csr_ll_remove_entry(&mac_ctx->sme.smeCmdActiveList, entry,
+					 LL_ACCESS_LOCK);
+	if (cmd->u.roamCmd.fReleaseProfile) {
+		csr_release_profile(mac_ctx, &cmd->u.roamCmd.roamProfile);
+		cmd->u.roamCmd.fReleaseProfile = false;
+	}
+	if (fRemoveCmd)
+		csr_release_command_roam(mac_ctx, cmd);
+	else
+		sms_log(mac_ctx, LOGE, FL("fail to remove cmd reason %d"),
+			cmd->u.roamCmd.roamReason);
+}
+
+/**
+ * csr_post_roam_failure() - post roam failure back to csr and issues a disassoc
+ * @pMac:               mac global context
+ * @session_id:         session id
+ * @roam_info:          roam info struct
+ * @scan_filter:        scan filter to free
+ * @cur_roam_profile:   current csr roam profile
+ *
+ * Return: void
+ */
+static void
+csr_post_roam_failure(tpAniSirGlobal mac_ctx,
+		      uint32_t session_id,
+		      tCsrRoamInfo *roam_info,
+		      tCsrScanResultFilter *scan_filter,
+		      tCsrRoamProfile *cur_roam_profile)
+{
+	CDF_STATUS status;
+
+	if (scan_filter) {
+		csr_free_scan_filter(mac_ctx, scan_filter);
+		cdf_mem_free(scan_filter);
+	}
+	if (cur_roam_profile)
+		cdf_mem_free(cur_roam_profile);
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+		csr_roam_synch_clean_up(mac_ctx, session_id);
+#endif
+	/* Inform the upper layers that the reassoc failed */
+	cdf_mem_zero(roam_info, sizeof(tCsrRoamInfo));
+	csr_roam_call_callback(mac_ctx, session_id, roam_info, 0,
+			       eCSR_ROAM_FT_REASSOC_FAILED, eSIR_SME_SUCCESS);
+	/*
+	 * Issue a disassoc request so that PE/LIM uses this to clean-up the FT
+	 * session. Upon success, we would re-enter this routine after receiving
+	 * the disassoc response and will fall into the reassoc fail sub-state.
+	 * And, eventually call csr_roam_complete which would remove the roam
+	 * command from SME active queue.
+	 */
+	status = csr_roam_issue_disassociate(mac_ctx, session_id,
+			eCSR_ROAM_SUBSTATE_DISASSOC_REASSOC_FAILURE, false);
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		sms_log(mac_ctx, LOGE,
+			FL("csr_roam_issue_disassociate failed, status %d"),
+			status);
+		csr_roam_complete(mac_ctx, eCsrJoinFailure, NULL);
+	}
+}
+
+/**
+ * csr_check_profile_in_scan_cache() - finds if roam profile is present in scan
+ * cache or not
+ * @pMac:                  mac global context
+ * @scan_filter:           out param, scan filter
+ * @neighbor_roam_info:    roam info struct
+ * @hBSSList:              scan result
+ *
+ * Return: true if found else false.
+ */
+static bool
+csr_check_profile_in_scan_cache(tpAniSirGlobal mac_ctx,
+				tCsrScanResultFilter **scan_filter,
+				tpCsrNeighborRoamControlInfo neighbor_roam_info,
+				tScanResultHandle *hBSSList)
+{
+	CDF_STATUS status;
+	*scan_filter = cdf_mem_malloc(sizeof(tCsrScanResultFilter));
+	if (NULL == *scan_filter) {
+		sms_log(mac_ctx, LOGE, FL("alloc for ScanFilter failed."));
+		return false;
+	}
+	cdf_mem_set(*scan_filter, sizeof(tCsrScanResultFilter), 0);
+	(*scan_filter)->scan_filter_for_roam = 1;
+	status = csr_roam_prepare_filter_from_profile(mac_ctx,
+			&neighbor_roam_info->csrNeighborRoamProfile,
+			*scan_filter);
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		sms_log(mac_ctx, LOGE,
+			FL("failed to prepare scan filter, status %d"),
+			status);
+		return false;
+	}
+	status = csr_scan_get_result(mac_ctx, *scan_filter, hBSSList);
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		sms_log(mac_ctx, LOGE,
+			FL("csr_scan_get_result failed, status %d"),
+			status);
+		return false;
+	}
+	return true;
+}
+
+void csr_roam_roaming_state_disassoc_rsp_processor(tpAniSirGlobal pMac,
+						   tSirSmeDisassocRsp *pSmeRsp)
+{
+#if defined WLAN_FEATURE_NEIGHBOR_ROAMING
+	tScanResultHandle hBSSList;
+	tCsrRoamInfo roamInfo;
+	tCsrScanResultFilter *pScanFilter = NULL;
+	uint32_t roamId = 0;
+	tCsrRoamProfile *pCurRoamProfile = NULL;
+#endif
+	CDF_STATUS status;
+	uint32_t sessionId;
+	tCsrRoamSession *pSession;
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL;
+	tSirSmeDisassocRsp SmeDisassocRsp;
+
+	csr_ser_des_unpack_diassoc_rsp((uint8_t *) pSmeRsp, &SmeDisassocRsp);
+	sessionId = SmeDisassocRsp.sessionId;
+	CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG, FL("sessionId %d"),
+		  sessionId);
+
+	if (csr_is_conn_state_infra(pMac, sessionId)) {
+		pMac->roam.roamSession[sessionId].connectState =
+			eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED;
+	}
+
+	pSession = CSR_GET_SESSION(pMac, sessionId);
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("session %d not found"), sessionId);
+		return;
+	}
+
+	if (CSR_IS_ROAM_SUBSTATE_DISASSOC_NO_JOIN(pMac, sessionId)) {
+		sms_log(pMac, LOG2, "***eCsrNothingToJoin***");
+		csr_roam_complete(pMac, eCsrNothingToJoin, NULL);
+	} else if (CSR_IS_ROAM_SUBSTATE_DISASSOC_FORCED(pMac, sessionId) ||
+		   CSR_IS_ROAM_SUBSTATE_DISASSOC_REQ(pMac, sessionId)) {
+		if (eSIR_SME_SUCCESS == SmeDisassocRsp.statusCode) {
+			sms_log(pMac, LOG2,
+				FL("CSR force disassociated successful"));
+			/*
+			 * A callback to HDD will be issued from
+			 * csr_roam_complete so no need to do anything here
+			 */
+		}
+		csr_roam_complete(pMac, eCsrNothingToJoin, NULL);
+	} else if (CSR_IS_ROAM_SUBSTATE_DISASSOC_HO(pMac, sessionId)) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
+			  FL("CSR SmeDisassocReq due to HO on session %d"),
+			  sessionId);
+		pNeighborRoamInfo = &pMac->roam.neighborRoamInfo[sessionId];
+#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
+		/*
+		 * First ensure if the roam profile is in the scan cache.
+		 * If not, post a reassoc failure and disconnect.
+		 */
+		if (!csr_check_profile_in_scan_cache(pMac, &pScanFilter,
+						pNeighborRoamInfo, &hBSSList))
+			goto POST_ROAM_FAILURE;
+
+		/*
+		 * After ensuring that the roam profile is in the scan result
+		 * list, dequeue the command from the active list.
+		 */
+		csr_dequeue_command(pMac);
+
+		/* notify HDD about handoff and provide the BSSID too */
+		roamInfo.reasonCode = eCsrRoamReasonBetterAP;
+
+		cdf_copy_macaddr(&roamInfo.bssid,
+			pNeighborRoamInfo->csrNeighborRoamProfile.BSSIDs.bssid);
+
+		csr_roam_call_callback(pMac, sessionId, &roamInfo, 0,
+				       eCSR_ROAM_ROAMING_START,
+				       eCSR_ROAM_RESULT_NONE);
+
+		/*
+		 * Copy the connected profile to apply the same for this
+		 * connection as well
+		 */
+		pCurRoamProfile = cdf_mem_malloc(sizeof(tCsrRoamProfile));
+		if (pCurRoamProfile != NULL) {
+			/*
+			 * notify sub-modules like QoS etc. that handoff
+			 * happening
+			 */
+			sme_qos_csr_event_ind(pMac, sessionId,
+					      SME_QOS_CSR_HANDOFF_ASSOC_REQ,
+					      NULL);
+			cdf_mem_set(pCurRoamProfile, sizeof(tCsrRoamProfile),
+				    0);
+			csr_roam_copy_profile(pMac, pCurRoamProfile,
+					      pSession->pCurRoamProfile);
+			/* make sure to put it at the head of the cmd queue */
+			status = csr_roam_issue_connect(pMac, sessionId,
+					pCurRoamProfile, hBSSList,
+					eCsrSmeIssuedAssocToSimilarAP,
+					roamId, true, false);
+			if (!CDF_IS_STATUS_SUCCESS(status))
+				sms_log(pMac, LOGE,
+					FL("issue_connect failed. status %d"),
+					status);
+
+			csr_release_profile(pMac, pCurRoamProfile);
+			cdf_mem_free(pCurRoamProfile);
+			csr_free_scan_filter(pMac, pScanFilter);
+			cdf_mem_free(pScanFilter);
+			return;
+		}
+
+POST_ROAM_FAILURE:
+	csr_post_roam_failure(pMac, sessionId, &roamInfo,
+			      pScanFilter, pCurRoamProfile);
+#endif
+	} /* else if ( CSR_IS_ROAM_SUBSTATE_DISASSOC_HO( pMac ) ) */
+	else if (CSR_IS_ROAM_SUBSTATE_REASSOC_FAIL(pMac, sessionId)) {
+		/* Disassoc due to Reassoc failure falls into this codepath */
+		csr_roam_complete(pMac, eCsrJoinFailure, NULL);
+	} else {
+		if (eSIR_SME_SUCCESS == SmeDisassocRsp.statusCode) {
+			/*
+			 * Successfully disassociated from the 'old' Bss.
+			 * We get Disassociate response in three conditions.
+			 * 1) The case where we are disasociating from an Infra
+			 *    Bss to start an IBSS.
+			 * 2) When we are disassociating from an Infra Bss to
+			 *    join an IBSS or a new infra network.
+			 * 3) Where we are doing an Infra to Infra roam between
+			 *    networks with different SSIDs.
+			 * In all cases, we set the new Bss configuration here
+			 * and attempt to join
+			 */
+			sms_log(pMac, LOG2,
+				FL("Disassociated successfully"));
+		} else {
+			sms_log(pMac, LOGE,
+				FL("DisassocReq failed, statusCode= 0x%08X"),
+				SmeDisassocRsp.statusCode);
+		}
+		/* We are not done yet. Get the data and continue roaming */
+		csr_roam_reissue_roam_command(pMac);
+	}
+}
+
+static void csr_roam_roaming_state_deauth_rsp_processor(tpAniSirGlobal pMac,
+							tSirSmeDeauthRsp *pSmeRsp)
+{
+	tSirResultCodes statusCode;
+	/* No one is sending eWNI_SME_DEAUTH_REQ to PE. */
+	sms_log(pMac, LOGW, FL("is no-op"));
+	statusCode = csr_get_de_auth_rsp_status_code(pSmeRsp);
+	pMac->roam.deauthRspStatus = statusCode;
+	if (CSR_IS_ROAM_SUBSTATE_DEAUTH_REQ(pMac, pSmeRsp->sessionId)) {
+		csr_roam_complete(pMac, eCsrNothingToJoin, NULL);
+	} else {
+		if (eSIR_SME_SUCCESS == statusCode) {
+			/* Successfully deauth from the 'old' Bss... */
+			/* */
+			sms_log(pMac, LOG2,
+				"CSR SmeDeauthReq disassociated Successfully");
+		} else {
+			sms_log(pMac, LOGW,
+				"SmeDeauthReq failed with statusCode= 0x%08X",
+				statusCode);
+		}
+		/* We are not done yet. Get the data and continue roaming */
+		csr_roam_reissue_roam_command(pMac);
+	}
+}
+
+static void csr_roam_roaming_state_start_bss_rsp_processor(tpAniSirGlobal pMac,
+							   tSirSmeStartBssRsp *
+							   pSmeStartBssRsp)
+{
+	eCsrRoamCompleteResult result;
+
+	if (eSIR_SME_SUCCESS == pSmeStartBssRsp->statusCode) {
+		sms_log(pMac, LOGW, "SmeStartBssReq Successful");
+		result = eCsrStartBssSuccess;
+	} else {
+		sms_log(pMac, LOGW,
+			"SmeStartBssReq failed with statusCode= 0x%08X",
+			pSmeStartBssRsp->statusCode);
+		/* Let csr_roam_complete decide what to do */
+		result = eCsrStartBssFailure;
+	}
+	csr_roam_complete(pMac, result, pSmeStartBssRsp);
+}
+
+/**
+ * csr_roaming_state_msg_processor() - process roaming messages
+ * @pMac:       mac global context
+ * @pMsgBuf:    message buffer
+ *
+ * We need to be careful on whether to cast pMsgBuf (pSmeRsp) to other type of
+ * strucutres. It depends on how the message is constructed. If the message is
+ * sent by lim_send_sme_rsp, the pMsgBuf is only a generic response and can only
+ * be used as pointer to tSirSmeRsp. For the messages where sender allocates
+ * memory for specific structures, then it can be cast accordingly.
+ *
+ * Return: status of operation
+ */
+void csr_roaming_state_msg_processor(tpAniSirGlobal pMac, void *pMsgBuf)
+{
+	tSirSmeRsp *pSmeRsp;
+	tSmeIbssPeerInd *pIbssPeerInd;
+	tCsrRoamInfo roamInfo;
+	pSmeRsp = (tSirSmeRsp *) pMsgBuf;
+	sms_log(pMac, LOG2, FL("Message %d[0x%04X] received in substate %s"),
+		pSmeRsp->messageType, pSmeRsp->messageType,
+		mac_trace_getcsr_roam_sub_state(
+			pMac->roam.curSubState[pSmeRsp->sessionId]));
+	pSmeRsp->messageType = pSmeRsp->messageType;
+	pSmeRsp->length = pSmeRsp->length;
+	pSmeRsp->statusCode = pSmeRsp->statusCode;
+
+	switch (pSmeRsp->messageType) {
+
+	case eWNI_SME_JOIN_RSP:
+		/* in Roaming state, process the Join response message... */
+		if (CSR_IS_ROAM_SUBSTATE_JOIN_REQ(pMac, pSmeRsp->sessionId))
+			/* We sent a JOIN_REQ */
+			csr_roam_join_rsp_processor(pMac,
+						    (tSirSmeJoinRsp *) pSmeRsp);
+		break;
+	case eWNI_SME_REASSOC_RSP:
+		/* or the Reassociation response message... */
+		if (CSR_IS_ROAM_SUBSTATE_REASSOC_REQ(pMac, pSmeRsp->sessionId))
+			csr_roam_roaming_state_reassoc_rsp_processor(pMac,
+						(tpSirSmeJoinRsp) pSmeRsp);
+		break;
+	case eWNI_SME_STOP_BSS_RSP:
+		/* or the Stop Bss response message... */
+		csr_roam_roaming_state_stop_bss_rsp_processor(pMac, pSmeRsp);
+		break;
+	case eWNI_SME_DISASSOC_RSP:
+		/* or the Disassociate response message... */
+		if (CSR_IS_ROAM_SUBSTATE_DISASSOC_REQ(pMac, pSmeRsp->sessionId)
+		    || CSR_IS_ROAM_SUBSTATE_DISASSOC_NO_JOIN(pMac,
+							pSmeRsp->sessionId)
+		    || CSR_IS_ROAM_SUBSTATE_REASSOC_FAIL(pMac,
+							pSmeRsp->sessionId)
+		    || CSR_IS_ROAM_SUBSTATE_DISASSOC_FORCED(pMac,
+							pSmeRsp->sessionId)
+		    || CSR_IS_ROAM_SUBSTATE_DISCONNECT_CONTINUE(pMac,
+							pSmeRsp->sessionId)
+		    || CSR_IS_ROAM_SUBSTATE_DISASSOC_HO(pMac,
+							pSmeRsp->sessionId)) {
+			CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
+				  FL("eWNI_SME_DISASSOC_RSP subState = %s"),
+				  mac_trace_getcsr_roam_sub_state(
+				  pMac->roam.curSubState[pSmeRsp->sessionId]));
+			csr_roam_roaming_state_disassoc_rsp_processor(pMac,
+						(tSirSmeDisassocRsp *) pSmeRsp);
+		}
+		break;
+	case eWNI_SME_DEAUTH_RSP:
+		/* or the Deauthentication response message... */
+		if (CSR_IS_ROAM_SUBSTATE_DEAUTH_REQ(pMac, pSmeRsp->sessionId))
+			csr_roam_roaming_state_deauth_rsp_processor(pMac,
+						(tSirSmeDeauthRsp *) pSmeRsp);
+		break;
+	case eWNI_SME_START_BSS_RSP:
+		/* or the Start BSS response message... */
+		if (CSR_IS_ROAM_SUBSTATE_START_BSS_REQ(pMac,
+						       pSmeRsp->sessionId))
+			csr_roam_roaming_state_start_bss_rsp_processor(pMac,
+						(tSirSmeStartBssRsp *) pSmeRsp);
+		break;
+	/* In case CSR issues STOP_BSS, we need to tell HDD about peer departed
+	 * becasue PE is removing them
+	 */
+	case eWNI_SME_IBSS_PEER_DEPARTED_IND:
+		pIbssPeerInd = (tSmeIbssPeerInd *) pSmeRsp;
+		sms_log(pMac, LOGE,
+			FL("Peer departed ntf from LIM in joining state"));
+		cdf_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0);
+		roamInfo.staId = (uint8_t) pIbssPeerInd->staId;
+		roamInfo.ucastSig = (uint8_t) pIbssPeerInd->ucastSig;
+		roamInfo.bcastSig = (uint8_t) pIbssPeerInd->bcastSig;
+		cdf_mem_copy(&roamInfo.peerMac, pIbssPeerInd->peerAddr,
+			     sizeof(struct cdf_mac_addr));
+		csr_roam_call_callback(pMac, pSmeRsp->sessionId, &roamInfo, 0,
+				       eCSR_ROAM_CONNECT_STATUS_UPDATE,
+				       eCSR_ROAM_RESULT_IBSS_PEER_DEPARTED);
+		break;
+	case eWNI_SME_GET_RSSI_REQ:
+	{
+		tAniGetRssiReq *pGetRssiReq = (tAniGetRssiReq *) pMsgBuf;
+		if (NULL != pGetRssiReq->rssiCallback)
+			((tCsrRssiCallback) pGetRssiReq->rssiCallback)
+				(pGetRssiReq->lastRSSI, pGetRssiReq->staId,
+				pGetRssiReq->pDevContext);
+		else
+			sms_log(pMac, LOGE,
+				FL("pGetRssiReq->rssiCallback is NULL"));
+	}
+	break;
+	default:
+		sms_log(pMac, LOG1,
+			FL("Unexpected message type = %d[0x%X] received in substate %s"),
+			pSmeRsp->messageType, pSmeRsp->messageType,
+			mac_trace_getcsr_roam_sub_state(
+				pMac->roam.curSubState[pSmeRsp->sessionId]));
+		/* If we are connected, check the link status change */
+		if (!csr_is_conn_state_disconnected(pMac, pSmeRsp->sessionId))
+			csr_roam_check_for_link_status_change(pMac, pSmeRsp);
+		break;
+	}
+}
+
+void csr_roam_joined_state_msg_processor(tpAniSirGlobal pMac, void *pMsgBuf)
+{
+	tSirSmeRsp *pSirMsg = (tSirSmeRsp *) pMsgBuf;
+	switch (pSirMsg->messageType) {
+	case eWNI_SME_GET_STATISTICS_RSP:
+		sms_log(pMac, LOG2, FL("Stats rsp from PE"));
+		csr_roam_stats_rsp_processor(pMac, pSirMsg);
+		break;
+	case eWNI_SME_UPPER_LAYER_ASSOC_CNF:
+	{
+		tCsrRoamSession *pSession;
+		tSirSmeAssocIndToUpperLayerCnf *pUpperLayerAssocCnf;
+		tCsrRoamInfo roamInfo;
+		tCsrRoamInfo *pRoamInfo = NULL;
+		uint32_t sessionId;
+		CDF_STATUS status;
+		sms_log(pMac, LOG1,
+			FL
+				("ASSOCIATION confirmation can be given to upper layer "));
+		cdf_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0);
+		pRoamInfo = &roamInfo;
+		pUpperLayerAssocCnf =
+			(tSirSmeAssocIndToUpperLayerCnf *) pMsgBuf;
+		status =
+			csr_roam_get_session_id_from_bssid(pMac,
+							   (struct cdf_mac_addr *)
+							   pUpperLayerAssocCnf->
+							   bssId, &sessionId);
+		pSession = CSR_GET_SESSION(pMac, sessionId);
+
+		if (!pSession) {
+			sms_log(pMac, LOGE,
+				FL("  session %d not found "),
+				sessionId);
+			return;
+		}
+
+		pRoamInfo->statusCode = eSIR_SME_SUCCESS;               /* send the status code as Success */
+		pRoamInfo->u.pConnectedProfile =
+			&pSession->connectedProfile;
+		pRoamInfo->staId = (uint8_t) pUpperLayerAssocCnf->aid;
+		pRoamInfo->rsnIELen =
+			(uint8_t) pUpperLayerAssocCnf->rsnIE.length;
+		pRoamInfo->prsnIE =
+			pUpperLayerAssocCnf->rsnIE.rsnIEdata;
+#ifdef FEATURE_WLAN_WAPI
+		pRoamInfo->wapiIELen =
+			(uint8_t) pUpperLayerAssocCnf->wapiIE.length;
+		pRoamInfo->pwapiIE =
+			pUpperLayerAssocCnf->wapiIE.wapiIEdata;
+#endif
+		pRoamInfo->addIELen =
+			(uint8_t) pUpperLayerAssocCnf->addIE.length;
+		pRoamInfo->paddIE =
+			pUpperLayerAssocCnf->addIE.addIEdata;
+		cdf_mem_copy(pRoamInfo->peerMac.bytes,
+			     pUpperLayerAssocCnf->peerMacAddr,
+			     sizeof(tSirMacAddr));
+		cdf_mem_copy(&pRoamInfo->bssid,
+			     pUpperLayerAssocCnf->bssId,
+			     sizeof(struct cdf_mac_addr));
+		pRoamInfo->wmmEnabledSta =
+			pUpperLayerAssocCnf->wmmEnabledSta;
+		pRoamInfo->timingMeasCap =
+			pUpperLayerAssocCnf->timingMeasCap;
+		cdf_mem_copy(&pRoamInfo->chan_info,
+			     &pUpperLayerAssocCnf->chan_info,
+			     sizeof(tSirSmeChanInfo));
+		if (CSR_IS_INFRA_AP(pRoamInfo->u.pConnectedProfile)) {
+			pMac->roam.roamSession[sessionId].connectState =
+				eCSR_ASSOC_STATE_TYPE_INFRA_CONNECTED;
+			pRoamInfo->fReassocReq =
+				pUpperLayerAssocCnf->reassocReq;
+			status =
+				csr_roam_call_callback(pMac, sessionId,
+						       pRoamInfo, 0,
+						       eCSR_ROAM_INFRA_IND,
+						       eCSR_ROAM_RESULT_INFRA_ASSOCIATION_CNF);
+		}
+		if (CSR_IS_WDS_AP(pRoamInfo->u.pConnectedProfile)) {
+			cdf_sleep(100);
+			pMac->roam.roamSession[sessionId].connectState = eCSR_ASSOC_STATE_TYPE_WDS_CONNECTED;           /* Sta */
+			status = csr_roam_call_callback(pMac, sessionId, pRoamInfo, 0, eCSR_ROAM_WDS_IND, eCSR_ROAM_RESULT_WDS_ASSOCIATION_IND);           /* Sta */
+		}
+
+	}
+	break;
+	default:
+		csr_roam_check_for_link_status_change(pMac, pSirMsg);
+		break;
+	}
+}
+
+CDF_STATUS csr_roam_issue_set_context_req(tpAniSirGlobal pMac,
+					  uint32_t sessionId,
+					  eCsrEncryptionType EncryptType,
+					  tSirBssDescription *pBssDescription,
+					  tSirMacAddr *bssId, bool addKey,
+					  bool fUnicast,
+					  tAniKeyDirection aniKeyDirection,
+					  uint8_t keyId, uint16_t keyLength,
+					  uint8_t *pKey, uint8_t paeRole)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tAniEdType edType;
+
+	if (eCSR_ENCRYPT_TYPE_UNKNOWN == EncryptType) {
+		EncryptType = eCSR_ENCRYPT_TYPE_NONE;
+	}
+
+	edType = csr_translate_encrypt_type_to_ed_type(EncryptType);
+
+	/*
+	 * Allow 0 keys to be set for the non-WPA encrypt types. For WPA encrypt
+	 * types, the num keys must be non-zero or LIM will reject the set
+	 * context (assumes the SET_CONTEXT does not occur until the keys are
+	 * distrubuted).
+	 */
+	if (CSR_IS_ENC_TYPE_STATIC(EncryptType) || addKey) {
+		tCsrRoamSetKey setKey;
+		setKey.encType = EncryptType;
+		setKey.keyDirection = aniKeyDirection;
+		cdf_mem_copy(&setKey.peerMac, bssId, sizeof(struct cdf_mac_addr));
+		/* 0 for supplicant */
+		setKey.paeRole = paeRole;
+		/* Key index */
+		setKey.keyId = keyId;
+		setKey.keyLength = keyLength;
+		if (keyLength) {
+			cdf_mem_copy(setKey.Key, pKey, keyLength);
+		}
+		status = csr_roam_issue_set_key_command(pMac, sessionId,
+							&setKey, 0);
+	}
+	return status;
+}
+
+/**
+ * csr_update_key_cmd() - update key info in set key command
+ * @mac_ctx:         mac global context
+ * @session:         roam session
+ * @set_key:         input set key command
+ * @set_key_cmd:     set key command to update
+ * @enqueue_cmd:     indicates if command need to be enqueued to sme
+ *
+ * This function will validate the key length, adjust if too long. Tt will
+ * update bool enqueue_cmd, to false if some error has occured key are local.
+ *
+ * Return: status of operation
+ */
+static CDF_STATUS
+csr_update_key_cmd(tpAniSirGlobal mac_ctx, tCsrRoamSession *session,
+		   tCsrRoamSetKey *set_key, tSmeCmd *set_key_cmd,
+		   bool *enqueue_cmd)
+{
+	switch (set_key->encType) {
+	case eCSR_ENCRYPT_TYPE_WEP40:
+	case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
+		/* KeyLength maybe 0 for static WEP */
+		if (set_key->keyLength) {
+			if (set_key->keyLength < CSR_WEP40_KEY_LEN) {
+				sms_log(mac_ctx, LOGW,
+					FL("Invalid WEP40 keylength [= %d]"),
+					set_key->keyLength);
+				*enqueue_cmd = false;
+				return CDF_STATUS_E_INVAL;
+			}
+
+			set_key_cmd->u.setKeyCmd.keyLength = CSR_WEP40_KEY_LEN;
+			cdf_mem_copy(set_key_cmd->u.setKeyCmd.Key, set_key->Key,
+				     CSR_WEP40_KEY_LEN);
+		}
+		*enqueue_cmd = true;
+		break;
+	case eCSR_ENCRYPT_TYPE_WEP104:
+	case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
+		/* KeyLength maybe 0 for static WEP */
+		if (set_key->keyLength) {
+			if (set_key->keyLength < CSR_WEP104_KEY_LEN) {
+				sms_log(mac_ctx, LOGW,
+					FL("Invalid WEP104 keylength [= %d]"),
+					set_key->keyLength);
+				*enqueue_cmd = false;
+				return CDF_STATUS_E_INVAL;
+			}
+
+			set_key_cmd->u.setKeyCmd.keyLength = CSR_WEP104_KEY_LEN;
+			cdf_mem_copy(set_key_cmd->u.setKeyCmd.Key, set_key->Key,
+				     CSR_WEP104_KEY_LEN);
+		}
+		*enqueue_cmd = true;
+		break;
+	case eCSR_ENCRYPT_TYPE_TKIP:
+		if (set_key->keyLength < CSR_TKIP_KEY_LEN) {
+			sms_log(mac_ctx, LOGW,
+				FL("Invalid TKIP keylength [= %d]"),
+				set_key->keyLength);
+			*enqueue_cmd = false;
+			return CDF_STATUS_E_INVAL;
+		}
+		set_key_cmd->u.setKeyCmd.keyLength = CSR_TKIP_KEY_LEN;
+		cdf_mem_copy(set_key_cmd->u.setKeyCmd.Key, set_key->Key,
+			     CSR_TKIP_KEY_LEN);
+		*enqueue_cmd = true;
+		break;
+	case eCSR_ENCRYPT_TYPE_AES:
+		if (set_key->keyLength < CSR_AES_KEY_LEN) {
+			sms_log(mac_ctx, LOGW,
+				FL("Invalid AES/CCMP keylength [= %d]"),
+				set_key->keyLength);
+			*enqueue_cmd = false;
+			return CDF_STATUS_E_INVAL;
+		}
+		set_key_cmd->u.setKeyCmd.keyLength = CSR_AES_KEY_LEN;
+		cdf_mem_copy(set_key_cmd->u.setKeyCmd.Key, set_key->Key,
+			     CSR_AES_KEY_LEN);
+		*enqueue_cmd = true;
+		break;
+#ifdef FEATURE_WLAN_WAPI
+	case eCSR_ENCRYPT_TYPE_WPI:
+		if (set_key->keyLength < CSR_WAPI_KEY_LEN) {
+			sms_log(mac_ctx, LOGW,
+				FL("Invalid WAPI keylength [= %d]"),
+				set_key->keyLength);
+			*enqueue_cmd = false;
+			return CDF_STATUS_E_INVAL;
+		}
+		set_key_cmd->u.setKeyCmd.keyLength = CSR_WAPI_KEY_LEN;
+		cdf_mem_copy(set_key_cmd->u.setKeyCmd.Key, set_key->Key,
+			     CSR_WAPI_KEY_LEN);
+		if (session->pCurRoamProfile) {
+			session->pCurRoamProfile->negotiatedUCEncryptionType =
+				eCSR_ENCRYPT_TYPE_WPI;
+		} else {
+			sms_log(mac_ctx, LOGW,
+				FL("pCurRoamProfile is NULL."));
+			*enqueue_cmd = false;
+			return CDF_STATUS_E_INVAL;
+		}
+		*enqueue_cmd = true;
+		break;
+#endif /* FEATURE_WLAN_WAPI */
+#ifdef FEATURE_WLAN_ESE
+	case eCSR_ENCRYPT_TYPE_KRK:
+		/* no need to enqueue KRK key request, since they are local */
+		*enqueue_cmd = false;
+		if (set_key->keyLength < CSR_KRK_KEY_LEN) {
+			sms_log(mac_ctx, LOGW,
+				FL("Invalid KRK keylength [= %d]"),
+				set_key->keyLength);
+			return CDF_STATUS_E_INVAL;
+		}
+		cdf_mem_copy(session->eseCckmInfo.krk, set_key->Key,
+			     CSR_KRK_KEY_LEN);
+		session->eseCckmInfo.reassoc_req_num = 1;
+		session->eseCckmInfo.krk_plumbed = true;
+		break;
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	case eCSR_ENCRYPT_TYPE_BTK:
+		/* no need to enqueue KRK key request, since they are local */
+		*enqueue_cmd = false;
+		if (set_key->keyLength < SIR_BTK_KEY_LEN) {
+			sms_log(mac_ctx, LOGW,
+				FL("LFR3:Invalid BTK keylength [= %d]"),
+				set_key->keyLength);
+			return CDF_STATUS_E_INVAL;
+		}
+		cdf_mem_copy(session->eseCckmInfo.btk, set_key->Key,
+			     SIR_BTK_KEY_LEN);
+		break;
+#endif
+#endif /* FEATURE_WLAN_ESE */
+#ifdef WLAN_FEATURE_11W
+	/* Check for 11w BIP */
+	case eCSR_ENCRYPT_TYPE_AES_CMAC:
+		if (set_key->keyLength < CSR_AES_KEY_LEN) {
+			sms_log(mac_ctx, LOGW,
+				FL("Invalid AES/CCMP keylength [= %d]"),
+				set_key->keyLength);
+			*enqueue_cmd = false;
+			return CDF_STATUS_E_INVAL;
+		}
+		set_key_cmd->u.setKeyCmd.keyLength = CSR_AES_KEY_LEN;
+		cdf_mem_copy(set_key_cmd->u.setKeyCmd.Key, set_key->Key,
+			     CSR_AES_KEY_LEN);
+		*enqueue_cmd = true;
+		break;
+#endif /* WLAN_FEATURE_11W */
+	default:
+		/* for open security also we want to enqueue command */
+		*enqueue_cmd = true;
+		return CDF_STATUS_SUCCESS;
+	} /* end of switch */
+	return CDF_STATUS_SUCCESS;
+}
+
+
+static CDF_STATUS csr_roam_issue_set_key_command(tpAniSirGlobal pMac,
+						 uint32_t sessionId,
+						 tCsrRoamSetKey *pSetKey,
+						 uint32_t roamId)
+{
+	CDF_STATUS status = CDF_STATUS_E_INVAL;
+	bool enqueue_cmd = true;
+	tSmeCmd *pCommand = NULL;
+#if defined(FEATURE_WLAN_ESE) || defined (FEATURE_WLAN_WAPI)
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+	if (NULL == pSession) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+			  FL("session %d not found"), sessionId);
+		return CDF_STATUS_E_FAILURE;
+	}
+#endif /* FEATURE_WLAN_ESE */
+
+	pCommand = csr_get_command_buffer(pMac);
+	if (NULL == pCommand) {
+		sms_log(pMac, LOGE, FL(" fail to get command buffer"));
+		return CDF_STATUS_E_RESOURCES;
+	}
+	cdf_mem_zero(pCommand, sizeof(tSmeCmd));
+	pCommand->command = eSmeCommandSetKey;
+	pCommand->sessionId = (uint8_t) sessionId;
+	/*
+	 * following function will validate the key length, Adjust if too long.
+	 * for static WEP the keys are not set thru' SetContextReq
+	 *
+	 * it will update bool enqueue_cmd, to false if some error has occured
+	 * key are local. enqueue sme command only if enqueue_cmd is true
+	 * status is indication of success or failure and will be returned to
+	 * called of current function if command is not enqueued due to key req
+	 * being local
+	 */
+	status = csr_update_key_cmd(pMac, pSession, pSetKey,
+				    pCommand, &enqueue_cmd);
+	if (enqueue_cmd) {
+		pCommand->u.setKeyCmd.roamId = roamId;
+		pCommand->u.setKeyCmd.encType = pSetKey->encType;
+		pCommand->u.setKeyCmd.keyDirection = pSetKey->keyDirection;
+		cdf_mem_copy(&pCommand->u.setKeyCmd.peerMac, &pSetKey->peerMac,
+			     sizeof(struct cdf_mac_addr));
+		/* 0 for supplicant */
+		pCommand->u.setKeyCmd.paeRole = pSetKey->paeRole;
+		pCommand->u.setKeyCmd.keyId = pSetKey->keyId;
+		cdf_mem_copy(pCommand->u.setKeyCmd.keyRsc, pSetKey->keyRsc,
+			     CSR_MAX_RSC_LEN);
+		/*
+		 * Always put set key to the head of the Q because it is the
+		 * only thing to get executed in case of WT_KEY state
+		 */
+
+		status = csr_queue_sme_command(pMac, pCommand, true);
+		if (!CDF_IS_STATUS_SUCCESS(status)) {
+			sms_log(pMac, LOGE,
+				FL("fail to send message status = %d"), status);
+			/* update to false so that command can be freed */
+			enqueue_cmd = false;
+		}
+	}
+
+	/*
+	 * Free the command if enqueue_cmd == false:
+	 * this means that command was not enqueued because either there has
+	 * been a failure, or it is a "local" operation like the set ESE CCKM
+	 * KRK key.
+	 */
+	if (false == enqueue_cmd)
+		csr_release_command_set_key(pMac, pCommand);
+
+	return status;
+}
+
+CDF_STATUS csr_roam_process_set_key_command(tpAniSirGlobal pMac, tSmeCmd *pCommand)
+{
+	CDF_STATUS status;
+	uint8_t numKeys = (pCommand->u.setKeyCmd.keyLength) ? 1 : 0;
+	tAniEdType edType =
+		csr_translate_encrypt_type_to_ed_type(pCommand->u.setKeyCmd.encType);
+	bool fUnicast =
+		(pCommand->u.setKeyCmd.peerMac[0] == 0xFF) ? false : true;
+	uint32_t sessionId = pCommand->sessionId;
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+	WLAN_HOST_DIAG_EVENT_DEF(setKeyEvent,
+				 host_event_wlan_security_payload_type);
+
+	if (NULL == pSession) {
+		sms_log(pMac, LOGE, FL("  session %d not found "), sessionId);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	if (eSIR_ED_NONE != edType) {
+		cdf_mem_set(&setKeyEvent,
+			    sizeof(host_event_wlan_security_payload_type), 0);
+		if (*((uint8_t *) &pCommand->u.setKeyCmd.peerMac) & 0x01) {
+			setKeyEvent.eventId = WLAN_SECURITY_EVENT_SET_GTK_REQ;
+			setKeyEvent.encryptionModeMulticast =
+				(uint8_t) diag_enc_type_from_csr_type(pCommand->u.
+								      setKeyCmd.encType);
+			setKeyEvent.encryptionModeUnicast =
+				(uint8_t) diag_enc_type_from_csr_type(pSession->
+								      connectedProfile.
+								      EncryptionType);
+		} else {
+			setKeyEvent.eventId = WLAN_SECURITY_EVENT_SET_PTK_REQ;
+			setKeyEvent.encryptionModeUnicast =
+				(uint8_t) diag_enc_type_from_csr_type(pCommand->u.
+								      setKeyCmd.encType);
+			setKeyEvent.encryptionModeMulticast =
+				(uint8_t) diag_enc_type_from_csr_type(pSession->
+								      connectedProfile.
+								      mcEncryptionType);
+		}
+		cdf_mem_copy(setKeyEvent.bssid,
+			     pSession->connectedProfile.bssid.bytes,
+			     CDF_MAC_ADDR_SIZE);
+		if (CSR_IS_ENC_TYPE_STATIC(pCommand->u.setKeyCmd.encType)) {
+			uint32_t defKeyId;
+			/* It has to be static WEP here */
+			if (IS_SIR_STATUS_SUCCESS
+				    (wlan_cfg_get_int
+					    (pMac, WNI_CFG_WEP_DEFAULT_KEYID, &defKeyId))) {
+				setKeyEvent.keyId = (uint8_t) defKeyId;
+			}
+		} else {
+			setKeyEvent.keyId = pCommand->u.setKeyCmd.keyId;
+		}
+		setKeyEvent.authMode =
+			(uint8_t) diag_auth_type_from_csr_type(pSession->
+							       connectedProfile.
+							       AuthType);
+		WLAN_HOST_DIAG_EVENT_REPORT(&setKeyEvent, EVENT_WLAN_SECURITY);
+	}
+#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
+	if (csr_is_set_key_allowed(pMac, sessionId)) {
+		status = csr_send_mb_set_context_req_msg(pMac, sessionId,
+							 (uint8_t *) &pCommand->u.
+							 setKeyCmd.peerMac, numKeys,
+							 edType, fUnicast,
+							 pCommand->u.setKeyCmd.
+							 keyDirection,
+							 pCommand->u.setKeyCmd.keyId,
+							 pCommand->u.setKeyCmd.
+							 keyLength,
+							 pCommand->u.setKeyCmd.Key,
+							 pCommand->u.setKeyCmd.
+							 paeRole,
+							 pCommand->u.setKeyCmd.
+							 keyRsc);
+	} else {
+		sms_log(pMac, LOGW, FL(" cannot process not connected"));
+		/* Set this status so the error handling take care of the case. */
+		status = CDF_STATUS_CSR_WRONG_STATE;
+	}
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		sms_log(pMac, LOGE, FL("  error status %d"), status);
+		csr_roam_call_callback(pMac, sessionId, NULL,
+				       pCommand->u.setKeyCmd.roamId,
+				       eCSR_ROAM_SET_KEY_COMPLETE,
+				       eCSR_ROAM_RESULT_FAILURE);
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+		if (eSIR_ED_NONE != edType) {
+			if (*((uint8_t *) &pCommand->u.setKeyCmd.peerMac) &
+			    0x01) {
+				setKeyEvent.eventId =
+					WLAN_SECURITY_EVENT_SET_GTK_RSP;
+			} else {
+				setKeyEvent.eventId =
+					WLAN_SECURITY_EVENT_SET_PTK_RSP;
+			}
+			setKeyEvent.status = WLAN_SECURITY_STATUS_FAILURE;
+			WLAN_HOST_DIAG_EVENT_REPORT(&setKeyEvent,
+						    EVENT_WLAN_SECURITY);
+		}
+#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
+	}
+	return status;
+}
+
+CDF_STATUS csr_roam_set_key(tpAniSirGlobal pMac, uint32_t sessionId,
+			    tCsrRoamSetKey *pSetKey, uint32_t roamId)
+{
+	CDF_STATUS status;
+
+	if (!csr_is_set_key_allowed(pMac, sessionId)) {
+		status = CDF_STATUS_CSR_WRONG_STATE;
+	} else {
+		status =
+			csr_roam_issue_set_key_command(pMac, sessionId, pSetKey, roamId);
+	}
+	return status;
+}
+
+/*
+   Prepare a filter base on a profile for parsing the scan results.
+   Upon successful return, caller MUST call csr_free_scan_filter on
+   pScanFilter when it is done with the filter.
+ */
+CDF_STATUS
+csr_roam_prepare_filter_from_profile(tpAniSirGlobal mac_ctx,
+				     tCsrRoamProfile *profile,
+				     tCsrScanResultFilter *scan_fltr)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	uint32_t size = 0;
+	uint8_t idx = 0;
+	tCsrChannelInfo *fltr_ch_info = &scan_fltr->ChannelInfo;
+	tCsrChannelInfo *profile_ch_info = &profile->ChannelInfo;
+	struct roam_ext_params *roam_params;
+	uint8_t i;
+
+	roam_params = &mac_ctx->roam.configParam.roam_params;
+
+	if (profile->BSSIDs.numOfBSSIDs) {
+		size = sizeof(struct cdf_mac_addr) * profile->BSSIDs.numOfBSSIDs;
+		scan_fltr->BSSIDs.bssid = cdf_mem_malloc(size);
+		if (NULL == scan_fltr->BSSIDs.bssid) {
+			status = CDF_STATUS_E_NOMEM;
+			goto free_filter;
+		}
+		scan_fltr->BSSIDs.numOfBSSIDs = profile->BSSIDs.numOfBSSIDs;
+		cdf_mem_copy(scan_fltr->BSSIDs.bssid,
+			     profile->BSSIDs.bssid, size);
+	}
+
+	if (profile->SSIDs.numOfSSIDs) {
+		if (!CSR_IS_WDS_STA(profile)) {
+			scan_fltr->SSIDs.numOfSSIDs = profile->SSIDs.numOfSSIDs;
+		} else {
+			/*
+			 * For WDS station we always use idx 1 for self SSID.
+			 * Index 0 for peer's SSID that we want to join
+			 */
+			scan_fltr->SSIDs.numOfSSIDs = 1;
+		}
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
+			FL("No of Allowed List:%d"),
+			roam_params->num_ssid_allowed_list);
+		if (scan_fltr->scan_filter_for_roam
+			&& roam_params->num_ssid_allowed_list) {
+			scan_fltr->SSIDs.numOfSSIDs =
+				roam_params->num_ssid_allowed_list;
+			size = sizeof(tCsrSSIDInfo) *
+				scan_fltr->SSIDs.numOfSSIDs;
+			scan_fltr->SSIDs.SSIDList = cdf_mem_malloc(size);
+			if (NULL == scan_fltr->SSIDs.SSIDList)
+				status = CDF_STATUS_E_FAILURE;
+			else
+				status = CDF_STATUS_SUCCESS;
+			if (!CDF_IS_STATUS_SUCCESS(status))
+				goto free_filter;
+			for  (i = 0;
+				i < roam_params->num_ssid_allowed_list;
+				i++) {
+				cdf_mem_copy((void *)
+				    scan_fltr->SSIDs.SSIDList[i].SSID.ssId,
+				    roam_params->ssid_allowed_list[i].ssId,
+				    roam_params->ssid_allowed_list[i].length);
+				scan_fltr->SSIDs.SSIDList[i].SSID.length =
+				    roam_params->ssid_allowed_list[i].length;
+				scan_fltr->SSIDs.SSIDList[i].handoffPermitted =
+					1;
+				scan_fltr->SSIDs.SSIDList[i].ssidHidden = 0;
+			}
+		} else {
+			size = sizeof(tCsrSSIDInfo) *
+				profile->SSIDs.numOfSSIDs;
+			scan_fltr->SSIDs.SSIDList = cdf_mem_malloc(size);
+			if (NULL == scan_fltr->SSIDs.SSIDList) {
+				status = CDF_STATUS_E_NOMEM;
+				goto free_filter;
+			}
+			cdf_mem_copy(scan_fltr->SSIDs.SSIDList,
+					profile->SSIDs.SSIDList, size);
+		}
+	}
+
+	if (!profile_ch_info->ChannelList
+	    || (profile_ch_info->ChannelList[0] == 0)) {
+		fltr_ch_info->numOfChannels = 0;
+		fltr_ch_info->ChannelList = NULL;
+	} else if (profile_ch_info->numOfChannels) {
+		fltr_ch_info->numOfChannels = 0;
+		fltr_ch_info->ChannelList =
+			cdf_mem_malloc(sizeof(*(fltr_ch_info->ChannelList)) *
+				       profile_ch_info->numOfChannels);
+		if (NULL == fltr_ch_info->ChannelList) {
+			status = CDF_STATUS_E_NOMEM;
+			goto free_filter;
+		}
+
+		for (idx = 0; idx < profile_ch_info->numOfChannels; idx++) {
+			if (csr_roam_is_channel_valid(mac_ctx,
+				profile_ch_info->ChannelList[idx])) {
+				fltr_ch_info->
+				ChannelList[fltr_ch_info->numOfChannels]
+					= profile_ch_info->ChannelList[idx];
+				fltr_ch_info->numOfChannels++;
+			} else {
+				sms_log(mac_ctx, LOG1,
+					FL("Channel (%d) is invalid"),
+					profile_ch_info->ChannelList[idx]);
+			}
+		}
+	} else {
+		sms_log(mac_ctx, LOGE, FL("Channel list empty"));
+		status = CDF_STATUS_E_FAILURE;
+		goto free_filter;
+	}
+	scan_fltr->uapsd_mask = profile->uapsd_mask;
+	scan_fltr->authType = profile->AuthType;
+	scan_fltr->EncryptionType = profile->EncryptionType;
+	scan_fltr->mcEncryptionType = profile->mcEncryptionType;
+	scan_fltr->BSSType = profile->BSSType;
+	scan_fltr->phyMode = profile->phyMode;
+#ifdef FEATURE_WLAN_WAPI
+	/*
+	 * check if user asked for WAPI with 11n or auto mode, in that
+	 * case modify the phymode to 11g
+	 */
+	if (csr_is_profile_wapi(profile)) {
+		if (scan_fltr->phyMode & eCSR_DOT11_MODE_11n)
+			scan_fltr->phyMode &= ~eCSR_DOT11_MODE_11n;
+		if (scan_fltr->phyMode & eCSR_DOT11_MODE_AUTO)
+			scan_fltr->phyMode &= ~eCSR_DOT11_MODE_AUTO;
+		if (!scan_fltr->phyMode)
+			scan_fltr->phyMode = eCSR_DOT11_MODE_11g;
+	}
+#endif /* FEATURE_WLAN_WAPI */
+	/*Save the WPS info */
+	scan_fltr->bWPSAssociation = profile->bWPSAssociation;
+	scan_fltr->bOSENAssociation = profile->bOSENAssociation;
+	if (profile->countryCode[0]) {
+		/*
+		 * This causes the matching function to use countryCode as one
+		 * of the criteria.
+		 */
+		cdf_mem_copy(scan_fltr->countryCode, profile->countryCode,
+			     WNI_CFG_COUNTRY_CODE_LEN);
+	}
+#ifdef WLAN_FEATURE_VOWIFI_11R
+	if (profile->MDID.mdiePresent) {
+		scan_fltr->MDID.mdiePresent = 1;
+		scan_fltr->MDID.mobilityDomain = profile->MDID.mobilityDomain;
+	}
+#endif
+
+#ifdef WLAN_FEATURE_11W
+	/* Management Frame Protection */
+	scan_fltr->MFPEnabled = profile->MFPEnabled;
+	scan_fltr->MFPRequired = profile->MFPRequired;
+	scan_fltr->MFPCapable = profile->MFPCapable;
+#endif
+	scan_fltr->csrPersona = profile->csrPersona;
+
+free_filter:
+	if (!CDF_IS_STATUS_SUCCESS(status))
+		csr_free_scan_filter(mac_ctx, scan_fltr);
+
+	return status;
+}
+
+bool csr_roam_issue_wm_status_change(tpAniSirGlobal pMac, uint32_t sessionId,
+				     eCsrRoamWmStatusChangeTypes Type,
+				     tSirSmeRsp *pSmeRsp)
+{
+	bool fCommandQueued = false;
+	tSmeCmd *pCommand;
+	do {
+		/* Validate the type is ok... */
+		if ((eCsrDisassociated != Type)
+		    && (eCsrDeauthenticated != Type))
+			break;
+		pCommand = csr_get_command_buffer(pMac);
+		if (!pCommand) {
+			sms_log(pMac, LOGE, FL(" fail to get command buffer"));
+			break;
+		}
+		/* Change the substate in case it is waiting for key */
+		if (CSR_IS_WAIT_FOR_KEY(pMac, sessionId)) {
+			csr_roam_stop_wait_for_key_timer(pMac);
+			csr_roam_substate_change(pMac, eCSR_ROAM_SUBSTATE_NONE,
+						 sessionId);
+		}
+		pCommand->command = eSmeCommandWmStatusChange;
+		pCommand->sessionId = (uint8_t) sessionId;
+		pCommand->u.wmStatusChangeCmd.Type = Type;
+		if (eCsrDisassociated == Type) {
+			cdf_mem_copy(&pCommand->u.wmStatusChangeCmd.u.
+				     DisassocIndMsg, pSmeRsp,
+				     sizeof(pCommand->u.wmStatusChangeCmd.u.
+					    DisassocIndMsg));
+		} else {
+			cdf_mem_copy(&pCommand->u.wmStatusChangeCmd.u.
+				     DeauthIndMsg, pSmeRsp,
+				     sizeof(pCommand->u.wmStatusChangeCmd.u.
+					    DeauthIndMsg));
+		}
+		if (CDF_IS_STATUS_SUCCESS
+			    (csr_queue_sme_command(pMac, pCommand, true))) {
+			fCommandQueued = true;
+		} else {
+			sms_log(pMac, LOGE, FL(" fail to send message "));
+			csr_release_command_wm_status_change(pMac, pCommand);
+		}
+
+		/* AP has issued Dissac/Deauth, Set the operating mode value to configured value */
+		csr_set_default_dot11_mode(pMac);
+	} while (0);
+	return fCommandQueued;
+}
+
+static CDF_STATUS csr_send_snr_request(void *pGetRssiReq)
+{
+	void *wma_handle;
+
+	wma_handle = cds_get_context(CDF_MODULE_ID_WMA);
+	if (!wma_handle) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+				"wma_handle is NULL");
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	if (CDF_STATUS_SUCCESS !=
+		wma_send_snr_request(wma_handle, pGetRssiReq)) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+			"Failed to Trigger wma stats request");
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	/* dont send success, otherwise call back
+	 * will released with out values */
+	return CDF_STATUS_E_BUSY;
+}
+
+static void csr_update_rssi(tpAniSirGlobal pMac, void *pMsg)
+{
+	int8_t rssi = 0;
+	tAniGetRssiReq *pGetRssiReq = (tAniGetRssiReq *) pMsg;
+	CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
+	if (pGetRssiReq) {
+		if (NULL != pGetRssiReq->p_cds_context) {
+			cdf_status = csr_send_snr_request(pGetRssiReq);
+		} else {
+			sms_log(pMac, LOGE,
+				FL("pGetRssiReq->p_cds_context is NULL"));
+			return;
+		}
+
+		if (NULL != pGetRssiReq->rssiCallback) {
+			if (cdf_status != CDF_STATUS_E_BUSY)
+				((tCsrRssiCallback) (pGetRssiReq->rssiCallback))
+					(rssi, pGetRssiReq->staId,
+					pGetRssiReq->pDevContext);
+			else
+				sms_log(pMac, LOG1,
+					FL
+						("rssi request is posted. waiting for reply"));
+		} else {
+			sms_log(pMac, LOGE,
+				FL("pGetRssiReq->rssiCallback is NULL"));
+			return;
+		}
+	} else {
+		sms_log(pMac, LOGE, FL("pGetRssiReq is NULL"));
+	}
+	return;
+
+}
+
+static void csr_update_snr(tpAniSirGlobal pMac, void *pMsg)
+{
+	tAniGetSnrReq *pGetSnrReq = (tAniGetSnrReq *) pMsg;
+
+	if (pGetSnrReq) {
+		if (CDF_STATUS_SUCCESS != wma_get_snr(pGetSnrReq)) {
+			sms_log(pMac, LOGE, FL("Error in wma_get_snr"));
+			return;
+		}
+
+	} else {
+		sms_log(pMac, LOGE, FL("pGetSnrReq is NULL"));
+	}
+	return;
+}
+
+#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
+void csr_tsm_stats_rsp_processor(tpAniSirGlobal pMac, void *pMsg)
+{
+	tAniGetTsmStatsRsp *pTsmStatsRsp = (tAniGetTsmStatsRsp *) pMsg;
+
+	if (NULL != pTsmStatsRsp) {
+		/* Get roam Rssi request is backed up and passed back to the response,
+		   Extract the request message to fetch callback */
+		tpAniGetTsmStatsReq reqBkp
+			= (tAniGetTsmStatsReq *) pTsmStatsRsp->tsmStatsReq;
+
+		if (NULL != reqBkp) {
+			if (NULL != reqBkp->tsmStatsCallback) {
+				((tCsrTsmStatsCallback)
+				 (reqBkp->tsmStatsCallback))(pTsmStatsRsp->
+							     tsmMetrics,
+							     pTsmStatsRsp->
+							     staId,
+							     reqBkp->
+							     pDevContext);
+				reqBkp->tsmStatsCallback = NULL;
+			}
+			cdf_mem_free(reqBkp);
+			pTsmStatsRsp->tsmStatsReq = NULL;
+		} else {
+			sms_log(pMac, LOGE, FL("reqBkp is NULL"));
+			if (NULL != reqBkp) {
+				cdf_mem_free(reqBkp);
+				pTsmStatsRsp->tsmStatsReq = NULL;
+			}
+		}
+	} else {
+		sms_log(pMac, LOGE, FL("pTsmStatsRsp is NULL"));
+	}
+	return;
+}
+
+void csr_send_ese_adjacent_ap_rep_ind(tpAniSirGlobal pMac, tCsrRoamSession *pSession)
+{
+	uint32_t roamTS2 = 0;
+	tCsrRoamInfo roamInfo;
+	tpPESession pSessionEntry = NULL;
+	uint8_t sessionId = CSR_SESSION_ID_INVALID;
+
+	if (NULL == pSession) {
+		sms_log(pMac, LOGE, FL("pSession is NULL"));
+		return;
+	}
+
+	roamTS2 = cdf_mc_timer_get_system_time();
+	roamInfo.tsmRoamDelay = roamTS2 - pSession->roamTS1;
+	sms_log(pMac, LOG1, "Bssid(" MAC_ADDRESS_STR ") Roaming Delay(%u ms)",
+		MAC_ADDR_ARRAY(pSession->connectedProfile.bssid.bytes),
+		roamInfo.tsmRoamDelay);
+
+	pSessionEntry = pe_find_session_by_bssid(pMac,
+					 pSession->connectedProfile.bssid.bytes,
+					 &sessionId);
+	if (NULL == pSessionEntry) {
+		sms_log(pMac, LOGE, FL("session %d not found"), sessionId);
+		return;
+	}
+
+	pSessionEntry->eseContext.tsm.tsmMetrics.RoamingDly
+		= roamInfo.tsmRoamDelay;
+
+	csr_roam_call_callback(pMac, pSession->sessionId, &roamInfo,
+			       0, eCSR_ROAM_ESE_ADJ_AP_REPORT_IND, 0);
+}
+#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
+
+CDF_STATUS csr_send_reset_ap_caps_changed(tpAniSirGlobal pMac, tSirMacAddr *bssId)
+{
+	tpSirResetAPCapsChange pMsg;
+	uint16_t len;
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+
+	/* Create the message and send to lim */
+	len = sizeof(tSirResetAPCapsChange);
+	pMsg = cdf_mem_malloc(len);
+	if (NULL == pMsg)
+		status = CDF_STATUS_E_NOMEM;
+	else
+		status = CDF_STATUS_SUCCESS;
+	if (CDF_IS_STATUS_SUCCESS(status)) {
+		cdf_mem_set(pMsg, sizeof(tSirResetAPCapsChange), 0);
+		pMsg->messageType = eWNI_SME_RESET_AP_CAPS_CHANGED;
+		pMsg->length = len;
+		cdf_mem_copy(pMsg->bssId, bssId, sizeof(tSirMacAddr));
+		sms_log(pMac, LOG1,
+			FL("CSR reset caps change for Bssid= " MAC_ADDRESS_STR),
+			MAC_ADDR_ARRAY(pMsg->bssId));
+		status = cds_send_mb_message_to_mac(pMsg);
+	} else {
+		sms_log(pMac, LOGE, FL("Memory allocation failed\n"));
+	}
+	return status;
+}
+
+static void
+csr_roam_chk_lnk_assoc_ind(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr)
+{
+	tCsrRoamSession *session;
+	uint32_t sessionId = CSR_SESSION_ID_INVALID;
+	CDF_STATUS status;
+	tCsrRoamInfo *roam_info_ptr = NULL;
+	tSirSmeAssocInd *pAssocInd;
+	tCsrRoamInfo roam_info;
+	cdf_mem_set(&roam_info, sizeof(roam_info), 0);
+
+	sms_log(mac_ctx, LOG1, FL("Receive WNI_SME_ASSOC_IND from SME"));
+	pAssocInd = (tSirSmeAssocInd *) msg_ptr;
+	status = csr_roam_get_session_id_from_bssid(mac_ctx,
+				(struct cdf_mac_addr *) pAssocInd->bssId, &sessionId);
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		sms_log(mac_ctx, LOG1,
+			FL("Couldn't find session_id for given BSSID"));
+		return;
+	}
+	session = CSR_GET_SESSION(mac_ctx, sessionId);
+	if (!session) {
+		sms_log(mac_ctx, LOGE, FL("session %d not found"), sessionId);
+		return;
+	}
+	roam_info_ptr = &roam_info;
+	/* Required for indicating the frames to upper layer */
+	roam_info_ptr->assocReqLength = pAssocInd->assocReqLength;
+	roam_info_ptr->assocReqPtr = pAssocInd->assocReqPtr;
+	roam_info_ptr->beaconPtr = pAssocInd->beaconPtr;
+	roam_info_ptr->beaconLength = pAssocInd->beaconLength;
+	roam_info_ptr->statusCode = eSIR_SME_SUCCESS;
+	roam_info_ptr->u.pConnectedProfile = &session->connectedProfile;
+	roam_info_ptr->staId = (uint8_t) pAssocInd->staId;
+	roam_info_ptr->rsnIELen = (uint8_t) pAssocInd->rsnIE.length;
+	roam_info_ptr->prsnIE = pAssocInd->rsnIE.rsnIEdata;
+#ifdef FEATURE_WLAN_WAPI
+	roam_info_ptr->wapiIELen = (uint8_t) pAssocInd->wapiIE.length;
+	roam_info_ptr->pwapiIE = pAssocInd->wapiIE.wapiIEdata;
+#endif
+	roam_info_ptr->addIELen = (uint8_t) pAssocInd->addIE.length;
+	roam_info_ptr->paddIE = pAssocInd->addIE.addIEdata;
+	cdf_mem_copy(roam_info_ptr->peerMac.bytes,
+		     pAssocInd->peerMacAddr,
+		     sizeof(tSirMacAddr));
+	cdf_mem_copy(roam_info_ptr->bssid.bytes,
+		     pAssocInd->bssId,
+		     sizeof(struct cdf_mac_addr));
+	roam_info_ptr->wmmEnabledSta = pAssocInd->wmmEnabledSta;
+	roam_info_ptr->timingMeasCap = pAssocInd->timingMeasCap;
+	cdf_mem_copy(&roam_info_ptr->chan_info,
+		     &pAssocInd->chan_info,
+		     sizeof(tSirSmeChanInfo));
+	if (CSR_IS_WDS_AP(roam_info_ptr->u.pConnectedProfile))
+		status = csr_roam_call_callback(mac_ctx, sessionId,
+					roam_info_ptr, 0, eCSR_ROAM_WDS_IND,
+					eCSR_ROAM_RESULT_WDS_ASSOCIATION_IND);
+	if (CSR_IS_INFRA_AP(roam_info_ptr->u.pConnectedProfile)) {
+		if (session->pCurRoamProfile &&
+		    CSR_IS_ENC_TYPE_STATIC(
+			session->pCurRoamProfile->negotiatedUCEncryptionType)) {
+			/* NO keys... these key parameters don't matter. */
+			csr_roam_issue_set_context_req(mac_ctx, sessionId,
+			session->pCurRoamProfile->negotiatedUCEncryptionType,
+			session->pConnectBssDesc,
+			&(roam_info_ptr->peerMac.bytes),
+			false, true, eSIR_TX_RX, 0, 0, NULL, 0);
+			roam_info_ptr->fAuthRequired = false;
+		} else {
+			roam_info_ptr->fAuthRequired = true;
+		}
+		status = csr_roam_call_callback(mac_ctx, sessionId,
+					roam_info_ptr, 0, eCSR_ROAM_INFRA_IND,
+					eCSR_ROAM_RESULT_INFRA_ASSOCIATION_IND);
+		if (!CDF_IS_STATUS_SUCCESS(status))
+			/* Refused due to Mac filtering */
+			roam_info_ptr->statusCode = eSIR_SME_ASSOC_REFUSED;
+	}
+
+	/* Send Association completion message to PE */
+	status = csr_send_assoc_cnf_msg(mac_ctx, pAssocInd, status);
+	/*
+	 * send a message to CSR itself just to avoid the EAPOL frames going
+	 * OTA before association response
+	 */
+	if (CSR_IS_WDS_AP(roam_info_ptr->u.pConnectedProfile)) {
+		status = csr_send_assoc_ind_to_upper_layer_cnf_msg(mac_ctx,
+						pAssocInd, status, sessionId);
+	} else if (CSR_IS_INFRA_AP(roam_info_ptr->u.pConnectedProfile)
+	    && (roam_info_ptr->statusCode != eSIR_SME_ASSOC_REFUSED)) {
+		roam_info_ptr->fReassocReq = pAssocInd->reassocReq;
+		status = csr_send_assoc_ind_to_upper_layer_cnf_msg(mac_ctx,
+						pAssocInd, status, sessionId);
+	}
+}
+
+static void
+csr_roam_chk_lnk_disassoc_ind(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr)
+{
+	tCsrRoamSession *session;
+	uint32_t sessionId = CSR_SESSION_ID_INVALID;
+	CDF_STATUS status;
+	tCsrRoamInfo *roam_info_ptr = NULL;
+	tSirSmeDisassocInd *pDisassocInd;
+	tSmeCmd cmd;
+	tCsrRoamInfo roam_info;
+
+	/*
+	 * Check if AP dis-associated us because of MIC failure. If so,
+	 * then we need to take action immediately and not wait till the
+	 * the WmStatusChange requests is pushed and processed
+	 */
+	pDisassocInd = (tSirSmeDisassocInd *) msg_ptr;
+	cdf_mem_set(&roam_info, sizeof(roam_info), 0);
+	status = csr_roam_get_session_id_from_bssid(mac_ctx,
+				(struct cdf_mac_addr *) pDisassocInd->bssId, &sessionId);
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		sms_log(mac_ctx, LOGE, FL("Session Id not found for BSSID "
+			MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pDisassocInd->bssId));
+		return;
+	}
+
+	sms_log(mac_ctx, LOGE,
+		FL("DISASSOCIATION Indication from MAC for session %d "),
+		sessionId);
+	sms_log(mac_ctx, LOGE,
+		FL("DISASSOCIATION from peer =" MAC_ADDRESS_STR
+		   " " " reason = %d status = %d "),
+		MAC_ADDR_ARRAY(pDisassocInd->peerMacAddr),
+		pDisassocInd->reasonCode,
+		pDisassocInd->statusCode);
+	/*
+	 * If we are in neighbor preauth done state then on receiving
+	 * disassoc or deauth we dont roam instead we just disassoc
+	 * from current ap and then go to disconnected state
+	 * This happens for ESE and 11r FT connections ONLY.
+	 */
+#ifdef WLAN_FEATURE_VOWIFI_11R
+	if (csr_roam_is11r_assoc(mac_ctx, sessionId) &&
+	    (csr_neighbor_roam_state_preauth_done(mac_ctx, sessionId)))
+		csr_neighbor_roam_tranistion_preauth_done_to_disconnected(
+							mac_ctx, sessionId);
+#endif
+#ifdef FEATURE_WLAN_ESE
+	if (csr_roam_is_ese_assoc(mac_ctx, sessionId) &&
+	    (csr_neighbor_roam_state_preauth_done(mac_ctx, sessionId)))
+		csr_neighbor_roam_tranistion_preauth_done_to_disconnected(
+							mac_ctx, sessionId);
+#endif
+#ifdef FEATURE_WLAN_LFR
+	if (csr_roam_is_fast_roam_enabled(mac_ctx, sessionId) &&
+	    (csr_neighbor_roam_state_preauth_done(mac_ctx, sessionId)))
+		csr_neighbor_roam_tranistion_preauth_done_to_disconnected(
+							mac_ctx, sessionId);
+#endif
+	session = CSR_GET_SESSION(mac_ctx, sessionId);
+	if (!session) {
+		sms_log(mac_ctx, LOGE, FL("session %d not found"), sessionId);
+		return;
+	}
+	if (csr_is_conn_state_infra(mac_ctx, sessionId))
+		session->connectState = eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED;
+#ifndef WLAN_MDM_CODE_REDUCTION_OPT
+	sme_qos_csr_event_ind(mac_ctx, (uint8_t) sessionId,
+			      SME_QOS_CSR_DISCONNECT_IND, NULL);
+#endif
+	csr_roam_link_down(mac_ctx, sessionId);
+	csr_roam_issue_wm_status_change(mac_ctx, sessionId,
+					eCsrDisassociated, msg_ptr);
+	if (CSR_IS_INFRA_AP(&session->connectedProfile)) {
+		roam_info_ptr = &roam_info;
+		roam_info_ptr->statusCode = pDisassocInd->statusCode;
+		roam_info_ptr->reasonCode = pDisassocInd->reasonCode;
+		roam_info_ptr->u.pConnectedProfile = &session->connectedProfile;
+		roam_info_ptr->staId = (uint8_t) pDisassocInd->staId;
+		cdf_mem_copy(roam_info_ptr->peerMac.bytes,
+			     pDisassocInd->peerMacAddr,
+			     sizeof(tSirMacAddr));
+		cdf_mem_copy(&roam_info_ptr->bssid.bytes,
+			     pDisassocInd->bssId,
+			     sizeof(struct cdf_mac_addr));
+		status = csr_roam_call_callback(mac_ctx, sessionId,
+						roam_info_ptr, 0,
+						eCSR_ROAM_INFRA_IND,
+						eCSR_ROAM_RESULT_DISASSOC_IND);
+		/*
+		 * STA/P2P client got  disassociated so remove any pending
+		 * deauth commands in sme pending list
+		 */
+		cmd.command = eSmeCommandRoam;
+		cmd.sessionId = (uint8_t) sessionId;
+		cmd.u.roamCmd.roamReason = eCsrForcedDeauthSta;
+		cdf_mem_copy(cmd.u.roamCmd.peerMac,
+			     pDisassocInd->peerMacAddr,
+			     sizeof(tSirMacAddr));
+		csr_roam_remove_duplicate_command(mac_ctx, sessionId, &cmd,
+						  eCsrForcedDeauthSta);
+	}
+}
+
+static void
+csr_roam_chk_lnk_deauth_ind(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr)
+{
+	tCsrRoamSession *session;
+	uint32_t sessionId = CSR_SESSION_ID_INVALID;
+	CDF_STATUS status;
+	tCsrRoamInfo *roam_info_ptr = NULL;
+	tSirSmeDeauthInd *pDeauthInd;
+	tCsrRoamInfo roam_info;
+
+	cdf_mem_set(&roam_info, sizeof(roam_info), 0);
+	sms_log(mac_ctx, LOG1, FL("DEAUTHENTICATION Indication from MAC"));
+	pDeauthInd = (tpSirSmeDeauthInd) msg_ptr;
+	status = csr_roam_get_session_id_from_bssid(mac_ctx,
+						   (struct cdf_mac_addr *) pDeauthInd->
+						   bssId, &sessionId);
+	if (!CDF_IS_STATUS_SUCCESS(status))
+		return;
+	/* If we are in neighbor preauth done state then on receiving
+	 * disassoc or deauth we dont roam instead we just disassoc
+	 * from current ap and then go to disconnected state
+	 * This happens for ESE and 11r FT connections ONLY.
+	 */
+#ifdef WLAN_FEATURE_VOWIFI_11R
+	if (csr_roam_is11r_assoc(mac_ctx, sessionId) &&
+	    (csr_neighbor_roam_state_preauth_done(mac_ctx, sessionId)))
+		csr_neighbor_roam_tranistion_preauth_done_to_disconnected(
+							mac_ctx, sessionId);
+#endif
+#ifdef FEATURE_WLAN_ESE
+	if (csr_roam_is_ese_assoc(mac_ctx, sessionId) &&
+	    (csr_neighbor_roam_state_preauth_done(mac_ctx, sessionId)))
+		csr_neighbor_roam_tranistion_preauth_done_to_disconnected(
+							mac_ctx, sessionId);
+#endif
+#ifdef FEATURE_WLAN_LFR
+	if (csr_roam_is_fast_roam_enabled(mac_ctx, sessionId) &&
+	    (csr_neighbor_roam_state_preauth_done(mac_ctx, sessionId)))
+		csr_neighbor_roam_tranistion_preauth_done_to_disconnected(
+							mac_ctx, sessionId);
+#endif
+	session = CSR_GET_SESSION(mac_ctx, sessionId);
+	if (!session) {
+		sms_log(mac_ctx, LOGE, FL("session %d not found"), sessionId);
+		return;
+	}
+
+	if (csr_is_conn_state_infra(mac_ctx, sessionId))
+		session->connectState = eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED;
+#ifndef WLAN_MDM_CODE_REDUCTION_OPT
+	sme_qos_csr_event_ind(mac_ctx, (uint8_t) sessionId,
+			      SME_QOS_CSR_DISCONNECT_IND, NULL);
+#endif
+	csr_roam_link_down(mac_ctx, sessionId);
+	csr_roam_issue_wm_status_change(mac_ctx, sessionId,
+					eCsrDeauthenticated,
+					msg_ptr);
+	if (CSR_IS_INFRA_AP(&session->connectedProfile)) {
+		roam_info_ptr = &roam_info;
+		roam_info_ptr->statusCode = pDeauthInd->statusCode;
+		roam_info_ptr->reasonCode = pDeauthInd->reasonCode;
+		roam_info_ptr->u.pConnectedProfile = &session->connectedProfile;
+		roam_info_ptr->staId = (uint8_t) pDeauthInd->staId;
+		cdf_mem_copy(roam_info_ptr->peerMac.bytes,
+			     pDeauthInd->peerMacAddr,
+			     sizeof(tSirMacAddr));
+		cdf_mem_copy(&roam_info_ptr->bssid.bytes,
+			     pDeauthInd->bssId,
+			     sizeof(struct cdf_mac_addr));
+		status = csr_roam_call_callback(mac_ctx, sessionId,
+						roam_info_ptr, 0,
+						eCSR_ROAM_INFRA_IND,
+						eCSR_ROAM_RESULT_DEAUTH_IND);
+	}
+}
+
+static void
+csr_roam_chk_lnk_swt_ch_ind(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr)
+{
+	tCsrRoamSession *session;
+	uint32_t sessionId = CSR_SESSION_ID_INVALID;
+	CDF_STATUS status;
+	tpSirSmeSwitchChannelInd pSwitchChnInd;
+
+	/* in case of STA, the SWITCH_CHANNEL originates from its AP */
+	sms_log(mac_ctx, LOGW, FL("eWNI_SME_SWITCH_CHL_IND from SME"));
+	pSwitchChnInd = (tpSirSmeSwitchChannelInd) msg_ptr;
+	/* Update with the new channel id. The channel id is hidden in the
+	 * statusCode.
+	 */
+	status = csr_roam_get_session_id_from_bssid(mac_ctx,
+			(struct cdf_mac_addr *) pSwitchChnInd->bssId, &sessionId);
+	if (CDF_IS_STATUS_SUCCESS(status)) {
+		session = CSR_GET_SESSION(mac_ctx, sessionId);
+		if (!session) {
+			sms_log(mac_ctx, LOGE,
+				FL("session %d not found"), sessionId);
+			return;
+		}
+		session->connectedProfile.operationChannel =
+			(uint8_t) pSwitchChnInd->newChannelId;
+		if (session->pConnectBssDesc) {
+			session->pConnectBssDesc->channelId =
+				(uint8_t) pSwitchChnInd->newChannelId;
+		}
+	}
+}
+
+static void
+csr_roam_chk_lnk_deauth_rsp(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr)
+{
+	tCsrRoamSession *session;
+	uint32_t sessionId = CSR_SESSION_ID_INVALID;
+	CDF_STATUS status;
+	tCsrRoamInfo *roam_info_ptr = NULL;
+	tSirSmeDeauthRsp *pDeauthRsp = (tSirSmeDeauthRsp *) msg_ptr;
+	tCsrRoamInfo roam_info;
+
+	cdf_mem_set(&roam_info, sizeof(roam_info), 0);
+	sms_log(mac_ctx, LOGW, FL("eWNI_SME_DEAUTH_RSP from SME"));
+	sessionId = pDeauthRsp->sessionId;
+	if (!CSR_IS_SESSION_VALID(mac_ctx, sessionId))
+		return;
+	session = CSR_GET_SESSION(mac_ctx, sessionId);
+	if (CSR_IS_INFRA_AP(&session->connectedProfile)) {
+		roam_info_ptr = &roam_info;
+		roam_info_ptr->u.pConnectedProfile = &session->connectedProfile;
+		cdf_mem_copy(roam_info_ptr->peerMac.bytes,
+			     pDeauthRsp->peerMacAddr,
+			     sizeof(tSirMacAddr));
+		roam_info_ptr->reasonCode = eCSR_ROAM_RESULT_FORCED;
+		roam_info_ptr->statusCode = pDeauthRsp->statusCode;
+		status = csr_roam_call_callback(mac_ctx, sessionId,
+						roam_info_ptr, 0,
+						eCSR_ROAM_LOSTLINK,
+						eCSR_ROAM_RESULT_FORCED);
+	}
+}
+
+static void
+csr_roam_chk_lnk_disassoc_rsp(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr)
+{
+	tCsrRoamSession *session;
+	uint32_t sessionId = CSR_SESSION_ID_INVALID;
+	CDF_STATUS status;
+	tCsrRoamInfo *roam_info_ptr = NULL;
+	tCsrRoamInfo roam_info;
+	/*
+	 * session id is invalid here so cant use it to access the array
+	 * curSubstate as index
+	 */
+	tSirSmeDisassocRsp *pDisassocRsp = (tSirSmeDisassocRsp *) msg_ptr;
+
+	cdf_mem_set(&roam_info, sizeof(roam_info), 0);
+	sms_log(mac_ctx, LOGW, FL("eWNI_SME_DISASSOC_RSP from SME "));
+	sessionId = pDisassocRsp->sessionId;
+	if (!CSR_IS_SESSION_VALID(mac_ctx, sessionId))
+		return;
+	session = CSR_GET_SESSION(mac_ctx, sessionId);
+	if (CSR_IS_INFRA_AP(&session->connectedProfile)) {
+		roam_info_ptr = &roam_info;
+		roam_info_ptr->u.pConnectedProfile = &session->connectedProfile;
+		cdf_mem_copy(roam_info_ptr->peerMac.bytes,
+			     pDisassocRsp->peerMacAddr,
+			     sizeof(tSirMacAddr));
+		roam_info_ptr->reasonCode = eCSR_ROAM_RESULT_FORCED;
+		roam_info_ptr->statusCode = pDisassocRsp->statusCode;
+		status = csr_roam_call_callback(mac_ctx, sessionId,
+						roam_info_ptr, 0,
+						eCSR_ROAM_LOSTLINK,
+						eCSR_ROAM_RESULT_FORCED);
+	}
+}
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+static void
+csr_roam_diag_mic_fail(tpAniSirGlobal mac_ctx, uint32_t sessionId)
+{
+	WLAN_HOST_DIAG_EVENT_DEF(secEvent,
+				 host_event_wlan_security_payload_type);
+	tCsrRoamSession *session = CSR_GET_SESSION(mac_ctx, sessionId);
+	if (!session) {
+		sms_log(mac_ctx, LOGE, FL("session %d not found"), sessionId);
+		return;
+	}
+	cdf_mem_set(&secEvent, sizeof(host_event_wlan_security_payload_type),
+		    0);
+	secEvent.eventId = WLAN_SECURITY_EVENT_MIC_ERROR;
+	secEvent.encryptionModeMulticast =
+		(uint8_t) diag_enc_type_from_csr_type(
+				session->connectedProfile.mcEncryptionType);
+	secEvent.encryptionModeUnicast =
+		(uint8_t) diag_enc_type_from_csr_type(
+				session->connectedProfile.EncryptionType);
+	secEvent.authMode =
+		(uint8_t) diag_auth_type_from_csr_type(
+				session->connectedProfile.AuthType);
+	cdf_mem_copy(secEvent.bssid, session->connectedProfile.bssid.bytes,
+			CDF_MAC_ADDR_SIZE);
+	WLAN_HOST_DIAG_EVENT_REPORT(&secEvent, EVENT_WLAN_SECURITY);
+}
+#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
+
+static void
+csr_roam_chk_lnk_mic_fail_ind(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr)
+{
+	uint32_t sessionId = CSR_SESSION_ID_INVALID;
+	CDF_STATUS status;
+	tCsrRoamInfo *roam_info_ptr = NULL;
+	tCsrRoamInfo roam_info;
+	tpSirSmeMicFailureInd pMicInd = (tpSirSmeMicFailureInd) msg_ptr;
+	eCsrRoamResult result = eCSR_ROAM_RESULT_MIC_ERROR_UNICAST;
+
+	cdf_mem_set(&roam_info, sizeof(roam_info), 0);
+	status = csr_roam_get_session_id_from_bssid(mac_ctx,
+				(struct cdf_mac_addr *) pMicInd->bssId, &sessionId);
+	if (CDF_IS_STATUS_SUCCESS(status)) {
+		cdf_mem_set(&roam_info, sizeof(tCsrRoamInfo), 0);
+		roam_info.u.pMICFailureInfo = &pMicInd->info;
+		roam_info_ptr = &roam_info;
+		if (pMicInd->info.multicast)
+			result = eCSR_ROAM_RESULT_MIC_ERROR_GROUP;
+		else
+			result = eCSR_ROAM_RESULT_MIC_ERROR_UNICAST;
+		csr_roam_call_callback(mac_ctx, sessionId, roam_info_ptr, 0,
+				       eCSR_ROAM_MIC_ERROR_IND, result);
+	}
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+	csr_roam_diag_mic_fail(mac_ctx, sessionId);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
+}
+
+static void
+csr_roam_chk_lnk_pbs_probe_req_ind(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr)
+{
+	uint32_t sessionId = CSR_SESSION_ID_INVALID;
+	CDF_STATUS status;
+	tCsrRoamInfo roam_info;
+	tpSirSmeProbeReqInd pProbeReqInd = (tpSirSmeProbeReqInd) msg_ptr;
+
+	cdf_mem_set(&roam_info, sizeof(roam_info), 0);
+	sms_log(mac_ctx, LOG1, FL("WPS PBC Probe request Indication from SME"));
+
+	status = csr_roam_get_session_id_from_bssid(mac_ctx,
+			(struct cdf_mac_addr *)pProbeReqInd->bssId, &sessionId);
+	if (CDF_IS_STATUS_SUCCESS(status)) {
+		cdf_mem_set(&roam_info, sizeof(tCsrRoamInfo), 0);
+		roam_info.u.pWPSPBCProbeReq = &pProbeReqInd->WPSPBCProbeReq;
+		csr_roam_call_callback(mac_ctx, sessionId, &roam_info,
+				       0, eCSR_ROAM_WPS_PBC_PROBE_REQ_IND,
+				       eCSR_ROAM_RESULT_WPS_PBC_PROBE_REQ_IND);
+	}
+}
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+static void
+csr_roam_diag_joined_new_bss(tpAniSirGlobal mac_ctx,
+				     tSirSmeNewBssInfo *pNewBss)
+{
+	host_log_ibss_pkt_type *pIbssLog;
+	uint32_t bi;
+	WLAN_HOST_DIAG_LOG_ALLOC(pIbssLog, host_log_ibss_pkt_type,
+				 LOG_WLAN_IBSS_C);
+	if (!pIbssLog)
+		return;
+	pIbssLog->eventId = WLAN_IBSS_EVENT_COALESCING;
+	if (pNewBss) {
+		cdf_mem_copy(pIbssLog->bssid, pNewBss->bssId, 6);
+		if (pNewBss->ssId.length)
+			cdf_mem_copy(pIbssLog->ssid, pNewBss->ssId.ssId,
+				     pNewBss->ssId.length);
+		pIbssLog->operatingChannel = pNewBss->channelNumber;
+	}
+	if (IS_SIR_STATUS_SUCCESS(wlan_cfg_get_int(mac_ctx,
+						   WNI_CFG_BEACON_INTERVAL,
+						   &bi)))
+		/* U8 is not enough for beacon interval */
+		pIbssLog->beaconInterval = (uint8_t) bi;
+	WLAN_HOST_DIAG_LOG_REPORT(pIbssLog);
+}
+#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
+
+static void
+csr_roam_chk_lnk_wm_status_change_ntf(tpAniSirGlobal mac_ctx,
+				      tSirSmeRsp *msg_ptr)
+{
+	tCsrRoamSession *session;
+	uint32_t sessionId = CSR_SESSION_ID_INVALID;
+	CDF_STATUS status;
+	tCsrRoamInfo *roam_info_ptr = NULL;
+	tSirSmeWmStatusChangeNtf *pStatusChangeMsg;
+	tCsrRoamInfo roam_info;
+	tSirSmeApNewCaps *pApNewCaps;
+	eCsrRoamResult result = eCSR_ROAM_RESULT_NONE;
+	tSirMacAddr Broadcastaddr = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+	tSirSmeNewBssInfo *pNewBss;
+	eRoamCmdStatus roamStatus = eCSR_ROAM_FAILED;
+
+	cdf_mem_set(&roam_info, sizeof(roam_info), 0);
+	pStatusChangeMsg = (tSirSmeWmStatusChangeNtf *) msg_ptr;
+	switch (pStatusChangeMsg->statusChangeCode) {
+	case eSIR_SME_IBSS_ACTIVE:
+		sessionId = csr_find_ibss_session(mac_ctx);
+		if (CSR_SESSION_ID_INVALID == sessionId)
+			break;
+		session = CSR_GET_SESSION(mac_ctx, sessionId);
+		if (!session) {
+			sms_log(mac_ctx, LOGE, FL("session %d not found"),
+				sessionId);
+			return;
+		}
+		session->connectState = eCSR_ASSOC_STATE_TYPE_IBSS_CONNECTED;
+		if (session->pConnectBssDesc) {
+			cdf_mem_copy(&roam_info.bssid,
+				     session->pConnectBssDesc->bssId,
+				     sizeof(struct cdf_mac_addr));
+			roam_info.u.pConnectedProfile =
+				&session->connectedProfile;
+			roam_info_ptr = &roam_info;
+		} else {
+			sms_log(mac_ctx, LOGE,
+				FL("CSR: connected BSS is empty"));
+		}
+		result = eCSR_ROAM_RESULT_IBSS_CONNECT;
+		roamStatus = eCSR_ROAM_CONNECT_STATUS_UPDATE;
+		break;
+
+	case eSIR_SME_IBSS_INACTIVE:
+		sessionId = csr_find_ibss_session(mac_ctx);
+		if (CSR_SESSION_ID_INVALID != sessionId) {
+			session = CSR_GET_SESSION(mac_ctx, sessionId);
+			if (!session) {
+				sms_log(mac_ctx, LOGE,
+					FL("session %d not found"), sessionId);
+				return;
+			}
+			session->connectState =
+				eCSR_ASSOC_STATE_TYPE_IBSS_DISCONNECTED;
+			result = eCSR_ROAM_RESULT_IBSS_INACTIVE;
+			roamStatus = eCSR_ROAM_CONNECT_STATUS_UPDATE;
+		}
+		break;
+
+	case eSIR_SME_JOINED_NEW_BSS:
+		/* IBSS coalescing. */
+		sms_log(mac_ctx, LOGW,
+			FL("CSR: eSIR_SME_JOINED_NEW_BSS received from PE"));
+		sessionId = csr_find_ibss_session(mac_ctx);
+		if (CSR_SESSION_ID_INVALID == sessionId)
+			break;
+		session = CSR_GET_SESSION(mac_ctx, sessionId);
+		if (!session) {
+			sms_log(mac_ctx, LOGE, FL("session %d not found"),
+				sessionId);
+			return;
+		}
+		/* update the connection state information */
+		pNewBss = &pStatusChangeMsg->statusChangeInfo.newBssInfo;
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+		csr_roam_diag_joined_new_bss(mac_ctx, pNewBss);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
+		csr_roam_update_connected_profile_from_new_bss(mac_ctx,
+							       sessionId,
+							       pNewBss);
+
+		if ((eCSR_ENCRYPT_TYPE_NONE ==
+		     session->connectedProfile.EncryptionType)) {
+			csr_roam_issue_set_context_req(mac_ctx,
+			    sessionId,
+			    session->connectedProfile.EncryptionType,
+			    session->pConnectBssDesc,
+			    &Broadcastaddr, false, false,
+			    eSIR_TX_RX, 0, 0, NULL, 0);
+		}
+		result = eCSR_ROAM_RESULT_IBSS_COALESCED;
+		roamStatus = eCSR_ROAM_IBSS_IND;
+		cdf_mem_copy(&roam_info.bssid, &pNewBss->bssId,
+			     sizeof(struct cdf_mac_addr));
+		roam_info_ptr = &roam_info;
+		/* This BSSID is the real BSSID, save it */
+		if (session->pConnectBssDesc)
+			cdf_mem_copy(session->pConnectBssDesc->bssId,
+				     &pNewBss->bssId, sizeof(struct cdf_mac_addr));
+		break;
+
+	/*
+	 * detection by LIM that the capabilities of the associated
+	 * AP have changed.
+	 */
+	case eSIR_SME_AP_CAPS_CHANGED:
+		pApNewCaps = &pStatusChangeMsg->statusChangeInfo.apNewCaps;
+		sms_log(mac_ctx, LOGW,
+			FL("CSR handling eSIR_SME_AP_CAPS_CHANGED"));
+		status = csr_roam_get_session_id_from_bssid(mac_ctx,
+				(struct cdf_mac_addr *)pApNewCaps->bssId, &sessionId);
+		if (!CDF_IS_STATUS_SUCCESS(status))
+			break;
+		if (eCSR_ROAMING_STATE_JOINED ==
+			mac_ctx->roam.curState[sessionId]
+		    && ((eCSR_ROAM_SUBSTATE_JOINED_REALTIME_TRAFFIC
+			== mac_ctx->roam.curSubState[sessionId])
+		    || (eCSR_ROAM_SUBSTATE_NONE ==
+			mac_ctx->roam.curSubState[sessionId])
+		    || (eCSR_ROAM_SUBSTATE_JOINED_NON_REALTIME_TRAFFIC
+			== mac_ctx->roam.curSubState[sessionId])
+		    || (eCSR_ROAM_SUBSTATE_JOINED_NO_TRAFFIC ==
+			 mac_ctx->roam.curSubState[sessionId]))) {
+			sms_log(mac_ctx, LOGW,
+				FL("Calling csr_roam_disconnect_internal"));
+			csr_roam_disconnect_internal(mac_ctx, sessionId,
+					eCSR_DISCONNECT_REASON_UNSPECIFIED);
+		} else {
+			sms_log(mac_ctx, LOGW,
+				FL("Skipping the new scan as CSR is in state %s and sub-state %s"),
+				mac_trace_getcsr_roam_state(
+					mac_ctx->roam.curState[sessionId]),
+				mac_trace_getcsr_roam_sub_state(
+					mac_ctx->roam.curSubState[sessionId]));
+			/* We ignore the caps change event if CSR is not in full
+			 * connected state. Send one event to PE to reset
+			 * limSentCapsChangeNtf Once limSentCapsChangeNtf set
+			 * 0, lim can send sub sequent CAPS change event
+			 * otherwise lim cannot send any CAPS change events to
+			 * SME
+			 */
+			csr_send_reset_ap_caps_changed(mac_ctx,
+						       &pApNewCaps->bssId);
+		}
+		break;
+
+	default:
+		roamStatus = eCSR_ROAM_FAILED;
+		result = eCSR_ROAM_RESULT_NONE;
+		break;
+	} /* end switch on statusChangeCode */
+	if (eCSR_ROAM_RESULT_NONE != result) {
+		csr_roam_call_callback(mac_ctx, sessionId, roam_info_ptr, 0,
+				       roamStatus, result);
+	}
+}
+
+static void
+csr_roam_chk_lnk_ibss_new_peer_ind(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr)
+{
+	tCsrRoamSession *session;
+	uint32_t sessionId = CSR_SESSION_ID_INVALID;
+	CDF_STATUS status;
+	tCsrRoamInfo *roam_info_ptr = NULL;
+	tSmeIbssPeerInd *pIbssPeerInd = (tSmeIbssPeerInd *) msg_ptr;
+	tCsrRoamInfo roam_info;
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+	host_log_ibss_pkt_type *pIbssLog;
+	WLAN_HOST_DIAG_LOG_ALLOC(pIbssLog, host_log_ibss_pkt_type,
+				 LOG_WLAN_IBSS_C);
+	if (pIbssLog) {
+		pIbssLog->eventId = WLAN_IBSS_EVENT_PEER_JOIN;
+		cdf_mem_copy(pIbssLog->peerMacAddr, &pIbssPeerInd->peerAddr, 6);
+		WLAN_HOST_DIAG_LOG_REPORT(pIbssLog);
+	}
+#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
+
+	cdf_mem_set(&roam_info, sizeof(roam_info), 0);
+	sessionId = csr_find_ibss_session(mac_ctx);
+	if (CSR_SESSION_ID_INVALID == sessionId)
+		return;
+	session = CSR_GET_SESSION(mac_ctx, sessionId);
+	if (!session) {
+		sms_log(mac_ctx, LOGE, FL("session %d not found"), sessionId);
+		return;
+	}
+	/*
+	 * Issue the set Context request to LIM to establish the Unicast STA
+	 * context for the new peer...
+	 */
+	if (!session->pConnectBssDesc) {
+		sms_log(mac_ctx, LOGW, FL("CSR: connected BSS is empty"));
+		goto callback_and_free;
+	}
+	cdf_mem_copy(&roam_info.peerMac, pIbssPeerInd->peerAddr,
+		     sizeof(struct cdf_mac_addr));
+	cdf_mem_copy(&roam_info.bssid, session->pConnectBssDesc->bssId,
+		     sizeof(struct cdf_mac_addr));
+	if (pIbssPeerInd->mesgLen > sizeof(tSmeIbssPeerInd)) {
+		roam_info.pbFrames = cdf_mem_malloc((pIbssPeerInd->mesgLen -
+					sizeof(tSmeIbssPeerInd)));
+		if (NULL == roam_info.pbFrames) {
+			status = CDF_STATUS_E_NOMEM;
+		} else {
+			status = CDF_STATUS_SUCCESS;
+			roam_info.nBeaconLength = pIbssPeerInd->mesgLen -
+							sizeof(tSmeIbssPeerInd);
+			cdf_mem_copy(roam_info.pbFrames,
+				((uint8_t *) pIbssPeerInd) +
+				sizeof(tSmeIbssPeerInd),
+				roam_info.nBeaconLength);
+		}
+		roam_info.staId = (uint8_t) pIbssPeerInd->staId;
+		roam_info.ucastSig = (uint8_t) pIbssPeerInd->ucastSig;
+		roam_info.bcastSig = (uint8_t) pIbssPeerInd->bcastSig;
+		roam_info.pBssDesc = cdf_mem_malloc(
+					session->pConnectBssDesc->length);
+		if (NULL == roam_info.pBssDesc) {
+			status = CDF_STATUS_E_NOMEM;
+			if (roam_info.pbFrames)
+				cdf_mem_free(roam_info.pbFrames);
+			if (roam_info.pBssDesc)
+				cdf_mem_free(roam_info.pBssDesc);
+		} else {
+			status = CDF_STATUS_SUCCESS;
+			cdf_mem_copy(roam_info.pBssDesc,
+				     session->pConnectBssDesc,
+				     session->pConnectBssDesc->length);
+			roam_info_ptr = &roam_info;
+		}
+	} else {
+		roam_info_ptr = &roam_info;
+	}
+	if ((eCSR_ENCRYPT_TYPE_NONE ==
+		session->connectedProfile.EncryptionType)) {
+		/* NO keys. these key parameters don't matter */
+		csr_roam_issue_set_context_req(mac_ctx, sessionId,
+			session->connectedProfile.EncryptionType,
+			session->pConnectBssDesc, &(pIbssPeerInd->peerAddr),
+			false, true, eSIR_TX_RX, 0, 0, NULL, 0);
+	}
+
+callback_and_free:
+	/* send up the sec type for the new peer */
+	if (roam_info_ptr)
+		roam_info_ptr->u.pConnectedProfile = &session->connectedProfile;
+	csr_roam_call_callback(mac_ctx, sessionId, roam_info_ptr, 0,
+			       eCSR_ROAM_CONNECT_STATUS_UPDATE,
+			       eCSR_ROAM_RESULT_IBSS_NEW_PEER);
+	if (roam_info_ptr) {
+		if (roam_info.pbFrames)
+			cdf_mem_free(roam_info.pbFrames);
+		if (roam_info.pBssDesc)
+			cdf_mem_free(roam_info.pBssDesc);
+	}
+}
+
+static void
+csr_roam_chk_lnk_ibss_peer_departed_ind(tpAniSirGlobal mac_ctx,
+					tSirSmeRsp *msg_ptr)
+{
+	uint32_t sessionId = CSR_SESSION_ID_INVALID;
+	tCsrRoamInfo roam_info;
+	tSmeIbssPeerInd *pIbssPeerInd;
+
+	if (NULL == msg_ptr) {
+		sms_log(mac_ctx, LOGE, FL("IBSS peer ind. message is NULL"));
+		return;
+	}
+	cdf_mem_set(&roam_info, sizeof(roam_info), 0);
+	pIbssPeerInd = (tSmeIbssPeerInd *) msg_ptr;
+	sessionId = csr_find_ibss_session(mac_ctx);
+	if (CSR_SESSION_ID_INVALID != sessionId) {
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+		host_log_ibss_pkt_type *pIbssLog;
+		WLAN_HOST_DIAG_LOG_ALLOC(pIbssLog, host_log_ibss_pkt_type,
+					 LOG_WLAN_IBSS_C);
+		if (pIbssLog) {
+			pIbssLog->eventId = WLAN_IBSS_EVENT_PEER_LEAVE;
+			if (pIbssPeerInd) {
+				cdf_mem_copy(pIbssLog->peerMacAddr,
+					     &pIbssPeerInd->peerAddr, 6);
+			}
+			WLAN_HOST_DIAG_LOG_REPORT(pIbssLog);
+		}
+#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
+		sms_log(mac_ctx, LOGW,
+			FL("CSR: Peer departed notification from LIM"));
+		roam_info.staId = (uint8_t) pIbssPeerInd->staId;
+		roam_info.ucastSig = (uint8_t) pIbssPeerInd->ucastSig;
+		roam_info.bcastSig = (uint8_t) pIbssPeerInd->bcastSig;
+		cdf_mem_copy(&roam_info.peerMac, pIbssPeerInd->peerAddr,
+			     sizeof(struct cdf_mac_addr));
+		csr_roam_call_callback(mac_ctx, sessionId, &roam_info, 0,
+				       eCSR_ROAM_CONNECT_STATUS_UPDATE,
+				       eCSR_ROAM_RESULT_IBSS_PEER_DEPARTED);
+	}
+}
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+static void
+csr_roam_diag_set_ctx_rsp(tpAniSirGlobal mac_ctx,
+			  tCsrRoamSession *session,
+			  tSirSmeSetContextRsp *pRsp)
+{
+	WLAN_HOST_DIAG_EVENT_DEF(setKeyEvent,
+				 host_event_wlan_security_payload_type);
+	if (eCSR_ENCRYPT_TYPE_NONE ==
+		session->connectedProfile.EncryptionType)
+		return;
+	cdf_mem_set(&setKeyEvent,
+		    sizeof(host_event_wlan_security_payload_type), 0);
+	if (pRsp->peerMacAddr[0] & 0x01)
+		setKeyEvent.eventId = WLAN_SECURITY_EVENT_SET_GTK_RSP;
+	else
+		setKeyEvent.eventId = WLAN_SECURITY_EVENT_SET_PTK_RSP;
+	setKeyEvent.encryptionModeMulticast =
+		(uint8_t) diag_enc_type_from_csr_type(
+				session->connectedProfile.mcEncryptionType);
+	setKeyEvent.encryptionModeUnicast =
+		(uint8_t) diag_enc_type_from_csr_type(
+				session->connectedProfile.EncryptionType);
+	cdf_mem_copy(setKeyEvent.bssid, session->connectedProfile.bssid.bytes,
+			CDF_MAC_ADDR_SIZE);
+	setKeyEvent.authMode =
+		(uint8_t) diag_auth_type_from_csr_type(
+					session->connectedProfile.AuthType);
+	if (eSIR_SME_SUCCESS != pRsp->statusCode)
+		setKeyEvent.status = WLAN_SECURITY_STATUS_FAILURE;
+	WLAN_HOST_DIAG_EVENT_REPORT(&setKeyEvent, EVENT_WLAN_SECURITY);
+}
+#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
+
+static void
+csr_roam_chk_lnk_set_ctx_rsp(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr)
+{
+	tCsrRoamSession *session;
+	uint32_t sessionId = CSR_SESSION_ID_INVALID;
+	CDF_STATUS status;
+	tCsrRoamInfo *roam_info_ptr = NULL;
+	tSmeCmd *cmd;
+	tCsrRoamInfo roam_info;
+	eCsrRoamResult result = eCSR_ROAM_RESULT_NONE;
+	tSirSmeSetContextRsp *pRsp = (tSirSmeSetContextRsp *) msg_ptr;
+	tListElem *entry;
+	tSirMacAddr Broadcastaddr = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+
+	cdf_mem_set(&roam_info, sizeof(roam_info), 0);
+	entry = csr_ll_peek_head(&mac_ctx->sme.smeCmdActiveList,
+				 LL_ACCESS_LOCK);
+	if (!entry) {
+		sms_log(mac_ctx, LOGE, FL("CSR: NO commands are ACTIVE ..."));
+		goto process_pending_n_exit;
+	}
+
+	cmd = GET_BASE_ADDR(entry, tSmeCmd, Link);
+	if (eSmeCommandSetKey != cmd->command) {
+		sms_log(mac_ctx, LOGE, FL("CSR: setkey cmd is not ACTIVE ..."));
+		goto process_pending_n_exit;
+	}
+	sessionId = cmd->sessionId;
+	session = CSR_GET_SESSION(mac_ctx, sessionId);
+	if (!session) {
+		sms_log(mac_ctx, LOGE, FL("session %d not found"), sessionId);
+		return;
+	}
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+	csr_roam_diag_set_ctx_rsp(mac_ctx, session, pRsp);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
+	if (CSR_IS_WAIT_FOR_KEY(mac_ctx, sessionId)) {
+		csr_roam_stop_wait_for_key_timer(mac_ctx);
+		/* We are done with authentication, whethere succeed or not */
+		csr_roam_substate_change(mac_ctx, eCSR_ROAM_SUBSTATE_NONE,
+					 sessionId);
+		/* We do it here because this linkup function is not called
+		 * after association  when a key needs to be set.
+		 */
+		if (csr_is_conn_state_connected_infra(mac_ctx, sessionId))
+			csr_roam_link_up(mac_ctx,
+					 session->connectedProfile.bssid);
+	}
+	if (eSIR_SME_SUCCESS == pRsp->statusCode) {
+		cdf_mem_copy(&roam_info.peerMac, &pRsp->peerMacAddr,
+			     sizeof(struct cdf_mac_addr));
+		/* Make sure we install the GTK before indicating to HDD as
+		 * authenticated. This is to prevent broadcast packets go out
+		 * after PTK and before GTK.
+		 */
+		if (cdf_mem_compare(&Broadcastaddr, pRsp->peerMacAddr,
+				    sizeof(tSirMacAddr))) {
+			tpSirSetActiveModeSetBncFilterReq pMsg;
+			pMsg = cdf_mem_malloc(
+				    sizeof(tSirSetActiveModeSetBncFilterReq));
+			pMsg->messageType = eWNI_SME_SET_BCN_FILTER_REQ;
+			pMsg->length = sizeof(uint8_t);
+			pMsg->seesionId = sessionId;
+			status = cds_send_mb_message_to_mac(pMsg);
+			result = eCSR_ROAM_RESULT_AUTHENTICATED;
+		} else {
+			result = eCSR_ROAM_RESULT_NONE;
+		}
+		roam_info_ptr = &roam_info;
+	} else {
+		result = eCSR_ROAM_RESULT_FAILURE;
+		sms_log(mac_ctx, LOGE,
+			FL("CSR: setkey command failed(%d) PeerMac "
+			MAC_ADDRESS_STR),
+			pRsp->statusCode, MAC_ADDR_ARRAY(pRsp->peerMacAddr));
+	}
+	csr_roam_call_callback(mac_ctx, sessionId, &roam_info,
+			       cmd->u.setKeyCmd.roamId,
+			       eCSR_ROAM_SET_KEY_COMPLETE, result);
+	/* Indicate SME_QOS that the SET_KEY is completed, so that SME_QOS
+	 * can go ahead and initiate the TSPEC if any are pending
+	 */
+	sme_qos_csr_event_ind(mac_ctx, (uint8_t) sessionId,
+			      SME_QOS_CSR_SET_KEY_SUCCESS_IND, NULL);
+#ifdef FEATURE_WLAN_ESE
+	/* Send Adjacent AP repot to new AP. */
+	if (result == eCSR_ROAM_RESULT_AUTHENTICATED
+	    && session->isPrevApInfoValid
+	    && session->connectedProfile.isESEAssoc) {
+#ifdef FEATURE_WLAN_ESE_UPLOAD
+		csr_send_ese_adjacent_ap_rep_ind(mac_ctx, session);
+#else
+		csr_ese_send_adjacent_ap_rep_msg(mac_ctx, session);
+#endif
+		session->isPrevApInfoValid = false;
+	}
+#endif
+	if (csr_ll_remove_entry(&mac_ctx->sme.smeCmdActiveList, entry,
+				LL_ACCESS_LOCK))
+		csr_release_command_set_key(mac_ctx, cmd);
+
+process_pending_n_exit:
+	sme_process_pending_queue(mac_ctx);
+}
+
+
+static void
+csr_roam_chk_lnk_max_assoc_exceeded(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr)
+{
+	uint32_t sessionId = CSR_SESSION_ID_INVALID;
+	tSmeMaxAssocInd *pSmeMaxAssocInd;
+	tCsrRoamInfo roam_info;
+
+	cdf_mem_set(&roam_info, sizeof(roam_info), 0);
+	pSmeMaxAssocInd = (tSmeMaxAssocInd *) msg_ptr;
+	sms_log(mac_ctx, LOG1,
+		FL("max assoc have been reached, new peer cannot be accepted"));
+	sessionId = pSmeMaxAssocInd->sessionId;
+	roam_info.sessionId = sessionId;
+	cdf_mem_copy(&roam_info.peerMac, pSmeMaxAssocInd->peerMac,
+		     sizeof(struct cdf_mac_addr));
+	csr_roam_call_callback(mac_ctx, sessionId, &roam_info, 0,
+			       eCSR_ROAM_INFRA_IND,
+			       eCSR_ROAM_RESULT_MAX_ASSOC_EXCEEDED);
+}
+
+void csr_roam_check_for_link_status_change(tpAniSirGlobal pMac, tSirSmeRsp *pSirMsg)
+{
+	if (NULL == pSirMsg) {
+		sms_log(pMac, LOGE, FL("pSirMsg is NULL"));
+		return;
+	}
+	switch (pSirMsg->messageType) {
+	case eWNI_SME_ASSOC_IND:
+		csr_roam_chk_lnk_assoc_ind(pMac, pSirMsg);
+		break;
+	case eWNI_SME_DISASSOC_IND:
+		csr_roam_chk_lnk_disassoc_ind(pMac, pSirMsg);
+		break;
+	case eWNI_SME_DEAUTH_IND:
+		csr_roam_chk_lnk_deauth_ind(pMac, pSirMsg);
+		break;
+	case eWNI_SME_SWITCH_CHL_IND:
+		csr_roam_chk_lnk_swt_ch_ind(pMac, pSirMsg);
+		break;
+	case eWNI_SME_DEAUTH_RSP:
+		csr_roam_chk_lnk_deauth_rsp(pMac, pSirMsg);
+		break;
+	case eWNI_SME_DISASSOC_RSP:
+		csr_roam_chk_lnk_disassoc_rsp(pMac, pSirMsg);
+		break;
+	case eWNI_SME_MIC_FAILURE_IND:
+		csr_roam_chk_lnk_mic_fail_ind(pMac, pSirMsg);
+		break;
+	case eWNI_SME_WPS_PBC_PROBE_REQ_IND:
+		csr_roam_chk_lnk_pbs_probe_req_ind(pMac, pSirMsg);
+		break;
+	case eWNI_SME_WM_STATUS_CHANGE_NTF:
+		csr_roam_chk_lnk_wm_status_change_ntf(pMac, pSirMsg);
+		break;
+	case eWNI_SME_IBSS_NEW_PEER_IND:
+		csr_roam_chk_lnk_ibss_new_peer_ind(pMac, pSirMsg);
+		break;
+	case eWNI_SME_IBSS_PEER_DEPARTED_IND:
+		csr_roam_chk_lnk_ibss_peer_departed_ind(pMac, pSirMsg);
+		break;
+	case eWNI_SME_SETCONTEXT_RSP:
+		csr_roam_chk_lnk_set_ctx_rsp(pMac, pSirMsg);
+		break;
+	case eWNI_SME_GET_STATISTICS_RSP:
+		sms_log(pMac, LOG2, FL("Stats rsp from PE"));
+		csr_roam_stats_rsp_processor(pMac, pSirMsg);
+		break;
+#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
+	case eWNI_SME_GET_TSM_STATS_RSP:
+		sms_log(pMac, LOG2, FL("TSM Stats rsp from PE"));
+		csr_tsm_stats_rsp_processor(pMac, pSirMsg);
+		break;
+#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
+	case eWNI_SME_GET_RSSI_REQ:
+		sms_log(pMac, LOG2, FL("GetRssiReq from self"));
+		csr_update_rssi(pMac, pSirMsg);
+		break;
+	case eWNI_SME_GET_SNR_REQ:
+		sms_log(pMac, LOG2, FL("GetSnrReq from self"));
+		csr_update_snr(pMac, pSirMsg);
+		break;
+#ifdef WLAN_FEATURE_VOWIFI_11R
+	case eWNI_SME_FT_PRE_AUTH_RSP:
+		csr_roam_ft_pre_auth_rsp_processor(pMac, (tpSirFTPreAuthRsp) pSirMsg);
+		break;
+#endif
+	case eWNI_SME_MAX_ASSOC_EXCEEDED:
+		csr_roam_chk_lnk_max_assoc_exceeded(pMac, pSirMsg);
+		break;
+	case eWNI_SME_CANDIDATE_FOUND_IND:
+		sms_log(pMac, LOG2, FL("Candidate found indication from PE"));
+		csr_neighbor_roam_candidate_found_ind_hdlr(pMac, pSirMsg);
+		break;
+	case eWNI_SME_HANDOFF_REQ:
+		sms_log(pMac, LOG2, FL("Handoff Req from self"));
+		csr_neighbor_roam_handoff_req_hdlr(pMac, pSirMsg);
+		break;
+	default:
+		break;
+	} /* end switch on message type */
+}
+
+void csr_call_roaming_completion_callback(tpAniSirGlobal pMac,
+					  tCsrRoamSession *pSession,
+					  tCsrRoamInfo *pRoamInfo, uint32_t roamId,
+					  eCsrRoamResult roamResult)
+{
+	if (pSession) {
+		if (pSession->bRefAssocStartCnt) {
+			pSession->bRefAssocStartCnt--;
+
+			if (0 != pSession->bRefAssocStartCnt) {
+				CDF_ASSERT(pSession->bRefAssocStartCnt == 0);
+				return;
+			}
+			/* Need to call association_completion because there is an assoc_start pending. */
+			csr_roam_call_callback(pMac, pSession->sessionId, NULL,
+					       roamId,
+					       eCSR_ROAM_ASSOCIATION_COMPLETION,
+					       eCSR_ROAM_RESULT_FAILURE);
+		}
+		csr_roam_call_callback(pMac, pSession->sessionId, pRoamInfo,
+				       roamId, eCSR_ROAM_ROAMING_COMPLETION,
+				       roamResult);
+	} else {
+		sms_log(pMac, LOGW, FL("  pSession is NULL"));
+	}
+}
+
+CDF_STATUS csr_roam_start_roaming(tpAniSirGlobal pMac, uint32_t sessionId,
+				  eCsrRoamingReason roamingReason)
+{
+	CDF_STATUS status = CDF_STATUS_E_FAILURE;
+	if (CSR_IS_LOSTLINK_ROAMING(roamingReason) &&
+	    (false == pMac->roam.roamSession[sessionId].fCancelRoaming)) {
+		status = csr_scan_request_lost_link1(pMac, sessionId);
+	}
+	return status;
+}
+
+/* return a bool to indicate whether roaming completed or continue. */
+bool csr_roam_complete_roaming(tpAniSirGlobal pMac, uint32_t sessionId,
+			       bool fForce, eCsrRoamResult roamResult)
+{
+	bool fCompleted = true;
+	uint32_t roamTime =
+		(uint32_t) (pMac->roam.configParam.nRoamingTime *
+			    CDF_TICKS_PER_SECOND);
+	uint32_t curTime = (uint32_t) cdf_mc_timer_get_system_ticks();
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("  session %d not found "), sessionId);
+		return false;
+	}
+	/* Check whether time is up */
+	if (pSession->fCancelRoaming || fForce ||
+	    ((curTime - pSession->roamingStartTime) > roamTime) ||
+	    eCsrReassocRoaming == pSession->roamingReason ||
+	    eCsrDynamicRoaming == pSession->roamingReason) {
+		sms_log(pMac, LOGW, FL("  indicates roaming completion"));
+		if (pSession->fCancelRoaming
+		    && CSR_IS_LOSTLINK_ROAMING(pSession->roamingReason)) {
+			/* roaming is cancelled, tell HDD to indicate disconnect */
+			/* Because LIM overload deauth_ind for both deauth frame and missed beacon */
+			/* we need to use this logic to detinguish it. For missed beacon, LIM set reason */
+			/* to be eSIR_BEACON_MISSED */
+			if (eSIR_BEACON_MISSED == pSession->roamingStatusCode) {
+				roamResult = eCSR_ROAM_RESULT_LOSTLINK;
+			} else if (eCsrLostlinkRoamingDisassoc ==
+				   pSession->roamingReason) {
+				roamResult = eCSR_ROAM_RESULT_DISASSOC_IND;
+			} else if (eCsrLostlinkRoamingDeauth ==
+				   pSession->roamingReason) {
+				roamResult = eCSR_ROAM_RESULT_DEAUTH_IND;
+			} else {
+				roamResult = eCSR_ROAM_RESULT_LOSTLINK;
+			}
+		}
+		csr_call_roaming_completion_callback(pMac, pSession, NULL, 0,
+						     roamResult);
+		pSession->roamingReason = eCsrNotRoaming;
+	} else {
+		pSession->roamResult = roamResult;
+		if (!CDF_IS_STATUS_SUCCESS
+			    (csr_roam_start_roaming_timer
+				    (pMac, sessionId, CDF_MC_TIMER_TO_SEC_UNIT))) {
+			csr_call_roaming_completion_callback(pMac, pSession, NULL,
+							     0, roamResult);
+			pSession->roamingReason = eCsrNotRoaming;
+		} else {
+			fCompleted = false;
+		}
+	}
+	return fCompleted;
+}
+
+void csr_roam_cancel_roaming(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("  session %d not found "), sessionId);
+		return;
+	}
+
+	if (CSR_IS_ROAMING(pSession)) {
+		sms_log(pMac, LOGW, "Cancel roaming");
+		pSession->fCancelRoaming = true;
+		if (CSR_IS_ROAM_JOINING(pMac, sessionId)
+		    && CSR_IS_ROAM_SUBSTATE_CONFIG(pMac, sessionId)) {
+			/* No need to do anything in here because the handler takes care of it */
+		} else {
+			eCsrRoamResult roamResult =
+				CSR_IS_LOSTLINK_ROAMING(pSession->
+							roamingReason) ?
+				eCSR_ROAM_RESULT_LOSTLINK : eCSR_ROAM_RESULT_NONE;
+			/* Roaming is stopped after here */
+			csr_roam_complete_roaming(pMac, sessionId, true,
+						  roamResult);
+			/* Since CSR may be in lostlink roaming situation, abort all roaming related activities */
+			csr_scan_abort_mac_scan(pMac, sessionId,
+						eCSR_SCAN_ABORT_DEFAULT);
+			csr_roam_stop_roaming_timer(pMac, sessionId);
+		}
+	}
+}
+
+void csr_roam_roaming_timer_handler(void *pv)
+{
+	tCsrTimerInfo *pInfo = (tCsrTimerInfo *) pv;
+	tpAniSirGlobal pMac = pInfo->pMac;
+	uint32_t sessionId = pInfo->sessionId;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("  session %d not found "), sessionId);
+		return;
+	}
+
+	if (false == pSession->fCancelRoaming) {
+		if (!CDF_IS_STATUS_SUCCESS
+			    (csr_roam_start_roaming
+				    (pMac, sessionId, pSession->roamingReason))) {
+			csr_call_roaming_completion_callback(pMac, pSession, NULL,
+							     0,
+							     pSession->roamResult);
+			pSession->roamingReason = eCsrNotRoaming;
+		}
+	}
+}
+
+CDF_STATUS csr_roam_start_roaming_timer(tpAniSirGlobal pMac, uint32_t sessionId,
+					uint32_t interval)
+{
+	CDF_STATUS status;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("  session %d not found"), sessionId);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	sms_log(pMac, LOG1, " csrScanStartRoamingTimer");
+	pSession->roamingTimerInfo.sessionId = (uint8_t) sessionId;
+	status = cdf_mc_timer_start(&pSession->hTimerRoaming,
+				    interval / CDF_MC_TIMER_TO_MS_UNIT);
+
+	return status;
+}
+
+CDF_STATUS csr_roam_stop_roaming_timer(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	return cdf_mc_timer_stop
+			(&pMac->roam.roamSession[sessionId].hTimerRoaming);
+}
+
+void csr_roam_wait_for_key_time_out_handler(void *pv)
+{
+	tCsrTimerInfo *pInfo = (tCsrTimerInfo *) pv;
+	tpAniSirGlobal pMac = pInfo->pMac;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, pInfo->sessionId);
+	CDF_STATUS status = CDF_STATUS_E_FAILURE;
+
+	if (pSession == NULL) {
+		sms_log(pMac, LOGE, "%s: session not found", __func__);
+		return;
+	}
+
+	sms_log(pMac, LOGW,
+		FL("WaitForKey timer expired in state=%s sub-state=%s"),
+		mac_trace_get_neighbour_roam_state(pMac->roam.
+						   neighborRoamInfo[pInfo->sessionId].
+						   neighborRoamState),
+		mac_trace_getcsr_roam_sub_state(pMac->roam.
+						curSubState[pInfo->sessionId]));
+
+	if (CSR_IS_WAIT_FOR_KEY(pMac, pInfo->sessionId)) {
+#ifdef FEATURE_WLAN_LFR
+		if (csr_neighbor_roam_is_handoff_in_progress(pMac, pInfo->sessionId)) {
+			/*
+			 * Enable heartbeat timer when hand-off is in progress
+			 * and Key Wait timer expired.
+			 */
+			sms_log(pMac, LOG2,
+				"Enabling HB timer after WaitKey expiry"
+				" (nHBCount=%d)",
+				pMac->roam.configParam.HeartbeatThresh24);
+			cfg_set_int(pMac, WNI_CFG_HEART_BEAT_THRESHOLD,
+					pMac->roam.configParam.HeartbeatThresh24);
+		}
+#endif
+		sms_log(pMac, LOGE, " SME pre-auth state timeout. ");
+
+		/* Change the substate so command queue is unblocked. */
+		if (CSR_ROAM_SESSION_MAX > pInfo->sessionId) {
+			csr_roam_substate_change(pMac, eCSR_ROAM_SUBSTATE_NONE,
+						 pInfo->sessionId);
+		}
+
+		if (csr_is_conn_state_connected_infra(pMac, pInfo->sessionId)) {
+			csr_roam_link_up(pMac,
+					 pSession->connectedProfile.bssid);
+			sme_process_pending_queue(pMac);
+			status = sme_acquire_global_lock(&pMac->sme);
+			if (CDF_IS_STATUS_SUCCESS(status)) {
+				csr_roam_disconnect(pMac, pInfo->sessionId,
+					eCSR_DISCONNECT_REASON_UNSPECIFIED);
+				sme_release_global_lock(&pMac->sme);
+			}
+		} else {
+			sms_log(pMac, LOGE, "%s: session not found", __func__);
+		}
+	}
+
+}
+
+CDF_STATUS csr_roam_start_wait_for_key_timer(tpAniSirGlobal pMac, uint32_t interval)
+{
+	CDF_STATUS status;
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+		&pMac->roam.neighborRoamInfo[pMac->roam.WaitForKeyTimerInfo.
+					     sessionId];
+#ifdef FEATURE_WLAN_LFR
+	if (csr_neighbor_roam_is_handoff_in_progress(pMac,
+						     pMac->roam.WaitForKeyTimerInfo.
+						     sessionId)) {
+		/* Disable heartbeat timer when hand-off is in progress */
+		sms_log(pMac, LOG2,
+			FL("disabling HB timer in state=%s sub-state=%s"),
+			mac_trace_get_neighbour_roam_state(pNeighborRoamInfo->
+							   neighborRoamState),
+			mac_trace_getcsr_roam_sub_state(pMac->roam.
+							curSubState[pMac->roam.
+								    WaitForKeyTimerInfo.
+								    sessionId]
+							));
+		cfg_set_int(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, 0);
+	}
+#endif
+	sms_log(pMac, LOG1, " csrScanStartWaitForKeyTimer");
+	status = cdf_mc_timer_start(&pMac->roam.hTimerWaitForKey,
+				    interval / CDF_MC_TIMER_TO_MS_UNIT);
+
+	return status;
+}
+
+CDF_STATUS csr_roam_stop_wait_for_key_timer(tpAniSirGlobal pMac)
+{
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+		&pMac->roam.neighborRoamInfo[pMac->roam.WaitForKeyTimerInfo.
+					     sessionId];
+
+	sms_log(pMac, LOG2,
+		FL("WaitForKey timer stopped in state=%s sub-state=%s"),
+		mac_trace_get_neighbour_roam_state(pNeighborRoamInfo->
+						   neighborRoamState),
+		mac_trace_getcsr_roam_sub_state(pMac->roam.
+						curSubState[pMac->roam.
+							    WaitForKeyTimerInfo.
+							    sessionId]));
+#ifdef FEATURE_WLAN_LFR
+	if (csr_neighbor_roam_is_handoff_in_progress(pMac,
+						     pMac->roam.WaitForKeyTimerInfo.
+						     sessionId)) {
+		/*
+		 * Enable heartbeat timer when hand-off is in progress
+		 * and Key Wait timer got stopped for some reason
+		 */
+		sms_log(pMac, LOG2, "Enabling HB timer after WaitKey stop"
+			" (nHBCount=%d)",
+			pMac->roam.configParam.HeartbeatThresh24);
+		cfg_set_int(pMac, WNI_CFG_HEART_BEAT_THRESHOLD,
+				pMac->roam.configParam.HeartbeatThresh24);
+	}
+#endif
+	return cdf_mc_timer_stop(&pMac->roam.hTimerWaitForKey);
+}
+
+void csr_roam_completion(tpAniSirGlobal pMac, uint32_t sessionId,
+			 tCsrRoamInfo *pRoamInfo, tSmeCmd *pCommand,
+			 eCsrRoamResult roamResult, bool fSuccess)
+{
+	eRoamCmdStatus roamStatus = csr_get_roam_complete_status(pMac, sessionId);
+	uint32_t roamId = 0;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("  session %d not found "), sessionId);
+		return;
+	}
+
+	if (pCommand) {
+		roamId = pCommand->u.roamCmd.roamId;
+		if (sessionId != pCommand->sessionId) {
+			CDF_ASSERT(sessionId == pCommand->sessionId);
+			return;
+		}
+	}
+	if (eCSR_ROAM_ROAMING_COMPLETION == roamStatus) {
+		/* if success, force roaming completion */
+		csr_roam_complete_roaming(pMac, sessionId, fSuccess, roamResult);
+	} else {
+		if (pSession->bRefAssocStartCnt != 0) {
+			CDF_ASSERT(pSession->bRefAssocStartCnt == 0);
+			return;
+		}
+		sms_log(pMac, LOGW,
+			FL
+				("  indicates association completion. roamResult = %d"),
+			roamResult);
+		csr_roam_call_callback(pMac, sessionId, pRoamInfo, roamId,
+				       roamStatus, roamResult);
+	}
+}
+
+CDF_STATUS csr_roam_lost_link(tpAniSirGlobal pMac, uint32_t sessionId,
+			      uint32_t type, tSirSmeRsp *pSirMsg)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tSirSmeDeauthInd *pDeauthIndMsg = NULL;
+	tSirSmeDisassocInd *pDisassocIndMsg = NULL;
+	eCsrRoamResult result = eCSR_ROAM_RESULT_LOSTLINK;
+	tCsrRoamInfo *pRoamInfo = NULL;
+	tCsrRoamInfo roamInfo;
+	bool fToRoam;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("  session %d not found "), sessionId);
+		return CDF_STATUS_E_FAILURE;
+	}
+	/* Only need to roam for infra station. In this case P2P client will roam as well */
+	fToRoam = CSR_IS_INFRASTRUCTURE(&pSession->connectedProfile);
+	pSession->fCancelRoaming = false;
+	if (eWNI_SME_DISASSOC_IND == type) {
+		result = eCSR_ROAM_RESULT_DISASSOC_IND;
+		pDisassocIndMsg = (tSirSmeDisassocInd *) pSirMsg;
+		pSession->roamingStatusCode = pDisassocIndMsg->statusCode;
+		pSession->joinFailStatusCode.reasonCode =
+			pDisassocIndMsg->reasonCode;
+	} else if (eWNI_SME_DEAUTH_IND == type) {
+		result = eCSR_ROAM_RESULT_DEAUTH_IND;
+		pDeauthIndMsg = (tSirSmeDeauthInd *) pSirMsg;
+		pSession->roamingStatusCode = pDeauthIndMsg->statusCode;
+		/* Convert into proper reason code */
+		if ((pDeauthIndMsg->reasonCode == eSIR_BEACON_MISSED) ||
+				(pDeauthIndMsg->reasonCode ==
+				eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON))
+			pSession->joinFailStatusCode.reasonCode = 0;
+		else
+			pSession->joinFailStatusCode.reasonCode =
+				pDeauthIndMsg->reasonCode;
+		/*
+		 * cfg layer expects 0 as reason code if
+		 * the driver dosent know the reason code
+		 * eSIR_BEACON_MISSED is defined as locally
+		 */
+	} else {
+		sms_log(pMac, LOGW, FL("gets an unknown type (%d)"), type);
+		result = eCSR_ROAM_RESULT_NONE;
+		pSession->joinFailStatusCode.reasonCode = 1;
+	}
+
+	/* call profile lost link routine here */
+	if (!CSR_IS_INFRA_AP(&pSession->connectedProfile)) {
+		csr_roam_call_callback(pMac, sessionId, NULL, 0,
+				       eCSR_ROAM_LOSTLINK_DETECTED, result);
+		/*Move the state to Idle after disconnection */
+		csr_roam_state_change(pMac, eCSR_ROAMING_STATE_IDLE, sessionId);
+
+	}
+
+	if (eWNI_SME_DISASSOC_IND == type) {
+		status = csr_send_mb_disassoc_cnf_msg(pMac, pDisassocIndMsg);
+	} else if (eWNI_SME_DEAUTH_IND == type) {
+		status = csr_send_mb_deauth_cnf_msg(pMac, pDeauthIndMsg);
+	}
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		/* If fail to send confirmation to PE, not to trigger roaming */
+		fToRoam = false;
+	}
+	/* prepare to tell HDD to disconnect */
+	cdf_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0);
+	roamInfo.statusCode = (tSirResultCodes) pSession->roamingStatusCode;
+	roamInfo.reasonCode = pSession->joinFailStatusCode.reasonCode;
+	if (eWNI_SME_DISASSOC_IND == type) {
+		/* staMacAddr */
+		cdf_mem_copy(roamInfo.peerMac.bytes,
+				pDisassocIndMsg->peerMacAddr,
+				sizeof(tSirMacAddr));
+		roamInfo.staId = (uint8_t) pDisassocIndMsg->staId;
+		roamInfo.reasonCode = pDisassocIndMsg->reasonCode;
+	} else if (eWNI_SME_DEAUTH_IND == type) {
+		/* staMacAddr */
+		cdf_mem_copy(roamInfo.peerMac.bytes,
+				pDeauthIndMsg->peerMacAddr,
+				sizeof(tSirMacAddr));
+		roamInfo.staId = (uint8_t) pDeauthIndMsg->staId;
+		roamInfo.reasonCode = pDeauthIndMsg->reasonCode;
+	}
+	sms_log(pMac, LOGW, FL("roamInfo.staId (%d)"), roamInfo.staId);
+
+	/* See if we can possibly roam.  If so, start the roaming process and notify HDD
+	   that we are roaming.  But if we cannot possibly roam, or if we are unable to
+	   currently roam, then notify HDD of the lost link */
+	if (fToRoam) {
+		/* Only remove the connected BSS in infrastructure mode */
+		csr_roam_remove_connected_bss_from_scan_cache(pMac,
+							      &pSession->
+							      connectedProfile);
+		/* Not to do anying for lostlink with WDS */
+		status = csr_roam_start_roaming(pMac, sessionId,
+				(eWNI_SME_DEAUTH_IND == type) ?
+				eCsrLostlinkRoamingDeauth :
+				eCsrLostlinkRoamingDisassoc);
+		if (pMac->roam.configParam.nRoamingTime) {
+			status = csr_roam_start_roaming(pMac, sessionId,
+					(eWNI_SME_DEAUTH_IND == type) ?
+					eCsrLostlinkRoamingDeauth :
+					eCsrLostlinkRoamingDisassoc);
+			if (CDF_IS_STATUS_SUCCESS(status)) {
+				cdf_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0);
+				/* For IBSS, we need to give some more info to HDD */
+				if (csr_is_bss_type_ibss
+					(pSession->connectedProfile.BSSType)) {
+					roamInfo.u.pConnectedProfile =
+						&pSession->connectedProfile;
+					roamInfo.statusCode =
+						(tSirResultCodes) pSession->
+						roamingStatusCode;
+					roamInfo.reasonCode =
+						pSession->joinFailStatusCode.
+						reasonCode;
+				} else {
+					roamInfo.reasonCode =
+						eCsrRoamReasonSmeIssuedForLostLink;
+				}
+				pRoamInfo = &roamInfo;
+				pSession->roamingReason =
+					(eWNI_SME_DEAUTH_IND ==
+					 type) ? eCsrLostlinkRoamingDeauth :
+					eCsrLostlinkRoamingDisassoc;
+				pSession->roamingStartTime =
+					(uint32_t) cdf_mc_timer_get_system_ticks();
+				csr_roam_call_callback(pMac, sessionId, pRoamInfo,
+						       0, eCSR_ROAM_ROAMING_START,
+						       eCSR_ROAM_RESULT_LOSTLINK);
+			} else {
+				sms_log(pMac, LOGW,
+					" %s Fail to start roaming, status = %d",
+					__func__, status);
+				fToRoam = false;
+			}
+		} else {
+			/* We are told not to roam, indicate lostlink */
+			fToRoam = false;
+		}
+	}
+	if (!fToRoam) {
+		/* Tell HDD about the lost link */
+		if (!CSR_IS_INFRA_AP(&pSession->connectedProfile)) {
+			/* Don't call csr_roam_call_callback for GO/SoftAp case as this indication
+			 * was already given as part of eWNI_SME_DISASSOC_IND msg handling in
+			 * csr_roam_check_for_link_status_change API.
+			 */
+			csr_roam_call_callback(pMac, sessionId, &roamInfo, 0,
+					       eCSR_ROAM_LOSTLINK, result);
+		}
+
+	}
+
+	return status;
+}
+
+CDF_STATUS csr_roam_lost_link_afterhandoff_failure(tpAniSirGlobal pMac,
+						   uint32_t sessionId)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tListElem *pEntry = NULL;
+	tSmeCmd *pCommand = NULL;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("  session %d not found "), sessionId);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	pSession->fCancelRoaming = false;
+	/* Only remove the connected BSS in infrastructure mode */
+	csr_roam_remove_connected_bss_from_scan_cache(pMac,
+						      &pSession->connectedProfile);
+	if (pMac->roam.configParam.nRoamingTime) {
+		status = csr_roam_start_roaming(pMac, sessionId,
+				pSession->roamingReason);
+		if (CDF_IS_STATUS_SUCCESS(status)) {
+			/*
+			 * before starting the lost link logic release
+			 * the roam command for handoff
+			 */
+			pEntry =
+				csr_ll_peek_head(&pMac->sme.smeCmdActiveList,
+						 LL_ACCESS_LOCK);
+			if (pEntry) {
+				pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
+			}
+			if (pCommand) {
+				if ((eSmeCommandRoam == pCommand->command) &&
+				    (eCsrSmeIssuedAssocToSimilarAP ==
+				     pCommand->u.roamCmd.roamReason)) {
+					if (csr_ll_remove_entry
+						    (&pMac->sme.smeCmdActiveList,
+						    pEntry, LL_ACCESS_LOCK)) {
+						csr_release_command_roam(pMac,
+									 pCommand);
+					}
+				}
+			}
+			sms_log(pMac, LOGW, "Lost link roaming started ...");
+		}
+	} else {
+		/* We are told not to roam, indicate lostlink */
+		status = CDF_STATUS_E_FAILURE;
+	}
+
+	return status;
+}
+
+void csr_roam_wm_status_change_complete(tpAniSirGlobal pMac)
+{
+	tListElem *pEntry;
+	tSmeCmd *pCommand;
+	pEntry = csr_ll_peek_head(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK);
+	if (pEntry) {
+		pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
+		if (eSmeCommandWmStatusChange == pCommand->command) {
+			/* Nothing to process in a Lost Link completion....  It just kicks off a */
+			/* roaming sequence. */
+			if (csr_ll_remove_entry
+				    (&pMac->sme.smeCmdActiveList, pEntry,
+				    LL_ACCESS_LOCK)) {
+				csr_release_command_wm_status_change(pMac, pCommand);
+			} else {
+				sms_log(pMac, LOGE,
+					" ******csr_roam_wm_status_change_complete fail to release command");
+			}
+
+		} else {
+			sms_log(pMac, LOGW,
+				"CSR: WmStatusChange Completion called but LOST LINK command is not ACTIVE ...");
+		}
+	} else {
+		sms_log(pMac, LOGW,
+			"CSR: WmStatusChange Completion called but NO commands are ACTIVE ...");
+	}
+	sme_process_pending_queue(pMac);
+}
+
+void csr_roam_process_wm_status_change_command(tpAniSirGlobal pMac,
+					       tSmeCmd *pCommand)
+{
+	CDF_STATUS status = CDF_STATUS_E_FAILURE;
+	tSirSmeRsp *pSirSmeMsg;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, pCommand->sessionId);
+
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("  session %d not found "),
+			pCommand->sessionId);
+		return;
+	}
+	sms_log(pMac, LOG1, FL("session:%d, CmdType : %d"),
+		pCommand->sessionId, pCommand->u.wmStatusChangeCmd.Type);
+
+	switch (pCommand->u.wmStatusChangeCmd.Type) {
+	case eCsrDisassociated:
+		pSirSmeMsg =
+			(tSirSmeRsp *) &pCommand->u.wmStatusChangeCmd.u.
+			DisassocIndMsg;
+		status =
+			csr_roam_lost_link(pMac, pCommand->sessionId,
+					   eWNI_SME_DISASSOC_IND, pSirSmeMsg);
+		break;
+	case eCsrDeauthenticated:
+		pSirSmeMsg =
+			(tSirSmeRsp *) &pCommand->u.wmStatusChangeCmd.u.
+			DeauthIndMsg;
+		status =
+			csr_roam_lost_link(pMac, pCommand->sessionId,
+					   eWNI_SME_DEAUTH_IND, pSirSmeMsg);
+		break;
+	default:
+		sms_log(pMac, LOGW, FL("gets an unknown command %d"),
+			pCommand->u.wmStatusChangeCmd.Type);
+		break;
+	}
+	/* For WDS, we want to stop BSS as well when it is indicated that it is disconnected. */
+	if (CSR_IS_CONN_WDS(&pSession->connectedProfile)) {
+		if (!CDF_IS_STATUS_SUCCESS
+			    (csr_roam_issue_stop_bss_cmd(pMac, pCommand->sessionId, true))) {
+			/* This is not good */
+			sms_log(pMac, LOGE,
+				FL("  failed to issue stopBSS command"));
+		}
+	}
+	/* Lost Link just triggers a roaming sequence.  We can complte the Lost Link */
+	/* command here since there is nothing else to do. */
+	csr_roam_wm_status_change_complete(pMac);
+}
+
+
+/**
+ * csr_compute_mode_and_band() - computes dot11mode
+ * @pMac:          mac global context
+ * @dot11_mode:    out param, do11 mode calculated
+ * @band:          out param, band caclculated
+ * @opr_ch:        operating channels
+ *
+ * This function finds dot11 mode based on current mode, operating channel and
+ * fw supported modes.
+ *
+ * Return: void
+ */
+static void
+csr_compute_mode_and_band(tpAniSirGlobal mac_ctx,
+			  eCsrCfgDot11Mode *dot11_mode,
+			  eCsrBand *band,
+			  uint8_t opr_ch)
+{
+	bool vht_24_ghz = mac_ctx->roam.configParam.enableVhtFor24GHz;
+	switch (mac_ctx->roam.configParam.uCfgDot11Mode) {
+	case eCSR_CFG_DOT11_MODE_11A:
+		*dot11_mode = eCSR_CFG_DOT11_MODE_11A;
+		*band = eCSR_BAND_5G;
+		break;
+	case eCSR_CFG_DOT11_MODE_11B:
+		*dot11_mode = eCSR_CFG_DOT11_MODE_11B;
+		*band = eCSR_BAND_24;
+		break;
+	case eCSR_CFG_DOT11_MODE_11G:
+		*dot11_mode = eCSR_CFG_DOT11_MODE_11G;
+		*band = eCSR_BAND_24;
+		break;
+	case eCSR_CFG_DOT11_MODE_11N:
+		*dot11_mode = eCSR_CFG_DOT11_MODE_11N;
+		*band = CSR_GET_BAND(opr_ch);
+		break;
+#ifdef WLAN_FEATURE_11AC
+	case eCSR_CFG_DOT11_MODE_11AC:
+		if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) {
+			/*
+			 * If the operating channel is in 2.4 GHz band, check
+			 * for INI item to disable VHT operation in 2.4 GHz band
+			 */
+			if (CDS_IS_CHANNEL_24GHZ(opr_ch) && !vht_24_ghz)
+				/* Disable 11AC operation */
+				*dot11_mode = eCSR_CFG_DOT11_MODE_11N;
+			else
+				*dot11_mode = eCSR_CFG_DOT11_MODE_11AC;
+		} else {
+			*dot11_mode = eCSR_CFG_DOT11_MODE_11N;
+		}
+		*band = CSR_GET_BAND(opr_ch);
+		break;
+	case eCSR_CFG_DOT11_MODE_11AC_ONLY:
+		if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) {
+			/*
+			 * If the operating channel is in 2.4 GHz band, check
+			 * for INI item to disable VHT operation in 2.4 GHz band
+			 */
+			if (CDS_IS_CHANNEL_24GHZ(opr_ch) && !vht_24_ghz)
+				/* Disable 11AC operation */
+				*dot11_mode = eCSR_CFG_DOT11_MODE_11N;
+			else
+				*dot11_mode = eCSR_CFG_DOT11_MODE_11AC_ONLY;
+		} else {
+			*dot11_mode = eCSR_CFG_DOT11_MODE_11N;
+		}
+		*band = CSR_GET_BAND(opr_ch);
+		break;
+#endif
+	case eCSR_CFG_DOT11_MODE_AUTO:
+#ifdef WLAN_FEATURE_11AC
+		if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) {
+			/*
+			 * If the operating channel is in 2.4 GHz band,
+			 * check for INI item to disable VHT operation
+			 * in 2.4 GHz band
+			 */
+			if (CDS_IS_CHANNEL_24GHZ(opr_ch)
+				&& !vht_24_ghz)
+				/* Disable 11AC operation */
+				*dot11_mode = eCSR_CFG_DOT11_MODE_11N;
+			else
+				*dot11_mode = eCSR_CFG_DOT11_MODE_11AC;
+		} else {
+			*dot11_mode = eCSR_CFG_DOT11_MODE_11N;
+		}
+#else
+		*dot11_mode = eCSR_CFG_DOT11_MODE_11N;
+#endif
+		*band = CSR_GET_BAND(opr_ch);
+		break;
+	default:
+		/*
+		 * Global dot11 Mode setting is 11a/b/g. use the channel number
+		 * to determine the Mode setting.
+		 */
+		if (eCSR_OPERATING_CHANNEL_AUTO == opr_ch) {
+			*band = mac_ctx->roam.configParam.eBand;
+			if (eCSR_BAND_24 == *band) {
+				/*
+				 * See reason in else if ( CDS_IS_CHANNEL_24GHZ
+				 * (opr_ch) ) to pick 11B
+				 */
+				*dot11_mode = eCSR_CFG_DOT11_MODE_11B;
+			} else {
+				/* prefer 5GHz */
+				*band = eCSR_BAND_5G;
+				*dot11_mode = eCSR_CFG_DOT11_MODE_11A;
+			}
+		} else if (CDS_IS_CHANNEL_24GHZ(opr_ch)) {
+			/*
+			 * WiFi tests require IBSS networks to start in 11b mode
+			 * without any change to the default parameter settings
+			 * on the adapter. We use ACU to start an IBSS through
+			 * creation of a startIBSS profile. This startIBSS
+			 * profile has Auto MACProtocol and the adapter property
+			 * setting for dot11Mode is also AUTO. So in this case,
+			 * let's start the IBSS network in 11b mode instead of
+			 * 11g mode. So this is for Auto=profile->MacProtocol &&
+			 * Auto=Global. dot11Mode && profile->channel is < 14,
+			 * then start the IBSS in b mode.
+			 *
+			 * Note: we used to have this start as an 11g IBSS for
+			 * best performance. now to specify that the user will
+			 * have to set the do11Mode in the property page to 11g
+			 * to force it.
+			 */
+			*dot11_mode = eCSR_CFG_DOT11_MODE_11B;
+			*band = eCSR_BAND_24;
+		} else {
+			/* else, it's a 5.0GHz channel.  Set mode to 11a. */
+			*dot11_mode = eCSR_CFG_DOT11_MODE_11A;
+			*band = eCSR_BAND_5G;
+		}
+		break;
+	} /* switch */
+}
+
+/**
+ * csr_roam_get_phy_mode_band_for_bss() - This function returns band and mode
+ * information.
+ * @mac_ctx:       mac global context
+ * @profile:       bss profile
+ * @band:          out param, band caclculated
+ * @opr_ch:        operating channels
+ *
+ * This function finds dot11 mode based on current mode, operating channel and
+ * fw supported modes. The only tricky part is that if phyMode is set to 11abg,
+ * this function may return eCSR_CFG_DOT11_MODE_11B instead of
+ * eCSR_CFG_DOT11_MODE_11G if everything is set to auto-pick.
+ *
+ * Return: dot11mode
+ */
+static eCsrCfgDot11Mode
+csr_roam_get_phy_mode_band_for_bss(tpAniSirGlobal mac_ctx,
+				   tCsrRoamProfile *profile,
+				   uint8_t opr_chn,
+				   eCsrBand *p_band)
+{
+	eCsrBand band;
+	eCsrCfgDot11Mode curr_mode = mac_ctx->roam.configParam.uCfgDot11Mode;
+	eCsrCfgDot11Mode cfg_dot11_mode =
+		csr_get_cfg_dot11_mode_from_csr_phy_mode(profile,
+			(eCsrPhyMode) profile->phyMode,
+			mac_ctx->roam.configParam.ProprietaryRatesEnabled);
+
+	/*
+	 * If the global setting for dot11Mode is set to auto/abg, we overwrite
+	 * the setting in the profile.
+	 */
+	if (((!CSR_IS_INFRA_AP(profile) && !CSR_IS_WDS(profile))
+	    && ((eCSR_CFG_DOT11_MODE_AUTO == curr_mode)
+	    || (eCSR_CFG_DOT11_MODE_ABG == curr_mode)))
+	    || (eCSR_CFG_DOT11_MODE_AUTO == cfg_dot11_mode)
+	    || (eCSR_CFG_DOT11_MODE_ABG == cfg_dot11_mode)) {
+		csr_compute_mode_and_band(mac_ctx, &cfg_dot11_mode,
+					  &band, opr_chn);
+	} /* if( eCSR_CFG_DOT11_MODE_ABG == cfg_dot11_mode ) */
+	else {
+		/* dot11 mode is set, lets pick the band */
+		if (eCSR_OPERATING_CHANNEL_AUTO == opr_chn) {
+			/* channel is Auto also. */
+			band = mac_ctx->roam.configParam.eBand;
+			if (eCSR_BAND_ALL == band) {
+				/* prefer 5GHz */
+				band = eCSR_BAND_5G;
+			}
+		} else{
+			band = CSR_GET_BAND(opr_chn);
+		}
+	}
+	if (p_band)
+		*p_band = band;
+
+	if (opr_chn == 14) {
+		sms_log(mac_ctx, LOGE, FL("Switching to Dot11B mode"));
+		cfg_dot11_mode = eCSR_CFG_DOT11_MODE_11B;
+	}
+
+	/*
+	 * Incase of WEP Security encryption type is coming as part of add key.
+	 * So while STart BSS dont have information
+	 */
+	if ((!CSR_IS_11n_ALLOWED(profile->EncryptionType.encryptionType[0])
+	    || ((profile->privacy == 1)
+		&& (profile->EncryptionType.encryptionType[0] ==
+		eCSR_ENCRYPT_TYPE_NONE)))
+		&& ((eCSR_CFG_DOT11_MODE_11N == cfg_dot11_mode) ||
+#ifdef WLAN_FEATURE_11AC
+	     (eCSR_CFG_DOT11_MODE_11AC == cfg_dot11_mode)
+#endif
+	     )) {
+		/* We cannot do 11n here */
+		if (CDS_IS_CHANNEL_24GHZ(opr_chn))
+			cfg_dot11_mode = eCSR_CFG_DOT11_MODE_11G;
+		else
+			cfg_dot11_mode = eCSR_CFG_DOT11_MODE_11A;
+	}
+	return cfg_dot11_mode;
+}
+
+CDF_STATUS csr_roam_issue_stop_bss(tpAniSirGlobal pMac, uint32_t sessionId,
+				   eCsrRoamSubState NewSubstate)
+{
+	CDF_STATUS status;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("  session %d not found "), sessionId);
+		return CDF_STATUS_E_FAILURE;
+	}
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+	{
+		host_log_ibss_pkt_type *pIbssLog;
+		WLAN_HOST_DIAG_LOG_ALLOC(pIbssLog, host_log_ibss_pkt_type,
+					 LOG_WLAN_IBSS_C);
+		if (pIbssLog) {
+			pIbssLog->eventId = WLAN_IBSS_EVENT_STOP_REQ;
+			WLAN_HOST_DIAG_LOG_REPORT(pIbssLog);
+		}
+	}
+#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
+	/* Set the roaming substate to 'stop Bss request'... */
+	csr_roam_substate_change(pMac, NewSubstate, sessionId);
+
+	/* attempt to stop the Bss (reason code is ignored...) */
+	status = csr_send_mb_stop_bss_req_msg(pMac, sessionId);
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		sms_log(pMac, LOGW,
+			FL("csr_send_mb_stop_bss_req_msg failed with status %d"),
+			status);
+	}
+	return status;
+}
+
+/* pNumChan is a caller allocated space with the sizeof pChannels */
+CDF_STATUS csr_get_cfg_valid_channels(tpAniSirGlobal pMac, uint8_t *pChannels,
+				      uint32_t *pNumChan)
+{
+	if (!IS_SIR_STATUS_SUCCESS(wlan_cfg_get_str(pMac,
+					WNI_CFG_VALID_CHANNEL_LIST,
+					(uint8_t *) pChannels, pNumChan)))
+		return CDF_STATUS_E_FAILURE;
+	return CDF_STATUS_SUCCESS;
+}
+
+tPowerdBm csr_get_cfg_max_tx_power(tpAniSirGlobal pMac, uint8_t channel)
+{
+	uint32_t cfgLength = 0;
+	uint16_t cfgId = 0;
+	tPowerdBm maxTxPwr = 0;
+	uint8_t *pCountryInfo = NULL;
+	CDF_STATUS status;
+	uint8_t count = 0;
+	uint8_t firstChannel;
+	uint8_t maxChannels;
+
+	if (CDS_IS_CHANNEL_5GHZ(channel)) {
+		cfgId = WNI_CFG_MAX_TX_POWER_5;
+		cfgLength = WNI_CFG_MAX_TX_POWER_5_LEN;
+	} else if (CDS_IS_CHANNEL_24GHZ(channel)) {
+		cfgId = WNI_CFG_MAX_TX_POWER_2_4;
+		cfgLength = WNI_CFG_MAX_TX_POWER_2_4_LEN;
+	} else
+		return maxTxPwr;
+
+	pCountryInfo = cdf_mem_malloc(cfgLength);
+	if (NULL == pCountryInfo)
+		status = CDF_STATUS_E_NOMEM;
+	else
+		status = CDF_STATUS_SUCCESS;
+	if (status != CDF_STATUS_SUCCESS) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+			  FL("%s: failed to allocate memory, status = %d"),
+			  __FUNCTION__, status);
+		goto error;
+	}
+	if (wlan_cfg_get_str(pMac, cfgId, (uint8_t *)pCountryInfo,
+			&cfgLength) != eSIR_SUCCESS) {
+		goto error;
+	}
+	/* Identify the channel and maxtxpower */
+	while (count <= (cfgLength - (sizeof(tSirMacChanInfo)))) {
+		firstChannel = pCountryInfo[count++];
+		maxChannels = pCountryInfo[count++];
+		maxTxPwr = pCountryInfo[count++];
+
+		if ((channel >= firstChannel) &&
+		    (channel < (firstChannel + maxChannels))) {
+			break;
+		}
+	}
+
+error:
+	if (NULL != pCountryInfo)
+		cdf_mem_free(pCountryInfo);
+
+	return maxTxPwr;
+}
+
+bool csr_roam_is_channel_valid(tpAniSirGlobal pMac, uint8_t channel)
+{
+	bool fValid = false;
+	uint32_t idxValidChannels;
+	uint32_t len = sizeof(pMac->roam.validChannelList);
+
+	if (CDF_IS_STATUS_SUCCESS
+		    (csr_get_cfg_valid_channels(pMac, pMac->roam.validChannelList, &len))) {
+		for (idxValidChannels = 0; (idxValidChannels < len);
+		     idxValidChannels++) {
+			if (channel ==
+			    pMac->roam.validChannelList[idxValidChannels]) {
+				fValid = true;
+				break;
+			}
+		}
+	}
+	pMac->roam.numValidChannels = len;
+	return fValid;
+}
+
+bool csr_roam_is_valid40_mhz_channel(tpAniSirGlobal pMac, uint8_t channel)
+{
+	bool fValid = false;
+	uint8_t i;
+	for (i = 0; i < pMac->scan.base40MHzChannels.numChannels; i++) {
+		if (channel == pMac->scan.base40MHzChannels.channelList[i]) {
+			fValid = true;
+			break;
+		}
+	}
+	return fValid;
+}
+
+/* This function check and validate whether the NIC can do CB (40MHz) */
+static ePhyChanBondState csr_get_cb_mode_from_ies(tpAniSirGlobal pMac,
+						  uint8_t primaryChn,
+						  tDot11fBeaconIEs *pIes)
+{
+	ePhyChanBondState eRet = PHY_SINGLE_CHANNEL_CENTERED;
+	uint8_t centerChn;
+	uint32_t ChannelBondingMode;
+	if (CDS_IS_CHANNEL_24GHZ(primaryChn)) {
+		/*
+		 * gChannelBondingMode24GHz configuration item is common for
+		 * SAP and STA mode and currently MDM does not support
+		 * HT40 in 2.4Ghz STA mode.
+		 * So disabling the HT40 in 2.4GHz station mode
+		 */
+#ifdef QCA_HT_20_24G_STA_ONLY
+		ChannelBondingMode = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
+#else
+		ChannelBondingMode =
+			pMac->roam.configParam.channelBondingMode24GHz;
+#endif
+	} else {
+		ChannelBondingMode =
+			pMac->roam.configParam.channelBondingMode5GHz;
+	}
+
+	if (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE == ChannelBondingMode)
+		return PHY_SINGLE_CHANNEL_CENTERED;
+
+	/* Figure what the other side's CB mode */
+	if (!(pIes->HTCaps.present && (eHT_CHANNEL_WIDTH_40MHZ ==
+		pIes->HTCaps.supportedChannelWidthSet))) {
+		return PHY_SINGLE_CHANNEL_CENTERED;
+	}
+
+	/* Check set as TKIP or not. */
+	if (((NULL != &(pIes->RSN.pwise_cipher_suites[0][0]) &&
+		(pIes->RSN.pwise_cipher_suite_count == 1)) &&
+		!memcmp(&(pIes->RSN.pwise_cipher_suites[0][0]),
+		     "\x00\x0f\xac\x02", 4))
+	    || (((NULL != &(pIes->WPA)) &&
+		 (pIes->WPA.unicast_cipher_count == 1))
+		&& ((NULL != &(pIes->WPA.unicast_ciphers[0]))
+		    && !memcmp(&(pIes->WPA.unicast_ciphers[0]),
+			       "\x00\x0f\xac\x02", 4)))) {
+		sms_log(pMac, LOGW,
+			" No channel bonding in TKIP mode ");
+		return PHY_SINGLE_CHANNEL_CENTERED;
+	}
+
+	if (!pIes->HTInfo.present)
+		return PHY_SINGLE_CHANNEL_CENTERED;
+
+	/*
+	 * This is called during INFRA STA/CLIENT and should use the merged
+	 * value of supported channel width and recommended tx width as per
+	 * standard
+	 */
+	sms_log(pMac, LOG1, "scws %u rtws %u sco %u",
+		pIes->HTCaps.supportedChannelWidthSet,
+		pIes->HTInfo.recommendedTxWidthSet,
+		pIes->HTInfo.secondaryChannelOffset);
+
+	if (pIes->HTInfo.recommendedTxWidthSet == eHT_CHANNEL_WIDTH_40MHZ)
+		eRet = (ePhyChanBondState)pIes->HTInfo.secondaryChannelOffset;
+	else
+		eRet = PHY_SINGLE_CHANNEL_CENTERED;
+
+	switch (eRet) {
+	case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
+		centerChn = primaryChn + CSR_CB_CENTER_CHANNEL_OFFSET;
+		break;
+	case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
+		centerChn = primaryChn - CSR_CB_CENTER_CHANNEL_OFFSET;
+		break;
+	case PHY_SINGLE_CHANNEL_CENTERED:
+	default:
+		centerChn = primaryChn;
+		break;
+	}
+
+	if ((PHY_SINGLE_CHANNEL_CENTERED != eRet)
+	    && !csr_roam_is_valid40_mhz_channel(pMac, centerChn)) {
+		sms_log(pMac, LOGE,
+			"Invalid center channel (%d), disable 40MHz mode",
+			centerChn);
+		eRet = PHY_SINGLE_CHANNEL_CENTERED;
+	}
+	return eRet;
+}
+
+bool csr_is_encryption_in_list(tpAniSirGlobal pMac,
+			       tCsrEncryptionList *pCipherList,
+			       eCsrEncryptionType encryptionType)
+{
+	bool fFound = false;
+	uint32_t idx;
+	for (idx = 0; idx < pCipherList->numEntries; idx++) {
+		if (pCipherList->encryptionType[idx] == encryptionType) {
+			fFound = true;
+			break;
+		}
+	}
+	return fFound;
+}
+
+bool csr_is_auth_in_list(tpAniSirGlobal pMac, tCsrAuthList *pAuthList,
+			 eCsrAuthType authType)
+{
+	bool fFound = false;
+	uint32_t idx;
+	for (idx = 0; idx < pAuthList->numEntries; idx++) {
+		if (pAuthList->authType[idx] == authType) {
+			fFound = true;
+			break;
+		}
+	}
+	return fFound;
+}
+
+bool csr_is_same_profile(tpAniSirGlobal pMac,
+			 tCsrRoamConnectedProfile *pProfile1,
+			 tCsrRoamProfile *pProfile2)
+{
+	uint32_t i;
+	bool fCheck = false;
+	tCsrScanResultFilter *pScanFilter = NULL;
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+
+	if (!(pProfile1 && pProfile2))
+		return fCheck;
+	pScanFilter = cdf_mem_malloc(sizeof(tCsrScanResultFilter));
+	if (NULL == pScanFilter)
+		return fCheck;
+
+	cdf_mem_set(pScanFilter, sizeof(tCsrScanResultFilter), 0);
+	status = csr_roam_prepare_filter_from_profile(pMac, pProfile2,
+						      pScanFilter);
+	if (!(CDF_IS_STATUS_SUCCESS(status)))
+		goto free_scan_filter;
+
+	for (i = 0; i < pScanFilter->SSIDs.numOfSSIDs; i++) {
+		fCheck = csr_is_ssid_match(pMac,
+				pScanFilter->SSIDs.SSIDList[i].SSID.ssId,
+				pScanFilter->SSIDs.SSIDList[i].SSID.length,
+				pProfile1->SSID.ssId,
+				pProfile1->SSID.length,
+				false);
+		if (fCheck)
+			break;
+	}
+	if (!fCheck)
+		goto free_scan_filter;
+
+	if (!csr_is_auth_in_list(pMac, &pProfile2->AuthType,
+				 pProfile1->AuthType)
+	    || (pProfile2->BSSType != pProfile1->BSSType)
+	    || !csr_is_encryption_in_list(pMac, &pProfile2->EncryptionType,
+					  pProfile1->EncryptionType)) {
+		fCheck = false;
+		goto free_scan_filter;
+	}
+#ifdef WLAN_FEATURE_VOWIFI_11R
+	if (pProfile1->MDID.mdiePresent || pProfile2->MDID.mdiePresent) {
+		if (pProfile1->MDID.mobilityDomain
+			!= pProfile2->MDID.mobilityDomain) {
+			fCheck = false;
+			goto free_scan_filter;
+		}
+	}
+#endif
+	/* Match found */
+	fCheck = true;
+free_scan_filter:
+	csr_free_scan_filter(pMac, pScanFilter);
+	cdf_mem_free(pScanFilter);
+	return fCheck;
+}
+
+bool csr_roam_is_same_profile_keys(tpAniSirGlobal pMac,
+				   tCsrRoamConnectedProfile *pConnProfile,
+				   tCsrRoamProfile *pProfile2)
+{
+	bool fCheck = false;
+	int i;
+	do {
+		/* Only check for static WEP */
+		if (!csr_is_encryption_in_list
+			    (pMac, &pProfile2->EncryptionType,
+			    eCSR_ENCRYPT_TYPE_WEP40_STATICKEY)
+		    && !csr_is_encryption_in_list(pMac,
+				&pProfile2->EncryptionType,
+				eCSR_ENCRYPT_TYPE_WEP104_STATICKEY)) {
+			fCheck = true;
+			break;
+		}
+		if (!csr_is_encryption_in_list
+			    (pMac, &pProfile2->EncryptionType,
+			    pConnProfile->EncryptionType))
+			break;
+		if (pConnProfile->Keys.defaultIndex !=
+		    pProfile2->Keys.defaultIndex)
+			break;
+		for (i = 0; i < CSR_MAX_NUM_KEY; i++) {
+			if (pConnProfile->Keys.KeyLength[i] !=
+			    pProfile2->Keys.KeyLength[i])
+				break;
+			if (!cdf_mem_compare(&pConnProfile->Keys.KeyMaterial[i],
+					     &pProfile2->Keys.KeyMaterial[i],
+					     pProfile2->Keys.KeyLength[i])) {
+				break;
+			}
+		}
+		if (i == CSR_MAX_NUM_KEY) {
+			fCheck = true;
+		}
+	} while (0);
+	return fCheck;
+}
+
+/* IBSS */
+
+uint8_t csr_roam_get_ibss_start_channel_number50(tpAniSirGlobal pMac)
+{
+	uint8_t channel = 0;
+	uint32_t idx;
+	uint32_t idxValidChannels;
+	bool fFound = false;
+	uint32_t len = sizeof(pMac->roam.validChannelList);
+
+	if (eCSR_OPERATING_CHANNEL_ANY != pMac->roam.configParam.AdHocChannel5G) {
+		channel = pMac->roam.configParam.AdHocChannel5G;
+		if (!csr_roam_is_channel_valid(pMac, channel)) {
+			channel = 0;
+		}
+	}
+	if (0 == channel
+	    &&
+	    CDF_IS_STATUS_SUCCESS(csr_get_cfg_valid_channels
+					  (pMac,
+					  (uint8_t *) pMac->roam.validChannelList,
+					  &len))) {
+		for (idx = 0; (idx < CSR_NUM_IBSS_START_CHANNELS_50) && !fFound;
+		     idx++) {
+			for (idxValidChannels = 0;
+			     (idxValidChannels < len) && !fFound;
+			     idxValidChannels++) {
+				if (csr_start_ibss_channels50[idx] ==
+				    pMac->roam.
+				    validChannelList[idxValidChannels]) {
+					fFound = true;
+					channel = csr_start_ibss_channels50[idx];
+				}
+			}
+		}
+		/*
+		 * this is rare, but if it does happen,
+		 * we find anyone in 11a bandwidth and
+		 * return the first 11a channel found!
+		 */
+		if (!fFound) {
+			for (idxValidChannels = 0; idxValidChannels < len;
+			     idxValidChannels++) {
+				if (CDS_IS_CHANNEL_5GHZ(pMac->roam.
+					validChannelList[idxValidChannels])) {
+					/* the max channel# in 11g is 14 */
+					if (idxValidChannels <
+					    CSR_NUM_IBSS_START_CHANNELS_50) {
+						channel =
+						pMac->roam.validChannelList
+						[idxValidChannels];
+					}
+					break;
+				}
+			}
+		}
+	} /* if */
+
+	return channel;
+}
+
+uint8_t csr_roam_get_ibss_start_channel_number24(tpAniSirGlobal pMac)
+{
+	uint8_t channel = 1;
+	uint32_t idx;
+	uint32_t idxValidChannels;
+	bool fFound = false;
+	uint32_t len = sizeof(pMac->roam.validChannelList);
+
+	if (eCSR_OPERATING_CHANNEL_ANY != pMac->roam.configParam.AdHocChannel24) {
+		channel = pMac->roam.configParam.AdHocChannel24;
+		if (!csr_roam_is_channel_valid(pMac, channel)) {
+			channel = 0;
+		}
+	}
+
+	if (0 == channel
+	    &&
+	    CDF_IS_STATUS_SUCCESS(csr_get_cfg_valid_channels
+					  (pMac,
+					  (uint8_t *) pMac->roam.validChannelList,
+					  &len))) {
+		for (idx = 0; (idx < CSR_NUM_IBSS_START_CHANNELS_24) && !fFound;
+		     idx++) {
+			for (idxValidChannels = 0;
+			     (idxValidChannels < len) && !fFound;
+			     idxValidChannels++) {
+				if (csr_start_ibss_channels24[idx] ==
+				    pMac->roam.
+				    validChannelList[idxValidChannels]) {
+					fFound = true;
+					channel = csr_start_ibss_channels24[idx];
+				}
+			}
+		}
+	}
+
+	return channel;
+}
+
+/**
+ * csr_populate_basic_rates() - populates OFDM or CCK rates
+ * @rates:         rate struct to populate
+ * @type:          true: ofdm rates, false: cck rates
+ * @masked:        indicates if rates are to be masked with
+ *                 CSR_DOT11_BASIC_RATE_MASK
+ *
+ * This function will populate OFDM or CCK rates
+ *
+ * Return: void
+ */
+static void
+csr_populate_basic_rates(tSirMacRateSet *rate_set, bool type, bool masked)
+{
+	uint8_t ofdm_rates[8] = {
+		SIR_MAC_RATE_6,
+		SIR_MAC_RATE_9,
+		SIR_MAC_RATE_12,
+		SIR_MAC_RATE_18,
+		SIR_MAC_RATE_24,
+		SIR_MAC_RATE_36,
+		SIR_MAC_RATE_48,
+		SIR_MAC_RATE_54
+	};
+	uint8_t cck_rates[4] = {
+		SIR_MAC_RATE_1,
+		SIR_MAC_RATE_2,
+		SIR_MAC_RATE_5_5,
+		SIR_MAC_RATE_11
+	};
+
+	if (type == true) {
+		rate_set->numRates = 8;
+		cdf_mem_copy(rate_set->rate, ofdm_rates, sizeof(ofdm_rates));
+		if (masked) {
+			rate_set->rate[0] |= CSR_DOT11_BASIC_RATE_MASK;
+			rate_set->rate[2] |= CSR_DOT11_BASIC_RATE_MASK;
+			rate_set->rate[4] |= CSR_DOT11_BASIC_RATE_MASK;
+		}
+	} else {
+		rate_set->numRates = 4;
+		cdf_mem_copy(rate_set->rate, cck_rates, sizeof(cck_rates));
+		if (masked) {
+			rate_set->rate[0] |= CSR_DOT11_BASIC_RATE_MASK;
+			rate_set->rate[1] |= CSR_DOT11_BASIC_RATE_MASK;
+			rate_set->rate[2] |= CSR_DOT11_BASIC_RATE_MASK;
+			rate_set->rate[3] |= CSR_DOT11_BASIC_RATE_MASK;
+		}
+	}
+}
+
+/**
+ * csr_convert_mode_to_nw_type() - convert mode into network type
+ * @dot11_mode:    dot11_mode
+ * @band:          2.4 or 5 GHz
+ *
+ * Return: tSirNwType
+ */
+static tSirNwType
+csr_convert_mode_to_nw_type(eCsrCfgDot11Mode dot11_mode, eCsrBand band)
+{
+	switch (dot11_mode) {
+	case eCSR_CFG_DOT11_MODE_11G:
+		return eSIR_11G_NW_TYPE;
+	case eCSR_CFG_DOT11_MODE_11B:
+		return eSIR_11B_NW_TYPE;
+	case eCSR_CFG_DOT11_MODE_11A:
+		return eSIR_11A_NW_TYPE;
+	case eCSR_CFG_DOT11_MODE_11N:
+	default:
+		/*
+		 * Because LIM only verifies it against 11a, 11b or 11g, set
+		 * only 11g or 11a here
+		 */
+		if (eCSR_BAND_24 == band)
+			return eSIR_11G_NW_TYPE;
+		else
+			return eSIR_11A_NW_TYPE;
+	}
+	return eSIR_DONOT_USE_NW_TYPE;
+}
+
+/**
+ * csr_roam_get_bss_start_parms() - get bss start param from profile
+ * @pMac:          mac global context
+ * @pProfile:      roam profile
+ * @pParam:        out param, start bss params
+ *
+ * This function populates start bss param from roam profile
+ *
+ * Return: void
+ */
+static void
+csr_roam_get_bss_start_parms(tpAniSirGlobal pMac,
+			     tCsrRoamProfile *pProfile,
+			     tCsrRoamStartBssParams *pParam)
+{
+	eCsrBand band;
+	uint8_t opr_ch = 0;
+	tSirNwType nw_type;
+	uint8_t tmp_opr_ch = 0;
+	tSirMacRateSet *opr_rates = &pParam->operationalRateSet;
+	tSirMacRateSet *ext_rates = &pParam->extendedRateSet;
+
+	if (pProfile->ChannelInfo.numOfChannels
+	    && pProfile->ChannelInfo.ChannelList) {
+		tmp_opr_ch = pProfile->ChannelInfo.ChannelList[0];
+	}
+
+	pParam->uCfgDot11Mode = csr_roam_get_phy_mode_band_for_bss(pMac,
+					 pProfile, tmp_opr_ch, &band);
+
+	if (((pProfile->csrPersona == CDF_P2P_CLIENT_MODE)
+	    || (pProfile->csrPersona == CDF_P2P_GO_MODE))
+	    && (pParam->uCfgDot11Mode == eCSR_CFG_DOT11_MODE_11B)) {
+		/* This should never happen */
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_FATAL,
+			  FL("For P2P (persona %d) dot11_mode is 11B"),
+			  pProfile->csrPersona);
+		CDF_ASSERT(0);
+	}
+
+	nw_type = csr_convert_mode_to_nw_type(pParam->uCfgDot11Mode, band);
+	ext_rates->numRates = 0;
+
+	switch (nw_type) {
+	default:
+		sms_log(pMac, LOGE, FL("sees an unknown pSirNwType (%d)"),
+			nw_type);
+	case eSIR_11A_NW_TYPE:
+		csr_populate_basic_rates(opr_rates, true, true);
+		if (eCSR_OPERATING_CHANNEL_ANY != tmp_opr_ch) {
+			opr_ch = tmp_opr_ch;
+			break;
+		}
+		opr_ch = csr_roam_get_ibss_start_channel_number50(pMac);
+		if (0 == opr_ch &&
+		    CSR_IS_PHY_MODE_DUAL_BAND(pProfile->phyMode) &&
+		    CSR_IS_PHY_MODE_DUAL_BAND(pMac->roam.configParam.phyMode)) {
+			/*
+			 * We could not find a 5G channel by auto pick, let's
+			 * try 2.4G channels. We only do this here because
+			 * csr_roam_get_phy_mode_band_for_bss always picks 11a
+			 * for AUTO
+			 */
+			nw_type = eSIR_11B_NW_TYPE;
+			opr_ch = csr_roam_get_ibss_start_channel_number24(pMac);
+			csr_populate_basic_rates(opr_rates, false, true);
+		}
+		break;
+	case eSIR_11B_NW_TYPE:
+		csr_populate_basic_rates(opr_rates, false, true);
+		if (eCSR_OPERATING_CHANNEL_ANY == tmp_opr_ch)
+			opr_ch = csr_roam_get_ibss_start_channel_number24(pMac);
+		else
+			opr_ch = tmp_opr_ch;
+		break;
+	case eSIR_11G_NW_TYPE:
+		/* For P2P Client and P2P GO, disable 11b rates */
+		if ((pProfile->csrPersona == CDF_P2P_CLIENT_MODE)
+		    || (pProfile->csrPersona == CDF_P2P_GO_MODE)
+		    || (eCSR_CFG_DOT11_MODE_11G_ONLY ==
+					pParam->uCfgDot11Mode)) {
+			csr_populate_basic_rates(opr_rates, true, true);
+		} else {
+			csr_populate_basic_rates(opr_rates, false, true);
+			csr_populate_basic_rates(ext_rates, true, false);
+		}
+
+		if (eCSR_OPERATING_CHANNEL_ANY == tmp_opr_ch)
+			opr_ch = csr_roam_get_ibss_start_channel_number24(pMac);
+		else
+			opr_ch = tmp_opr_ch;
+		break;
+	}
+	pParam->operationChn = opr_ch;
+	pParam->sirNwType = nw_type;
+	pParam->ch_params.ch_width = pProfile->ch_params.ch_width;
+	pParam->ch_params.center_freq_seg0 =
+		pProfile->ch_params.center_freq_seg0;
+	pParam->ch_params.center_freq_seg1 =
+		pProfile->ch_params.center_freq_seg1;
+	pParam->ch_params.sec_ch_offset =
+		pProfile->ch_params.sec_ch_offset;
+}
+
+static void
+csr_roam_get_bss_start_parms_from_bss_desc(tpAniSirGlobal pMac,
+					   tSirBssDescription *pBssDesc,
+					   tDot11fBeaconIEs *pIes,
+					   tCsrRoamStartBssParams *pParam)
+{
+	if (!pParam) {
+		sms_log(pMac, LOGE, FL("BSS param's pointer is NULL"));
+		return;
+	}
+
+	pParam->sirNwType = pBssDesc->nwType;
+	pParam->cbMode = PHY_SINGLE_CHANNEL_CENTERED;
+	pParam->operationChn = pBssDesc->channelId;
+	cdf_mem_copy(&pParam->bssid, pBssDesc->bssId, sizeof(struct cdf_mac_addr));
+
+	if (!pIes) {
+		pParam->ssId.length = 0;
+		pParam->operationalRateSet.numRates = 0;
+		sms_log(pMac, LOGE, FL("IEs struct pointer is NULL"));
+		return;
+	}
+
+	if (pIes->SuppRates.present) {
+		pParam->operationalRateSet.numRates = pIes->SuppRates.num_rates;
+		if (pIes->SuppRates.num_rates > SIR_MAC_RATESET_EID_MAX) {
+			sms_log(pMac, LOGE,
+				FL("num_rates: %d > max val, resetting"),
+				pIes->SuppRates.num_rates);
+			pIes->SuppRates.num_rates = SIR_MAC_RATESET_EID_MAX;
+		}
+		cdf_mem_copy(pParam->operationalRateSet.rate,
+			     pIes->SuppRates.rates,
+			     sizeof(*pIes->SuppRates.rates) *
+			     pIes->SuppRates.num_rates);
+	}
+	if (pIes->ExtSuppRates.present) {
+		pParam->extendedRateSet.numRates = pIes->ExtSuppRates.num_rates;
+		if (pIes->ExtSuppRates.num_rates > SIR_MAC_RATESET_EID_MAX) {
+			sms_log(pMac, LOGE,
+				FL("num_rates: %d > max val, resetting"),
+				pIes->ExtSuppRates.num_rates);
+			pIes->ExtSuppRates.num_rates = SIR_MAC_RATESET_EID_MAX;
+		}
+		cdf_mem_copy(pParam->extendedRateSet.rate,
+			     pIes->ExtSuppRates.rates,
+			     sizeof(*pIes->ExtSuppRates.rates) *
+			     pIes->ExtSuppRates.num_rates);
+	}
+	if (pIes->SSID.present) {
+		pParam->ssId.length = pIes->SSID.num_ssid;
+		cdf_mem_copy(pParam->ssId.ssId, pIes->SSID.ssid,
+			     pParam->ssId.length);
+	}
+	pParam->cbMode = csr_get_cb_mode_from_ies(pMac, pParam->operationChn,
+						  pIes);
+}
+
+static void csr_roam_determine_max_rate_for_ad_hoc(tpAniSirGlobal pMac,
+						   tSirMacRateSet *pSirRateSet)
+{
+	uint8_t MaxRate = 0;
+	uint32_t i;
+	uint8_t *pRate;
+
+	pRate = pSirRateSet->rate;
+	for (i = 0; i < pSirRateSet->numRates; i++) {
+		MaxRate =
+			CSR_MAX(MaxRate, (pRate[i] & (~CSR_DOT11_BASIC_RATE_MASK)));
+	}
+
+	/* Save the max rate in the connected state information... */
+
+	/* modify LastRates variable as well */
+
+	return;
+}
+
+CDF_STATUS csr_roam_issue_start_bss(tpAniSirGlobal pMac, uint32_t sessionId,
+				    tCsrRoamStartBssParams *pParam,
+				    tCsrRoamProfile *pProfile,
+				    tSirBssDescription *pBssDesc, uint32_t roamId)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	eCsrBand eBand;
+	/* Set the roaming substate to 'Start BSS attempt'... */
+	csr_roam_substate_change(pMac, eCSR_ROAM_SUBSTATE_START_BSS_REQ,
+				 sessionId);
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+	/* Need to figure out whether we need to log WDS??? */
+	if (CSR_IS_IBSS(pProfile)) {
+		host_log_ibss_pkt_type *pIbssLog;
+		WLAN_HOST_DIAG_LOG_ALLOC(pIbssLog, host_log_ibss_pkt_type,
+					 LOG_WLAN_IBSS_C);
+		if (pIbssLog) {
+			if (pBssDesc) {
+				pIbssLog->eventId =
+					WLAN_IBSS_EVENT_JOIN_IBSS_REQ;
+				cdf_mem_copy(pIbssLog->bssid, pBssDesc->bssId,
+					     6);
+			} else {
+				pIbssLog->eventId =
+					WLAN_IBSS_EVENT_START_IBSS_REQ;
+			}
+			cdf_mem_copy(pIbssLog->ssid, pParam->ssId.ssId,
+				     pParam->ssId.length);
+			if (pProfile->ChannelInfo.numOfChannels == 0) {
+				pIbssLog->channelSetting = AUTO_PICK;
+			} else {
+				pIbssLog->channelSetting = SPECIFIED;
+			}
+			pIbssLog->operatingChannel = pParam->operationChn;
+			WLAN_HOST_DIAG_LOG_REPORT(pIbssLog);
+		}
+	}
+#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
+	/* Put RSN information in for Starting BSS */
+	pParam->nRSNIELength = (uint16_t) pProfile->nRSNReqIELength;
+	pParam->pRSNIE = pProfile->pRSNReqIE;
+
+	pParam->privacy = pProfile->privacy;
+	pParam->fwdWPSPBCProbeReq = pProfile->fwdWPSPBCProbeReq;
+	pParam->authType = pProfile->csr80211AuthType;
+	pParam->beaconInterval = pProfile->beaconInterval;
+	pParam->dtimPeriod = pProfile->dtimPeriod;
+	pParam->ApUapsdEnable = pProfile->ApUapsdEnable;
+	pParam->ssidHidden = pProfile->SSIDs.SSIDList[0].ssidHidden;
+	if (CSR_IS_INFRA_AP(pProfile) && (pParam->operationChn != 0)) {
+		if (csr_is_valid_channel(pMac, pParam->operationChn) !=
+		    CDF_STATUS_SUCCESS) {
+			pParam->operationChn = INFRA_AP_DEFAULT_CHANNEL;
+		}
+	}
+	pParam->protEnabled = pProfile->protEnabled;
+	pParam->obssProtEnabled = pProfile->obssProtEnabled;
+	pParam->ht_protection = pProfile->cfg_protection;
+	pParam->wps_state = pProfile->wps_state;
+
+	pParam->uCfgDot11Mode =
+		csr_roam_get_phy_mode_band_for_bss(pMac, pProfile,
+						   pParam->
+						   operationChn,
+						   &eBand);
+	pParam->bssPersona = pProfile->csrPersona;
+
+#ifdef WLAN_FEATURE_11W
+	pParam->mfpCapable = (0 != pProfile->MFPCapable);
+	pParam->mfpRequired = (0 != pProfile->MFPRequired);
+#endif
+
+	pParam->addIeParams.probeRespDataLen =
+		pProfile->addIeParams.probeRespDataLen;
+	pParam->addIeParams.probeRespData_buff =
+		pProfile->addIeParams.probeRespData_buff;
+
+	pParam->addIeParams.assocRespDataLen =
+		pProfile->addIeParams.assocRespDataLen;
+	pParam->addIeParams.assocRespData_buff =
+		pProfile->addIeParams.assocRespData_buff;
+
+	if (CSR_IS_IBSS(pProfile)) {
+		pParam->addIeParams.probeRespBCNDataLen =
+			pProfile->nWPAReqIELength;
+		pParam->addIeParams.probeRespBCNData_buff = pProfile->pWPAReqIE;
+	} else {
+		pParam->addIeParams.probeRespBCNDataLen =
+			pProfile->addIeParams.probeRespBCNDataLen;
+		pParam->addIeParams.probeRespBCNData_buff =
+			pProfile->addIeParams.probeRespBCNData_buff;
+	}
+	pParam->sap_dot11mc = pProfile->sap_dot11mc;
+
+	/* When starting an IBSS, start on the channel from the Profile. */
+	status =
+		csr_send_mb_start_bss_req_msg(pMac, sessionId, pProfile->BSSType, pParam,
+					      pBssDesc);
+	return status;
+}
+
+static void csr_roam_prepare_bss_params(tpAniSirGlobal pMac, uint32_t sessionId,
+					tCsrRoamProfile *pProfile,
+					tSirBssDescription *pBssDesc,
+					tBssConfigParam *pBssConfig,
+					tDot11fBeaconIEs *pIes)
+{
+	uint8_t Channel;
+	ePhyChanBondState cbMode = PHY_SINGLE_CHANNEL_CENTERED;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("  session %d not found "), sessionId);
+		return;
+	}
+
+	if (pBssDesc) {
+		csr_roam_get_bss_start_parms_from_bss_desc(pMac, pBssDesc, pIes,
+							   &pSession->bssParams);
+		/* Since csr_roam_get_bss_start_parms_from_bss_desc fills in the bssid for pSession->bssParams */
+		/* The following code has to be do after that. */
+		/* For WDS station, use selfMac as the self BSSID */
+		if (CSR_IS_WDS_STA(pProfile)) {
+			cdf_mem_copy(&pSession->bssParams.bssid,
+				     &pSession->selfMacAddr,
+				     sizeof(struct cdf_mac_addr));
+		}
+	} else {
+		csr_roam_get_bss_start_parms(pMac, pProfile, &pSession->bssParams);
+		/* Use the first SSID */
+		if (pProfile->SSIDs.numOfSSIDs) {
+			cdf_mem_copy(&pSession->bssParams.ssId,
+				     pProfile->SSIDs.SSIDList,
+				     sizeof(tSirMacSSid));
+		}
+		/* For WDS station, use selfMac as the self BSSID */
+		if (CSR_IS_WDS_STA(pProfile)) {
+			cdf_mem_copy(&pSession->bssParams.bssid,
+				     &pSession->selfMacAddr,
+				     sizeof(struct cdf_mac_addr));
+		}
+		/* Use the first BSSID */
+		else if (pProfile->BSSIDs.numOfBSSIDs) {
+			cdf_mem_copy(&pSession->bssParams.bssid,
+				     pProfile->BSSIDs.bssid,
+				     sizeof(struct cdf_mac_addr));
+		} else {
+			cdf_mem_set(&pSession->bssParams.bssid,
+				    sizeof(struct cdf_mac_addr), 0);
+		}
+	}
+	Channel = pSession->bssParams.operationChn;
+	/* Set operating channel in pProfile which will be used */
+	/* in csr_roam_set_bss_config_cfg() to determine channel bonding */
+	/* mode and will be configured in CFG later */
+	pProfile->operationChannel = Channel;
+
+	if (Channel == 0) {
+		sms_log(pMac, LOGE,
+			"   CSR cannot find a channel to start IBSS");
+	} else {
+
+		csr_roam_determine_max_rate_for_ad_hoc(pMac,
+						       &pSession->bssParams.
+						       operationalRateSet);
+		if (CSR_IS_INFRA_AP(pProfile) || CSR_IS_START_IBSS(pProfile)) {
+			if (CDS_IS_CHANNEL_24GHZ(Channel)) {
+				cbMode =
+					pMac->roam.configParam.
+					channelBondingMode24GHz;
+			} else {
+				cbMode =
+					pMac->roam.configParam.
+					channelBondingMode5GHz;
+			}
+			sms_log(pMac, LOG1, "## cbMode %d", cbMode);
+			pBssConfig->cbMode = cbMode;
+			pSession->bssParams.cbMode = cbMode;
+		}
+	}
+}
+
+static CDF_STATUS csr_roam_start_ibss(tpAniSirGlobal pMac, uint32_t sessionId,
+				      tCsrRoamProfile *pProfile,
+				      bool *pfSameIbss)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	bool fSameIbss = false;
+
+	if (csr_is_conn_state_ibss(pMac, sessionId)) {
+		/* Check if any profile parameter has changed ? If any profile parameter */
+		/* has changed then stop old BSS and start a new one with new parameters */
+		if (csr_is_same_profile
+			    (pMac, &pMac->roam.roamSession[sessionId].connectedProfile,
+			    pProfile)) {
+			fSameIbss = true;
+		} else {
+			status =
+				csr_roam_issue_stop_bss(pMac, sessionId,
+							eCSR_ROAM_SUBSTATE_DISCONNECT_CONTINUE_ROAMING);
+		}
+	} else if (csr_is_conn_state_connected_infra(pMac, sessionId)) {
+		/* Disassociate from the connected Infrastructure network... */
+		status =
+			csr_roam_issue_disassociate(pMac, sessionId,
+						    eCSR_ROAM_SUBSTATE_DISCONNECT_CONTINUE_ROAMING,
+						    false);
+	} else {
+		tBssConfigParam *pBssConfig;
+
+		pBssConfig = cdf_mem_malloc(sizeof(tBssConfigParam));
+		if (NULL == pBssConfig)
+			status = CDF_STATUS_E_NOMEM;
+		else
+			status = CDF_STATUS_SUCCESS;
+		if (CDF_IS_STATUS_SUCCESS(status)) {
+			cdf_mem_set(pBssConfig, sizeof(tBssConfigParam), 0);
+			/* there is no Bss description before we start an IBSS so we need to adopt */
+			/* all Bss configuration parameters from the Profile. */
+			status =
+				csr_roam_prepare_bss_config_from_profile(pMac, pProfile,
+									 pBssConfig,
+									 NULL);
+			if (CDF_IS_STATUS_SUCCESS(status)) {
+				/* save dotMode */
+				pMac->roam.roamSession[sessionId].bssParams.
+				uCfgDot11Mode = pBssConfig->uCfgDot11Mode;
+				/* Prepare some more parameters for this IBSS */
+				csr_roam_prepare_bss_params(pMac, sessionId,
+							    pProfile, NULL,
+							    pBssConfig, NULL);
+				status =
+					csr_roam_set_bss_config_cfg(pMac, sessionId,
+								    pProfile, NULL,
+								    pBssConfig, NULL,
+								    false);
+			}
+
+			cdf_mem_free(pBssConfig);
+		} /* Allocate memory */
+	}
+
+	if (pfSameIbss) {
+		*pfSameIbss = fSameIbss;
+	}
+	return status;
+}
+
+static void csr_roam_update_connected_profile_from_new_bss(tpAniSirGlobal pMac,
+							   uint32_t sessionId,
+							   tSirSmeNewBssInfo *pNewBss)
+{
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("  session %d not found "), sessionId);
+		return;
+	}
+
+	if (pNewBss) {
+		/* Set the operating channel. */
+		pSession->connectedProfile.operationChannel =
+			pNewBss->channelNumber;
+		/* move the BSSId from the BSS description into the connected state information. */
+		cdf_mem_copy(&pSession->connectedProfile.bssid.bytes,
+			     &(pNewBss->bssId), sizeof(struct cdf_mac_addr));
+	}
+	return;
+}
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+CDF_STATUS csr_roam_set_psk_pmk(tpAniSirGlobal pMac, uint32_t sessionId,
+				uint8_t *pPSK_PMK, size_t pmk_len)
+{
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("session %d not found"), sessionId);
+		return CDF_STATUS_E_FAILURE;
+	}
+	cdf_mem_copy(pSession->psk_pmk, pPSK_PMK, sizeof(pSession->psk_pmk));
+	pSession->pmk_len = pmk_len;
+	return CDF_STATUS_SUCCESS;
+}
+#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+static void
+csr_roam_diag_set_pmkid(tCsrRoamSession *pSession)
+{
+	WLAN_HOST_DIAG_EVENT_DEF(secEvent,
+				 host_event_wlan_security_payload_type);
+	cdf_mem_set(&secEvent,
+	    sizeof(host_event_wlan_security_payload_type), 0);
+	secEvent.eventId = WLAN_SECURITY_EVENT_PMKID_UPDATE;
+	secEvent.encryptionModeMulticast =
+		(uint8_t) diag_enc_type_from_csr_type(
+			pSession->connectedProfile.mcEncryptionType);
+	secEvent.encryptionModeUnicast =
+		(uint8_t) diag_enc_type_from_csr_type(
+			pSession->connectedProfile.EncryptionType);
+	cdf_mem_copy(secEvent.bssid,
+		     pSession->connectedProfile.bssid.bytes,
+			CDF_MAC_ADDR_SIZE);
+	secEvent.authMode = (uint8_t) diag_auth_type_from_csr_type(
+				pSession->connectedProfile.AuthType);
+	WLAN_HOST_DIAG_EVENT_REPORT(&secEvent, EVENT_WLAN_SECURITY);
+}
+#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
+
+CDF_STATUS
+csr_roam_set_pmkid_cache(tpAniSirGlobal pMac, uint32_t sessionId,
+			 tPmkidCacheInfo *pPMKIDCache, uint32_t numItems,
+			 bool update_entire_cache)
+{
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+	uint32_t i = 0;
+	tPmkidCacheInfo *pmksa;
+
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("session %d not found"), sessionId);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	sms_log(pMac, LOGW, FL("numItems = %d"), numItems);
+
+	if (numItems > CSR_MAX_PMKID_ALLOWED)
+		return CDF_STATUS_E_INVAL;
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+	csr_roam_diag_set_pmkid(pSession);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
+
+	if (update_entire_cache) {
+		if (numItems && pPMKIDCache) {
+			pSession->NumPmkidCache = (uint16_t) numItems;
+			cdf_mem_copy(pSession->PmkidCacheInfo, pPMKIDCache,
+				sizeof(tPmkidCacheInfo) * numItems);
+			pSession->curr_cache_idx = (uint16_t)numItems;
+		}
+		return CDF_STATUS_SUCCESS;
+	}
+
+	for (i = 0; i < numItems; i++) {
+		pmksa = &pPMKIDCache[i];
+
+		/* Delete the entry if present */
+		csr_roam_del_pmkid_from_cache(pMac, sessionId,
+				pmksa->BSSID.bytes, false);
+
+		/* Add entry to the cache */
+		cdf_copy_macaddr(
+		    &pSession->PmkidCacheInfo[pSession->curr_cache_idx].BSSID,
+		    &pmksa->BSSID);
+		cdf_mem_copy(
+		    pSession->PmkidCacheInfo[pSession->curr_cache_idx].PMKID,
+		    pmksa->PMKID, CSR_RSN_PMKID_SIZE);
+
+		/* Increment the CSR local cache index */
+		if (pSession->curr_cache_idx < (CSR_MAX_PMKID_ALLOWED - 1))
+			pSession->curr_cache_idx++;
+		else
+			pSession->curr_cache_idx = 0;
+
+		pSession->NumPmkidCache++;
+		if (pSession->NumPmkidCache > CSR_MAX_PMKID_ALLOWED)
+			pSession->NumPmkidCache = CSR_MAX_PMKID_ALLOWED;
+	}
+	return CDF_STATUS_SUCCESS;
+}
+
+CDF_STATUS csr_roam_del_pmkid_from_cache(tpAniSirGlobal pMac,
+					 uint32_t sessionId,
+					 const uint8_t *pBSSId,
+					 bool flush_cache)
+{
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+	bool fMatchFound = false;
+	uint32_t Index;
+	uint32_t curr_idx;
+	uint32_t i;
+
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("  session %d not found "), sessionId);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	/* Check if there are no entries to delete */
+	if (0 == pSession->NumPmkidCache) {
+		sms_log(pMac, LOG1, FL("No entries to delete/Flush"));
+		return CDF_STATUS_SUCCESS;
+	}
+
+	if (flush_cache) {
+		/* Flush the entire cache */
+		cdf_mem_zero(pSession->PmkidCacheInfo,
+			     sizeof(tPmkidCacheInfo) * CSR_MAX_PMKID_ALLOWED);
+		pSession->NumPmkidCache = 0;
+		pSession->curr_cache_idx = 0;
+		return CDF_STATUS_SUCCESS;
+	}
+
+	/* !flush_cache - so look up in the cache */
+	for (Index = 0; Index < CSR_MAX_PMKID_ALLOWED; Index++) {
+		if (cdf_mem_compare(pSession->PmkidCacheInfo[Index].BSSID.bytes,
+				    pBSSId, CDF_MAC_ADDR_SIZE)) {
+			fMatchFound = 1;
+
+			/* Clear this - the matched entry */
+			cdf_mem_zero(&pSession->PmkidCacheInfo[Index],
+				     sizeof(tPmkidCacheInfo));
+			break;
+		}
+	}
+
+	if (Index == CSR_MAX_PMKID_ALLOWED && !fMatchFound) {
+		sms_log(pMac, LOG1, FL("No such PMKSA entry exists"
+			MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pBSSId));
+		return CDF_STATUS_SUCCESS;
+	}
+
+	/* Match Found, Readjust the other entries */
+	curr_idx = pSession->curr_cache_idx;
+	if (Index < curr_idx) {
+		for (i = Index; i < (curr_idx - 1); i++) {
+			cdf_mem_copy(&pSession->PmkidCacheInfo[i],
+				     &pSession->PmkidCacheInfo[i + 1],
+				     sizeof(tPmkidCacheInfo));
+		}
+
+		pSession->curr_cache_idx--;
+		cdf_mem_zero(&pSession->PmkidCacheInfo
+			     [pSession->curr_cache_idx],
+			     sizeof(tPmkidCacheInfo));
+	} else if (Index > curr_idx) {
+		for (i = Index; i > (curr_idx); i--) {
+			cdf_mem_copy(&pSession->PmkidCacheInfo[i],
+				     &pSession->PmkidCacheInfo[i - 1],
+				     sizeof(tPmkidCacheInfo));
+		}
+
+		cdf_mem_zero(&pSession->PmkidCacheInfo
+			     [pSession->curr_cache_idx],
+			     sizeof(tPmkidCacheInfo));
+	}
+
+	/* Decrement the count since an entry has been deleted */
+	pSession->NumPmkidCache--;
+	return CDF_STATUS_SUCCESS;
+}
+
+uint32_t csr_roam_get_num_pmkid_cache(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	return pMac->roam.roamSession[sessionId].NumPmkidCache;
+}
+
+CDF_STATUS csr_roam_get_pmkid_cache(tpAniSirGlobal pMac, uint32_t sessionId,
+				    uint32_t *pNum, tPmkidCacheInfo *pPmkidCache)
+{
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+	tPmkidCacheInfo *pmksa;
+	uint16_t i, j;
+
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("session %d not found "), sessionId);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	if (!pNum || !pPmkidCache) {
+		sms_log(pMac, LOGE, FL("Either pNum or pPmkidCache is NULL"));
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	if (pSession->NumPmkidCache == 0) {
+		*pNum = 0;
+		return CDF_STATUS_SUCCESS;
+	}
+
+	if (*pNum < pSession->NumPmkidCache) {
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	if (pSession->NumPmkidCache > CSR_MAX_PMKID_ALLOWED) {
+		sms_log(pMac, LOGE,
+			FL(
+			"NumPmkidCache :%d is more than CSR_MAX_PMKID_ALLOWED, resetting to CSR_MAX_PMKID_ALLOWED"),
+			pSession->NumPmkidCache);
+		pSession->NumPmkidCache = CSR_MAX_PMKID_ALLOWED;
+	}
+
+	for (i = 0, j = 0; ((j < pSession->NumPmkidCache) &&
+		(i < CSR_MAX_PMKID_ALLOWED)); i++) {
+		/* Fill the valid entries */
+		pmksa = &pSession->PmkidCacheInfo[i];
+		if (!cdf_is_macaddr_zero(&pmksa->BSSID)) {
+			cdf_mem_copy(pPmkidCache, pmksa,
+				     sizeof(tPmkidCacheInfo));
+			pPmkidCache++;
+			j++;
+		}
+	}
+
+	*pNum = pSession->NumPmkidCache;
+	return CDF_STATUS_SUCCESS;
+}
+
+CDF_STATUS csr_roam_get_wpa_rsn_req_ie(tpAniSirGlobal pMac, uint32_t sessionId,
+				       uint32_t *pLen, uint8_t *pBuf)
+{
+	CDF_STATUS status = CDF_STATUS_E_INVAL;
+	uint32_t len;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("  session %d not found "), sessionId);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	if (pLen) {
+		len = *pLen;
+		*pLen = pSession->nWpaRsnReqIeLength;
+		if (pBuf) {
+			if (len >= pSession->nWpaRsnReqIeLength) {
+				cdf_mem_copy(pBuf, pSession->pWpaRsnReqIE,
+					     pSession->nWpaRsnReqIeLength);
+				status = CDF_STATUS_SUCCESS;
+			}
+		}
+	}
+	return status;
+}
+
+CDF_STATUS csr_roam_get_wpa_rsn_rsp_ie(tpAniSirGlobal pMac, uint32_t sessionId,
+				       uint32_t *pLen, uint8_t *pBuf)
+{
+	CDF_STATUS status = CDF_STATUS_E_INVAL;
+	uint32_t len;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("  session %d not found "), sessionId);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	if (pLen) {
+		len = *pLen;
+		*pLen = pSession->nWpaRsnRspIeLength;
+		if (pBuf) {
+			if (len >= pSession->nWpaRsnRspIeLength) {
+				cdf_mem_copy(pBuf, pSession->pWpaRsnRspIE,
+					     pSession->nWpaRsnRspIeLength);
+				status = CDF_STATUS_SUCCESS;
+			}
+		}
+	}
+	return status;
+}
+
+#ifdef FEATURE_WLAN_WAPI
+CDF_STATUS csr_roam_get_wapi_req_ie(tpAniSirGlobal pMac, uint32_t sessionId,
+				    uint32_t *pLen, uint8_t *pBuf)
+{
+	CDF_STATUS status = CDF_STATUS_E_INVAL;
+	uint32_t len;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("  session %d not found "), sessionId);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	if (pLen) {
+		len = *pLen;
+		*pLen = pSession->nWapiReqIeLength;
+		if (pBuf) {
+			if (len >= pSession->nWapiReqIeLength) {
+				cdf_mem_copy(pBuf, pSession->pWapiReqIE,
+					     pSession->nWapiReqIeLength);
+				status = CDF_STATUS_SUCCESS;
+			}
+		}
+	}
+	return status;
+}
+
+CDF_STATUS csr_roam_get_wapi_rsp_ie(tpAniSirGlobal pMac, uint32_t sessionId,
+				    uint32_t *pLen, uint8_t *pBuf)
+{
+	CDF_STATUS status = CDF_STATUS_E_INVAL;
+	uint32_t len;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("  session %d not found "), sessionId);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	if (pLen) {
+		len = *pLen;
+		*pLen = pSession->nWapiRspIeLength;
+		if (pBuf) {
+			if (len >= pSession->nWapiRspIeLength) {
+				cdf_mem_copy(pBuf, pSession->pWapiRspIE,
+					     pSession->nWapiRspIeLength);
+				status = CDF_STATUS_SUCCESS;
+			}
+		}
+	}
+	return status;
+}
+#endif /* FEATURE_WLAN_WAPI */
+eRoamCmdStatus csr_get_roam_complete_status(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	eRoamCmdStatus retStatus = eCSR_ROAM_CONNECT_COMPLETION;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("  session %d not found "), sessionId);
+		return retStatus;
+	}
+
+	if (CSR_IS_ROAMING(pSession)) {
+		retStatus = eCSR_ROAM_ROAMING_COMPLETION;
+		pSession->fRoaming = false;
+	}
+	return retStatus;
+}
+
+/* This function remove the connected BSS from te cached scan result */
+CDF_STATUS
+csr_roam_remove_connected_bss_from_scan_cache(tpAniSirGlobal pMac,
+					tCsrRoamConnectedProfile *pConnProfile)
+{
+	CDF_STATUS status = CDF_STATUS_E_FAILURE;
+	tCsrScanResultFilter *pScanFilter = NULL;
+	tListElem *pEntry;
+	tCsrScanResult *pResult;
+	tDot11fBeaconIEs *pIes;
+	bool fMatch;
+
+	if ((cdf_is_macaddr_zero(&pConnProfile->bssid) ||
+	     cdf_is_macaddr_broadcast(&pConnProfile->bssid)))
+		return status;
+	/*
+	 * Prepare the filter. Only fill in the necessary fields. Not all fields
+	 * are needed
+	 */
+	pScanFilter = cdf_mem_malloc(sizeof(tCsrScanResultFilter));
+	if (NULL == pScanFilter)
+		return CDF_STATUS_E_NOMEM;
+
+	cdf_mem_set(pScanFilter, sizeof(tCsrScanResultFilter), 0);
+	pScanFilter->BSSIDs.bssid = cdf_mem_malloc(sizeof(struct cdf_mac_addr));
+	if (NULL == pScanFilter->BSSIDs.bssid) {
+		cdf_mem_free(pScanFilter);
+		return CDF_STATUS_E_NOMEM;
+	}
+	cdf_mem_copy(pScanFilter->BSSIDs.bssid,
+		     &pConnProfile->bssid, sizeof(struct cdf_mac_addr));
+	pScanFilter->BSSIDs.numOfBSSIDs = 1;
+	if (!csr_is_nullssid(pConnProfile->SSID.ssId,
+			pConnProfile->SSID.length)) {
+		pScanFilter->SSIDs.SSIDList = cdf_mem_malloc(
+							sizeof(tCsrSSIDInfo));
+		if (NULL == pScanFilter->SSIDs.SSIDList) {
+			csr_free_scan_filter(pMac, pScanFilter);
+			cdf_mem_free(pScanFilter);
+			return CDF_STATUS_E_NOMEM;
+		}
+		cdf_mem_copy(&pScanFilter->SSIDs.SSIDList[0].SSID,
+			&pConnProfile->SSID, sizeof(tSirMacSSid));
+	}
+	pScanFilter->authType.numEntries = 1;
+	pScanFilter->authType.authType[0] = pConnProfile->AuthType;
+	pScanFilter->BSSType = pConnProfile->BSSType;
+	pScanFilter->EncryptionType.numEntries = 1;
+	pScanFilter->EncryptionType.encryptionType[0] =
+		pConnProfile->EncryptionType;
+	pScanFilter->mcEncryptionType.numEntries = 1;
+	pScanFilter->mcEncryptionType.encryptionType[0] =
+		pConnProfile->mcEncryptionType;
+	/* We ignore the channel for now, BSSID should be enough */
+	pScanFilter->ChannelInfo.numOfChannels = 0;
+	/* Also ignore the following fields */
+	pScanFilter->uapsd_mask = 0;
+	pScanFilter->bWPSAssociation = false;
+	pScanFilter->bOSENAssociation = false;
+	pScanFilter->countryCode[0] = 0;
+	pScanFilter->phyMode = eCSR_DOT11_MODE_AUTO;
+	csr_ll_lock(&pMac->scan.scanResultList);
+	pEntry = csr_ll_peek_head(&pMac->scan.scanResultList, LL_ACCESS_NOLOCK);
+	while (pEntry) {
+		pResult = GET_BASE_ADDR(pEntry, tCsrScanResult, Link);
+		pIes = (tDot11fBeaconIEs *) (pResult->Result.pvIes);
+		fMatch = csr_match_bss(pMac, &pResult->Result.BssDescriptor,
+				       pScanFilter, NULL, NULL, NULL, &pIes);
+		/* Release the IEs allocated by csr_match_bss is needed */
+		if (!pResult->Result.pvIes) {
+			/*
+			 * need to free the IEs since it is allocated
+			 * by csr_match_bss
+			 */
+			cdf_mem_free(pIes);
+		}
+		if (fMatch) {
+			/* We found the one */
+			if (csr_ll_remove_entry(&pMac->scan.scanResultList,
+						pEntry, LL_ACCESS_NOLOCK))
+				/* Free the memory */
+				csr_free_scan_result_entry(pMac, pResult);
+			break;
+		}
+		pEntry = csr_ll_next(&pMac->scan.scanResultList,
+				    pEntry, LL_ACCESS_NOLOCK);
+	} /* while */
+	csr_ll_unlock(&pMac->scan.scanResultList);
+	csr_free_scan_filter(pMac, pScanFilter);
+	cdf_mem_free(pScanFilter);
+	return status;
+}
+
+static CDF_STATUS csr_roam_start_wds(tpAniSirGlobal pMac, uint32_t sessionId,
+				     tCsrRoamProfile *pProfile,
+				     tSirBssDescription *pBssDesc)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+	tBssConfigParam bssConfig;
+
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("  session %d not found "), sessionId);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	if (csr_is_conn_state_ibss(pMac, sessionId)) {
+		status =
+			csr_roam_issue_stop_bss(pMac, sessionId,
+						eCSR_ROAM_SUBSTATE_DISCONNECT_CONTINUE_ROAMING);
+	} else if (csr_is_conn_state_connected_infra(pMac, sessionId)) {
+		/* Disassociate from the connected Infrastructure network... */
+		status =
+			csr_roam_issue_disassociate(pMac, sessionId,
+						    eCSR_ROAM_SUBSTATE_DISCONNECT_CONTINUE_ROAMING,
+						    false);
+	} else {
+		/* We don't expect Bt-AMP HDD not to disconnect the last connection first at this time. */
+		/* Otherwise we need to add code to handle the */
+		/* situation just like IBSS. Though for WDS station, we need to send disassoc to PE first then */
+		/* send stop_bss to PE, before we can continue. */
+
+		if (csr_is_conn_state_wds(pMac, sessionId)) {
+			CDF_ASSERT(0);
+			return CDF_STATUS_E_FAILURE;
+		}
+		cdf_mem_set(&bssConfig, sizeof(tBssConfigParam), 0);
+		/* Assume HDD provide bssid in profile */
+		cdf_copy_macaddr(&pSession->bssParams.bssid,
+				 pProfile->BSSIDs.bssid);
+		/* there is no Bss description before we start an WDS so we need */
+		/* to adopt all Bss configuration parameters from the Profile. */
+		status =
+			csr_roam_prepare_bss_config_from_profile(pMac, pProfile,
+								 &bssConfig, pBssDesc);
+		if (CDF_IS_STATUS_SUCCESS(status)) {
+			/* Save profile for late use */
+			csr_free_roam_profile(pMac, sessionId);
+			pSession->pCurRoamProfile =
+				cdf_mem_malloc(sizeof(tCsrRoamProfile));
+			if (pSession->pCurRoamProfile != NULL) {
+				cdf_mem_set(pSession->pCurRoamProfile,
+					    sizeof(tCsrRoamProfile), 0);
+				csr_roam_copy_profile(pMac,
+						      pSession->pCurRoamProfile,
+						      pProfile);
+			}
+			/* Prepare some more parameters for this WDS */
+			csr_roam_prepare_bss_params(pMac, sessionId, pProfile, NULL,
+						    &bssConfig, NULL);
+			status =
+				csr_roam_set_bss_config_cfg(pMac, sessionId, pProfile,
+							    NULL, &bssConfig, NULL,
+							    false);
+		}
+	}
+
+	return status;
+}
+
+/**
+ * csr_add_supported_5Ghz_channels()- Add valid 5Ghz channels
+ * in Join req.
+ * @mac_ctx: pointer to global mac structure
+ * @csr_join_req: join req sent to lim
+ *
+ * This function is called to update valid 5Ghz channels
+ * in Join req.
+ *
+ * Return: void
+ */
+static void csr_add_supported_5Ghz_channels(tpAniSirGlobal mac_ctx,
+					tSirSmeJoinReq *csr_join_req)
+{
+	uint16_t i, j;
+	uint32_t size = 0;
+
+	if (!csr_join_req) {
+		sms_log(mac_ctx, LOGE, FL("  csr_join_reqis NULL"));
+		return;
+	}
+
+	size = sizeof(mac_ctx->roam.validChannelList);
+	if (CDF_IS_STATUS_SUCCESS
+		(csr_get_cfg_valid_channels(mac_ctx,
+		(uint8_t *) mac_ctx->roam.validChannelList,
+				&size))) {
+		for (i = 0, j = 0; i < size; i++) {
+			/* Only add 5ghz channels.*/
+			if (CDS_IS_CHANNEL_5GHZ
+					(mac_ctx->roam.validChannelList[i])) {
+				csr_join_req->supportedChannels.channelList[j] =
+					mac_ctx->roam.validChannelList[i];
+				j++;
+			}
+		}
+		csr_join_req->supportedChannels.numChnl = j;
+	} else {
+		sms_log(mac_ctx, LOGE,
+			FL("can not find any valid channel"));
+		csr_join_req->supportedChannels.numChnl = 0;
+	}
+}
+
+/**
+ * The communication between HDD and LIM is thru mailbox (MB).
+ * Both sides will access the data structure "tSirSmeJoinReq".
+ * The rule is, while the components of "tSirSmeJoinReq" can be accessed in the
+ * regular way like tSirSmeJoinReq.assocType, this guideline stops at component
+ * tSirRSNie;
+ * any acces to the components after tSirRSNie is forbidden because the space
+ * from tSirRSNie is squeezed with the component "tSirBssDescription" and since
+ * the size of actual 'tSirBssDescription' varies, the receiving side should
+ * keep in mind not to access the components DIRECTLY after tSirRSNie.
+ */
+CDF_STATUS csr_send_join_req_msg(tpAniSirGlobal pMac, uint32_t sessionId,
+				 tSirBssDescription *pBssDescription,
+				 tCsrRoamProfile *pProfile,
+				 tDot11fBeaconIEs *pIes, uint16_t messageType)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	uint8_t acm_mask = 0, uapsd_mask;
+	uint16_t msgLen, ieLen;
+	tSirMacRateSet OpRateSet;
+	tSirMacRateSet ExRateSet;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+	uint32_t dwTmp, ucDot11Mode = 0;
+	/* RSN MAX is bigger than WPA MAX */
+	uint8_t wpaRsnIE[DOT11F_IE_RSN_MAX_LEN];
+	uint8_t txBFCsnValue = 0;
+	tSirSmeJoinReq *csr_join_req;
+	tSirMacCapabilityInfo *pAP_capabilityInfo;
+	tAniBool fTmp;
+	int8_t pwrLimit = 0;
+	struct ps_global_info *ps_global_info = &pMac->sme.ps_global_info;
+	struct ps_params *ps_param = &ps_global_info->ps_params[sessionId];
+	uint8_t ese_config = 0;
+
+
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("  session %d not found "), sessionId);
+		return CDF_STATUS_E_FAILURE;
+	}
+	/* To satisfy klockworks */
+	if (NULL == pBssDescription) {
+		sms_log(pMac, LOGE, FL(" pBssDescription is NULL"));
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	do {
+		pSession->joinFailStatusCode.statusCode = eSIR_SME_SUCCESS;
+		pSession->joinFailStatusCode.reasonCode = 0;
+		cdf_mem_copy(&pSession->joinFailStatusCode.bssId,
+		       &pBssDescription->bssId, sizeof(tSirMacAddr));
+		/*
+		 * the tSirSmeJoinReq which includes a single
+		 * bssDescription. it includes a single uint32_t for the
+		 * IE fields, but the length field in the bssDescription
+		 * needs to be interpreted to determine length of IE fields
+		 * So, take the size of the tSirSmeJoinReq, subtract  size of
+		 * bssDescription, add the number of bytes indicated by the
+		 * length field of the bssDescription, add the size of length
+		 * field  because it not included in the lenghth field.
+		 */
+		msgLen = sizeof(tSirSmeJoinReq) - sizeof(*pBssDescription) +
+				pBssDescription->length +
+				sizeof(pBssDescription->length) +
+				/*
+				 * add in the size of the WPA IE that
+				 * we may build.
+				 */
+				sizeof(tCsrWpaIe) + sizeof(tCsrWpaAuthIe) +
+				sizeof(uint16_t);
+		csr_join_req = cdf_mem_malloc(msgLen);
+		if (NULL == csr_join_req)
+			status = CDF_STATUS_E_NOMEM;
+		else
+			status = CDF_STATUS_SUCCESS;
+		if (!CDF_IS_STATUS_SUCCESS(status))
+			break;
+		cdf_mem_set(csr_join_req, msgLen, 0);
+		csr_join_req->messageType = messageType;
+		csr_join_req->length = msgLen;
+		csr_join_req->sessionId = (uint8_t) sessionId;
+		csr_join_req->transactionId = 0;
+		if (pIes->SSID.present && pIes->SSID.num_ssid) {
+			csr_join_req->ssId.length = pIes->SSID.num_ssid;
+			cdf_mem_copy(&csr_join_req->ssId.ssId, pIes->SSID.ssid,
+				     pIes->SSID.num_ssid);
+		} else
+			csr_join_req->ssId.length = 0;
+		cdf_mem_copy(&csr_join_req->selfMacAddr, &pSession->selfMacAddr,
+			     sizeof(tSirMacAddr));
+		/* bsstype */
+		dwTmp = csr_translate_bsstype_to_mac_type
+						(pProfile->BSSType);
+		/* Override BssType for BTAMP */
+		if (dwTmp == eSIR_BTAMP_STA_MODE)
+			dwTmp = eSIR_BTAMP_AP_MODE;
+			csr_join_req->bsstype = dwTmp;
+		/* dot11mode */
+		ucDot11Mode =
+			csr_translate_to_wni_cfg_dot11_mode(pMac,
+							    pSession->bssParams.
+							    uCfgDot11Mode);
+		if (pBssDescription->channelId <= 14
+		    && false == pMac->roam.configParam.enableVhtFor24GHz
+		    && WNI_CFG_DOT11_MODE_11AC == ucDot11Mode) {
+			/* Need to disable VHT operation in 2.4 GHz band */
+			ucDot11Mode = WNI_CFG_DOT11_MODE_11N;
+		}
+		csr_join_req->dot11mode = (uint8_t) ucDot11Mode;
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+		csr_join_req->cc_switch_mode =
+			pMac->roam.configParam.cc_switch_mode;
+#endif
+		csr_join_req->staPersona = (uint8_t) pProfile->csrPersona;
+		csr_join_req->cbMode = (uint8_t) pSession->bssParams.cbMode;
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
+			  FL("CSR PERSONA=%d CSR CbMode %d"),
+			  pProfile->csrPersona, pSession->bssParams.cbMode);
+		csr_join_req->uapsdPerAcBitmask = pProfile->uapsd_mask;
+		status =
+			csr_get_rate_set(pMac, pProfile,
+					 (eCsrPhyMode) pProfile->phyMode,
+					 pBssDescription, pIes, &OpRateSet,
+					 &ExRateSet);
+		ps_param->uapsd_per_ac_bit_mask =
+			pProfile->uapsd_mask;
+		if (CDF_IS_STATUS_SUCCESS(status)) {
+			/* OperationalRateSet */
+			if (OpRateSet.numRates) {
+				csr_join_req->operationalRateSet.numRates =
+					OpRateSet.numRates;
+				cdf_mem_copy(&csr_join_req->operationalRateSet.
+						rate, OpRateSet.rate,
+						OpRateSet.numRates);
+			} else
+				csr_join_req->operationalRateSet.numRates = 0;
+
+			/* ExtendedRateSet */
+			if (ExRateSet.numRates) {
+				csr_join_req->extendedRateSet.numRates =
+					ExRateSet.numRates;
+				cdf_mem_copy(&csr_join_req->extendedRateSet.
+						rate, ExRateSet.rate,
+						ExRateSet.numRates);
+			} else
+				csr_join_req->extendedRateSet.numRates = 0;
+		} else {
+			csr_join_req->operationalRateSet.numRates = 0;
+			csr_join_req->extendedRateSet.numRates = 0;
+		}
+		/* rsnIE */
+		if (csr_is_profile_wpa(pProfile)) {
+			/* Insert the Wpa IE into the join request */
+			ieLen =
+				csr_retrieve_wpa_ie(pMac, pProfile,
+						pBssDescription, pIes,
+						(tCsrWpaIe *) (wpaRsnIE));
+		} else if (csr_is_profile_rsn(pProfile)) {
+			/* Insert the RSN IE into the join request */
+			ieLen =
+				csr_retrieve_rsn_ie(pMac, sessionId, pProfile,
+						    pBssDescription, pIes,
+						    (tCsrRSNIe *) (wpaRsnIE));
+		}
+#ifdef FEATURE_WLAN_WAPI
+		else if (csr_is_profile_wapi(pProfile)) {
+			/* Insert the WAPI IE into the join request */
+			ieLen =
+				csr_retrieve_wapi_ie(pMac, sessionId, pProfile,
+						     pBssDescription, pIes,
+						     (tCsrWapiIe *) (wpaRsnIE));
+		}
+#endif /* FEATURE_WLAN_WAPI */
+		else {
+			ieLen = 0;
+		}
+		/* remember the IE for future use */
+		if (ieLen) {
+			if (ieLen > DOT11F_IE_RSN_MAX_LEN) {
+				sms_log(pMac, LOGE,
+					FL
+					(" WPA RSN IE length :%d is more than DOT11F_IE_RSN_MAX_LEN, resetting to %d"),
+					ieLen, DOT11F_IE_RSN_MAX_LEN);
+				ieLen = DOT11F_IE_RSN_MAX_LEN;
+			}
+#ifdef FEATURE_WLAN_WAPI
+			if (csr_is_profile_wapi(pProfile)) {
+				/* Check whether we need to allocate more mem */
+				if (ieLen > pSession->nWapiReqIeLength) {
+					if (pSession->pWapiReqIE
+					    && pSession->nWapiReqIeLength) {
+						cdf_mem_free(pSession->
+							     pWapiReqIE);
+					}
+					pSession->pWapiReqIE =
+						cdf_mem_malloc(ieLen);
+					if (NULL == pSession->pWapiReqIE)
+						status = CDF_STATUS_E_NOMEM;
+					else
+						status = CDF_STATUS_SUCCESS;
+					if (!CDF_IS_STATUS_SUCCESS(status))
+						break;
+				}
+				pSession->nWapiReqIeLength = ieLen;
+				cdf_mem_copy(pSession->pWapiReqIE, wpaRsnIE,
+					     ieLen);
+				csr_join_req->rsnIE.length = ieLen;
+				cdf_mem_copy(&csr_join_req->rsnIE.rsnIEdata,
+						 wpaRsnIE, ieLen);
+			} else  /* should be WPA/WPA2 otherwise */
+#endif /* FEATURE_WLAN_WAPI */
+			{
+				/* Check whether we need to allocate more mem */
+				if (ieLen > pSession->nWpaRsnReqIeLength) {
+					if (pSession->pWpaRsnReqIE
+					    && pSession->nWpaRsnReqIeLength) {
+						cdf_mem_free(pSession->
+							     pWpaRsnReqIE);
+					}
+					pSession->pWpaRsnReqIE =
+						cdf_mem_malloc(ieLen);
+					if (NULL == pSession->pWpaRsnReqIE)
+						status = CDF_STATUS_E_NOMEM;
+					else
+						status = CDF_STATUS_SUCCESS;
+					if (!CDF_IS_STATUS_SUCCESS(status))
+						break;
+				}
+				pSession->nWpaRsnReqIeLength = ieLen;
+				cdf_mem_copy(pSession->pWpaRsnReqIE, wpaRsnIE,
+					     ieLen);
+				csr_join_req->rsnIE.length = ieLen;
+				cdf_mem_copy(&csr_join_req->rsnIE.rsnIEdata,
+						 wpaRsnIE, ieLen);
+			}
+		} else {
+			/* free whatever old info */
+			pSession->nWpaRsnReqIeLength = 0;
+			if (pSession->pWpaRsnReqIE) {
+				cdf_mem_free(pSession->pWpaRsnReqIE);
+				pSession->pWpaRsnReqIE = NULL;
+			}
+#ifdef FEATURE_WLAN_WAPI
+			pSession->nWapiReqIeLength = 0;
+			if (pSession->pWapiReqIE) {
+				cdf_mem_free(pSession->pWapiReqIE);
+				pSession->pWapiReqIE = NULL;
+			}
+#endif /* FEATURE_WLAN_WAPI */
+			csr_join_req->rsnIE.length = 0;
+		}
+#ifdef FEATURE_WLAN_ESE
+		if (eWNI_SME_JOIN_REQ == messageType)
+			csr_join_req->cckmIE.length = 0;
+		else if (eWNI_SME_REASSOC_REQ == messageType) {
+			/* cckmIE */
+			if (csr_is_profile_ese(pProfile)) {
+				/* Insert the CCKM IE into the join request */
+#ifdef FEATURE_WLAN_ESE_UPLOAD
+				ieLen = pSession->suppCckmIeInfo.cckmIeLen;
+				cdf_mem_copy((void *)(wpaRsnIE),
+						pSession->suppCckmIeInfo.cckmIe,
+						ieLen);
+#else
+				ieLen = csrConstructEseCckmIe(pMac,
+						pSession,
+						pProfile,
+						pBssDescription,
+						pSession->
+						pWpaRsnReqIE,
+						pSession->
+						nWpaRsnReqIeLength,
+						(void *)(wpaRsnIE));
+#endif /* FEATURE_WLAN_ESE_UPLOAD */
+			} else
+				ieLen = 0;
+			/*
+			 * If present, copy the IE into the
+			 * eWNI_SME_REASSOC_REQ message buffer
+			 */
+			if (ieLen) {
+				/*
+				 * Copy the CCKM IE over from the temp
+				 * buffer (wpaRsnIE)
+				 */
+				csr_join_req->cckmIE.length = ieLen;
+				cdf_mem_copy(&csr_join_req->cckmIE.cckmIEdata,
+						wpaRsnIE, ieLen);
+			} else
+				csr_join_req->cckmIE.length = 0;
+		}
+#endif /* FEATURE_WLAN_ESE */
+		/* addIEScan */
+		if (pProfile->nAddIEScanLength && pProfile->pAddIEScan) {
+			ieLen = pProfile->nAddIEScanLength;
+			if (ieLen > pSession->nAddIEScanLength) {
+				if (pSession->pAddIEScan
+					&& pSession->nAddIEScanLength) {
+					cdf_mem_free(pSession->pAddIEScan);
+				}
+				pSession->pAddIEScan = cdf_mem_malloc(ieLen);
+				if (NULL == pSession->pAddIEScan)
+					status = CDF_STATUS_E_NOMEM;
+				else
+					status = CDF_STATUS_SUCCESS;
+				if (!CDF_IS_STATUS_SUCCESS(status))
+					break;
+			}
+			pSession->nAddIEScanLength = ieLen;
+			cdf_mem_copy(pSession->pAddIEScan, pProfile->pAddIEScan,
+					ieLen);
+			csr_join_req->addIEScan.length = ieLen;
+			cdf_mem_copy(&csr_join_req->addIEScan.addIEdata,
+					pProfile->pAddIEScan, ieLen);
+		} else {
+			pSession->nAddIEScanLength = 0;
+			if (pSession->pAddIEScan) {
+				cdf_mem_free(pSession->pAddIEScan);
+				pSession->pAddIEScan = NULL;
+			}
+			csr_join_req->addIEScan.length = 0;
+		}
+		/* addIEAssoc */
+		if (pProfile->nAddIEAssocLength && pProfile->pAddIEAssoc) {
+			ieLen = pProfile->nAddIEAssocLength;
+			if (ieLen > pSession->nAddIEAssocLength) {
+				if (pSession->pAddIEAssoc
+				    && pSession->nAddIEAssocLength) {
+					cdf_mem_free(pSession->pAddIEAssoc);
+				}
+				pSession->pAddIEAssoc = cdf_mem_malloc(ieLen);
+				if (NULL == pSession->pAddIEAssoc)
+					status = CDF_STATUS_E_NOMEM;
+				else
+					status = CDF_STATUS_SUCCESS;
+				if (!CDF_IS_STATUS_SUCCESS(status))
+					break;
+			}
+			pSession->nAddIEAssocLength = ieLen;
+			cdf_mem_copy(pSession->pAddIEAssoc,
+				     pProfile->pAddIEAssoc, ieLen);
+			csr_join_req->addIEAssoc.length = ieLen;
+			cdf_mem_copy(&csr_join_req->addIEAssoc.addIEdata,
+					 pProfile->pAddIEAssoc, ieLen);
+		} else {
+			pSession->nAddIEAssocLength = 0;
+			if (pSession->pAddIEAssoc) {
+				cdf_mem_free(pSession->pAddIEAssoc);
+				pSession->pAddIEAssoc = NULL;
+			}
+			csr_join_req->addIEAssoc.length = 0;
+		}
+
+		if (eWNI_SME_REASSOC_REQ == messageType) {
+			/* Unmask any AC in reassoc that is ACM-set */
+			uapsd_mask = (uint8_t) pProfile->uapsd_mask;
+			if (uapsd_mask && (NULL != pBssDescription)) {
+				if (CSR_IS_QOS_BSS(pIes)
+						&& CSR_IS_UAPSD_BSS(pIes))
+#ifndef WLAN_MDM_CODE_REDUCTION_OPT
+					acm_mask =
+						sme_qos_get_acm_mask(pMac,
+								pBssDescription,
+								pIes);
+#endif /* WLAN_MDM_CODE_REDUCTION_OPT */
+				else
+					uapsd_mask = 0;
+			}
+		}
+
+		csr_join_req->UCEncryptionType =
+				csr_translate_encrypt_type_to_ed_type
+					(pProfile->negotiatedUCEncryptionType);
+
+		csr_join_req->MCEncryptionType =
+				csr_translate_encrypt_type_to_ed_type
+					(pProfile->negotiatedMCEncryptionType);
+#ifdef WLAN_FEATURE_11W
+		if (pProfile->MFPEnabled)
+			csr_join_req->MgmtEncryptionType = eSIR_ED_AES_128_CMAC;
+		else
+			csr_join_req->MgmtEncryptionType = eSIR_ED_NONE;
+#endif
+#ifdef FEATURE_WLAN_ESE
+		ese_config =  pMac->roam.configParam.isEseIniFeatureEnabled;
+#endif
+#ifdef WLAN_FEATURE_VOWIFI_11R
+		pProfile->MDID.mdiePresent = pBssDescription->mdiePresent;
+		if (csr_is_profile11r(pProfile)
+#ifdef FEATURE_WLAN_ESE
+		    &&
+		    !((pProfile->negotiatedAuthType ==
+		       eCSR_AUTH_TYPE_OPEN_SYSTEM) && (pIes->ESEVersion.present)
+		      && (ese_config))
+#endif
+			)
+			csr_join_req->is11Rconnection = true;
+		else
+			csr_join_req->is11Rconnection = false;
+#endif
+#ifdef FEATURE_WLAN_ESE
+		if (true == ese_config)
+			csr_join_req->isESEFeatureIniEnabled = true;
+		else
+			csr_join_req->isESEFeatureIniEnabled = false;
+
+		/* A profile can not be both ESE and 11R. But an 802.11R AP
+		 * may be advertising support for ESE as well. So if we are
+		 * associating Open or explicitly ESE then we will get ESE.
+		 * If we are associating explictly 11R only then we will get
+		 * 11R.
+		 */
+		if ((csr_is_profile_ese(pProfile) ||
+			((pIes->ESEVersion.present) &&
+			(pProfile->negotiatedAuthType ==
+				eCSR_AUTH_TYPE_OPEN_SYSTEM)))
+			&& (ese_config))
+			csr_join_req->isESEconnection = true;
+		else
+			csr_join_req->isESEconnection = false;
+
+		if (eWNI_SME_JOIN_REQ == messageType) {
+			tESETspecInfo eseTspec;
+			/*
+			 * ESE-Tspec IEs in the ASSOC request is presently not
+			 * supported. so nullify the TSPEC parameters
+			 */
+			cdf_mem_set(&eseTspec, sizeof(tESETspecInfo), 0);
+			cdf_mem_copy(&csr_join_req->eseTspecInfo,
+					&eseTspec, sizeof(tESETspecInfo));
+		} else if (eWNI_SME_REASSOC_REQ == messageType) {
+			if ((csr_is_profile_ese(pProfile) ||
+				((pIes->ESEVersion.present)
+				&& (pProfile->negotiatedAuthType ==
+					eCSR_AUTH_TYPE_OPEN_SYSTEM))) &&
+				(ese_config)) {
+				tESETspecInfo eseTspec;
+				cdf_mem_set(&eseTspec, sizeof(tESETspecInfo),
+						0);
+				eseTspec.numTspecs =
+					sme_qos_ese_retrieve_tspec_info(pMac,
+						sessionId,
+						(tTspecInfo *) &eseTspec.
+							tspec[0]);
+				csr_join_req->eseTspecInfo.numTspecs =
+					eseTspec.numTspecs;
+				if (eseTspec.numTspecs) {
+					cdf_mem_copy(&csr_join_req->eseTspecInfo
+						.tspec[0],
+						&eseTspec.tspec[0],
+						(eseTspec.numTspecs *
+							sizeof(tTspecInfo)));
+				}
+			} else {
+				tESETspecInfo eseTspec;
+				/**
+				 * ESE-Tspec IEs in the ASSOC request is
+				 * presently not supported. so nullify the TSPEC
+				 * parameters
+				 */
+				cdf_mem_set(&eseTspec, sizeof(tESETspecInfo),
+						0);
+				cdf_mem_copy(&csr_join_req->eseTspecInfo,
+						&eseTspec,
+						sizeof(tESETspecInfo));
+			}
+		}
+#endif /* FEATURE_WLAN_ESE */
+#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR)
+		if (ese_config
+#ifdef FEATURE_WLAN_LFR
+		    || csr_roam_is_fast_roam_enabled(pMac, sessionId)
+#endif
+		    ) {
+			csr_join_req->isFastTransitionEnabled = true;
+		} else {
+			csr_join_req->isFastTransitionEnabled = false;
+		}
+#endif
+#ifdef FEATURE_WLAN_LFR
+		if (csr_roam_is_fast_roam_enabled(pMac, sessionId))
+			csr_join_req->isFastRoamIniFeatureEnabled = true;
+		else
+			csr_join_req->isFastRoamIniFeatureEnabled = false;
+#endif
+
+		csr_join_req->txLdpcIniFeatureEnabled =
+			(uint8_t) pMac->roam.configParam.txLdpcEnable;
+
+		if ((csr_is11h_supported(pMac))
+		    && (CDS_IS_CHANNEL_5GHZ(pBssDescription->channelId))
+		    && (pIes->Country.present)
+		    && (!pMac->roam.configParam.
+			fSupplicantCountryCodeHasPriority)) {
+			csr_save_to_channel_power2_g_5_g(pMac,
+				pIes->Country.num_triplets *
+				sizeof(tSirMacChanInfo),
+				(tSirMacChanInfo *)
+				(&pIes->Country.triplets[0]));
+			csr_apply_power2_current(pMac);
+		}
+		cdf_mem_copy(&csr_join_req->htConfig,
+				&pSession->htConfig, sizeof(tSirHTConfig));
+#ifdef WLAN_FEATURE_11AC
+		csr_join_req->txBFIniFeatureEnabled =
+				(uint8_t) pMac->roam.configParam.txBFEnable;
+
+		if (pMac->roam.configParam.txBFEnable) {
+			txBFCsnValue =
+				(uint8_t)pMac->roam.configParam.txBFCsnValue;
+			if (IS_BSS_VHT_CAPABLE(pIes->VHTCaps) &&
+					pIes->VHTCaps.numSoundingDim)
+				txBFCsnValue = CDF_MIN(txBFCsnValue,
+						pIes->VHTCaps.numSoundingDim);
+			else if (IS_BSS_VHT_CAPABLE(pIes->vendor2_ie.VHTCaps)
+				&& pIes->vendor2_ie.VHTCaps.numSoundingDim)
+				txBFCsnValue = CDF_MIN(txBFCsnValue,
+					pIes->vendor2_ie.VHTCaps.numSoundingDim);
+		}
+		csr_join_req->txBFCsnValue = txBFCsnValue;
+
+		csr_join_req->txMuBformee =
+			(uint8_t) pMac->roam.configParam.txMuBformee;
+
+		csr_join_req->enableVhtpAid =
+			(uint8_t) pMac->roam.configParam.enableVhtpAid;
+
+		csr_join_req->enableVhtGid =
+			(uint8_t) pMac->roam.configParam.enableVhtGid;
+
+#endif
+		csr_join_req->enableAmpduPs =
+			(uint8_t) pMac->roam.configParam.enableAmpduPs;
+
+		csr_join_req->enableHtSmps =
+			(uint8_t) pMac->roam.configParam.enableHtSmps;
+
+		csr_join_req->htSmps = (uint8_t) pMac->roam.configParam.htSmps;
+
+		csr_join_req->isAmsduSupportInAMPDU =
+			(uint8_t) pMac->roam.configParam.isAmsduSupportInAMPDU;
+
+		if (pMac->roam.roamSession[sessionId].fWMMConnection)
+			csr_join_req->isWMEenabled = true;
+		else
+			csr_join_req->isWMEenabled = false;
+
+		if (pMac->roam.roamSession[sessionId].fQOSConnection)
+			csr_join_req->isQosEnabled = true;
+		else
+			csr_join_req->isQosEnabled = false;
+
+		if (pProfile->bOSENAssociation)
+			csr_join_req->isOSENConnection = true;
+		else
+			csr_join_req->isOSENConnection = false;
+
+		pAP_capabilityInfo =
+			(tSirMacCapabilityInfo *)
+				&pBssDescription->capabilityInfo;
+		/*
+		 * tell the target AP my 11H capability only if both AP and STA
+		 * support
+		 * 11H and the channel being used is 11a
+		 */
+		if (csr_is11h_supported(pMac) && pAP_capabilityInfo->spectrumMgt
+			&& eSIR_11A_NW_TYPE == pBssDescription->nwType) {
+			fTmp = (tAniBool) 1;
+		} else
+			fTmp = (tAniBool) 0;
+
+		csr_join_req->spectrumMgtIndicator = fTmp;
+		csr_join_req->powerCap.minTxPower = MIN_TX_PWR_CAP;
+		/*
+		 * This is required for 11k test VoWiFi Ent: Test 2.
+		 * We need the power capabilities for Assoc Req.
+		 * This macro is provided by the halPhyCfg.h. We pick our
+		 * max and min capability by the halPhy provided macros
+		 */
+		pwrLimit = csr_get_cfg_max_tx_power(pMac,
+					pBssDescription->channelId);
+		if (0 != pwrLimit)
+			csr_join_req->powerCap.maxTxPower = pwrLimit;
+		else
+			csr_join_req->powerCap.maxTxPower = MAX_TX_PWR_CAP;
+
+		csr_add_supported_5Ghz_channels(pMac, csr_join_req);
+
+		csr_join_req->uapsdPerAcBitmask = (uint8_t)pProfile->uapsd_mask;
+		/* Move the entire BssDescription into the join request. */
+		cdf_mem_copy(&csr_join_req->bssDescription, pBssDescription,
+				pBssDescription->length +
+				sizeof(pBssDescription->length));
+
+		/*
+		 * conc_custom_rule1:
+		 * If SAP comes up first and STA comes up later then SAP
+		 * need to follow STA's channel in 2.4Ghz. In following if
+		 * condition we are adding sanity check, just to make sure that
+		 * if this rule is enabled then don't allow STA to connect on
+		 * 5gz channel and also by this time SAP's channel should be the
+		 * same as STA's channel.
+		 */
+		if (pMac->roam.configParam.conc_custom_rule1) {
+			if ((0 ==
+			     pMac->
+			      roam.configParam.is_sta_connection_in_5gz_enabled)
+			     && CDS_IS_CHANNEL_5GHZ(pBssDescription->
+							channelId)) {
+				CDF_TRACE(CDF_MODULE_ID_SME,
+					  CDF_TRACE_LEVEL_ERROR,
+					  FL("STA-conn on 5G isn't allowed"));
+				status = CDF_STATUS_E_FAILURE;
+				break;
+			}
+			if (!CDS_IS_CHANNEL_5GHZ(pBssDescription->channelId) &&
+				(false == csr_is_conn_allow_2g_band(pMac,
+						pBssDescription->channelId))) {
+				status = CDF_STATUS_E_FAILURE;
+				break;
+			}
+		}
+
+		/*
+		 * conc_custom_rule2:
+		 * If P2PGO comes up first and STA comes up later then P2PGO
+		 * need to follow STA's channel in 5Ghz. In following if
+		 * condition we are just adding sanity check to make sure that
+		 * by this time P2PGO's channel is same as STA's channel.
+		 */
+		if (pMac->roam.configParam.conc_custom_rule2) {
+			if (!CDS_IS_CHANNEL_24GHZ(pBssDescription->channelId) &&
+				(false == csr_is_conn_allow_5g_band(pMac,
+				pBssDescription->channelId))) {
+					status = CDF_STATUS_E_FAILURE;
+					break;
+			}
+		}
+		status = cds_send_mb_message_to_mac(csr_join_req);
+		if (!CDF_IS_STATUS_SUCCESS(status)) {
+			/*
+			 * cds_send_mb_message_to_mac would've released the mem
+			 * allocated by csr_join_req. Let's make it defensive by
+			 * assigning NULL to the pointer.
+			 */
+			csr_join_req = NULL;
+			break;
+		} else {
+#ifndef WLAN_MDM_CODE_REDUCTION_OPT
+			if (eWNI_SME_JOIN_REQ == messageType) {
+				/* Notify QoS module that join happening */
+				pSession->join_bssid_count++;
+				CDF_TRACE(CDF_MODULE_ID_SME,
+						CDF_TRACE_LEVEL_DEBUG,
+						"BSSID Count = %d",
+						pSession->join_bssid_count);
+				sme_qos_csr_event_ind(pMac, (uint8_t) sessionId,
+						SME_QOS_CSR_JOIN_REQ, NULL);
+			} else if (eWNI_SME_REASSOC_REQ == messageType) {
+				/* Notify QoS module that reassoc happening */
+				sme_qos_csr_event_ind(pMac, (uint8_t) sessionId,
+						SME_QOS_CSR_REASSOC_REQ,
+						NULL);
+			}
+#endif
+		}
+	} while (0);
+
+	/* Clean up the memory in case of any failure */
+	if (!CDF_IS_STATUS_SUCCESS(status) && (NULL != csr_join_req))
+		cdf_mem_free(csr_join_req);
+
+	return status;
+}
+
+/* */
+CDF_STATUS csr_send_mb_disassoc_req_msg(tpAniSirGlobal pMac, uint32_t sessionId,
+					tSirMacAddr bssId, uint16_t reasonCode)
+{
+	tSirSmeDisassocReq *pMsg;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!CSR_IS_SESSION_VALID(pMac, sessionId))
+		return CDF_STATUS_E_FAILURE;
+
+	pMsg = cdf_mem_malloc(sizeof(tSirSmeDisassocReq));
+	if (NULL == pMsg)
+		return CDF_STATUS_E_NOMEM;
+
+	cdf_mem_set(pMsg, sizeof(tSirSmeDisassocReq), 0);
+	pMsg->messageType = eWNI_SME_DISASSOC_REQ;
+	pMsg->length = sizeof(tSirSmeDisassocReq);
+	pMsg->sessionId = sessionId;
+	pMsg->transactionId = 0;
+	if ((pSession->pCurRoamProfile != NULL)
+		&& ((CSR_IS_INFRA_AP(pSession->pCurRoamProfile))
+		|| (CSR_IS_WDS_AP(pSession->pCurRoamProfile)))) {
+		cdf_mem_copy(&pMsg->bssId,
+			     &pSession->selfMacAddr,
+			     sizeof(tSirMacAddr));
+		cdf_mem_copy(&pMsg->peerMacAddr,
+			     bssId,
+			     sizeof(tSirMacAddr));
+	} else {
+		cdf_mem_copy(&pMsg->bssId,
+			     bssId,
+			     sizeof(tSirMacAddr));
+		cdf_mem_copy(&pMsg->peerMacAddr,
+			     bssId,
+			     sizeof(tSirMacAddr));
+	}
+	pMsg->reasonCode = reasonCode;
+	/*
+	 * The state will be DISASSOC_HANDOFF only when we are doing
+	 * handoff. Here we should not send the disassoc over the air
+	 * to the AP
+	 */
+	if (CSR_IS_ROAM_SUBSTATE_DISASSOC_HO(pMac, sessionId)
+#ifdef WLAN_FEATURE_VOWIFI_11R
+	    && csr_roam_is11r_assoc(pMac, sessionId)
+#endif
+	    ) {
+		/* Set DoNotSendOverTheAir flag to 1 only for handoff case */
+		pMsg->doNotSendOverTheAir = CSR_DONT_SEND_DISASSOC_OVER_THE_AIR;
+	}
+	return cds_send_mb_message_to_mac(pMsg);
+}
+
+CDF_STATUS csr_send_mb_tkip_counter_measures_req_msg(tpAniSirGlobal pMac,
+						     uint32_t sessionId, bool bEnable,
+						     tSirMacAddr bssId)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tSirSmeTkipCntrMeasReq *pMsg;
+	do {
+		pMsg = cdf_mem_malloc(sizeof(tSirSmeTkipCntrMeasReq));
+		if (NULL == pMsg)
+			status = CDF_STATUS_E_NOMEM;
+		else
+			status = CDF_STATUS_SUCCESS;
+		if (!CDF_IS_STATUS_SUCCESS(status))
+			break;
+		cdf_mem_set(pMsg, sizeof(tSirSmeTkipCntrMeasReq), 0);
+		pMsg->messageType = eWNI_SME_TKIP_CNTR_MEAS_REQ;
+		pMsg->length = sizeof(tSirSmeTkipCntrMeasReq);
+		pMsg->sessionId = sessionId;
+		pMsg->transactionId = 0;
+		cdf_mem_copy(pMsg->bssId, bssId, sizeof(tSirMacAddr));
+		pMsg->bEnable = bEnable;
+		status = cds_send_mb_message_to_mac(pMsg);
+	} while (0);
+	return status;
+}
+
+CDF_STATUS
+csr_send_mb_get_associated_stas_req_msg(tpAniSirGlobal pMac, uint32_t sessionId,
+					CDF_MODULE_ID modId, tSirMacAddr bssId,
+					void *pUsrContext, void *pfnSapEventCallback,
+					uint8_t *pAssocStasBuf)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tSirSmeGetAssocSTAsReq *pMsg;
+	do {
+		pMsg = cdf_mem_malloc(sizeof(tSirSmeGetAssocSTAsReq));
+		if (NULL == pMsg)
+			status = CDF_STATUS_E_NOMEM;
+		else
+			status = CDF_STATUS_SUCCESS;
+		if (!CDF_IS_STATUS_SUCCESS(status))
+			break;
+		cdf_mem_set(pMsg, sizeof(tSirSmeGetAssocSTAsReq), 0);
+		pMsg->messageType = eWNI_SME_GET_ASSOC_STAS_REQ;
+		cdf_mem_copy(pMsg->bssId, bssId, sizeof(tSirMacAddr));
+		pMsg->modId = modId;
+		cdf_mem_copy(pMsg->pUsrContext,
+				pUsrContext, sizeof(void *));
+		cdf_mem_copy(pMsg->pSapEventCallback,
+				pfnSapEventCallback, sizeof(void *));
+		cdf_mem_copy(pMsg->pAssocStasArray,
+				pAssocStasBuf, sizeof(void *));
+		pMsg->length = sizeof(struct sSirSmeGetAssocSTAsReq);
+		status = cds_send_mb_message_to_mac(pMsg);
+	} while (0);
+	return status;
+}
+
+CDF_STATUS
+csr_send_mb_get_wpspbc_sessions(tpAniSirGlobal pMac, uint32_t sessionId,
+				tSirMacAddr bssId, void *pUsrContext,
+				void *pfnSapEventCallback,
+				struct cdf_mac_addr pRemoveMac)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tSirSmeGetWPSPBCSessionsReq *pMsg;
+
+	do {
+		pMsg = cdf_mem_malloc(sizeof(tSirSmeGetWPSPBCSessionsReq));
+		if (NULL == pMsg)
+			status = CDF_STATUS_E_NOMEM;
+		else
+			status = CDF_STATUS_SUCCESS;
+		if (!CDF_IS_STATUS_SUCCESS(status))
+			break;
+		cdf_mem_set(pMsg, sizeof(tSirSmeGetWPSPBCSessionsReq), 0);
+		pMsg->messageType = eWNI_SME_GET_WPSPBC_SESSION_REQ;
+		cdf_mem_copy(pMsg->pUsrContext, pUsrContext, sizeof(void *));
+		cdf_mem_copy(pMsg->pSapEventCallback, pfnSapEventCallback,
+			     sizeof(void *));
+		cdf_mem_copy(pMsg->bssId, bssId, sizeof(tSirMacAddr));
+		cdf_mem_copy(pMsg->pRemoveMac, pRemoveMac.bytes,
+			     CDF_MAC_ADDR_SIZE);
+		pMsg->length = sizeof(struct sSirSmeGetWPSPBCSessionsReq);
+		status = cds_send_mb_message_to_mac(pMsg);
+	} while (0);
+	return status;
+}
+
+CDF_STATUS csr_send_chng_mcc_beacon_interval(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	tpSirChangeBIParams pMsg;
+	uint16_t len = 0;
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("  session %d not found "), sessionId);
+		return CDF_STATUS_E_FAILURE;
+	}
+	/* NO need to update the Beacon Params if update beacon parameter flag is not set */
+	if (!pMac->roam.roamSession[sessionId].bssParams.updatebeaconInterval)
+		return CDF_STATUS_SUCCESS;
+
+	pMac->roam.roamSession[sessionId].bssParams.updatebeaconInterval =
+		false;
+
+	/* Create the message and send to lim */
+	len = sizeof(tSirChangeBIParams);
+	pMsg = cdf_mem_malloc(len);
+	if (NULL == pMsg)
+		status = CDF_STATUS_E_NOMEM;
+	else
+		status = CDF_STATUS_SUCCESS;
+	if (CDF_IS_STATUS_SUCCESS(status)) {
+		cdf_mem_set(pMsg, sizeof(tSirChangeBIParams), 0);
+		pMsg->messageType = eWNI_SME_CHNG_MCC_BEACON_INTERVAL;
+		pMsg->length = len;
+
+		/* bssId */
+		cdf_mem_copy((tSirMacAddr *) pMsg->bssId,
+			     &pSession->selfMacAddr, sizeof(tSirMacAddr));
+		sms_log(pMac, LOG1,
+			FL("CSR Attempting to change BI for Bssid= "
+			   MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pMsg->bssId));
+		pMsg->sessionId = sessionId;
+		sms_log(pMac, LOG1, FL("  session %d BeaconInterval %d"),
+			sessionId,
+			pMac->roam.roamSession[sessionId].bssParams.
+			beaconInterval);
+		pMsg->beaconInterval =
+			pMac->roam.roamSession[sessionId].bssParams.beaconInterval;
+		status = cds_send_mb_message_to_mac(pMsg);
+	}
+	return status;
+}
+
+#ifdef QCA_HT_2040_COEX
+CDF_STATUS csr_set_ht2040_mode(tpAniSirGlobal pMac, uint32_t sessionId,
+			       ePhyChanBondState cbMode, bool obssEnabled)
+{
+	tpSirSetHT2040Mode pMsg;
+	uint16_t len = 0;
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("  session %d not found "), sessionId);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	/* Create the message and send to lim */
+	len = sizeof(tSirSetHT2040Mode);
+	pMsg = cdf_mem_malloc(len);
+	if (NULL == pMsg)
+		status = CDF_STATUS_E_NOMEM;
+	else
+		status = CDF_STATUS_SUCCESS;
+	if (CDF_IS_STATUS_SUCCESS(status)) {
+		cdf_mem_set(pMsg, sizeof(tSirSetHT2040Mode), 0);
+		pMsg->messageType = eWNI_SME_SET_HT_2040_MODE;
+		pMsg->length = len;
+
+		/* bssId */
+		cdf_mem_copy((tSirMacAddr *) pMsg->bssId,
+			     &pSession->selfMacAddr, sizeof(tSirMacAddr));
+		sms_log(pMac, LOG1,
+			FL("CSR Attempting to set HT20/40 mode for Bssid= "
+			   MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pMsg->bssId));
+		pMsg->sessionId = sessionId;
+		sms_log(pMac, LOG1, FL("  session %d HT20/40 mode %d"),
+			sessionId, cbMode);
+		pMsg->cbMode = cbMode;
+		pMsg->obssEnabled = obssEnabled;
+		status = cds_send_mb_message_to_mac(pMsg);
+	}
+	return status;
+}
+#endif
+
+CDF_STATUS csr_send_mb_deauth_req_msg(tpAniSirGlobal pMac, uint32_t sessionId,
+				      tSirMacAddr bssId, uint16_t reasonCode)
+{
+	tSirSmeDeauthReq *pMsg;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!CSR_IS_SESSION_VALID(pMac, sessionId))
+		return CDF_STATUS_E_FAILURE;
+
+	pMsg = cdf_mem_malloc(sizeof(tSirSmeDeauthReq));
+	if (NULL == pMsg)
+		return CDF_STATUS_E_NOMEM;
+
+	cdf_mem_set(pMsg, sizeof(tSirSmeDeauthReq), 0);
+	pMsg->messageType = eWNI_SME_DEAUTH_REQ;
+	pMsg->length = sizeof(tSirSmeDeauthReq);
+	pMsg->sessionId = sessionId;
+	pMsg->transactionId = 0;
+
+	if ((pSession->pCurRoamProfile != NULL)
+	     && ((CSR_IS_INFRA_AP(pSession->pCurRoamProfile))
+	     || (CSR_IS_WDS_AP(pSession->pCurRoamProfile)))) {
+		cdf_mem_copy(&pMsg->bssId,
+			     &pSession->selfMacAddr,
+			     sizeof(tSirMacAddr));
+	} else {
+		cdf_mem_copy(&pMsg->bssId,
+			     bssId,
+			     sizeof(tSirMacAddr));
+	}
+
+	/* Set the peer MAC address before sending the message to LIM */
+	cdf_mem_copy(&pMsg->peerMacAddr,
+		     bssId,
+		     sizeof(tSirMacAddr));
+	pMsg->reasonCode = reasonCode;
+
+	return cds_send_mb_message_to_mac(pMsg);
+}
+
+CDF_STATUS csr_send_mb_disassoc_cnf_msg(tpAniSirGlobal pMac,
+					tpSirSmeDisassocInd pDisassocInd)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tSirSmeDisassocCnf *pMsg;
+	do {
+		pMsg = cdf_mem_malloc(sizeof(tSirSmeDisassocCnf));
+		if (NULL == pMsg)
+			status = CDF_STATUS_E_NOMEM;
+		else
+			status = CDF_STATUS_SUCCESS;
+		if (!CDF_IS_STATUS_SUCCESS(status))
+			break;
+		cdf_mem_set(pMsg, sizeof(tSirSmeDisassocCnf), 0);
+		pMsg->messageType = eWNI_SME_DISASSOC_CNF;
+		pMsg->statusCode = eSIR_SME_SUCCESS;
+		pMsg->length = sizeof(tSirSmeDisassocCnf);
+		cdf_mem_copy(pMsg->peerMacAddr, pDisassocInd->peerMacAddr,
+			     sizeof(pMsg->peerMacAddr));
+		status = CDF_STATUS_SUCCESS;
+		if (!CDF_IS_STATUS_SUCCESS(status)) {
+			cdf_mem_free(pMsg);
+			break;
+		}
+
+		cdf_mem_copy(pMsg->bssId, pDisassocInd->bssId,
+			     sizeof(pMsg->peerMacAddr));
+		status = CDF_STATUS_SUCCESS;
+		if (!CDF_IS_STATUS_SUCCESS(status)) {
+			cdf_mem_free(pMsg);
+			break;
+		}
+
+		status = cds_send_mb_message_to_mac(pMsg);
+	} while (0);
+	return status;
+}
+
+CDF_STATUS csr_send_mb_deauth_cnf_msg(tpAniSirGlobal pMac,
+				      tpSirSmeDeauthInd pDeauthInd)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tSirSmeDeauthCnf *pMsg;
+	do {
+		pMsg = cdf_mem_malloc(sizeof(tSirSmeDeauthCnf));
+		if (NULL == pMsg)
+			status = CDF_STATUS_E_NOMEM;
+		else
+			status = CDF_STATUS_SUCCESS;
+		if (!CDF_IS_STATUS_SUCCESS(status))
+			break;
+		cdf_mem_set(pMsg, sizeof(tSirSmeDeauthCnf), 0);
+		pMsg->messageType = eWNI_SME_DEAUTH_CNF;
+		pMsg->statusCode = eSIR_SME_SUCCESS;
+		pMsg->length = sizeof(tSirSmeDeauthCnf);
+		cdf_mem_copy(pMsg->bssId, pDeauthInd->bssId,
+			     sizeof(pMsg->bssId));
+		status = CDF_STATUS_SUCCESS;
+		if (!CDF_IS_STATUS_SUCCESS(status)) {
+			cdf_mem_free(pMsg);
+			break;
+		}
+		cdf_mem_copy(pMsg->peerMacAddr, pDeauthInd->peerMacAddr,
+			     sizeof(pMsg->peerMacAddr));
+		status = CDF_STATUS_SUCCESS;
+		if (!CDF_IS_STATUS_SUCCESS(status)) {
+			cdf_mem_free(pMsg);
+			break;
+		}
+		status = cds_send_mb_message_to_mac(pMsg);
+	} while (0);
+	return status;
+}
+
+CDF_STATUS csr_send_assoc_cnf_msg(tpAniSirGlobal pMac, tpSirSmeAssocInd pAssocInd,
+				  CDF_STATUS Halstatus)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tSirSmeAssocCnf *pMsg;
+
+	sms_log(pMac, LOG1,
+		FL("Posting eWNI_SME_ASSOC_CNF to LIM.HalStatus :%d"),
+		Halstatus);
+	do {
+		pMsg = cdf_mem_malloc(sizeof(tSirSmeAssocCnf));
+		if (NULL == pMsg)
+			return CDF_STATUS_E_NOMEM;
+		cdf_mem_set(pMsg, sizeof(tSirSmeAssocCnf), 0);
+		pMsg->messageType = eWNI_SME_ASSOC_CNF;
+		pMsg->length = sizeof(tSirSmeAssocCnf);
+		if (CDF_IS_STATUS_SUCCESS(Halstatus))
+			pMsg->statusCode = eSIR_SME_SUCCESS;
+		else
+			pMsg->statusCode = eSIR_SME_ASSOC_REFUSED;
+		/* bssId */
+		cdf_mem_copy(pMsg->bssId, pAssocInd->bssId,
+			     sizeof(tSirMacAddr));
+		/* peerMacAddr */
+		cdf_mem_copy(pMsg->peerMacAddr, pAssocInd->peerMacAddr,
+			     sizeof(tSirMacAddr));
+		/* aid */
+		pMsg->aid = pAssocInd->aid;
+		/* alternateBssId */
+		cdf_mem_copy(pMsg->alternateBssId, pAssocInd->bssId,
+			     sizeof(tSirMacAddr));
+		/* alternateChannelId */
+		pMsg->alternateChannelId = 11;
+		/* pMsg is freed by cds_send_mb_message_to_mac in anycase*/
+		status = cds_send_mb_message_to_mac(pMsg);
+	} while (0);
+	return status;
+}
+
+CDF_STATUS csr_send_assoc_ind_to_upper_layer_cnf_msg(tpAniSirGlobal pMac,
+						     tpSirSmeAssocInd pAssocInd,
+						     CDF_STATUS Halstatus,
+						     uint8_t sessionId)
+{
+	tSirMsgQ msgQ;
+	tSirSmeAssocIndToUpperLayerCnf *pMsg;
+	uint8_t *pBuf;
+	tSirResultCodes statusCode;
+	uint16_t wTmp;
+	do {
+		pMsg = cdf_mem_malloc(sizeof(tSirSmeAssocIndToUpperLayerCnf));
+		if (NULL == pMsg)
+			return CDF_STATUS_E_NOMEM;
+		cdf_mem_set(pMsg, sizeof(tSirSmeAssocIndToUpperLayerCnf), 0);
+
+		pMsg->messageType = eWNI_SME_UPPER_LAYER_ASSOC_CNF;
+		pMsg->length = sizeof(tSirSmeAssocIndToUpperLayerCnf);
+
+		pMsg->sessionId = sessionId;
+
+		pBuf = (uint8_t *) &pMsg->statusCode;
+		if (CDF_IS_STATUS_SUCCESS(Halstatus))
+			statusCode = eSIR_SME_SUCCESS;
+		else
+			statusCode = eSIR_SME_ASSOC_REFUSED;
+		cdf_mem_copy(pBuf, &statusCode, sizeof(tSirResultCodes));
+		pBuf += sizeof(tSirResultCodes);
+		/* bssId */
+		cdf_mem_copy((tSirMacAddr *) pBuf, pAssocInd->bssId,
+			     sizeof(tSirMacAddr));
+		pBuf += sizeof(tSirMacAddr);
+		/* peerMacAddr */
+		cdf_mem_copy((tSirMacAddr *) pBuf, pAssocInd->peerMacAddr,
+			     sizeof(tSirMacAddr));
+		pBuf += sizeof(tSirMacAddr);
+		/* StaId */
+		wTmp = pAssocInd->staId;
+		cdf_mem_copy(pBuf, &wTmp, sizeof(uint16_t));
+		pBuf += sizeof(uint16_t);
+		/* alternateBssId */
+		cdf_mem_copy((tSirMacAddr *) pBuf, pAssocInd->bssId,
+			     sizeof(tSirMacAddr));
+		pBuf += sizeof(tSirMacAddr);
+		/* alternateChannelId */
+		*pBuf = 11;
+		pBuf += sizeof(uint8_t);
+		/* Instead of copying roam Info, we just copy only WmmEnabled, RsnIE information */
+		/* Wmm */
+		*pBuf = pAssocInd->wmmEnabledSta;
+		pBuf += sizeof(uint8_t);
+		/* RSN IE */
+		cdf_mem_copy((tSirRSNie *) pBuf, &pAssocInd->rsnIE,
+			     sizeof(tSirRSNie));
+		pBuf += sizeof(tSirRSNie);
+#ifdef FEATURE_WLAN_WAPI
+		/* WAPI IE */
+		cdf_mem_copy((tSirWAPIie *) pBuf, &pAssocInd->wapiIE,
+			     sizeof(tSirWAPIie));
+		pBuf += sizeof(tSirWAPIie);
+#endif
+		/* Additional IE */
+		cdf_mem_copy((void *)pBuf, &pAssocInd->addIE,
+			     sizeof(tSirAddie));
+		pBuf += sizeof(tSirAddie);
+		/* reassocReq */
+		*pBuf = pAssocInd->reassocReq;
+		pBuf += sizeof(uint8_t);
+		/* timingMeasCap */
+		*pBuf = pAssocInd->timingMeasCap;
+		pBuf += sizeof(uint8_t);
+		cdf_mem_copy((void *)pBuf, &pAssocInd->chan_info,
+			     sizeof(tSirSmeChanInfo));
+		msgQ.type = eWNI_SME_UPPER_LAYER_ASSOC_CNF;
+		msgQ.bodyptr = pMsg;
+		msgQ.bodyval = 0;
+		sys_process_mmh_msg(pMac, &msgQ);
+	} while (0);
+	return CDF_STATUS_SUCCESS;
+}
+
+CDF_STATUS csr_send_mb_set_context_req_msg(tpAniSirGlobal pMac, uint32_t sessionId,
+					   tSirMacAddr peerMacAddr, uint8_t numKeys,
+					   tAniEdType edType, bool fUnicast,
+					   tAniKeyDirection aniKeyDirection,
+					   uint8_t keyId, uint8_t keyLength,
+					   uint8_t *pKey, uint8_t paeRole,
+					   uint8_t *pKeyRsc)
+{
+	tSirSmeSetContextReq *pMsg;
+	uint16_t msgLen;
+	CDF_STATUS status = CDF_STATUS_E_FAILURE;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+	sms_log(pMac, LOG1, FL("keylength is %d, Encry type is : %d"),
+		keyLength, edType);
+	do {
+		if ((1 != numKeys) && (0 != numKeys))
+			break;
+		/*
+		 * All of these fields appear in every SET_CONTEXT message.
+		 * Below we'll add in the size for each key set. Since we only support
+		 * up to one key, we always allocate memory for 1 key.
+		 */
+		msgLen = sizeof(struct sSirSmeSetContextReq);
+
+		pMsg = cdf_mem_malloc(msgLen);
+		if (NULL == pMsg)
+			return CDF_STATUS_E_NOMEM;
+		cdf_mem_set(pMsg, msgLen, 0);
+		pMsg->messageType = eWNI_SME_SETCONTEXT_REQ;
+		pMsg->length = msgLen;
+		pMsg->sessionId = (uint8_t) sessionId;
+		pMsg->transactionId = 0;
+		cdf_mem_copy(pMsg->peerMacAddr, peerMacAddr,
+			     sizeof(tSirMacAddr));
+		cdf_mem_copy(pMsg->bssId,
+			     pSession->connectedProfile.bssid.bytes,
+			     sizeof(tSirMacAddr));
+
+		/**
+		 * Set the pMsg->keyMaterial.length field
+		 * (this length is defined as all data that follows the
+		 * edType field in the tSirKeyMaterial keyMaterial; field).
+		 *
+		 * NOTE:  This keyMaterial.length contains the length of a
+		 * MAX size key, though the keyLength can be shorter than this
+		 * max size.  Is LIM interpreting this ok ?
+		 */
+		pMsg->keyMaterial.length =
+				sizeof(pMsg->keyMaterial.numKeys) +
+				(numKeys * sizeof(pMsg->keyMaterial.key));
+		pMsg->keyMaterial.edType = edType;
+		pMsg->keyMaterial.numKeys = numKeys;
+		pMsg->keyMaterial.key[0].keyId = keyId;
+		pMsg->keyMaterial.key[0].unicast = fUnicast;
+		pMsg->keyMaterial.key[0].keyDirection = aniKeyDirection;
+		cdf_mem_copy(pMsg->keyMaterial.key[0].keyRsc,
+				pKeyRsc, CSR_MAX_RSC_LEN);
+		/* 0 is Supplicant */
+		pMsg->keyMaterial.key[0].paeRole = paeRole;
+		pMsg->keyMaterial.key[0].keyLength = keyLength;
+		if (keyLength && pKey) {
+			cdf_mem_copy(pMsg->keyMaterial.key[0].key,
+					pKey, keyLength);
+			sms_log(pMac, LOG1,
+				FL("SME set keyIndx (%d) encType (%d) key"),
+				keyId, edType);
+			sir_dump_buf(pMac, SIR_SMS_MODULE_ID, LOG1, pKey,
+				     keyLength);
+		}
+		status = cds_send_mb_message_to_mac(pMsg);
+	} while (0);
+	return status;
+}
+
+CDF_STATUS csr_send_mb_start_bss_req_msg(tpAniSirGlobal pMac, uint32_t sessionId,
+					 eCsrRoamBssType bssType,
+					 tCsrRoamStartBssParams *pParam,
+					 tSirBssDescription *pBssDesc)
+{
+	tSirSmeStartBssReq *pMsg;
+	uint16_t wTmp;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("  session %d not found "), sessionId);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	pSession->joinFailStatusCode.statusCode = eSIR_SME_SUCCESS;
+	pSession->joinFailStatusCode.reasonCode = 0;
+	pMsg = cdf_mem_malloc(sizeof(tSirSmeStartBssReq));
+	if (NULL == pMsg)
+		return CDF_STATUS_E_NOMEM;
+
+	cdf_mem_set(pMsg, sizeof(tSirSmeStartBssReq), 0);
+	pMsg->messageType = eWNI_SME_START_BSS_REQ;
+	pMsg->sessionId = sessionId;
+	pMsg->length = sizeof(tSirSmeStartBssReq);
+	pMsg->transactionId = 0;
+	cdf_mem_copy(pMsg->bssId, pParam->bssid.bytes, sizeof(tSirMacAddr));
+	/* selfMacAddr */
+	cdf_mem_copy(pMsg->selfMacAddr,
+		     pSession->selfMacAddr.bytes,
+		     sizeof(tSirMacAddr));
+	/* beaconInterval */
+	if (pBssDesc && pBssDesc->beaconInterval)
+		wTmp = pBssDesc->beaconInterval;
+	else if (pParam->beaconInterval)
+		wTmp = pParam->beaconInterval;
+	else
+		wTmp = WNI_CFG_BEACON_INTERVAL_STADEF;
+
+	if (csr_isconcurrentsession_valid(pMac, sessionId, pParam->bssPersona)
+		== CDF_STATUS_SUCCESS) {
+		csr_validate_mcc_beacon_interval(pMac,
+						 pParam->operationChn,
+						 &wTmp,
+						 sessionId,
+						 pParam->bssPersona);
+		/* Update the beacon Interval */
+		pParam->beaconInterval = wTmp;
+	} else {
+		sms_log(pMac, LOGE,
+			FL("****Start BSS failed persona already exists***"));
+		cdf_mem_free(pMsg);
+		return CDF_STATUS_E_FAILURE;
+	}
+	pMsg->beaconInterval = wTmp;
+	pMsg->dot11mode =
+		csr_translate_to_wni_cfg_dot11_mode(pMac,
+						    pParam->uCfgDot11Mode);
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+	pMsg->cc_switch_mode = pMac->roam.configParam.cc_switch_mode;
+#endif
+	pMsg->bssType = csr_translate_bsstype_to_mac_type(bssType);
+	cdf_mem_copy(&pMsg->ssId, &pParam->ssId, sizeof(pParam->ssId));
+	pMsg->channelId = pParam->operationChn;
+	/* What should we really do for the cbmode. */
+	pMsg->cbMode = (ePhyChanBondState) pParam->cbMode;
+	pMsg->vht_channel_width = pParam->ch_params.ch_width;
+	pMsg->center_freq_seg0 = pParam->ch_params.center_freq_seg0;
+	pMsg->center_freq_seg1 = pParam->ch_params.center_freq_seg1;
+	pMsg->sec_ch_offset = pParam->ch_params.sec_ch_offset;
+	pMsg->privacy = pParam->privacy;
+	pMsg->apUapsdEnable = pParam->ApUapsdEnable;
+	pMsg->ssidHidden = pParam->ssidHidden;
+	pMsg->fwdWPSPBCProbeReq = (uint8_t) pParam->fwdWPSPBCProbeReq;
+	pMsg->protEnabled = (uint8_t) pParam->protEnabled;
+	pMsg->obssProtEnabled = (uint8_t) pParam->obssProtEnabled;
+	/* set cfg related to protection */
+	pMsg->ht_capab = pParam->ht_protection;
+	pMsg->authType = pParam->authType;
+	pMsg->dtimPeriod = pParam->dtimPeriod;
+	pMsg->wps_state = pParam->wps_state;
+	pMsg->isCoalesingInIBSSAllowed = pMac->isCoalesingInIBSSAllowed;
+	pMsg->bssPersona = pParam->bssPersona;
+	pMsg->txLdpcIniFeatureEnabled = pMac->roam.configParam.txLdpcEnable;
+#ifdef WLAN_FEATURE_11W
+	pMsg->pmfCapable = pParam->mfpCapable;
+	pMsg->pmfRequired = pParam->mfpRequired;
+#endif
+
+	if (pParam->nRSNIELength > sizeof(pMsg->rsnIE.rsnIEdata)) {
+		cdf_mem_free(pMsg);
+		return CDF_STATUS_E_INVAL;
+	}
+	pMsg->rsnIE.length = pParam->nRSNIELength;
+	cdf_mem_copy(pMsg->rsnIE.rsnIEdata,
+		     pParam->pRSNIE,
+		     pParam->nRSNIELength);
+	pMsg->nwType = (tSirNwType)pParam->sirNwType;
+	cdf_mem_copy(&pMsg->operationalRateSet,
+		     &pParam->operationalRateSet,
+		     sizeof(tSirMacRateSet));
+	cdf_mem_copy(&pMsg->extendedRateSet,
+		     &pParam->extendedRateSet,
+		     sizeof(tSirMacRateSet));
+	cdf_mem_copy(&pMsg->htConfig,
+		     &pSession->htConfig,
+		     sizeof(tSirHTConfig));
+	cdf_mem_copy(&pMsg->addIeParams,
+		     &pParam->addIeParams,
+		     sizeof(pParam->addIeParams));
+	pMsg->obssEnabled = pMac->roam.configParam.obssEnabled;
+	pMsg->sap_dot11mc = pParam->sap_dot11mc;
+
+	return cds_send_mb_message_to_mac(pMsg);
+}
+
+CDF_STATUS csr_send_mb_stop_bss_req_msg(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	tSirSmeStopBssReq *pMsg;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("  session %d not found "), sessionId);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	pMsg = cdf_mem_malloc(sizeof(tSirSmeStopBssReq));
+	if (NULL == pMsg)
+		return CDF_STATUS_E_NOMEM;
+	cdf_mem_set(pMsg, sizeof(tSirSmeStopBssReq), 0);
+	pMsg->messageType = eWNI_SME_STOP_BSS_REQ;
+	pMsg->sessionId = sessionId;
+	pMsg->length = sizeof(tSirSmeStopBssReq);
+	pMsg->transactionId = 0;
+	pMsg->reasonCode = 0;
+	/*
+	 * if BSSType is WDS sta, use selfmacAddr as bssid,
+	 * else use bssid in connectedProfile
+	 */
+	if (CSR_IS_CONN_WDS_STA(&pSession->connectedProfile))
+		cdf_mem_copy(&pMsg->bssId,
+			     &pSession->selfMacAddr.bytes,
+			     sizeof(tSirMacAddr));
+	else
+		cdf_mem_copy(&pMsg->bssId,
+			     &pSession->connectedProfile.bssid.bytes,
+			     sizeof(tSirMacAddr));
+	return cds_send_mb_message_to_mac(pMsg);
+}
+
+CDF_STATUS csr_reassoc(tpAniSirGlobal pMac, uint32_t sessionId,
+		       tCsrRoamModifyProfileFields *pModProfileFields,
+		       uint32_t *pRoamId, bool fForce)
+{
+	CDF_STATUS status = CDF_STATUS_E_FAILURE;
+	uint32_t roamId = 0;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+	if ((csr_is_conn_state_connected(pMac, sessionId)) &&
+	    (fForce || (!cdf_mem_compare(&pModProfileFields,
+				     &pSession->connectedProfile.
+				     modifyProfileFields,
+				     sizeof(tCsrRoamModifyProfileFields))))) {
+		roamId = GET_NEXT_ROAM_ID(&pMac->roam);
+		if (pRoamId) {
+			*pRoamId = roamId;
+		}
+
+		status =
+			csr_roam_issue_reassoc(pMac, sessionId, NULL,
+					       pModProfileFields,
+					       eCsrSmeIssuedReassocToSameAP,
+					       roamId, false);
+	}
+	return status;
+}
+
+static CDF_STATUS csr_roam_session_opened(tpAniSirGlobal pMac,
+					  uint32_t sessionId)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tCsrRoamInfo roamInfo;
+	cdf_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0);
+	status = csr_roam_call_callback(pMac, sessionId, &roamInfo, 0,
+					eCSR_ROAM_SESSION_OPENED,
+					eCSR_ROAM_RESULT_NONE);
+	return status;
+}
+
+CDF_STATUS csr_process_add_sta_session_rsp(tpAniSirGlobal pMac, uint8_t *pMsg)
+{
+	tListElem *pEntry = NULL;
+	tSmeCmd *pCommand = NULL;
+	struct add_sta_self_params *rsp;
+	struct send_extcap_ie *msg;
+	CDF_STATUS status;
+
+	if (pMsg == NULL) {
+		sms_log(pMac, LOGE, "in %s msg ptr is NULL", __func__);
+		return CDF_STATUS_E_FAILURE;
+	}
+	pEntry = csr_ll_peek_head(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK);
+	if (!pEntry) {
+		sms_log(pMac, LOGE, "in %s NO commands are ACTIVE ...",
+			__func__);
+		return CDF_STATUS_E_FAILURE;
+	}
+	pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
+	if (eSmeCommandAddStaSession != pCommand->command) {
+		sms_log(pMac, LOGE, "in %s Cmd not in active list ...",
+			__func__);
+		return CDF_STATUS_E_FAILURE;
+	}
+	rsp = (struct add_sta_self_params *) pMsg;
+	sms_log(pMac, LOG1, "Add Sta self rsp status = %d", rsp->status);
+
+	if (CDF_STATUS_SUCCESS == rsp->status &&
+		(WMI_VDEV_TYPE_STA == rsp->type ||
+		(WMI_VDEV_TYPE_AP == rsp->type &&
+		 WMI_UNIFIED_VDEV_SUBTYPE_P2P_DEVICE == rsp->sub_type))) {
+		sms_log(pMac, LOG1, FL("send SET IE msg to PE"));
+		msg = cdf_mem_malloc(sizeof(*msg));
+		if (NULL == msg) {
+			sms_log(pMac, LOGE, FL("Memory allocation failed"));
+			return CDF_STATUS_E_NOMEM;
+		}
+
+		cdf_mem_set(msg, sizeof(*msg), 0);
+		msg->msg_type = eWNI_SME_SET_IE_REQ;
+		msg->session_id = rsp->session_id;
+		msg->length = sizeof(*msg);
+		status = cds_send_mb_message_to_mac(msg);
+		if (!CDF_IS_STATUS_SUCCESS(status))
+			sms_log(pMac, LOGE,
+				FL("Failed to send down the set IE req "));
+	}
+
+	csr_roam_session_opened(pMac, pCommand->sessionId);
+	/* Remove this command out of the active list */
+	if (csr_ll_remove_entry(&pMac->sme.smeCmdActiveList, pEntry,
+		 LL_ACCESS_LOCK)) {
+	/* Now put this command back on the avilable command list */
+		csr_release_command(pMac, pCommand);
+	}
+	sme_process_pending_queue(pMac);
+	return CDF_STATUS_SUCCESS;
+}
+
+CDF_STATUS csr_issue_add_sta_for_session_req(tpAniSirGlobal pMac, uint32_t sessionId,
+					     tSirMacAddr sessionMacAddr,
+					     uint32_t type, uint32_t subType)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tSmeCmd *pCommand;
+	pCommand = csr_get_command_buffer(pMac);
+	if (NULL == pCommand) {
+		status = CDF_STATUS_E_RESOURCES;
+	} else {
+		pCommand->command = eSmeCommandAddStaSession;
+		pCommand->sessionId = (uint8_t) sessionId;
+		cdf_mem_copy(pCommand->u.addStaSessionCmd.selfMacAddr,
+			     sessionMacAddr, sizeof(tSirMacAddr));
+		pCommand->u.addStaSessionCmd.currDeviceMode =
+			pMac->sme.currDeviceMode;
+		pCommand->u.addStaSessionCmd.type = type;
+		pCommand->u.addStaSessionCmd.subType = subType;
+		status = csr_queue_sme_command(pMac, pCommand, true);
+		if (!CDF_IS_STATUS_SUCCESS(status)) {
+			/* Should be panic?? */
+			sms_log(pMac, LOGE,
+				FL(" fail to send message status = %d"), status);
+		}
+	}
+	return status;
+}
+
+CDF_STATUS csr_process_add_sta_session_command(tpAniSirGlobal pMac,
+					       tSmeCmd *pCommand)
+{
+	tAddStaForSessionCmd *pAddStaReq =
+		&pCommand->u.addStaSessionCmd;
+	uint8_t sessionId = pCommand->sessionId;
+	struct add_sta_self_params *add_sta_self_req;
+	CDF_STATUS status = CDF_STATUS_E_NOMEM;
+	tSirMsgQ msg;
+
+	add_sta_self_req = cdf_mem_malloc(sizeof(struct add_sta_self_params));
+	if (NULL == add_sta_self_req) {
+		lim_log(pMac, LOGP,
+			FL
+			("Unable to allocate memory for tAddSelfStaParams"));
+		return status;
+	}
+
+	cdf_mem_copy(add_sta_self_req->self_mac_addr, pAddStaReq->selfMacAddr,
+			sizeof(tSirMacAddr));
+	add_sta_self_req->curr_device_mode = pAddStaReq->currDeviceMode;
+	add_sta_self_req->session_id = sessionId;
+	add_sta_self_req->type = pAddStaReq->type;
+	add_sta_self_req->sub_type = pAddStaReq->subType;
+
+	msg.type = WMA_ADD_STA_SELF_REQ;
+	msg.reserved = 0;
+	msg.bodyptr = add_sta_self_req;
+	msg.bodyval = 0;
+
+	lim_log(pMac, LOG1,
+		 FL
+		 ("Send WMA_ADD_STA_SELF_REQ for selfMac=" MAC_ADDRESS_STR),
+		 MAC_ADDR_ARRAY(add_sta_self_req->self_mac_addr));
+	MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, msg.type));
+	status = wma_post_ctrl_msg(pMac, &msg);
+
+	if (status != CDF_STATUS_SUCCESS) {
+		lim_log(pMac, LOGP, FL("wma_post_ctrl_msg failed"));
+		cdf_mem_free(add_sta_self_req);
+		add_sta_self_req = NULL;
+	}
+	return status;
+}
+
+CDF_STATUS csr_roam_open_session(tpAniSirGlobal pMac,
+				 csr_roam_completeCallback callback,
+				 void *pContext,
+				 uint8_t *pSelfMacAddr, uint8_t *pbSessionId,
+				 uint32_t type, uint32_t subType)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	uint32_t i, value = 0;
+	union {
+		uint16_t nCfgValue16;
+		tSirMacHTCapabilityInfo htCapInfo;
+	} uHTCapabilityInfo;
+	tCsrRoamSession *pSession;
+	*pbSessionId = CSR_SESSION_ID_INVALID;
+
+	for (i = 0; i < pMac->sme.max_intf_count; i++) {
+		if (!CSR_IS_SESSION_VALID(pMac, i)) {
+			pSession = CSR_GET_SESSION(pMac, i);
+			if (!pSession) {
+				sms_log(pMac, LOGE,
+					FL
+						("Session does not exist for interface %d"),
+					i);
+				break;
+			}
+			status = CDF_STATUS_SUCCESS;
+			pSession->sessionActive = true;
+			pSession->sessionId = (uint8_t) i;
+
+#ifdef WLAN_FEATURE_VOWIFI_11R
+			/* Initialize FT related data structures only in STA mode */
+			sme_ft_open(pMac, pSession->sessionId);
+#endif
+
+			pSession->callback = callback;
+			pSession->pContext = pContext;
+			cdf_mem_copy(&pSession->selfMacAddr, pSelfMacAddr,
+				     sizeof(struct cdf_mac_addr));
+			*pbSessionId = (uint8_t) i;
+			status =
+				cdf_mc_timer_init(&pSession->hTimerRoaming,
+						  CDF_TIMER_TYPE_SW,
+						  csr_roam_roaming_timer_handler,
+						  &pSession->roamingTimerInfo);
+			if (!CDF_IS_STATUS_SUCCESS(status)) {
+				sms_log(pMac, LOGE,
+					FL
+						("cannot allocate memory for Roaming timer"));
+				break;
+			}
+			/* get the HT capability info */
+			if (wlan_cfg_get_int(pMac, WNI_CFG_HT_CAP_INFO, &value)
+					!= eSIR_SUCCESS) {
+				CDF_TRACE(CDF_MODULE_ID_CDF,
+					  CDF_TRACE_LEVEL_ERROR,
+					  "%s: could not get HT capability info",
+					  __func__);
+				break;
+			}
+#ifdef FEATURE_WLAN_BTAMP_UT_RF
+			status = cdf_mc_timer_init(&pSession->hTimerJoinRetry,
+						   CDF_TIMER_TYPE_SW,
+						   csr_roam_join_retry_timer_handler,
+						   &pSession->
+						   joinRetryTimerInfo);
+			if (!CDF_IS_STATUS_SUCCESS(status)) {
+				sms_log(pMac, LOGE,
+					FL
+						("cannot allocate memory for join retry timer"));
+				break;
+			}
+#endif
+			uHTCapabilityInfo.nCfgValue16 = 0xFFFF & value;
+			pSession->htConfig.ht_rx_ldpc =
+				uHTCapabilityInfo.htCapInfo.advCodingCap;
+			pSession->htConfig.ht_tx_stbc =
+				uHTCapabilityInfo.htCapInfo.txSTBC;
+			pSession->htConfig.ht_rx_stbc =
+				uHTCapabilityInfo.htCapInfo.rxSTBC;
+			pSession->htConfig.ht_sgi = true;
+			status =
+				csr_issue_add_sta_for_session_req(pMac, i, pSelfMacAddr,
+								  type, subType);
+			break;
+		}
+	}
+	if (pMac->sme.max_intf_count == i) {
+		/* No session is available */
+		sms_log(pMac, LOGE,
+			"%s: Reached max interfaces: %d! Session creation will fail",
+			__func__, pMac->sme.max_intf_count);
+		status = CDF_STATUS_E_RESOURCES;
+	}
+	return status;
+}
+
+CDF_STATUS csr_process_del_sta_session_rsp(tpAniSirGlobal pMac, uint8_t *pMsg)
+{
+	CDF_STATUS status = CDF_STATUS_E_FAILURE;
+	tListElem *pEntry = NULL;
+	tSmeCmd *pCommand = NULL;
+	struct del_sta_self_params *rsp;
+	uint8_t sessionId;
+
+	if (pMsg == NULL) {
+		sms_log(pMac, LOGE, FL("msg ptr is NULL"));
+		return status;
+	}
+	pEntry = csr_ll_peek_head(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK);
+	if (!pEntry) {
+		sms_log(pMac, LOGE, FL("NO commands are ACTIVE ..."));
+		return status;
+	}
+	pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
+	sessionId = pCommand->sessionId;
+	if (eSmeCommandDelStaSession != pCommand->command) {
+		sms_log(pMac, LOGE, FL("NO Del sta session command ACTIVE"));
+		return status;
+	}
+	rsp = (struct del_sta_self_params *) pMsg;
+	sms_log(pMac, LOG1, FL("Del Sta rsp status = %d"), rsp->status);
+	/* This session is done. */
+	csr_cleanup_session(pMac, sessionId);
+	if (pCommand->u.delStaSessionCmd.callback) {
+		status = sme_release_global_lock(&pMac->sme);
+		if (!CDF_IS_STATUS_SUCCESS(status))
+			sms_log(pMac, LOG1, FL("Failed to Release Lock"));
+		else {
+			pCommand->u.delStaSessionCmd.
+				callback(pCommand->u.delStaSessionCmd.pContext);
+			status = sme_acquire_global_lock(&pMac->sme);
+			if (!CDF_IS_STATUS_SUCCESS(status)) {
+				sms_log(pMac, LOG1, FL("Failed to get Lock"));
+				return status;
+			}
+		}
+	}
+	/* Remove this command out of the active list */
+	if (csr_ll_remove_entry(&pMac->sme.smeCmdActiveList, pEntry,
+		LL_ACCESS_LOCK)) {
+		/* Now put this command back on the avilable command list */
+		csr_release_command(pMac, pCommand);
+	}
+	sme_process_pending_queue(pMac);
+	status = CDF_STATUS_SUCCESS;
+	return status;
+}
+
+
+CDF_STATUS csr_issue_del_sta_for_session_req(tpAniSirGlobal pMac, uint32_t sessionId,
+					     tSirMacAddr sessionMacAddr,
+					     csr_roamSessionCloseCallback callback,
+					     void *pContext)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tSmeCmd *pCommand;
+	pCommand = csr_get_command_buffer(pMac);
+	if (NULL == pCommand) {
+		status = CDF_STATUS_E_RESOURCES;
+	} else {
+		pCommand->command = eSmeCommandDelStaSession;
+		pCommand->sessionId = (uint8_t) sessionId;
+		pCommand->u.delStaSessionCmd.callback = callback;
+		pCommand->u.delStaSessionCmd.pContext = pContext;
+		cdf_mem_copy(pCommand->u.delStaSessionCmd.selfMacAddr,
+			     sessionMacAddr, sizeof(tSirMacAddr));
+		status = csr_queue_sme_command(pMac, pCommand, true);
+		if (!CDF_IS_STATUS_SUCCESS(status)) {
+			/* Should be panic?? */
+			sms_log(pMac, LOGE,
+				FL(" fail to send message status = %d"), status);
+		}
+	}
+	return status;
+}
+
+CDF_STATUS csr_process_del_sta_session_command(tpAniSirGlobal pMac,
+					       tSmeCmd *pCommand)
+{
+	struct del_sta_self_params *del_sta_self_req;
+	tSirMsgQ msg;
+	CDF_STATUS status = CDF_STATUS_E_FAILURE;
+	del_sta_self_req = cdf_mem_malloc(sizeof(struct del_sta_self_params));
+	if (NULL == del_sta_self_req) {
+		lim_log(pMac, LOGP,
+			FL(" mem alloc failed for tDelStaSelfParams"));
+		return CDF_STATUS_E_NOMEM;
+	}
+
+	cdf_mem_copy(del_sta_self_req->self_mac_addr,
+		pCommand->u.delStaSessionCmd.selfMacAddr,
+		sizeof(tSirMacAddr));
+
+	del_sta_self_req->session_id = pCommand->sessionId;
+	msg.type = WMA_DEL_STA_SELF_REQ;
+	msg.reserved = 0;
+	msg.bodyptr = del_sta_self_req;
+	msg.bodyval = 0;
+
+	sms_log(pMac, LOG1,
+		FL("sending WMA_DEL_STA_SELF_REQ"));
+	MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, msg.type));
+	status = wma_post_ctrl_msg(pMac, &msg);
+	if (status != CDF_STATUS_SUCCESS) {
+		sms_log(pMac, LOGP, FL("wma_post_ctrl_msg failed"));
+		cdf_mem_free(del_sta_self_req);
+	}
+	return status;
+}
+
+static void purge_csr_session_cmd_list(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	tDblLinkList *pList = &pMac->roam.roamCmdPendingList;
+	tListElem *pEntry, *pNext;
+	tSmeCmd *pCommand;
+	tDblLinkList localList;
+
+	cdf_mem_zero(&localList, sizeof(tDblLinkList));
+	if (!CDF_IS_STATUS_SUCCESS(csr_ll_open(pMac->hHdd, &localList))) {
+		sms_log(pMac, LOGE, FL(" failed to open list"));
+		return;
+	}
+	csr_ll_lock(pList);
+	pEntry = csr_ll_peek_head(pList, LL_ACCESS_NOLOCK);
+	while (pEntry != NULL) {
+		pNext = csr_ll_next(pList, pEntry, LL_ACCESS_NOLOCK);
+		pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
+		if (pCommand->sessionId == sessionId) {
+			if (csr_ll_remove_entry(pList, pEntry, LL_ACCESS_NOLOCK)) {
+				csr_ll_insert_tail(&localList, pEntry,
+						   LL_ACCESS_NOLOCK);
+			}
+		}
+		pEntry = pNext;
+	}
+	csr_ll_unlock(pList);
+
+	while ((pEntry = csr_ll_remove_head(&localList, LL_ACCESS_NOLOCK))) {
+		pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
+		csr_abort_command(pMac, pCommand, true);
+	}
+	csr_ll_close(&localList);
+}
+
+void csr_cleanup_session(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
+		tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+		csr_roam_stop(pMac, sessionId);
+
+		/* Clean up FT related data structures */
+#if defined WLAN_FEATURE_VOWIFI_11R
+		sme_ft_close(pMac, sessionId);
+#endif
+		csr_free_connect_bss_desc(pMac, sessionId);
+		csr_roam_free_connect_profile(pMac, &pSession->connectedProfile);
+		csr_roam_free_connected_info(pMac, &pSession->connectedInfo);
+		cdf_mc_timer_destroy(&pSession->hTimerRoaming);
+#ifdef FEATURE_WLAN_BTAMP_UT_RF
+		cdf_mc_timer_destroy(&pSession->hTimerJoinRetry);
+#endif
+		purge_sme_session_cmd_list(pMac, sessionId,
+					   &pMac->sme.smeCmdPendingList);
+		purge_sme_session_cmd_list(pMac, sessionId,
+						   &pMac->sme.
+						   smeScanCmdPendingList);
+
+		purge_csr_session_cmd_list(pMac, sessionId);
+		csr_init_session(pMac, sessionId);
+	}
+}
+
+CDF_STATUS csr_roam_close_session(tpAniSirGlobal pMac, uint32_t sessionId,
+				  bool fSync,
+				  csr_roamSessionCloseCallback callback,
+				  void *pContext)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
+		tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+		if (fSync) {
+			csr_cleanup_session(pMac, sessionId);
+		} else {
+			purge_sme_session_cmd_list(pMac, sessionId,
+						   &pMac->sme.smeCmdPendingList);
+			purge_sme_session_cmd_list(pMac, sessionId,
+					   &pMac->sme.smeScanCmdPendingList);
+
+			purge_csr_session_cmd_list(pMac, sessionId);
+			status = csr_issue_del_sta_for_session_req(pMac,
+						 sessionId,
+						 pSession->selfMacAddr.bytes,
+						 callback, pContext);
+		}
+	} else {
+		status = CDF_STATUS_E_INVAL;
+	}
+	return status;
+}
+
+static void csr_init_session(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("  session %d not found "), sessionId);
+		return;
+	}
+
+	pSession->sessionActive = false;
+	pSession->sessionId = CSR_SESSION_ID_INVALID;
+	pSession->callback = NULL;
+	pSession->pContext = NULL;
+	pSession->connectState = eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED;
+	csr_free_roam_profile(pMac, sessionId);
+	csr_roam_free_connect_profile(pMac, &pSession->connectedProfile);
+	csr_roam_free_connected_info(pMac, &pSession->connectedInfo);
+	csr_free_connect_bss_desc(pMac, sessionId);
+	csr_scan_enable(pMac);
+	cdf_mem_set(&pSession->selfMacAddr, sizeof(struct cdf_mac_addr), 0);
+	if (pSession->pWpaRsnReqIE) {
+		cdf_mem_free(pSession->pWpaRsnReqIE);
+		pSession->pWpaRsnReqIE = NULL;
+	}
+	pSession->nWpaRsnReqIeLength = 0;
+	if (pSession->pWpaRsnRspIE) {
+		cdf_mem_free(pSession->pWpaRsnRspIE);
+		pSession->pWpaRsnRspIE = NULL;
+	}
+	pSession->nWpaRsnRspIeLength = 0;
+#ifdef FEATURE_WLAN_WAPI
+	if (pSession->pWapiReqIE) {
+		cdf_mem_free(pSession->pWapiReqIE);
+		pSession->pWapiReqIE = NULL;
+	}
+	pSession->nWapiReqIeLength = 0;
+	if (pSession->pWapiRspIE) {
+		cdf_mem_free(pSession->pWapiRspIE);
+		pSession->pWapiRspIE = NULL;
+	}
+	pSession->nWapiRspIeLength = 0;
+#endif /* FEATURE_WLAN_WAPI */
+	if (pSession->pAddIEScan) {
+		cdf_mem_free(pSession->pAddIEScan);
+		pSession->pAddIEScan = NULL;
+	}
+	pSession->nAddIEScanLength = 0;
+	if (pSession->pAddIEAssoc) {
+		cdf_mem_free(pSession->pAddIEAssoc);
+		pSession->pAddIEAssoc = NULL;
+	}
+	pSession->nAddIEAssocLength = 0;
+}
+
+CDF_STATUS csr_roam_get_session_id_from_bssid(tpAniSirGlobal pMac,
+					      struct cdf_mac_addr *bssid,
+					      uint32_t *pSessionId)
+{
+	CDF_STATUS status = CDF_STATUS_E_FAILURE;
+	uint32_t i;
+	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
+		if (CSR_IS_SESSION_VALID(pMac, i)) {
+			if (cdf_is_macaddr_equal(bssid,
+				    &pMac->roam.roamSession[i].connectedProfile.
+				    bssid)) {
+				/* Found it */
+				status = CDF_STATUS_SUCCESS;
+				*pSessionId = i;
+				break;
+			}
+		}
+	}
+	return status;
+}
+
+/* This function assumes that we only support one IBSS session. We cannot use BSSID to identify */
+/* session because for IBSS, the bssid changes. */
+static uint32_t csr_find_ibss_session(tpAniSirGlobal pMac)
+{
+	uint32_t i, nRet = CSR_SESSION_ID_INVALID;
+	tCsrRoamSession *pSession;
+	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
+		if (CSR_IS_SESSION_VALID(pMac, i)) {
+			pSession = CSR_GET_SESSION(pMac, i);
+			if (pSession->pCurRoamProfile
+			    &&
+			    (csr_is_bss_type_ibss
+				     (pSession->connectedProfile.BSSType))) {
+				/* Found it */
+				nRet = i;
+				break;
+			}
+		}
+	}
+	return nRet;
+}
+
+static void csr_roam_link_up(tpAniSirGlobal pMac, struct cdf_mac_addr bssid)
+{
+	/* Update the current BSS info in ho control block based on connected
+	   profile info from pmac global structure                              */
+
+	sms_log(pMac, LOGW,
+		" csr_roam_link_up: WLAN link UP with AP= " MAC_ADDRESS_STR,
+		MAC_ADDR_ARRAY(bssid.bytes));
+	/* Check for user misconfig of RSSI trigger threshold                  */
+	pMac->roam.configParam.vccRssiThreshold =
+		(0 == pMac->roam.configParam.vccRssiThreshold) ?
+		CSR_VCC_RSSI_THRESHOLD : pMac->roam.configParam.vccRssiThreshold;
+	pMac->roam.vccLinkQuality = eCSR_ROAM_LINK_QUAL_POOR_IND;
+	/* Check for user misconfig of UL MAC Loss trigger threshold           */
+	pMac->roam.configParam.vccUlMacLossThreshold =
+		(0 == pMac->roam.configParam.vccUlMacLossThreshold) ?
+		CSR_VCC_UL_MAC_LOSS_THRESHOLD : pMac->roam.configParam.
+		vccUlMacLossThreshold;
+#if   defined WLAN_FEATURE_NEIGHBOR_ROAMING
+	{
+		uint32_t sessionId = 0;
+		/* Indicate the neighbor roal algorithm about the connect indication */
+		csr_roam_get_session_id_from_bssid(pMac, &bssid,
+						   &sessionId);
+		csr_neighbor_roam_indicate_connect(pMac, sessionId,
+						   CDF_STATUS_SUCCESS);
+	}
+#endif
+}
+
+static void csr_roam_link_down(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("  session %d not found "), sessionId);
+		return;
+	}
+	/* Only to handle the case for Handover on infra link */
+	if (eCSR_BSS_TYPE_INFRASTRUCTURE != pSession->connectedProfile.BSSType) {
+		return;
+	}
+	/*
+	 * Incase of station mode, immediately stop data transmission whenever
+	 * link down is detected.
+	 */
+	if (csr_roam_is_sta_mode(pMac, sessionId)
+	    && !CSR_IS_ROAM_SUBSTATE_DISASSOC_HO(pMac, sessionId)
+#ifdef WLAN_FEATURE_VOWIFI_11R
+	    && !csr_roam_is11r_assoc(pMac, sessionId)
+#endif
+	    ) {
+		sms_log(pMac, LOG1, FL("Inform Link lost for session %d"),
+			sessionId);
+		csr_roam_call_callback(pMac, sessionId, NULL, 0,
+				       eCSR_ROAM_LOSTLINK,
+				       eCSR_ROAM_RESULT_LOSTLINK);
+	}
+	/* deregister the clients requesting stats from PE/TL & also stop the corresponding timers */
+	csr_roam_dereg_statistics_req(pMac);
+	pMac->roam.vccLinkQuality = eCSR_ROAM_LINK_QUAL_POOR_IND;
+#if   defined WLAN_FEATURE_NEIGHBOR_ROAMING
+	/* Indicate the neighbor roal algorithm about the disconnect indication */
+	csr_neighbor_roam_indicate_disconnect(pMac, sessionId);
+#endif
+
+	/* Remove this code once SLM_Sessionization is supported */
+	/* BMPS_WORKAROUND_NOT_NEEDED */
+	if (!IS_FEATURE_SUPPORTED_BY_FW(SLM_SESSIONIZATION) &&
+	    csr_is_infra_ap_started(pMac) &&
+	    pMac->roam.configParam.doBMPSWorkaround) {
+		pMac->roam.configParam.doBMPSWorkaround = 0;
+	}
+
+}
+
+void csr_roam_tl_stats_timer_handler(void *pv)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(pv);
+	CDF_STATUS status;
+	pMac->roam.tlStatsReqInfo.timerRunning = false;
+
+	sms_log(pMac, LOG1,
+		FL
+			(" TL stat timer is no-op. It needs to support multiple stations"));
+
+	if (!pMac->roam.tlStatsReqInfo.timerRunning) {
+		if (pMac->roam.tlStatsReqInfo.periodicity) {
+			/* start timer */
+			status =
+				cdf_mc_timer_start(&pMac->roam.tlStatsReqInfo.
+						   hTlStatsTimer,
+						   pMac->roam.tlStatsReqInfo.
+						   periodicity);
+			if (!CDF_IS_STATUS_SUCCESS(status)) {
+				sms_log(pMac, LOGE,
+					FL
+						("csr_roam_tl_stats_timer_handler:cannot start TlStatsTimer timer"));
+				return;
+			}
+			pMac->roam.tlStatsReqInfo.timerRunning = true;
+		}
+	}
+}
+
+void csr_roam_pe_stats_timer_handler(void *pv)
+{
+	tCsrPeStatsReqInfo *pPeStatsReqListEntry = (tCsrPeStatsReqInfo *) pv;
+	CDF_STATUS status;
+	tpAniSirGlobal pMac = pPeStatsReqListEntry->pMac;
+	CDF_STATUS cdf_status;
+	pPeStatsReqListEntry->timerRunning = false;
+	if (pPeStatsReqListEntry->timerStopFailed == true) {
+		/* If we entered here, meaning the timer could not be successfully */
+		/* stopped in csr_roam_remove_entry_from_pe_stats_req_list(). So do it here. */
+
+		/* Destroy the timer */
+		cdf_status =
+			cdf_mc_timer_destroy(&pPeStatsReqListEntry->hPeStatsTimer);
+		if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+			sms_log(pMac, LOGE,
+				FL
+					("csr_roam_pe_stats_timer_handler:failed to destroy hPeStatsTimer timer"));
+		}
+		/* Free the entry */
+		cdf_mem_free(pPeStatsReqListEntry);
+		pPeStatsReqListEntry = NULL;
+	} else {
+		if (!pPeStatsReqListEntry->rspPending) {
+			status =
+				csr_send_mb_stats_req_msg(pMac,
+							  pPeStatsReqListEntry->
+							  statsMask & ~(1 <<
+									eCsrGlobalClassDStats),
+							  pPeStatsReqListEntry->staId,
+							  pPeStatsReqListEntry->
+							  sessionId);
+			if (!CDF_IS_STATUS_SUCCESS(status)) {
+				sms_log(pMac, LOGE,
+					FL
+						("csr_roam_pe_stats_timer_handler:failed to send down stats req to PE"));
+			} else {
+				pPeStatsReqListEntry->rspPending = true;
+			}
+		}
+		/* send down a req */
+		if (pPeStatsReqListEntry->periodicity &&
+		    (CDF_TIMER_STATE_STOPPED ==
+		     cdf_mc_timer_get_current_state(&pPeStatsReqListEntry->
+						    hPeStatsTimer))) {
+			if (pPeStatsReqListEntry->periodicity <
+					pMac->roam.configParam.
+					statsReqPeriodicityInPS) {
+				pPeStatsReqListEntry->periodicity =
+					pMac->roam.configParam.
+					statsReqPeriodicityInPS;
+			}
+			/* start timer */
+			cdf_status =
+				cdf_mc_timer_start(&pPeStatsReqListEntry->
+						   hPeStatsTimer,
+						   pPeStatsReqListEntry->
+						   periodicity);
+			if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+				sms_log(pMac, LOGE,
+					FL
+						("csr_roam_pe_stats_timer_handler:cannot start hPeStatsTimer timer"));
+				return;
+			}
+			pPeStatsReqListEntry->timerRunning = true;
+
+		}
+
+	}
+}
+
+void csr_roam_stats_client_timer_handler(void *pv)
+{
+	tCsrStatsClientReqInfo *pStaEntry = (tCsrStatsClientReqInfo *) pv;
+	if (CDF_TIMER_STATE_STOPPED ==
+	    cdf_mc_timer_get_current_state(&pStaEntry->timer)) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
+			  FL("roam stats client timer is stopped"));
+	}
+}
+
+CDF_STATUS csr_send_mb_stats_req_msg(tpAniSirGlobal pMac, uint32_t statsMask,
+				     uint8_t staId, uint8_t sessionId)
+{
+	tAniGetPEStatsReq *pMsg;
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	pMsg = cdf_mem_malloc(sizeof(tAniGetPEStatsReq));
+	if (NULL == pMsg) {
+		sms_log(pMac, LOGE, FL("Failed to allocate mem for stats req "));
+		return CDF_STATUS_E_NOMEM;
+	}
+	/* need to initiate a stats request to PE */
+	pMsg->msgType = eWNI_SME_GET_STATISTICS_REQ;
+	pMsg->msgLen = (uint16_t) sizeof(tAniGetPEStatsReq);
+	pMsg->staId = staId;
+	pMsg->statsMask = statsMask;
+	pMsg->sessionId = sessionId;
+	status = cds_send_mb_message_to_mac(pMsg);
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		sms_log(pMac, LOG1, FL("Failed to send down the stats req "));
+	}
+	return status;
+}
+
+/**
+ * csr_update_stats() - updates correct stats struct in mac_ctx
+ * @mac:             mac global context
+ * @stats_type:      stats type
+ * @sme_stats_rsp:   stats rsp msg packet
+ * @stats:           input stats data buffer to fill in mac_ctx struct
+ * @length:          out param - stats length
+ *
+ * This function fills corresponding stats struct in mac_cts based on stats type
+ * passed
+ *
+ * Return: void
+ */
+static void
+csr_update_stats(tpAniSirGlobal mac, uint8_t stats_type,
+		 tAniGetPEStatsRsp *sme_stats_rsp,
+		 uint8_t **stats, uint32_t *length)
+{
+	switch (stats_type) {
+	case eCsrSummaryStats:
+		sms_log(mac, LOG2, FL("summary stats"));
+		cdf_mem_copy((uint8_t *) &mac->roam.summaryStatsInfo, *stats,
+			     sizeof(tCsrSummaryStatsInfo));
+		*stats += sizeof(tCsrSummaryStatsInfo);
+		*length -= sizeof(tCsrSummaryStatsInfo);
+		break;
+	case eCsrGlobalClassAStats:
+		sms_log(mac, LOG2, FL("ClassA stats"));
+		cdf_mem_copy((uint8_t *) &mac->roam.classAStatsInfo, *stats,
+			     sizeof(tCsrGlobalClassAStatsInfo));
+		*stats += sizeof(tCsrGlobalClassAStatsInfo);
+		*length -= sizeof(tCsrGlobalClassAStatsInfo);
+		break;
+	case eCsrGlobalClassBStats:
+		sms_log(mac, LOG2, FL("ClassB stats"));
+		cdf_mem_copy((uint8_t *) &mac->roam.classBStatsInfo, *stats,
+			     sizeof(tCsrGlobalClassBStatsInfo));
+		*stats += sizeof(tCsrGlobalClassBStatsInfo);
+		*length -= sizeof(tCsrGlobalClassBStatsInfo);
+		break;
+	case eCsrGlobalClassCStats:
+		sms_log(mac, LOG2, FL("ClassC stats"));
+		cdf_mem_copy((uint8_t *) &mac->roam.classCStatsInfo, *stats,
+			     sizeof(tCsrGlobalClassCStatsInfo));
+		*stats += sizeof(tCsrGlobalClassCStatsInfo);
+		*length -= sizeof(tCsrGlobalClassCStatsInfo);
+		break;
+	case eCsrPerStaStats:
+		sms_log(mac, LOG2, FL("PerSta stats"));
+		if (CSR_MAX_STA > sme_stats_rsp->staId) {
+			cdf_mem_copy(
+				&mac->roam.perStaStatsInfo[sme_stats_rsp->staId],
+				*stats, sizeof(tCsrPerStaStatsInfo));
+		} else {
+			sms_log(mac, LOGE, FL("out bound staId:%d. failed to copy PerSta stats"),
+				sme_stats_rsp->staId);
+			CDF_ASSERT(0);
+		}
+		*stats += sizeof(tCsrPerStaStatsInfo);
+		*length -= sizeof(tCsrPerStaStatsInfo);
+		break;
+	default:
+		sms_log(mac, LOGW, FL("unknown stats type"));
+		break;
+	}
+}
+
+/**
+ * csr_roam_stats_rsp_processor() - processes stats rsp msg
+ * @pMac             mac global context
+ * @pSirMsg:         incoming message
+ *
+ * Return: void
+ */
+void csr_roam_stats_rsp_processor(tpAniSirGlobal pMac, tSirSmeRsp *pSirMsg)
+{
+	tAniGetPEStatsRsp *pSmeStatsRsp;
+	tListElem *pEntry = NULL;
+	tCsrStatsClientReqInfo *pTempStaEntry = NULL;
+	tCsrPeStatsReqInfo *pPeStaEntry = NULL;
+	uint32_t tempMask = 0;
+	uint8_t counter = 0;
+	uint8_t *pStats = NULL;
+	uint32_t length = 0;
+	void *p_cds_gctx;
+	int8_t rssi = 0, snr = 0;
+	uint32_t *pRssi = NULL, *pSnr = NULL;
+	uint32_t linkCapacity;
+	pSmeStatsRsp = (tAniGetPEStatsRsp *) pSirMsg;
+
+	if (pSmeStatsRsp->rc) {
+		sms_log(pMac, LOGW, FL("stats rsp from PE shows failure"));
+		goto post_update;
+	}
+	tempMask = pSmeStatsRsp->statsMask;
+	pStats = ((uint8_t *) &pSmeStatsRsp->statsMask) +
+		sizeof(pSmeStatsRsp->statsMask);
+	/*
+	 * subtract all statistics from this length, and after processing the
+	 * entire 'stat' part of the message, if the length is not zero, then
+	 * rssi is piggy packed in this 'stats' message.
+	 */
+	length = pSmeStatsRsp->msgLen - sizeof(tAniGetPEStatsRsp);
+	/* new stats info from PE, fill up the stats strucutres in PMAC */
+	while (tempMask) {
+		if (tempMask & 1) {
+			csr_update_stats(pMac, counter, pSmeStatsRsp,
+					 &pStats, &length);
+		}
+		tempMask >>= 1;
+		counter++;
+	}
+	p_cds_gctx = cds_get_global_context();
+	if (length != 0) {
+		pRssi = (uint32_t *) pStats;
+		rssi = (int8_t) *pRssi;
+		pStats += sizeof(uint32_t);
+		length -= sizeof(uint32_t);
+	} else {
+		/* If riva is not sending rssi, continue to use the hack */
+		rssi = RSSI_HACK_BMPS;
+	}
+
+	if (length != 0) {
+		linkCapacity = *(uint32_t *) pStats;
+		pStats += sizeof(uint32_t);
+		length -= sizeof(uint32_t);
+	} else {
+		linkCapacity = 0;
+	}
+
+	if (length != 0) {
+		pSnr = (uint32_t *) pStats;
+		snr = (int8_t) *pSnr;
+	} else {
+		snr = SNR_HACK_BMPS;
+	}
+
+post_update:
+	/* make sure to update the pe stats req list */
+	pEntry = csr_roam_find_in_pe_stats_req_list(pMac, pSmeStatsRsp->statsMask);
+	if (pEntry) {
+		pPeStaEntry = GET_BASE_ADDR(pEntry, tCsrPeStatsReqInfo, link);
+		pPeStaEntry->rspPending = false;
+
+	}
+	/* check the one timer cases */
+	pEntry = csr_roam_check_client_req_list(pMac, pSmeStatsRsp->statsMask);
+	if (pEntry) {
+		pTempStaEntry =
+			GET_BASE_ADDR(pEntry, tCsrStatsClientReqInfo, link);
+		if (pTempStaEntry->timerExpired) {
+			/* send up the stats report */
+			csr_roam_report_statistics(pMac, pTempStaEntry->statsMask,
+						   pTempStaEntry->callback,
+						   pTempStaEntry->staId,
+						   pTempStaEntry->pContext);
+			/* also remove from the client list */
+			csr_roam_remove_stat_list_entry(pMac, pEntry);
+			pTempStaEntry = NULL;
+		}
+	}
+}
+
+tListElem *csr_roam_find_in_pe_stats_req_list(tpAniSirGlobal pMac, uint32_t statsMask)
+{
+	tListElem *pEntry = NULL;
+	tCsrPeStatsReqInfo *pTempStaEntry = NULL;
+	pEntry = csr_ll_peek_head(&pMac->roam.peStatsReqList, LL_ACCESS_LOCK);
+	if (!pEntry) {
+		/* list empty */
+		sms_log(pMac, LOG2,
+			"csr_roam_find_in_pe_stats_req_list: List empty, no request to PE");
+		return NULL;
+	}
+	while (pEntry) {
+		pTempStaEntry = GET_BASE_ADDR(pEntry, tCsrPeStatsReqInfo, link);
+		if (pTempStaEntry->statsMask == statsMask) {
+			sms_log(pMac, LOG3,
+				"csr_roam_find_in_pe_stats_req_list: match found");
+			break;
+		}
+		pEntry =
+			csr_ll_next(&pMac->roam.peStatsReqList, pEntry,
+				    LL_ACCESS_NOLOCK);
+	}
+	return pEntry;
+}
+
+tListElem *csr_roam_checkn_update_client_req_list(tpAniSirGlobal pMac,
+						  tCsrStatsClientReqInfo *pStaEntry,
+						  bool update)
+{
+	tListElem *pEntry;
+	tCsrStatsClientReqInfo *pTempStaEntry;
+	pEntry = csr_ll_peek_head(&pMac->roam.statsClientReqList, LL_ACCESS_LOCK);
+	if (!pEntry) {
+		/* list empty */
+		sms_log(pMac, LOG2,
+			"csr_roam_checkn_update_client_req_list: List empty, no request from "
+			"upper layer client(s)");
+		return NULL;
+	}
+	while (pEntry) {
+		pTempStaEntry =
+			GET_BASE_ADDR(pEntry, tCsrStatsClientReqInfo, link);
+		if ((pTempStaEntry->requesterId == pStaEntry->requesterId)
+		    && (pTempStaEntry->statsMask == pStaEntry->statsMask)) {
+			sms_log(pMac, LOG3,
+				"csr_roam_checkn_update_client_req_list: match found");
+			if (update) {
+				pTempStaEntry->periodicity =
+					pStaEntry->periodicity;
+				pTempStaEntry->callback = pStaEntry->callback;
+				pTempStaEntry->pContext = pStaEntry->pContext;
+			}
+			break;
+		}
+		pEntry =
+			csr_ll_next(&pMac->roam.statsClientReqList, pEntry,
+				    LL_ACCESS_NOLOCK);
+	}
+	return pEntry;
+}
+
+tListElem *csr_roam_check_client_req_list(tpAniSirGlobal pMac, uint32_t statsMask)
+{
+	tListElem *pEntry;
+	tCsrStatsClientReqInfo *pTempStaEntry;
+	pEntry = csr_ll_peek_head(&pMac->roam.statsClientReqList, LL_ACCESS_LOCK);
+	if (!pEntry) {
+		/* list empty */
+		sms_log(pMac, LOG2,
+			"csr_roam_check_client_req_list: List empty, no request from "
+			"upper layer client(s)");
+		return NULL;
+	}
+	while (pEntry) {
+		pTempStaEntry =
+			GET_BASE_ADDR(pEntry, tCsrStatsClientReqInfo, link);
+		if ((pTempStaEntry->
+		     statsMask & ~(1 << eCsrGlobalClassDStats)) == statsMask) {
+			sms_log(pMac, LOG3,
+				"csr_roam_check_client_req_list: match found");
+			break;
+		}
+		pEntry =
+			csr_ll_next(&pMac->roam.statsClientReqList, pEntry,
+				    LL_ACCESS_NOLOCK);
+	}
+	return pEntry;
+}
+
+void csr_roam_vcc_trigger(tpAniSirGlobal pMac)
+{
+	eCsrRoamLinkQualityInd newVccLinkQuality;
+	uint32_t ul_mac_loss = 0;
+	uint32_t ul_mac_loss_trigger_threshold;
+	/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+	/*-------------------------------------------------------------------------
+	   Link quality is currently binary based on OBIWAN recommended triggers
+	   Check for a change in link quality and notify client if necessary
+	   -------------------------------------------------------------------------*/
+	ul_mac_loss_trigger_threshold =
+		pMac->roam.configParam.vccUlMacLossThreshold;
+	if (0 == ul_mac_loss_trigger_threshold) {
+		CDF_ASSERT(ul_mac_loss_trigger_threshold != 0);
+		return;
+	}
+	sms_log(pMac, LOGW, "csr_roam_vcc_trigger: UL_MAC_LOSS_THRESHOLD is %d",
+		ul_mac_loss_trigger_threshold);
+	if (ul_mac_loss_trigger_threshold < ul_mac_loss) {
+		sms_log(pMac, LOGW, "csr_roam_vcc_trigger: link quality is POOR ");
+		newVccLinkQuality = eCSR_ROAM_LINK_QUAL_POOR_IND;
+	} else {
+		sms_log(pMac, LOGW, "csr_roam_vcc_trigger: link quality is GOOD");
+		newVccLinkQuality = eCSR_ROAM_LINK_QUAL_GOOD_IND;
+	}
+	sms_log(pMac, LOGW,
+		"csr_roam_vcc_trigger: link qual : *** UL_MAC_LOSS %d *** ",
+		ul_mac_loss);
+	if (newVccLinkQuality != pMac->roam.vccLinkQuality) {
+		sms_log(pMac, LOGW,
+			"csr_roam_vcc_trigger: link quality changed: trigger necessary");
+		if (NULL != pMac->roam.linkQualityIndInfo.callback) {
+			sms_log(pMac, LOGW,
+				"csr_roam_vcc_trigger: link quality indication %d",
+				newVccLinkQuality);
+
+			/* we now invoke the callback once to notify client of initial value   */
+			pMac->roam.linkQualityIndInfo.
+			callback(newVccLinkQuality,
+				 pMac->roam.linkQualityIndInfo.context);
+			/* event: EVENT_WLAN_VCC */
+		}
+	}
+	pMac->roam.vccLinkQuality = newVccLinkQuality;
+
+}
+
+tCsrStatsClientReqInfo *csr_roam_insert_entry_into_list(tpAniSirGlobal pMac,
+							tDblLinkList *pStaList,
+							tCsrStatsClientReqInfo *
+							pStaEntry)
+{
+	tCsrStatsClientReqInfo *pNewStaEntry = NULL;
+	/* if same entity requested for same set of stats with different periodicity & */
+	/* callback update it */
+	if (NULL == csr_roam_checkn_update_client_req_list(pMac, pStaEntry, true)) {
+
+		pNewStaEntry = cdf_mem_malloc(sizeof(tCsrStatsClientReqInfo));
+		if (NULL == pNewStaEntry) {
+			sms_log(pMac, LOGW,
+				"csr_roam_insert_entry_into_list: couldn't allocate memory for the "
+				"entry");
+			return NULL;
+		}
+
+		pNewStaEntry->callback = pStaEntry->callback;
+		pNewStaEntry->pContext = pStaEntry->pContext;
+		pNewStaEntry->periodicity = pStaEntry->periodicity;
+		pNewStaEntry->requesterId = pStaEntry->requesterId;
+		pNewStaEntry->statsMask = pStaEntry->statsMask;
+		pNewStaEntry->pPeStaEntry = pStaEntry->pPeStaEntry;
+		pNewStaEntry->pMac = pStaEntry->pMac;
+		pNewStaEntry->staId = pStaEntry->staId;
+		pNewStaEntry->timerExpired = pStaEntry->timerExpired;
+
+		csr_ll_insert_tail(pStaList, &pNewStaEntry->link, LL_ACCESS_LOCK);
+	}
+	return pNewStaEntry;
+}
+
+tCsrPeStatsReqInfo *csr_roam_insert_entry_into_pe_stats_req_list(tpAniSirGlobal pMac,
+								 tDblLinkList *
+								 pStaList,
+								 tCsrPeStatsReqInfo *
+								 pStaEntry)
+{
+	tCsrPeStatsReqInfo *pNewStaEntry = NULL;
+	pNewStaEntry = cdf_mem_malloc(sizeof(tCsrPeStatsReqInfo));
+	if (NULL == pNewStaEntry) {
+		sms_log(pMac, LOGW,
+			"csr_roam_insert_entry_into_pe_stats_req_list: couldn't allocate memory for the "
+			"entry");
+		return NULL;
+	}
+
+	pNewStaEntry->hPeStatsTimer = pStaEntry->hPeStatsTimer;
+	pNewStaEntry->numClient = pStaEntry->numClient;
+	pNewStaEntry->periodicity = pStaEntry->periodicity;
+	pNewStaEntry->statsMask = pStaEntry->statsMask;
+	pNewStaEntry->pMac = pStaEntry->pMac;
+	pNewStaEntry->staId = pStaEntry->staId;
+	pNewStaEntry->timerRunning = pStaEntry->timerRunning;
+	pNewStaEntry->rspPending = pStaEntry->rspPending;
+
+	csr_ll_insert_tail(pStaList, &pNewStaEntry->link, LL_ACCESS_LOCK);
+	return pNewStaEntry;
+}
+
+CDF_STATUS csr_get_rssi(tpAniSirGlobal pMac,
+			tCsrRssiCallback callback,
+			uint8_t staId,
+			struct cdf_mac_addr bssId,
+			int8_t lastRSSI, void *pContext, void *p_cds_context)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	cds_msg_t msg;
+	uint32_t sessionId;
+
+	tAniGetRssiReq *pMsg;
+	sms_log(pMac, LOG2, FL("called"));
+
+	status = csr_roam_get_session_id_from_bssid(pMac, &bssId, &sessionId);
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		callback(lastRSSI, staId, pContext);
+		sms_log(pMac, LOGE, FL("Failed to get SessionId"));
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	pMsg = cdf_mem_malloc(sizeof(tAniGetRssiReq));
+	if (NULL == pMsg) {
+		sms_log(pMac, LOGE,
+			" csr_get_rssi: failed to allocate mem for req ");
+		return CDF_STATUS_E_NOMEM;
+	}
+
+	pMsg->msgType = eWNI_SME_GET_RSSI_REQ;
+	pMsg->msgLen = (uint16_t) sizeof(tAniGetRssiReq);
+	pMsg->sessionId = sessionId;
+	pMsg->staId = staId;
+	pMsg->rssiCallback = callback;
+	pMsg->pDevContext = pContext;
+	pMsg->p_cds_context = p_cds_context;
+	/*
+	 * store RSSI at time of calling, so that if RSSI request cannot
+	 * be sent to firmware, this value can be used to return immediately
+	 */
+	pMsg->lastRSSI = lastRSSI;
+	msg.type = eWNI_SME_GET_RSSI_REQ;
+	msg.bodyptr = pMsg;
+	msg.reserved = 0;
+	if (CDF_STATUS_SUCCESS != cds_mq_post_message(CDS_MQ_ID_SME, &msg)) {
+		sms_log(pMac, LOGE, " csr_get_rssi failed to post msg to self ");
+		cdf_mem_free((void *)pMsg);
+		status = CDF_STATUS_E_FAILURE;
+	}
+	sms_log(pMac, LOG2, FL("returned"));
+	return status;
+}
+
+CDF_STATUS csr_get_snr(tpAniSirGlobal pMac,
+		       tCsrSnrCallback callback,
+		       uint8_t staId, struct cdf_mac_addr bssId, void *pContext)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	cds_msg_t msg;
+	uint32_t sessionId;
+
+	tAniGetSnrReq *pMsg;
+
+	sms_log(pMac, LOG2, FL("called"));
+
+	pMsg = (tAniGetSnrReq *) cdf_mem_malloc(sizeof(tAniGetSnrReq));
+	if (NULL == pMsg) {
+		sms_log(pMac, LOGE, "%s: failed to allocate mem for req",
+			__func__);
+		return CDF_STATUS_E_NOMEM;
+	}
+
+	csr_roam_get_session_id_from_bssid(pMac, &bssId, &sessionId);
+
+	pMsg->msgType = eWNI_SME_GET_SNR_REQ;
+	pMsg->msgLen = (uint16_t) sizeof(tAniGetSnrReq);
+	pMsg->sessionId = sessionId;
+	pMsg->staId = staId;
+	pMsg->snrCallback = callback;
+	pMsg->pDevContext = pContext;
+	msg.type = eWNI_SME_GET_SNR_REQ;
+	msg.bodyptr = pMsg;
+	msg.reserved = 0;
+
+	if (CDF_STATUS_SUCCESS != cds_mq_post_message(CDS_MQ_ID_SME, &msg)) {
+		sms_log(pMac, LOGE, "%s failed to post msg to self", __func__);
+		cdf_mem_free((void *)pMsg);
+		status = CDF_STATUS_E_FAILURE;
+	}
+
+	sms_log(pMac, LOG2, FL("returned"));
+	return status;
+}
+
+#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
+CDF_STATUS csr_get_tsm_stats(tpAniSirGlobal pMac,
+			     tCsrTsmStatsCallback callback,
+			     uint8_t staId,
+			     struct cdf_mac_addr bssId,
+			     void *pContext, void *p_cds_context, uint8_t tid)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tAniGetTsmStatsReq *pMsg = NULL;
+	pMsg = cdf_mem_malloc(sizeof(tAniGetTsmStatsReq));
+	if (!pMsg) {
+		sms_log(pMac, LOGE,
+			"csr_get_tsm_stats: failed to allocate mem for req");
+		return CDF_STATUS_E_NOMEM;
+	}
+	/* need to initiate a stats request to PE */
+	pMsg->msgType = eWNI_SME_GET_TSM_STATS_REQ;
+	pMsg->msgLen = (uint16_t) sizeof(tAniGetTsmStatsReq);
+	pMsg->staId = staId;
+	pMsg->tid = tid;
+	cdf_mem_copy(pMsg->bssId, bssId.bytes, sizeof(tSirMacAddr));
+	pMsg->tsmStatsCallback = callback;
+	pMsg->pDevContext = pContext;
+	pMsg->p_cds_context = p_cds_context;
+	status = cds_send_mb_message_to_mac(pMsg);
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		sms_log(pMac, LOG1,
+			" csr_get_tsm_stats: failed to send down the rssi req");
+		/* pMsg is freed by cds_send_mb_message_to_mac */
+		status = CDF_STATUS_E_FAILURE;
+	}
+	return status;
+}
+#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
+
+/**
+ * csr_deregister_client_request() - deregisters a get stats request
+ * @mac_ctx:       mac global context
+ * @sta_entry:     stats request entry
+ *
+ * Return: status of operation
+ */
+static CDF_STATUS
+csr_deregister_client_request(tpAniSirGlobal mac_ctx,
+			      tCsrStatsClientReqInfo *sta_entry)
+{
+	CDF_STATUS status;
+	tListElem *entry = NULL;
+	tCsrStatsClientReqInfo *ptr_sta_entry = NULL;
+
+	entry = csr_roam_checkn_update_client_req_list(mac_ctx, sta_entry,
+						      false);
+	if (!entry) {
+		sms_log(mac_ctx, LOGW,
+			FL("callback is empty in the request & couldn't find any existing request in statsClientReqList"));
+		return CDF_STATUS_E_FAILURE;
+	}
+	/* clean up & return */
+	ptr_sta_entry = GET_BASE_ADDR(entry, tCsrStatsClientReqInfo, link);
+	if (NULL != ptr_sta_entry->pPeStaEntry) {
+		ptr_sta_entry->pPeStaEntry->numClient--;
+		/* check if we need to delete the entry from peStatsReqList */
+		if (!ptr_sta_entry->pPeStaEntry->numClient)
+			csr_roam_remove_entry_from_pe_stats_req_list(mac_ctx,
+						ptr_sta_entry->pPeStaEntry);
+	}
+	/* check if we need to stop the tl stats timer too */
+	mac_ctx->roam.tlStatsReqInfo.numClient--;
+	if (!mac_ctx->roam.tlStatsReqInfo.numClient) {
+		if (mac_ctx->roam.tlStatsReqInfo.timerRunning) {
+			status = cdf_mc_timer_stop(
+				&mac_ctx->roam.tlStatsReqInfo.hTlStatsTimer);
+			if (!CDF_IS_STATUS_SUCCESS(status)) {
+				sms_log(mac_ctx, LOGE,
+					FL("cannot stop TlStatsTimer timer"));
+				return status;
+			}
+		}
+		mac_ctx->roam.tlStatsReqInfo.periodicity = 0;
+		mac_ctx->roam.tlStatsReqInfo.timerRunning = false;
+	}
+	cdf_mc_timer_stop(&ptr_sta_entry->timer);
+	/* Destroy the cdf timer... */
+	status = cdf_mc_timer_destroy(&ptr_sta_entry->timer);
+	if (!CDF_IS_STATUS_SUCCESS(status))
+		sms_log(mac_ctx, LOGE,
+			FL("failed to destroy Client req timer"));
+
+	csr_roam_remove_stat_list_entry(mac_ctx, entry);
+	return CDF_STATUS_SUCCESS;
+}
+
+/**
+ * csr_insert_stats_request_to_list() - inserts request to existing list
+ * @mac_ctx:       mac global context
+ * @sta_entry:     stats request entry
+ * @periodicity:   periodicity of stats
+ *
+ * Return: status of operation
+ */
+static CDF_STATUS
+csr_insert_stats_request_to_list(tpAniSirGlobal mac_ctx,
+				 tCsrStatsClientReqInfo *sta_entry,
+				 uint32_t periodicity)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tCsrStatsClientReqInfo *ptr_sta_entry = csr_roam_insert_entry_into_list(
+				mac_ctx, &mac_ctx->roam.statsClientReqList,
+				sta_entry);
+	if (!ptr_sta_entry) {
+		sms_log(mac_ctx, LOGW,
+			FL("Failed to insert req in statsClientReqList"));
+		return CDF_STATUS_E_FAILURE;
+	}
+	/* Init & start timer if needed */
+	ptr_sta_entry->periodicity = periodicity;
+	if (ptr_sta_entry->periodicity) {
+		status = cdf_mc_timer_init(&ptr_sta_entry->timer,
+					CDF_TIMER_TYPE_SW,
+					csr_roam_stats_client_timer_handler,
+					ptr_sta_entry);
+		if (!CDF_IS_STATUS_SUCCESS(status)) {
+			sms_log(mac_ctx, LOGE,
+				FL("cannot init StatsClient timer"));
+			return CDF_STATUS_E_FAILURE;
+		}
+		status = cdf_mc_timer_start(&ptr_sta_entry->timer,
+					    ptr_sta_entry->periodicity);
+		if (!CDF_IS_STATUS_SUCCESS(status)) {
+			sms_log(mac_ctx, LOGE,
+				FL("cannot start StatsClient timer"));
+			return CDF_STATUS_E_FAILURE;
+		}
+	}
+	return status;
+}
+
+/**
+ * csr_get_statistics_from_tl() - fetch stats from tl layer
+ * @mac_ctx:       mac global context
+ * @cache:         indicate if cached stats are required
+ * @staId:         station id
+ * @periodicity:   periodicity of stats
+ *
+ * Return: status of operation
+ */
+static CDF_STATUS
+csr_get_statistics_from_tl(tpAniSirGlobal mac_ctx,
+			   bool cache,
+			   uint8_t staId,
+			   uint32_t periodicity)
+{
+	CDF_STATUS status;
+
+	if (cache && mac_ctx->roam.tlStatsReqInfo.numClient) {
+		sms_log(mac_ctx, LOGE, FL("Looking for cached stats from TL"));
+		mac_ctx->roam.tlStatsReqInfo.numClient++;
+		return CDF_STATUS_SUCCESS;
+	}
+
+	/* update periodicity */
+	if (mac_ctx->roam.tlStatsReqInfo.periodicity)
+		mac_ctx->roam.tlStatsReqInfo.periodicity =
+		    CDF_MIN(periodicity,
+			    mac_ctx->roam.tlStatsReqInfo.periodicity);
+	else
+		mac_ctx->roam.tlStatsReqInfo.periodicity = periodicity;
+
+	if (mac_ctx->roam.tlStatsReqInfo.periodicity
+	    < CSR_MIN_TL_STAT_QUERY_PERIOD) {
+		mac_ctx->roam.tlStatsReqInfo.periodicity =
+		CSR_MIN_TL_STAT_QUERY_PERIOD;
+	}
+
+	if (!mac_ctx->roam.tlStatsReqInfo.timerRunning) {
+
+		if (mac_ctx->roam.tlStatsReqInfo.periodicity) {
+			/* start timer */
+			status = cdf_mc_timer_start(
+				&mac_ctx->roam.tlStatsReqInfo.hTlStatsTimer,
+				mac_ctx->roam.tlStatsReqInfo.periodicity);
+			if (!CDF_IS_STATUS_SUCCESS(status)) {
+				sms_log(mac_ctx, LOGE,
+					FL("cannot start TlStatsTimer timer"));
+				return CDF_STATUS_E_FAILURE;
+			}
+			mac_ctx->roam.tlStatsReqInfo.timerRunning = true;
+		}
+	}
+	mac_ctx->roam.tlStatsReqInfo.numClient++;
+	return CDF_STATUS_SUCCESS;
+}
+
+CDF_STATUS csr_get_statistics(tpAniSirGlobal pMac,
+			      eCsrStatsRequesterType requesterId,
+			      uint32_t statsMask,
+			      tCsrStatsCallback callback,
+			      uint32_t periodicity,
+			      bool cache,
+			      uint8_t staId,
+			      void *pContext,
+			      uint8_t sessionId)
+{
+	tCsrStatsClientReqInfo staEntry;
+	tCsrPeStatsReqInfo *pPeStaEntry = NULL;
+	bool found = false;
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	bool insertInClientList = false;
+	uint32_t temp_mask = 0;
+
+	if (csr_is_all_session_disconnected(pMac))
+		return CDF_STATUS_E_FAILURE;
+
+	if (csr_neighbor_middle_of_roaming(pMac, sessionId)) {
+		sms_log(pMac, LOG1, FL("in the middle of roaming states"));
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	if ((!statsMask) && (!callback)) {
+		sms_log(pMac, LOGW,
+			FL("statsMask & callback empty in the request"));
+		return CDF_STATUS_E_FAILURE;
+	}
+	/* for the search list method for deregister */
+	staEntry.requesterId = requesterId;
+	staEntry.statsMask = statsMask;
+	/* requester wants to deregister or just an error */
+	if ((statsMask) && (!callback))
+		return csr_deregister_client_request(pMac, &staEntry);
+
+	if (cache && !periodicity) {
+		/* return the cached stats */
+		csr_roam_report_statistics(pMac, statsMask, callback, staId,
+					   pContext);
+		return CDF_STATUS_SUCCESS;
+	}
+	/* add the request in the client req list */
+	staEntry.callback = callback;
+	staEntry.pContext = pContext;
+	staEntry.periodicity = periodicity;
+	staEntry.pPeStaEntry = NULL;
+	staEntry.staId = staId;
+	staEntry.pMac = pMac;
+	staEntry.timerExpired = false;
+	staEntry.sessionId = sessionId;
+
+	/* if periodic report requested with non cached result from PE/TL */
+	if (periodicity) {
+		/* if looking for stats from PE */
+		temp_mask = statsMask & ~(1 << eCsrGlobalClassDStats);
+		if (temp_mask) {
+			/* check if same req made already & waiting for rsp */
+			pPeStaEntry = csr_roam_check_pe_stats_req_list(pMac,
+					temp_mask, periodicity, &found,
+					staId, sessionId);
+			if (!pPeStaEntry)
+				/* bail out, maxed out on num of req for PE */
+				return CDF_STATUS_E_FAILURE;
+			else
+				staEntry.pPeStaEntry = pPeStaEntry;
+		}
+		/*
+		 * request stats from TL rightaway if requested by client,
+		 * update tlStatsReqInfo if needed
+		 */
+		temp_mask = statsMask & (1 << eCsrGlobalClassDStats);
+		if (temp_mask) {
+			status = csr_get_statistics_from_tl(pMac, cache, staId,
+							    periodicity);
+			if (!CDF_IS_STATUS_SUCCESS(status))
+				return status;
+		}
+		insertInClientList = true;
+	}
+	/* if one time report requested with non cached result from PE/TL */
+	else if (!cache && !periodicity) {
+		temp_mask = statsMask & ~(1 << eCsrGlobalClassDStats);
+		if (temp_mask) {
+			/* send down a req */
+			status = csr_send_mb_stats_req_msg(pMac,
+						temp_mask, staId, sessionId);
+			if (!CDF_IS_STATUS_SUCCESS(status))
+				sms_log(pMac, LOGE,
+					FL("failed to send down stats req"));
+			/*
+			 * so that when the stats rsp comes back from PE we
+			 * respond to upper layer right away
+			 */
+			staEntry.timerExpired = true;
+			insertInClientList = true;
+		}
+		/* if looking for stats from TL only */
+		if (!insertInClientList) {
+			/* return the stats */
+			csr_roam_report_statistics(pMac, statsMask, callback,
+						   staId, pContext);
+			return CDF_STATUS_SUCCESS;
+		}
+	}
+	if (insertInClientList)
+		return csr_insert_stats_request_to_list(pMac, &staEntry,
+							periodicity);
+
+	return CDF_STATUS_SUCCESS;
+}
+
+static tSirRetStatus
+csr_roam_scan_offload_populate_mac_header(tpAniSirGlobal pMac,
+					  uint8_t *pBD,
+					  uint8_t type,
+					  uint8_t subType,
+					  tSirMacAddr peerAddr,
+					  tSirMacAddr selfMacAddr)
+{
+	tSirRetStatus statusCode = eSIR_SUCCESS;
+	tpSirMacMgmtHdr pMacHdr;
+
+	/* Prepare MAC management header */
+	pMacHdr = (tpSirMacMgmtHdr) (pBD);
+
+	/* Prepare FC */
+	pMacHdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION;
+	pMacHdr->fc.type = type;
+	pMacHdr->fc.subType = subType;
+
+	/* Prepare Address 1 */
+	cdf_mem_copy((uint8_t *) pMacHdr->da, (uint8_t *) peerAddr,
+		     sizeof(tSirMacAddr));
+
+	sir_copy_mac_addr(pMacHdr->sa, selfMacAddr);
+
+	/* Prepare Address 3 */
+	cdf_mem_copy((uint8_t *) pMacHdr->bssId, (uint8_t *) peerAddr,
+		     sizeof(tSirMacAddr));
+	return statusCode;
+} /*** csr_roam_scan_offload_populate_mac_header() ***/
+
+static tSirRetStatus
+csr_roam_scan_offload_prepare_probe_req_template(tpAniSirGlobal pMac,
+						 uint8_t nChannelNum,
+						 uint32_t dot11mode,
+						 tSirMacAddr selfMacAddr,
+						 uint8_t *pFrame,
+						 uint16_t *pusLen,
+						 tCsrRoamSession *psession)
+{
+	tDot11fProbeRequest pr;
+	uint32_t nStatus, nBytes, nPayload;
+	tSirRetStatus nSirStatus;
+	/*Bcast tx */
+	tSirMacAddr bssId = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+	/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+	cdf_mem_set((uint8_t *) &pr, sizeof(pr), 0);
+
+	populate_dot11f_supp_rates(pMac, nChannelNum, &pr.SuppRates, NULL);
+
+	if (WNI_CFG_DOT11_MODE_11B != dot11mode) {
+		populate_dot11f_ext_supp_rates1(pMac, nChannelNum,
+						&pr.ExtSuppRates);
+	}
+
+	if (IS_DOT11_MODE_HT(dot11mode)) {
+		populate_dot11f_ht_caps(pMac, NULL, &pr.HTCaps);
+		pr.HTCaps.advCodingCap = psession->htConfig.ht_rx_ldpc;
+		pr.HTCaps.txSTBC = psession->htConfig.ht_tx_stbc;
+		pr.HTCaps.rxSTBC = psession->htConfig.ht_rx_stbc;
+		if (!psession->htConfig.ht_sgi) {
+			pr.HTCaps.shortGI20MHz = pr.HTCaps.shortGI40MHz = 0;
+		}
+	}
+
+	nStatus = dot11f_get_packed_probe_request_size(pMac, &pr, &nPayload);
+	if (DOT11F_FAILED(nStatus)) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+			  "Failed to calculate the packed size f"
+			  "or a Probe Request (0x%08x).\n", nStatus);
+
+		nPayload = sizeof(tDot11fProbeRequest);
+	} else if (DOT11F_WARNED(nStatus)) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+			  "There were warnings while calculating"
+			  "the packed size for a Probe Request ("
+			  "0x%08x).\n", nStatus);
+	}
+
+	nBytes = nPayload + sizeof(tSirMacMgmtHdr);
+
+	/* Prepare outgoing frame */
+	cdf_mem_set(pFrame, nBytes, 0);
+
+	nSirStatus =
+		csr_roam_scan_offload_populate_mac_header(pMac, pFrame,
+							  SIR_MAC_MGMT_FRAME,
+							  SIR_MAC_MGMT_PROBE_REQ, bssId,
+							  selfMacAddr);
+
+	if (eSIR_SUCCESS != nSirStatus) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+			  "Failed to populate the buffer descriptor for a Probe Request (%d).\n",
+			  nSirStatus);
+		return nSirStatus;
+	}
+
+	nStatus = dot11f_pack_probe_request(pMac, &pr, pFrame +
+					    sizeof(tSirMacMgmtHdr),
+					    nPayload, &nPayload);
+	if (DOT11F_FAILED(nStatus)) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+			  "Failed to pack a Probe Request (0x%08x).\n",
+			  nStatus);
+		return eSIR_FAILURE;
+	} else if (DOT11F_WARNED(nStatus)) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+			  "There were warnings while packing a Probe Request (0x%08x).\n",
+			  nStatus);
+	}
+
+	*pusLen = nPayload + sizeof(tSirMacMgmtHdr);
+	return eSIR_SUCCESS;
+}
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+CDF_STATUS csr_roam_set_key_mgmt_offload(tpAniSirGlobal pMac,
+					 uint32_t sessionId,
+					 bool nRoamKeyMgmtOffloadEnabled)
+{
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("session %d not found"), sessionId);
+		return CDF_STATUS_E_FAILURE;
+	}
+	pSession->RoamKeyMgmtOffloadEnabled = nRoamKeyMgmtOffloadEnabled;
+	return CDF_STATUS_SUCCESS;
+}
+
+/**
+ * csr_update_roam_scan_offload_request() - updates req msg with roam offload
+ * paramters
+ * @pMac:          mac global context
+ * @req_buf:       out param, roam offload scan request packet
+ * @session:       roam session
+ *
+ * Return: void
+ */
+static void
+csr_update_roam_scan_offload_request(tpAniSirGlobal mac_ctx,
+				     tSirRoamOffloadScanReq *req_buf,
+				     tCsrRoamSession *session)
+{
+	cdf_mem_copy(req_buf->PSK_PMK, session->psk_pmk,
+		     sizeof(req_buf->PSK_PMK));
+	req_buf->pmk_len = session->pmk_len;
+	CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
+		  "LFR3: PMK Length = %d", req_buf->pmk_len);
+	req_buf->R0KH_ID_Length = session->ftSmeContext.r0kh_id_len;
+	cdf_mem_copy(req_buf->R0KH_ID,
+		     session->ftSmeContext.r0kh_id,
+		     req_buf->R0KH_ID_Length);
+	req_buf->Prefer5GHz = mac_ctx->roam.configParam.nRoamPrefer5GHz;
+	req_buf->RoamRssiCatGap = mac_ctx->roam.configParam.bCatRssiOffset;
+	req_buf->Select5GHzMargin = mac_ctx->roam.configParam.nSelect5GHzMargin;
+	if (wlan_cfg_get_int(mac_ctx, WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT,
+			     (uint32_t *) &req_buf->ReassocFailureTimeout)
+	    != eSIR_SUCCESS) {
+		sms_log(mac_ctx, LOGE,
+			FL("could not retrieve ReassocFailureTimeout value"));
+		req_buf->ReassocFailureTimeout =
+			DEFAULT_REASSOC_FAILURE_TIMEOUT;
+	}
+#ifdef FEATURE_WLAN_ESE
+	if (csr_is_auth_type_ese(req_buf->ConnectedNetwork.authentication)) {
+		cdf_mem_copy(req_buf->KRK, session->eseCckmInfo.krk,
+			     SIR_KRK_KEY_LEN);
+		cdf_mem_copy(req_buf->BTK, session->eseCckmInfo.btk,
+			     SIR_BTK_KEY_LEN);
+	}
+#endif
+	req_buf->AcUapsd.acbe_uapsd =
+		SIR_UAPSD_GET(ACBE, mac_ctx->lim.gUapsdPerAcBitmask);
+	req_buf->AcUapsd.acbk_uapsd =
+		SIR_UAPSD_GET(ACBK, mac_ctx->lim.gUapsdPerAcBitmask);
+	req_buf->AcUapsd.acvi_uapsd =
+		SIR_UAPSD_GET(ACVI, mac_ctx->lim.gUapsdPerAcBitmask);
+	req_buf->AcUapsd.acvo_uapsd =
+		SIR_UAPSD_GET(ACVO, mac_ctx->lim.gUapsdPerAcBitmask);
+}
+#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
+
+/**
+ * csr_check_band_channel_match() - check if passed band and channel match
+ * paramters
+ * @band:       band to match with channel
+ * @channel:    channel to match with band
+ *
+ * Return: bool if match else false
+ */
+static bool
+csr_check_band_channel_match(eCsrBand band, uint8_t channel)
+{
+	if (eCSR_BAND_ALL == band)
+		return true;
+
+	if (eCSR_BAND_24 == band && CDS_IS_CHANNEL_24GHZ(channel))
+		return true;
+
+	if (eCSR_BAND_5G == band && CDS_IS_CHANNEL_5GHZ(channel))
+		return true;
+
+	return false;
+}
+
+/**
+ * csr_fetch_ch_lst_from_ini() - fetch channel list from ini and update req msg
+ * paramters
+ * @mac_ctx:      global mac ctx
+ * @roam_info:    roam info struct
+ * @req_buf:      out param, roam offload scan request packet
+ *
+ * Return: result of operation
+ */
+static CDF_STATUS
+csr_fetch_ch_lst_from_ini(tpAniSirGlobal mac_ctx,
+			  tpCsrNeighborRoamControlInfo roam_info,
+			  tSirRoamOffloadScanReq *req_buf)
+{
+	eCsrBand band;
+	uint8_t i = 0;
+	uint8_t num_channels = 0;
+	uint8_t *ch_lst = roam_info->cfgParams.channelInfo.ChannelList;
+	/*
+	 * The INI channels need to be filtered with respect to the current band
+	 * that is supported.
+	 */
+	band = mac_ctx->roam.configParam.bandCapability;
+	if ((eCSR_BAND_24 != band) && (eCSR_BAND_5G != band)
+	    && (eCSR_BAND_ALL != band)) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+			  FL("Invalid band(%d), roam scan offload req aborted"),
+			  band);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	for (i = 0; i < roam_info->cfgParams.channelInfo.numOfChannels; i++) {
+		if (!csr_check_band_channel_match(band, *ch_lst))
+			continue;
+		/* Allow DFS channels only if the DFS roaming is enabled */
+		if (((mac_ctx->roam.configParam.allowDFSChannelRoam !=
+		     CSR_ROAMING_DFS_CHANNEL_DISABLED)
+		     || (!CDS_IS_DFS_CH(*ch_lst)))
+		    && csr_roam_is_channel_valid(mac_ctx, *ch_lst)
+		    && *ch_lst && (num_channels < SIR_ROAM_MAX_CHANNELS)) {
+			req_buf->ConnectedNetwork.ChannelCache[num_channels++] =
+				*ch_lst;
+		}
+		ch_lst++;
+	}
+	req_buf->ConnectedNetwork.ChannelCount = num_channels;
+	req_buf->ChannelCacheType = CHANNEL_LIST_STATIC;
+	return CDF_STATUS_SUCCESS;
+}
+
+/**
+ * csr_fetch_ch_lst_from_occupied_lst() - fetch channel list from occupied list
+ * and update req msg
+ * paramters
+ * @mac_ctx:      global mac ctx
+ * @session_id:   session id
+ * @reason:       reason to roam
+ * @req_buf:      out param, roam offload scan request packet
+ * @roam_info:    roam info struct
+ *
+ * Return: void
+ */
+static void
+csr_fetch_ch_lst_from_occupied_lst(tpAniSirGlobal mac_ctx,
+				   uint8_t session_id,
+				   uint8_t reason,
+				   tSirRoamOffloadScanReq *req_buf,
+				   tpCsrNeighborRoamControlInfo roam_info)
+{
+	uint8_t i = 0;
+	uint8_t num_channels = 0;
+	uint8_t *ch_lst =
+		mac_ctx->scan.occupiedChannels[session_id].channelList;
+	CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
+		"Num of channels before filtering=%d",
+		mac_ctx->scan.occupiedChannels[session_id].numChannels);
+	for (i = 0; i < mac_ctx->scan.occupiedChannels[session_id].numChannels;
+	     i++) {
+		if (((mac_ctx->roam.configParam.allowDFSChannelRoam !=
+		    CSR_ROAMING_DFS_CHANNEL_DISABLED)
+			|| (!CDS_IS_DFS_CH(*ch_lst)))
+			&& *ch_lst && (num_channels < SIR_ROAM_MAX_CHANNELS)) {
+			req_buf->ConnectedNetwork.ChannelCache[num_channels++] =
+				*ch_lst;
+		}
+		if (*ch_lst)
+			CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
+				"DFSRoam=%d, ChnlState=%d, Chnl=%d, num_ch=%d",
+				mac_ctx->roam.configParam.allowDFSChannelRoam,
+				cds_get_channel_state(*ch_lst), *ch_lst,
+				num_channels);
+		ch_lst++;
+	}
+	req_buf->ConnectedNetwork.ChannelCount = num_channels;
+	/*
+	 * If the profile changes as to what it was earlier, inform the FW
+	 * through FLUSH as ChannelCacheType in which case, the FW will flush
+	 * the occupied channels for the earlier profile and try to learn them
+	 * afresh
+	 */
+	if (reason == REASON_FLUSH_CHANNEL_LIST)
+		req_buf->ChannelCacheType = CHANNEL_LIST_DYNAMIC_FLUSH;
+	else {
+		if (csr_neighbor_roam_is_new_connected_profile(mac_ctx,
+							       session_id))
+			req_buf->ChannelCacheType = CHANNEL_LIST_DYNAMIC_INIT;
+		else
+			req_buf->ChannelCacheType = CHANNEL_LIST_DYNAMIC_UPDATE;
+	}
+}
+
+#ifdef FEATURE_WLAN_ESE
+/**
+ * csr_fetch_ch_lst_from_received_list() - fetch channel list from received list
+ * and update req msg
+ * paramters
+ * @mac_ctx:            global mac ctx
+ * @roam_info:          roam info struct
+ * @curr_ch_lst_info:   current channel list info
+ * @req_buf:            out param, roam offload scan request packet
+ *
+ * Return: void
+ */
+static void
+csr_fetch_ch_lst_from_received_list(tpAniSirGlobal mac_ctx,
+				    tpCsrNeighborRoamControlInfo roam_info,
+				    tpCsrChannelInfo curr_ch_lst_info,
+				    tSirRoamOffloadScanReq *req_buf)
+{
+	uint8_t i = 0;
+	uint8_t num_channels = 0;
+	uint8_t *ch_lst = NULL;
+
+	if (curr_ch_lst_info->numOfChannels == 0)
+		return;
+
+	ch_lst = curr_ch_lst_info->ChannelList;
+	for (i = 0; i < curr_ch_lst_info->numOfChannels; i++) {
+		if (((mac_ctx->roam.configParam.allowDFSChannelRoam
+		      != CSR_ROAMING_DFS_CHANNEL_DISABLED) ||
+		     (!CDS_IS_DFS_CH(*ch_lst))) && *ch_lst) {
+			req_buf->ConnectedNetwork.ChannelCache[num_channels++] =
+				*ch_lst;
+		}
+		ch_lst++;
+	}
+	req_buf->ConnectedNetwork.ChannelCount = num_channels;
+	req_buf->ChannelCacheType = CHANNEL_LIST_DYNAMIC_UPDATE;
+}
+#endif
+
+/**
+ * csr_fetch_valid_ch_lst() - fetch channel list from valid channel list and
+ * update req msg
+ * paramters
+ * @mac_ctx:            global mac ctx
+ * @req_buf:            out param, roam offload scan request packet
+ *
+ * Return: void
+ */
+static CDF_STATUS
+csr_fetch_valid_ch_lst(tpAniSirGlobal mac_ctx,
+		       tSirRoamOffloadScanReq *req_buf)
+{
+	CDF_STATUS status;
+	uint32_t host_channels = 0;
+	uint8_t *ch_lst = NULL;
+	uint8_t i = 0, num_channels = 0;
+
+	host_channels = sizeof(mac_ctx->roam.validChannelList);
+	status = csr_get_cfg_valid_channels(mac_ctx,
+					    mac_ctx->roam.validChannelList,
+					    &host_channels);
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+			  FL("Failed to get the valid channel list"));
+		return status;
+	}
+	ch_lst = mac_ctx->roam.validChannelList;
+	mac_ctx->roam.numValidChannels = host_channels;
+	for (i = 0; i < mac_ctx->roam.numValidChannels; i++) {
+		if (((mac_ctx->roam.configParam.allowDFSChannelRoam
+		      != CSR_ROAMING_DFS_CHANNEL_DISABLED) ||
+		     (!CDS_IS_DFS_CH(*ch_lst))) && *ch_lst) {
+			req_buf->ValidChannelList[num_channels++] = *ch_lst;
+		}
+		ch_lst++;
+	}
+	req_buf->ValidChannelCount = num_channels;
+	return status;
+}
+
+/**
+ * csr_create_roam_scan_offload_request() - init roam offload scan request
+ *
+ * paramters
+ * @mac_ctx:      global mac ctx
+ * @command:      roam scan offload command input
+ * @session_id:   session id
+ * @reason:       reason to roam
+ * @session:      roam session
+ * @roam_info:    roam info struct
+ *
+ * Return: roam offload scan request packet buffer
+ */
+static tSirRoamOffloadScanReq *
+csr_create_roam_scan_offload_request(tpAniSirGlobal mac_ctx,
+				     uint8_t command,
+				     uint8_t session_id,
+				     uint8_t reason,
+				     tCsrRoamSession *session,
+				     tpCsrNeighborRoamControlInfo roam_info)
+{
+	CDF_STATUS status;
+	uint8_t i, j, dot11_mode;
+	bool ese_neighbor_list_recvd = false;
+	uint8_t ch_cache_str[128] = { 0 };
+	tSirRoamOffloadScanReq *req_buf = NULL;
+	tpCsrChannelInfo curr_ch_lst_info =
+		&roam_info->roamChannelInfo.currentChannelListInfo;
+#ifdef FEATURE_WLAN_ESE
+	/*
+	 * this flag will be true if connection is ESE and no neighbor
+	 * list received or if the connection is not ESE
+	 */
+	ese_neighbor_list_recvd = ((roam_info->isESEAssoc)
+		&& (roam_info->roamChannelInfo.IAPPNeighborListReceived
+		    == false))
+		|| (roam_info->isESEAssoc == false);
+#endif /* FEATURE_WLAN_ESE */
+
+	req_buf = cdf_mem_malloc(sizeof(tSirRoamOffloadScanReq));
+	if (NULL == req_buf) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+			  FL("Mem alloc for roam scan offload req failed."));
+		return NULL;
+	}
+	cdf_mem_zero(req_buf, sizeof(tSirRoamOffloadScanReq));
+	req_buf->Command = command;
+	/*
+	 * If command is STOP, then pass down ScanOffloadEnabled as Zero. This
+	 * will handle the case of host driver reloads, but Riva still up and
+	 * running
+	 */
+	if (command == ROAM_SCAN_OFFLOAD_STOP) {
+		/*
+		 * clear the roaming parameters that are per connection.
+		 * For a new connection, they have to be programmed again.
+		 */
+		if (csr_neighbor_middle_of_roaming((tHalHandle)mac_ctx,
+				session_id))
+			req_buf->middle_of_roaming = 1;
+		else
+			csr_roam_reset_roam_params(mac_ctx);
+		req_buf->RoamScanOffloadEnabled = 0;
+	} else {
+		req_buf->RoamScanOffloadEnabled =
+			mac_ctx->roam.configParam.isRoamOffloadScanEnabled;
+	}
+	cdf_mem_copy(req_buf->ConnectedNetwork.currAPbssid,
+		     roam_info->currAPbssid.bytes, sizeof(struct cdf_mac_addr));
+	req_buf->ConnectedNetwork.ssId.length =
+		mac_ctx->roam.roamSession[session_id].
+		connectedProfile.SSID.length;
+	cdf_mem_copy(req_buf->ConnectedNetwork.ssId.ssId,
+		mac_ctx->roam.roamSession[session_id].
+		connectedProfile.SSID.ssId,
+		req_buf->ConnectedNetwork.ssId.length);
+	req_buf->ConnectedNetwork.authentication =
+		mac_ctx->roam.roamSession[session_id].connectedProfile.AuthType;
+	req_buf->ConnectedNetwork.encryption =
+		mac_ctx->roam.roamSession[session_id].
+		connectedProfile.EncryptionType;
+	req_buf->ConnectedNetwork.mcencryption =
+		mac_ctx->roam.roamSession[session_id].
+		connectedProfile.mcEncryptionType;
+#ifdef WLAN_FEATURE_11W
+	req_buf->ConnectedNetwork.mfp_enabled =
+	    mac_ctx->roam.roamSession[session_id].connectedProfile.MFPEnabled;
+#endif
+	req_buf->delay_before_vdev_stop =
+		roam_info->cfgParams.delay_before_vdev_stop;
+	req_buf->OpportunisticScanThresholdDiff =
+		roam_info->cfgParams.nOpportunisticThresholdDiff;
+	req_buf->RoamRescanRssiDiff =
+		roam_info->cfgParams.nRoamRescanRssiDiff;
+	req_buf->RoamRssiDiff = mac_ctx->roam.configParam.RoamRssiDiff;
+	req_buf->reason = reason;
+	req_buf->NeighborScanTimerPeriod =
+		roam_info->cfgParams.neighborScanPeriod;
+	req_buf->NeighborRoamScanRefreshPeriod =
+		roam_info->cfgParams.neighborResultsRefreshPeriod;
+	req_buf->NeighborScanChannelMinTime =
+		roam_info->cfgParams.minChannelScanTime;
+	req_buf->NeighborScanChannelMaxTime =
+		roam_info->cfgParams.maxChannelScanTime;
+	req_buf->EmptyRefreshScanPeriod =
+		roam_info->cfgParams.emptyScanRefreshPeriod;
+	req_buf->RoamBmissFirstBcnt =
+		roam_info->cfgParams.nRoamBmissFirstBcnt;
+	req_buf->RoamBmissFinalBcnt =
+		roam_info->cfgParams.nRoamBmissFinalBcnt;
+	req_buf->RoamBeaconRssiWeight =
+		roam_info->cfgParams.nRoamBeaconRssiWeight;
+	/* MAWC feature */
+	req_buf->MAWCEnabled = mac_ctx->roam.configParam.MAWCEnabled;
+#ifdef FEATURE_WLAN_ESE
+	req_buf->IsESEAssoc =
+		csr_neighbor_roam_is_ese_assoc(mac_ctx, session_id) &&
+		((req_buf->ConnectedNetwork.authentication ==
+			eCSR_AUTH_TYPE_OPEN_SYSTEM)  ||
+		(csr_is_auth_type_ese(req_buf->
+			ConnectedNetwork.authentication)));
+	CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
+			FL("LFR3:IsEseAssoc=%d\n"), req_buf->IsESEAssoc);
+#endif
+	if (ese_neighbor_list_recvd || curr_ch_lst_info->numOfChannels == 0) {
+		/*
+		 * Retrieve the Channel Cache either from ini or from the
+		 * occupied channels list. Give Preference to INI Channels
+		 */
+		if (roam_info->cfgParams.channelInfo.numOfChannels) {
+			status = csr_fetch_ch_lst_from_ini(mac_ctx, roam_info,
+							   req_buf);
+			if (!CDF_IS_STATUS_SUCCESS(status)) {
+				cdf_mem_free(req_buf);
+				return NULL;
+			}
+		} else {
+			csr_fetch_ch_lst_from_occupied_lst(mac_ctx, session_id,
+						reason, req_buf, roam_info);
+		}
+	}
+#ifdef FEATURE_WLAN_ESE
+	else {
+		/*
+		 * If ESE is enabled, and a neighbor Report is received,then
+		 * Ignore the INI Channels or the Occupied Channel List.
+		 * Consider the channels in the neighbor list sent by the ESE AP
+		 */
+		 csr_fetch_ch_lst_from_received_list(mac_ctx, roam_info,
+						curr_ch_lst_info, req_buf);
+	}
+#endif
+	for (i = 0, j = 0; i < req_buf->ConnectedNetwork.ChannelCount; i++) {
+		if (j < sizeof(ch_cache_str)) {
+			j += snprintf(ch_cache_str + j,
+				      sizeof(ch_cache_str) - j, " %d",
+				      req_buf->ConnectedNetwork.
+				      ChannelCache[i]);
+		} else
+			break;
+	}
+	CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
+		  FL("ChnlCacheType:%d, No of Chnls:%d,Channels: %s"),
+		  req_buf->ChannelCacheType,
+		  req_buf->ConnectedNetwork.ChannelCount, ch_cache_str);
+
+	/* Maintain the Valid Channels List */
+	status = csr_fetch_valid_ch_lst(mac_ctx, req_buf);
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		cdf_mem_free(req_buf);
+		return NULL;
+	}
+
+	req_buf->MDID.mdiePresent =
+		mac_ctx->roam.roamSession[session_id].
+		connectedProfile.MDID.mdiePresent;
+	req_buf->MDID.mobilityDomain =
+		mac_ctx->roam.roamSession[session_id].
+		connectedProfile.MDID.mobilityDomain;
+	req_buf->sessionId = session_id;
+	req_buf->nProbes = mac_ctx->roam.configParam.nProbes;
+	req_buf->HomeAwayTime = mac_ctx->roam.configParam.nRoamScanHomeAwayTime;
+
+	/*
+	 * Home Away Time should be at least equal to (MaxDwell time + (2*RFS)),
+	 * where RFS is the RF Switching time. It is twice RFS to consider the
+	 * time to go off channel and return to the home channel.
+	 */
+	if (req_buf->HomeAwayTime < (req_buf->NeighborScanChannelMaxTime +
+	     (2 * CSR_ROAM_SCAN_CHANNEL_SWITCH_TIME))) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_WARN,
+			  FL("Invalid config, Home away time(%d) is less than (twice RF switching time + channel max time)(%d). Hence enforcing home away time to disable (0)"),
+			  req_buf->HomeAwayTime,
+			  (req_buf->NeighborScanChannelMaxTime +
+			   (2 * CSR_ROAM_SCAN_CHANNEL_SWITCH_TIME)));
+		req_buf->HomeAwayTime = 0;
+	}
+	CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
+		  FL("HomeAwayTime:%d"), req_buf->HomeAwayTime);
+
+	/*Prepare a probe request for 2.4GHz band and one for 5GHz band */
+	dot11_mode = (uint8_t) csr_translate_to_wni_cfg_dot11_mode(mac_ctx,
+				csr_find_best_phy_mode(mac_ctx,
+					mac_ctx->roam.configParam.phyMode));
+	csr_roam_scan_offload_prepare_probe_req_template(mac_ctx,
+		SIR_ROAM_SCAN_24G_DEFAULT_CH, dot11_mode,
+		session->selfMacAddr.bytes, req_buf->p24GProbeTemplate,
+		&req_buf->us24GProbeTemplateLen, session);
+
+	csr_roam_scan_offload_prepare_probe_req_template(mac_ctx,
+		SIR_ROAM_SCAN_5G_DEFAULT_CH, dot11_mode,
+		session->selfMacAddr.bytes,
+		req_buf->p5GProbeTemplate, &req_buf->us5GProbeTemplateLen,
+		session);
+	req_buf->allowDFSChannelRoam =
+	mac_ctx->roam.configParam.allowDFSChannelRoam;
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	req_buf->RoamOffloadEnabled = csr_roamIsRoamOffloadEnabled(mac_ctx);
+	req_buf->RoamKeyMgmtOffloadEnabled = session->RoamKeyMgmtOffloadEnabled;
+	/* Roam Offload piggybacks upon the Roam Scan offload command. */
+	if (req_buf->RoamOffloadEnabled)
+		csr_update_roam_scan_offload_request(mac_ctx, req_buf, session);
+	cdf_mem_copy(&req_buf->roam_params,
+		&mac_ctx->roam.configParam.roam_params,
+		sizeof(req_buf->roam_params));
+#endif
+	return req_buf;
+}
+/**
+ * check_allowed_ssid_list() - Check the WhiteList
+ * @req_buffer:      Buffer which contains the connected profile SSID.
+ * @roam_params:     Buffer which contains the whitelist SSID's.
+ *
+ * Check if the connected profile SSID exists in the whitelist.
+ * It is assumed that the framework provides this also in the whitelist.
+ * If it exists there is no issue. Otherwise add it to the list.
+ *
+ * Return: None
+ */
+static void check_allowed_ssid_list(tSirRoamOffloadScanReq *req_buffer,
+		struct roam_ext_params *roam_params)
+{
+	int i = 0;
+	bool match = false;
+	for (i = 0; i < roam_params->num_ssid_allowed_list; i++) {
+		if ((roam_params->ssid_allowed_list[i].length ==
+			req_buffer->ConnectedNetwork.ssId.length) &&
+			cdf_mem_compare(roam_params->ssid_allowed_list[i].ssId,
+				req_buffer->ConnectedNetwork.ssId.ssId,
+				roam_params->ssid_allowed_list[i].length)) {
+			CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
+				"Whitelist contains connected profile SSID");
+			match = true;
+			break;
+		}
+	}
+	if (!match) {
+		if (roam_params->num_ssid_allowed_list >=
+				MAX_SSID_ALLOWED_LIST) {
+			CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
+				"Whitelist is FULL. Cannot Add another entry");
+			return;
+		}
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
+				"Adding Connected profile SSID to whitelist");
+		/* i is the next available index to add the entry.*/
+		i = roam_params->num_ssid_allowed_list;
+		cdf_mem_copy(roam_params->ssid_allowed_list[i].ssId,
+				req_buffer->ConnectedNetwork.ssId.ssId,
+				req_buffer->ConnectedNetwork.ssId.length);
+		roam_params->ssid_allowed_list[i].length =
+			req_buffer->ConnectedNetwork.ssId.length;
+		roam_params->num_ssid_allowed_list++;
+	}
+}
+
+/*
+ * Below Table describe whether RSO command can be send down to fimrware or not.
+ * Host check it on the basis of previous RSO command sent down to firmware.
+ *||==========================================================================||
+ *|| New cmd        |            LAST SENT COMMAND --->                       ||
+ *||====|=====================================================================||
+ *||    V           |  RSO_START  |  RSO_STOP  |  RSO_RESTART | RSO_UPDATE_CFG||
+ *|| -------------------------------------------------------------------------||
+ *|| RSO_START      |     NO      |   YES      |     NO       |      NO       ||
+ *|| RSO_STOP       |    YES      |   YES      |     YES      |      YES      ||
+ *|| RSO_RESTART    |    YES      |   NO       |     NO       |      YES      ||
+ *|| RSO_UPDATE_CFG |    YES      |   NO       |     YES      |      YES      ||
+ *||==========================================================================||
+ **/
+#define RSO_START_BIT       (1<<ROAM_SCAN_OFFLOAD_START)
+#define RSO_STOP_BIT        (1<<ROAM_SCAN_OFFLOAD_STOP)
+#define RSO_RESTART_BIT     (1<<ROAM_SCAN_OFFLOAD_RESTART)
+#define RSO_UPDATE_CFG_BIT  (1<<ROAM_SCAN_OFFLOAD_UPDATE_CFG)
+#define RSO_START_ALLOW_MASK   (RSO_STOP_BIT)
+#define RSO_STOP_ALLOW_MASK    (RSO_UPDATE_CFG_BIT | RSO_RESTART_BIT | \
+		RSO_STOP_BIT | RSO_START_BIT)
+#define RSO_RESTART_ALLOW_MASK (RSO_UPDATE_CFG_BIT | RSO_START_BIT)
+#define RSO_UPDATE_CFG_ALLOW_MASK  (RSO_UPDATE_CFG_BIT | RSO_STOP_BIT | \
+		RSO_START_BIT)
+
+bool csr_is_RSO_cmd_allowed(tpAniSirGlobal mac_ctx, uint8_t command,
+		uint8_t session_id)
+{
+	tpCsrNeighborRoamControlInfo neigh_roam_info =
+		&mac_ctx->roam.neighborRoamInfo[session_id];
+	uint8_t desiredMask = 0;
+	bool ret_val;
+
+	switch (command) {
+	case ROAM_SCAN_OFFLOAD_START:
+		desiredMask = RSO_START_ALLOW_MASK;
+		break;
+	case ROAM_SCAN_OFFLOAD_STOP:
+		desiredMask = RSO_STOP_ALLOW_MASK;
+		break;
+	case ROAM_SCAN_OFFLOAD_RESTART:
+		desiredMask = RSO_RESTART_ALLOW_MASK;
+		break;
+	case ROAM_SCAN_OFFLOAD_UPDATE_CFG:
+		desiredMask = RSO_UPDATE_CFG_ALLOW_MASK;
+		break;
+	default:
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+			FL("Wrong RSO command %d, not allowed"), command);
+		return 0;/*Cmd Not allowed*/
+	}
+	ret_val = desiredMask & (1 << neigh_roam_info->last_sent_cmd);
+	return ret_val;
+}
+
+/**
+ * csr_roam_offload_scan() - populates roam offload scan request and sends to
+ * WMA
+ *
+ * paramters
+ * @mac_ctx:      global mac ctx
+ * @session_id:   session id
+ * @command:      roam scan offload command input
+ * @reason:       reason to roam
+ *
+ * Return: result of operation
+ */
+CDF_STATUS
+csr_roam_offload_scan(tpAniSirGlobal mac_ctx, uint8_t session_id,
+		      uint8_t command, uint8_t reason)
+{
+	uint8_t *state = NULL;
+	cds_msg_t msg;
+	tSirRoamOffloadScanReq *req_buf;
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tCsrRoamSession *session = CSR_GET_SESSION(mac_ctx, session_id);
+	tpCsrNeighborRoamControlInfo roam_info =
+		&mac_ctx->roam.neighborRoamInfo[session_id];
+	struct roam_ext_params *roam_params_dst;
+	struct roam_ext_params *roam_params_src;
+	uint8_t i;
+
+	if (NULL == session) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+			  FL("session is null"));
+		return CDF_STATUS_E_FAILURE;
+	}
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	if (session->roamOffloadSynchParams.bRoamSynchInProgress
+	    && (ROAM_SCAN_OFFLOAD_STOP == command)) {
+		/*
+		 * When roam synch is in progress for propagation, there is no
+		 * need to send down the STOP command since the firmware is not
+		 * expecting any WMI commands when the roam synch is in progress
+		 */
+		b_roam_scan_offload_started = false;
+		return CDF_STATUS_SUCCESS;
+	}
+#endif
+	if (0 == csr_roam_is_roam_offload_scan_enabled(mac_ctx)) {
+		sms_log(mac_ctx, LOGE, "isRoamOffloadScanEnabled not set");
+		return CDF_STATUS_E_FAILURE;
+	}
+	if (!csr_is_RSO_cmd_allowed(mac_ctx, command, session_id) &&
+			reason != REASON_ROAM_SET_BLACKLIST_BSSID) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+			FL("RSO out-of-sync command %d lastSentCmd %d"),
+			command, roam_info->last_sent_cmd);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	if ((true == b_roam_scan_offload_started)
+	    && (ROAM_SCAN_OFFLOAD_START == command)) {
+		sms_log(mac_ctx, LOGE, "Roam Scan Offload is already started");
+		return CDF_STATUS_E_FAILURE;
+	}
+	/*
+	 * The Dynamic Config Items Update may happen even if the state is in
+	 * INIT. It is important to ensure that the command is passed down to
+	 * the FW only if the Infra Station is in a connected state.A connected
+	 * station could also be in a PREAUTH or REASSOC states.So, consider not
+	 * sending the command down in INIT state. We also have to ensure that
+	 * if there is a STOP command we always have to inform Riva,
+	 * irrespective of whichever state we are in
+	 */
+
+	if ((roam_info->neighborRoamState ==
+	     eCSR_NEIGHBOR_ROAM_STATE_INIT) &&
+	    (command != ROAM_SCAN_OFFLOAD_STOP) &&
+	    (reason != REASON_ROAM_SET_BLACKLIST_BSSID)) {
+		state = mac_trace_get_neighbour_roam_state(
+				roam_info->neighborRoamState);
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
+			  FL("Scan Command not sent to FW state=%s and cmd=%d"),
+			  state,  command);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	req_buf = csr_create_roam_scan_offload_request(mac_ctx, command,
+						       session_id, reason,
+						       session, roam_info);
+	if (!req_buf) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+			  FL("Failed to create req packet"));
+		return CDF_STATUS_E_FAILURE;
+	}
+	roam_params_dst = &req_buf->roam_params;
+	roam_params_src = &mac_ctx->roam.configParam.roam_params;
+	if (reason == REASON_ROAM_SET_SSID_ALLOWED)
+		check_allowed_ssid_list(req_buf, roam_params_src);
+	/*
+	 * Configure the lookup threshold either from INI or from framework.
+	 * If both are present, give higher priority to the one from framework.
+	 */
+	if (roam_params_src->alert_rssi_threshold)
+		req_buf->LookupThreshold =
+			roam_params_src->alert_rssi_threshold;
+	else
+		req_buf->LookupThreshold =
+			(int8_t)roam_info->cfgParams.neighborLookupThreshold *
+			(-1);
+	cdf_mem_copy(roam_params_dst, roam_params_src,
+		sizeof(struct roam_ext_params));
+	/*
+	 * rssi_diff which is updated via framework is equivalent to the
+	 * INI RoamRssiDiff parameter and hence should be updated.
+	 */
+	if (roam_params_src->rssi_diff)
+		req_buf->RoamRssiDiff = roam_params_src->rssi_diff;
+	CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
+		"num_bssid_avoid_list: %d, num_ssid_allowed_list: %d, "
+		"num_bssid_favored: %d, raise_rssi_thresh_5g: %d, "
+		"drop_rssi_thresh_5g: %d, raise_rssi_type_5g: %d, "
+		"raise_factor_5g: %d, drop_rssi_type_5g: %d, "
+		"drop_factor_5g: %d, max_raise_rssi_5g: %d, "
+		"max_drop_rssi_5g: %d, rssi_diff: %d, alert_rssi_threshold:%d",
+		roam_params_dst->num_bssid_avoid_list,
+		roam_params_dst->num_ssid_allowed_list,
+		roam_params_dst->num_bssid_favored,
+		roam_params_dst->raise_rssi_thresh_5g,
+		roam_params_dst->drop_rssi_thresh_5g,
+		roam_params_dst->raise_rssi_type_5g,
+		roam_params_dst->raise_factor_5g,
+		roam_params_dst->drop_rssi_type_5g,
+		roam_params_dst->drop_factor_5g,
+		roam_params_dst->max_raise_rssi_5g,
+		roam_params_dst->max_drop_rssi_5g,
+		req_buf->RoamRssiDiff, roam_params_dst->alert_rssi_threshold);
+
+	for (i = 0; i < roam_params_dst->num_bssid_avoid_list; i++) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
+			"Blacklist Bssid: ("MAC_ADDRESS_STR")",
+			MAC_ADDR_ARRAY(roam_params_dst->bssid_avoid_list[i]));
+	}
+	for (i = 0; i < roam_params_dst->num_ssid_allowed_list; i++) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
+			"Whitelist: %.*s",
+			roam_params_dst->ssid_allowed_list[i].length,
+			roam_params_dst->ssid_allowed_list[i].ssId);
+	}
+	for (i = 0; i < roam_params_dst->num_bssid_favored; i++) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
+			"Preferred Bssid: ("MAC_ADDRESS_STR") score: %d",
+			MAC_ADDR_ARRAY(roam_params_dst->bssid_favored[i]),
+			roam_params_dst->bssid_favored_factor[i]);
+	}
+
+	req_buf->hi_rssi_scan_max_count =
+		roam_info->cfgParams.hi_rssi_scan_max_count;
+	req_buf->hi_rssi_scan_rssi_delta =
+		roam_info->cfgParams.hi_rssi_scan_rssi_delta;
+	req_buf->hi_rssi_scan_delay =
+		roam_info->cfgParams.hi_rssi_scan_delay;
+	req_buf->hi_rssi_scan_rssi_ub =
+		roam_info->cfgParams.hi_rssi_scan_rssi_ub;
+
+	msg.type = WMA_ROAM_SCAN_OFFLOAD_REQ;
+	msg.reserved = 0;
+	msg.bodyptr = req_buf;
+	if (!CDF_IS_STATUS_SUCCESS
+		    (cds_mq_post_message(CDF_MODULE_ID_WMA, &msg))) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+			  "%s: Not able to post message to WMA",
+			  __func__);
+		cdf_mem_free(req_buf);
+		return CDF_STATUS_E_FAILURE;
+	} else {
+		if (ROAM_SCAN_OFFLOAD_START == command)
+			b_roam_scan_offload_started = true;
+		else if (ROAM_SCAN_OFFLOAD_STOP == command)
+			b_roam_scan_offload_started = false;
+	}
+	/* update the last sent cmd */
+	roam_info->last_sent_cmd = command;
+
+	CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
+		  "Roam Scan Offload Command %d, Reason %d", command, reason);
+	return status;
+}
+
+CDF_STATUS csr_roam_offload_scan_rsp_hdlr(tpAniSirGlobal pMac,
+					  tpSirRoamOffloadScanRsp scanOffloadRsp)
+{
+	switch (scanOffloadRsp->reason) {
+	case 0:
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
+			  "Rsp for Roam Scan Offload with failure status");
+		break;
+	case REASON_OS_REQUESTED_ROAMING_NOW:
+		csr_neighbor_roam_proceed_with_handoff_req(pMac,
+							   scanOffloadRsp->sessionId);
+		break;
+
+	default:
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
+			  "Rsp for Roam Scan Offload with reason %d",
+			  scanOffloadRsp->reason);
+	}
+	return CDF_STATUS_SUCCESS;
+}
+
+tCsrPeStatsReqInfo *csr_roam_check_pe_stats_req_list(tpAniSirGlobal pMac,
+						     uint32_t statsMask,
+						     uint32_t periodicity,
+						     bool *pFound,
+						     uint8_t staId, uint8_t sessionId)
+{
+	bool found = false;
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tCsrPeStatsReqInfo staEntry;
+	tCsrPeStatsReqInfo *pTempStaEntry = NULL;
+	tListElem *pStaEntry = NULL;
+	CDF_STATUS cdf_status;
+	*pFound = false;
+
+	pStaEntry = csr_roam_find_in_pe_stats_req_list(pMac, statsMask);
+	if (pStaEntry) {
+		pTempStaEntry =
+			GET_BASE_ADDR(pStaEntry, tCsrPeStatsReqInfo, link);
+		if (pTempStaEntry->periodicity) {
+			pTempStaEntry->periodicity =
+				CDF_MIN(periodicity,
+					pTempStaEntry->periodicity);
+		} else {
+			pTempStaEntry->periodicity = periodicity;
+		}
+		pTempStaEntry->numClient++;
+		found = true;
+	} else {
+		cdf_mem_set(&staEntry, sizeof(tCsrPeStatsReqInfo), 0);
+		staEntry.numClient = 1;
+		staEntry.periodicity = periodicity;
+		staEntry.pMac = pMac;
+		staEntry.rspPending = false;
+		staEntry.staId = staId;
+		staEntry.statsMask = statsMask;
+		staEntry.timerRunning = false;
+		staEntry.sessionId = sessionId;
+		pTempStaEntry =
+			csr_roam_insert_entry_into_pe_stats_req_list(pMac,
+								     &pMac->roam.
+								     peStatsReqList,
+								     &staEntry);
+		if (!pTempStaEntry) {
+			/* msg */
+			sms_log(pMac, LOGW,
+				"csr_roam_check_pe_stats_req_list: Failed to insert req in peStatsReqList");
+			return NULL;
+		}
+	}
+	pTempStaEntry->periodicity =
+		pMac->roam.configParam.statsReqPeriodicityInPS;
+
+	if (!pTempStaEntry->timerRunning) {
+		/* send down a req in case of one time req, for periodic ones wait for timer to expire */
+		if (!pTempStaEntry->rspPending && !pTempStaEntry->periodicity) {
+			status = csr_send_mb_stats_req_msg(pMac,
+							   statsMask & ~(1 <<
+									 eCsrGlobalClassDStats),
+							   staId, sessionId);
+			if (!CDF_IS_STATUS_SUCCESS(status)) {
+				sms_log(pMac, LOGE,
+					FL
+						("csr_roam_check_pe_stats_req_list:failed to send down stats req to PE"));
+			} else {
+				pTempStaEntry->rspPending = true;
+			}
+		}
+		if (pTempStaEntry->periodicity) {
+			if (!found) {
+
+				cdf_status =
+					cdf_mc_timer_init(&pTempStaEntry->
+							  hPeStatsTimer,
+							  CDF_TIMER_TYPE_SW,
+							  csr_roam_pe_stats_timer_handler,
+							  pTempStaEntry);
+				if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+					sms_log(pMac, LOGE,
+						FL
+							("csr_roam_check_pe_stats_req_list:cannot init hPeStatsTimer timer"));
+					return NULL;
+				}
+			}
+			/* start timer */
+			sms_log(pMac, LOG1,
+				"csr_roam_check_pe_stats_req_list:peStatsTimer period %d",
+				pTempStaEntry->periodicity);
+			cdf_status =
+				cdf_mc_timer_start(&pTempStaEntry->hPeStatsTimer,
+						   pTempStaEntry->periodicity);
+			if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+				sms_log(pMac, LOGE,
+					FL
+						("csr_roam_check_pe_stats_req_list:cannot start hPeStatsTimer timer"));
+				return NULL;
+			}
+			pTempStaEntry->timerRunning = true;
+		}
+	}
+	*pFound = found;
+	return pTempStaEntry;
+}
+
+/*
+    pStaEntry is no longer invalid upon the return of this function.
+ */
+static void csr_roam_remove_stat_list_entry(tpAniSirGlobal pMac, tListElem *pEntry)
+{
+	if (pEntry) {
+		if (csr_ll_remove_entry
+			    (&pMac->roam.statsClientReqList, pEntry, LL_ACCESS_LOCK)) {
+			cdf_mem_free(GET_BASE_ADDR
+					     (pEntry, tCsrStatsClientReqInfo, link));
+		}
+	}
+}
+
+void csr_roam_remove_entry_from_pe_stats_req_list(tpAniSirGlobal pMac,
+						tCsrPeStatsReqInfo *pPeStaEntry)
+{
+	tListElem *pEntry;
+	tCsrPeStatsReqInfo *pTempStaEntry;
+	CDF_STATUS cdf_status;
+	pEntry = csr_ll_peek_head(&pMac->roam.peStatsReqList, LL_ACCESS_LOCK);
+	if (!pEntry) {
+		sms_log(pMac, LOGE, FL(" List empty, no stats req for PE"));
+		return;
+	}
+	while (pEntry) {
+		pTempStaEntry = GET_BASE_ADDR(pEntry, tCsrPeStatsReqInfo, link);
+		if (NULL == pTempStaEntry
+			|| (pTempStaEntry->statsMask !=
+				pPeStaEntry->statsMask)) {
+			pEntry = csr_ll_next(&pMac->roam.peStatsReqList, pEntry,
+					LL_ACCESS_NOLOCK);
+			continue;
+		}
+		sms_log(pMac, LOGW, FL("Match found"));
+		if (pTempStaEntry->timerRunning) {
+			cdf_status = cdf_mc_timer_stop(
+					&pTempStaEntry->hPeStatsTimer);
+			/*
+			 * If we are not able to stop the timer here, just
+			 * remove the entry from the linked list. Destroy the
+			 * timer object and free the memory in the timer CB
+			 */
+			if (cdf_status == CDF_STATUS_SUCCESS) {
+				/* the timer is successfully stopped */
+				pTempStaEntry->timerRunning = false;
+				/* Destroy the timer */
+				cdf_status = cdf_mc_timer_destroy(
+						&pTempStaEntry->hPeStatsTimer);
+			} else {
+				/*
+				 * the timer could not be stopped. Hence destroy
+				 * and free the memory for the PE stat entry in
+				 * the timer CB.
+				 */
+				pTempStaEntry->timerStopFailed = true;
+			}
+			if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+				sms_log(pMac, LOGE,
+					FL("failed to stop/destroy timer"));
+			}
+		}
+
+		if (csr_ll_remove_entry(&pMac->roam.peStatsReqList, pEntry,
+					LL_ACCESS_LOCK)) {
+			/*
+			 * Only free the memory if we could stop the timer
+			 * successfully
+			 */
+			if (!pTempStaEntry->timerStopFailed) {
+				cdf_mem_free(pTempStaEntry);
+				pTempStaEntry = NULL;
+			}
+			break;
+		}
+		pEntry = csr_ll_next(&pMac->roam.peStatsReqList, pEntry,
+				     LL_ACCESS_NOLOCK);
+	} /* end of while loop */
+	return;
+}
+
+void csr_roam_report_statistics(tpAniSirGlobal pMac, uint32_t statsMask,
+				tCsrStatsCallback callback, uint8_t staId,
+				void *pContext)
+{
+	uint8_t stats[500];
+	uint8_t *pStats = NULL;
+	uint32_t tempMask = 0;
+	uint8_t counter = 0;
+	if (!callback) {
+		sms_log(pMac, LOGE, FL("Cannot report callback NULL"));
+		return;
+	}
+	if (!statsMask) {
+		sms_log(pMac, LOGE, FL("Cannot report statsMask is 0"));
+		return;
+	}
+	pStats = stats;
+	tempMask = statsMask;
+	while (tempMask) {
+		if (tempMask & 1) {
+			/* new stats info from PE, fill up the stats strucutres in PMAC */
+			switch (counter) {
+			case eCsrSummaryStats:
+				sms_log(pMac, LOG2, FL("Summary stats"));
+				cdf_mem_copy(pStats,
+					     (uint8_t *) &pMac->roam.
+					     summaryStatsInfo,
+					     sizeof(tCsrSummaryStatsInfo));
+				pStats += sizeof(tCsrSummaryStatsInfo);
+				break;
+			case eCsrGlobalClassAStats:
+				sms_log(pMac, LOG2, FL("ClassA stats"));
+				cdf_mem_copy(pStats,
+					     (uint8_t *) &pMac->roam.
+					     classAStatsInfo,
+					     sizeof(tCsrGlobalClassAStatsInfo));
+				pStats += sizeof(tCsrGlobalClassAStatsInfo);
+				break;
+			case eCsrGlobalClassBStats:
+				sms_log(pMac, LOG2, FL("ClassB stats"));
+				cdf_mem_copy(pStats,
+					     (uint8_t *) &pMac->roam.
+					     classBStatsInfo,
+					     sizeof(tCsrGlobalClassBStatsInfo));
+				pStats += sizeof(tCsrGlobalClassBStatsInfo);
+				break;
+			case eCsrGlobalClassCStats:
+				sms_log(pMac, LOG2, FL("ClassC stats"));
+				cdf_mem_copy(pStats,
+					     (uint8_t *) &pMac->roam.
+					     classCStatsInfo,
+					     sizeof(tCsrGlobalClassCStatsInfo));
+				pStats += sizeof(tCsrGlobalClassCStatsInfo);
+				break;
+			case eCsrGlobalClassDStats:
+				sms_log(pMac, LOG2, FL("ClassD stats"));
+				cdf_mem_copy(pStats,
+					     (uint8_t *) &pMac->roam.
+					     classDStatsInfo,
+					     sizeof(tCsrGlobalClassDStatsInfo));
+				pStats += sizeof(tCsrGlobalClassDStatsInfo);
+				break;
+			case eCsrPerStaStats:
+				sms_log(pMac, LOG2, FL("PerSta stats"));
+				cdf_mem_copy(pStats,
+					     (uint8_t *) &pMac->roam.
+					     perStaStatsInfo[staId],
+					     sizeof(tCsrPerStaStatsInfo));
+				pStats += sizeof(tCsrPerStaStatsInfo);
+				break;
+			default:
+				sms_log(pMac, LOGE,
+					FL("Unknown stats type and counter %d"),
+					counter);
+				break;
+			}
+		}
+		tempMask >>= 1;
+		counter++;
+	}
+	callback(stats, pContext);
+}
+
+CDF_STATUS csr_roam_dereg_statistics_req(tpAniSirGlobal pMac)
+{
+	tListElem *pEntry = NULL;
+	tListElem *pPrevEntry = NULL;
+	tCsrStatsClientReqInfo *pTempStaEntry = NULL;
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	CDF_STATUS cdf_status;
+	pEntry = csr_ll_peek_head(&pMac->roam.statsClientReqList, LL_ACCESS_LOCK);
+	if (!pEntry) {
+		/* list empty */
+		sms_log(pMac, LOGW,
+			"csr_roam_dereg_statistics_req: List empty, no request from "
+			"upper layer client(s)");
+		return status;
+	}
+	while (pEntry) {
+		if (pPrevEntry) {
+			pTempStaEntry =
+				GET_BASE_ADDR(pPrevEntry, tCsrStatsClientReqInfo,
+					      link);
+			/* send up the stats report */
+			csr_roam_report_statistics(pMac, pTempStaEntry->statsMask,
+						   pTempStaEntry->callback,
+						   pTempStaEntry->staId,
+						   pTempStaEntry->pContext);
+			csr_roam_remove_stat_list_entry(pMac, pPrevEntry);
+		}
+		pTempStaEntry =
+			GET_BASE_ADDR(pEntry, tCsrStatsClientReqInfo, link);
+		if (pTempStaEntry->pPeStaEntry) {
+			/* pPeStaEntry can be NULL */
+			pTempStaEntry->pPeStaEntry->numClient--;
+			/* check if we need to delete the entry from peStatsReqList too */
+			if (!pTempStaEntry->pPeStaEntry->numClient) {
+				csr_roam_remove_entry_from_pe_stats_req_list(pMac,
+									     pTempStaEntry->
+									     pPeStaEntry);
+			}
+		}
+		/* check if we need to stop the tl stats timer too */
+		pMac->roam.tlStatsReqInfo.numClient--;
+		if (!pMac->roam.tlStatsReqInfo.numClient) {
+			if (pMac->roam.tlStatsReqInfo.timerRunning) {
+				status =
+					cdf_mc_timer_stop(&pMac->roam.
+							  tlStatsReqInfo.
+							  hTlStatsTimer);
+				if (!CDF_IS_STATUS_SUCCESS(status)) {
+					sms_log(pMac, LOGE,
+						FL
+							("csr_roam_dereg_statistics_req:cannot stop TlStatsTimer timer"));
+					/* we will continue */
+				}
+			}
+			pMac->roam.tlStatsReqInfo.periodicity = 0;
+			pMac->roam.tlStatsReqInfo.timerRunning = false;
+		}
+		if (pTempStaEntry->periodicity) {
+			/* While creating StaEntry in csr_get_statistics, */
+			/* Initializing and starting timer only when periodicity is set. */
+			/* So Stop and Destroy timer only when periodicity is set. */
+
+			cdf_mc_timer_stop(&pTempStaEntry->timer);
+			/* Destroy the cdf timer... */
+			cdf_status =
+				cdf_mc_timer_destroy(&pTempStaEntry->timer);
+			if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+				sms_log(pMac, LOGE,
+					FL
+						("csr_roam_dereg_statistics_req:failed to destroy Client req timer"));
+			}
+		}
+
+		pPrevEntry = pEntry;
+		pEntry =
+			csr_ll_next(&pMac->roam.statsClientReqList, pEntry,
+				    LL_ACCESS_NOLOCK);
+	}
+	/* the last one */
+	if (pPrevEntry) {
+		pTempStaEntry =
+			GET_BASE_ADDR(pPrevEntry, tCsrStatsClientReqInfo, link);
+		/* send up the stats report */
+		csr_roam_report_statistics(pMac, pTempStaEntry->statsMask,
+					   pTempStaEntry->callback,
+					   pTempStaEntry->staId,
+					   pTempStaEntry->pContext);
+		csr_roam_remove_stat_list_entry(pMac, pPrevEntry);
+	}
+	return status;
+
+}
+
+tSmeCmd *csr_get_command_buffer(tpAniSirGlobal pMac)
+{
+	tSmeCmd *pCmd = sme_get_command_buffer(pMac);
+	if (pCmd) {
+		pMac->roam.sPendingCommands++;
+	}
+	return pCmd;
+}
+
+void csr_release_command(tpAniSirGlobal pMac, tSmeCmd *pCommand)
+{
+	if (pMac->roam.sPendingCommands > 0) {
+		/* All command allocated through csr_get_command_buffer need to */
+		/* decrement the pending count when releasing. */
+		pMac->roam.sPendingCommands--;
+		sme_release_command(pMac, pCommand);
+	} else {
+		sms_log(pMac, LOGE, FL("no pending commands"));
+		CDF_ASSERT(0);
+	}
+}
+
+/* Return SUCCESS is the command is queued, failed */
+CDF_STATUS csr_queue_sme_command(tpAniSirGlobal pMac, tSmeCmd *pCommand,
+				 bool fHighPriority)
+{
+	bool fNoCmdPending;
+
+	if (!SME_IS_START(pMac)) {
+		sms_log(pMac, LOGE, FL("Sme in stop state"));
+		CDF_ASSERT(0);
+		return CDF_STATUS_E_PERM;
+	}
+
+	if ((eSmeCommandScan == pCommand->command) && pMac->scan.fDropScanCmd) {
+		sms_log(pMac, LOGW, FL(" drop scan (scan reason %d) command"),
+			pCommand->u.scanCmd.reason);
+		return CDF_STATUS_CSR_WRONG_STATE;
+	}
+
+	if ((pCommand->command == eSmeCommandScan)
+	    || (pCommand->command == eSmeCommandRemainOnChannel)) {
+		sms_log(pMac, LOGW,
+		FL("scan pending list count %d scan_id %d"),
+			pMac->sme.smeScanCmdPendingList.Count,
+			pCommand->u.scanCmd.scanID);
+		csr_ll_insert_tail(&pMac->sme.smeScanCmdPendingList,
+				   &pCommand->Link, LL_ACCESS_LOCK);
+		/* process the command queue... */
+		sme_process_pending_queue(pMac);
+		return CDF_STATUS_SUCCESS;
+	}
+	/* Make sure roamCmdPendingList is not empty first */
+	fNoCmdPending =
+		csr_ll_is_list_empty(&pMac->roam.roamCmdPendingList, false);
+	if (fNoCmdPending) {
+		sme_push_command(pMac, pCommand, fHighPriority);
+	} else {
+		/* no list lock is needed since SME lock is held */
+		if (!fHighPriority) {
+			csr_ll_insert_tail(&pMac->roam.roamCmdPendingList,
+					&pCommand->Link, false);
+		} else {
+			csr_ll_insert_head(&pMac->roam.roamCmdPendingList,
+					&pCommand->Link, false);
+		}
+	}
+	return CDF_STATUS_SUCCESS;
+}
+
+CDF_STATUS csr_roam_update_apwpsie(tpAniSirGlobal pMac, uint32_t sessionId,
+				   tSirAPWPSIEs *pAPWPSIES)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tSirUpdateAPWPSIEsReq *pMsg;
+
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+	if (NULL == pSession) {
+		sms_log(pMac, LOGE,
+			FL("  Session does not exist for session id %d"),
+			sessionId);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	do {
+		pMsg = cdf_mem_malloc(sizeof(tSirUpdateAPWPSIEsReq));
+		if (NULL == pMsg)
+			return CDF_STATUS_E_NOMEM;
+		cdf_mem_set(pMsg, sizeof(tSirUpdateAPWPSIEsReq), 0);
+		pMsg->messageType = eWNI_SME_UPDATE_APWPSIE_REQ;
+		pMsg->transactionId = 0;
+		cdf_mem_copy(pMsg->bssId, &pSession->selfMacAddr,
+				sizeof(tSirMacAddr));
+		pMsg->sessionId = sessionId;
+		cdf_mem_copy(&pMsg->APWPSIEs, pAPWPSIES,
+				sizeof(tSirAPWPSIEs));
+		pMsg->length = sizeof(struct sSirUpdateAPWPSIEsReq);
+		status = cds_send_mb_message_to_mac(pMsg);
+	} while (0);
+	return status;
+}
+
+CDF_STATUS csr_roam_update_wparsni_es(tpAniSirGlobal pMac, uint32_t sessionId,
+				      tSirRSNie *pAPSirRSNie)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tSirUpdateAPWPARSNIEsReq *pMsg;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+	if (NULL == pSession) {
+		sms_log(pMac, LOGE,
+			FL("  Session does not exist for session id %d"),
+			sessionId);
+		return CDF_STATUS_E_FAILURE;
+	}
+	do {
+		pMsg = cdf_mem_malloc(sizeof(tSirUpdateAPWPARSNIEsReq));
+		if (NULL == pMsg)
+			return CDF_STATUS_E_NOMEM;
+		cdf_mem_set(pMsg, sizeof(tSirUpdateAPWPARSNIEsReq), 0);
+		pMsg->messageType = eWNI_SME_SET_APWPARSNIEs_REQ;
+		pMsg->transactionId = 0;
+		cdf_mem_copy(pMsg->bssId, &pSession->selfMacAddr,
+				sizeof(tSirMacAddr));
+		pMsg->sessionId = sessionId;
+		cdf_mem_copy(&pMsg->APWPARSNIEs, pAPSirRSNie,
+			     sizeof(tSirRSNie));
+		pMsg->length = sizeof(struct sSirUpdateAPWPARSNIEsReq);
+		status = cds_send_mb_message_to_mac(pMsg);
+	} while (0);
+	return status;
+}
+
+#ifdef WLAN_FEATURE_VOWIFI_11R
+CDF_STATUS
+csr_roam_issue_ft_preauth_req(tHalHandle hHal, uint32_t sessionId,
+			      tpSirBssDescription pBssDescription)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	tpSirFTPreAuthReq pftPreAuthReq;
+	uint16_t auth_req_len = 0;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (NULL == pSession) {
+		sms_log(pMac, LOGE,
+			FL("Session does not exist for session id(%d)"),
+			sessionId);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	auth_req_len = sizeof(tSirFTPreAuthReq);
+	pftPreAuthReq = (tpSirFTPreAuthReq) cdf_mem_malloc(auth_req_len);
+	if (NULL == pftPreAuthReq) {
+		sms_log(pMac, LOGE,
+			FL("Memory allocation for FT Preauth request failed"));
+		return CDF_STATUS_E_NOMEM;
+	}
+	/* Save the SME Session ID here. We need it while processing the preauth response */
+	pSession->ftSmeContext.smeSessionId = sessionId;
+	cdf_mem_zero(pftPreAuthReq, auth_req_len);
+
+	pftPreAuthReq->pbssDescription =
+		(tpSirBssDescription) cdf_mem_malloc(sizeof(pBssDescription->length)
+						     + pBssDescription->length);
+	if (NULL == pftPreAuthReq->pbssDescription) {
+		sms_log(pMac, LOGE,
+			FL("Memory allocation for FT Preauth request failed"));
+		return CDF_STATUS_E_NOMEM;
+	}
+
+	pftPreAuthReq->messageType = eWNI_SME_FT_PRE_AUTH_REQ;
+
+	pftPreAuthReq->preAuthchannelNum = pBssDescription->channelId;
+
+	cdf_mem_copy((void *)&pftPreAuthReq->currbssId,
+		     (void *)pSession->connectedProfile.bssid.bytes,
+		     sizeof(tSirMacAddr));
+	cdf_mem_copy((void *)&pftPreAuthReq->preAuthbssId,
+		     (void *)pBssDescription->bssId, sizeof(tSirMacAddr));
+
+#ifdef WLAN_FEATURE_VOWIFI_11R
+	if (csr_roam_is11r_assoc(pMac, sessionId) &&
+	    (pMac->roam.roamSession[sessionId].connectedProfile.AuthType !=
+	     eCSR_AUTH_TYPE_OPEN_SYSTEM)) {
+		pftPreAuthReq->ft_ies_length =
+			(uint16_t) pSession->ftSmeContext.auth_ft_ies_length;
+		cdf_mem_copy(pftPreAuthReq->ft_ies,
+			     pSession->ftSmeContext.auth_ft_ies,
+			     pSession->ftSmeContext.auth_ft_ies_length);
+	} else
+#endif
+	{
+		pftPreAuthReq->ft_ies_length = 0;
+	}
+	cdf_mem_copy(pftPreAuthReq->pbssDescription, pBssDescription,
+		     sizeof(pBssDescription->length) + pBssDescription->length);
+	pftPreAuthReq->length = auth_req_len;
+	return cds_send_mb_message_to_mac(pftPreAuthReq);
+}
+
+/*--------------------------------------------------------------------------
+ * This will receive and process the FT Pre Auth Rsp from the current
+ * associated ap.
+ *
+ * This will invoke the hdd call back. This is so that hdd can now
+ * send the FTIEs from the Auth Rsp (Auth Seq 2) to the supplicant.
+   ------------------------------------------------------------------------*/
+void csr_roam_ft_pre_auth_rsp_processor(tHalHandle hHal,
+					tpSirFTPreAuthRsp pFTPreAuthRsp)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+#if defined(FEATURE_WLAN_LFR) || defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_ESE_UPLOAD)
+	tCsrRoamInfo roamInfo;
+#endif
+	eCsrAuthType conn_Auth_type;
+	uint32_t sessionId = pFTPreAuthRsp->smeSessionId;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (NULL == pSession) {
+		sms_log(pMac, LOGE, FL("pSession is NULL"));
+		return;
+	}
+#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
+	status =
+		csr_neighbor_roam_preauth_rsp_handler(pMac, pFTPreAuthRsp->smeSessionId,
+						      pFTPreAuthRsp->status);
+	if (status != CDF_STATUS_SUCCESS) {
+		/*
+		 * Bail out if pre-auth was not even processed.
+		 */
+		sms_log(pMac, LOGE,
+			FL("Preauth was not processed: %d SessionID: %d"),
+			status, sessionId);
+		return;
+	}
+#endif
+
+	/* The below function calls/timers should be invoked only if the pre-auth is successful */
+	if (CDF_STATUS_SUCCESS != (CDF_STATUS) pFTPreAuthRsp->status)
+		return;
+	/* Implies a success */
+	pSession->ftSmeContext.FTState = eFT_AUTH_COMPLETE;
+	/* Indicate SME QoS module the completion of Preauth success. This will trigger the creation of RIC IEs */
+	pSession->ftSmeContext.psavedFTPreAuthRsp = pFTPreAuthRsp;
+	/* No need to notify qos module if this is a non 11r & ESE roam */
+	if (csr_roam_is11r_assoc(pMac, pFTPreAuthRsp->smeSessionId)
+#if defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_ESE_UPLOAD)
+		 || csr_roam_is_ese_assoc(pMac, pFTPreAuthRsp->smeSessionId)
+#endif
+	) {
+		sme_qos_csr_event_ind(pMac,
+				      pSession->ftSmeContext.smeSessionId,
+				      SME_QOS_CSR_PREAUTH_SUCCESS_IND, NULL);
+	}
+	/* Start the pre-auth reassoc interval timer with a period of 400ms. When this expires,
+	 * actual transition from the current to handoff AP is triggered */
+	status =
+		cdf_mc_timer_start(&pSession->ftSmeContext.preAuthReassocIntvlTimer,
+				   60);
+	if (CDF_STATUS_SUCCESS != status) {
+		sms_log(pMac, LOGE,
+			FL
+				("Preauth reassoc interval timer start failed to start with status %d"),
+			status);
+		return;
+	}
+	/* Save the received response */
+	cdf_mem_copy((void *)&pSession->ftSmeContext.preAuthbssId,
+		     (void *)pFTPreAuthRsp->preAuthbssId, sizeof(struct cdf_mac_addr));
+	if (csr_roam_is11r_assoc(pMac, pFTPreAuthRsp->smeSessionId))
+		csr_roam_call_callback(pMac, pFTPreAuthRsp->smeSessionId, NULL, 0,
+				       eCSR_ROAM_FT_RESPONSE,
+				       eCSR_ROAM_RESULT_NONE);
+
+#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
+	if (csr_roam_is_ese_assoc(pMac, pFTPreAuthRsp->smeSessionId)) {
+		/* read TSF */
+		csr_roam_read_tsf(pMac, (uint8_t *) roamInfo.timestamp,
+				  pFTPreAuthRsp->smeSessionId);
+		/* Save the bssid from the received response */
+		cdf_mem_copy((void *)&roamInfo.bssid,
+			     (void *)pFTPreAuthRsp->preAuthbssId,
+			     sizeof(struct cdf_mac_addr));
+		csr_roam_call_callback(pMac, pFTPreAuthRsp->smeSessionId,
+				       &roamInfo, 0, eCSR_ROAM_CCKM_PREAUTH_NOTIFY,
+				       0);
+	}
+#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
+
+#ifdef FEATURE_WLAN_LFR
+	/* If Legacy Fast Roaming is enabled, signal the supplicant */
+	/* So he can send us a PMK-ID for this candidate AP. */
+	if (csr_roam_is_fast_roam_enabled(pMac, pFTPreAuthRsp->smeSessionId)) {
+		/* Save the bssid from the received response */
+		cdf_mem_copy((void *)&roamInfo.bssid,
+			     (void *)pFTPreAuthRsp->preAuthbssId,
+			     sizeof(struct cdf_mac_addr));
+		csr_roam_call_callback(pMac, pFTPreAuthRsp->smeSessionId,
+				       &roamInfo, 0, eCSR_ROAM_PMK_NOTIFY, 0);
+	}
+#endif
+
+	/* If its an Open Auth, FT IEs are not provided by supplicant */
+	/* Hence populate them here */
+	conn_Auth_type =
+		pMac->roam.roamSession[sessionId].connectedProfile.AuthType;
+
+	pSession->ftSmeContext.addMDIE = false;
+	if (csr_roam_is11r_assoc(pMac, pFTPreAuthRsp->smeSessionId) &&
+	    (conn_Auth_type == eCSR_AUTH_TYPE_OPEN_SYSTEM)) {
+		uint16_t ft_ies_length;
+		ft_ies_length = pFTPreAuthRsp->ric_ies_length;
+
+		if ((pSession->ftSmeContext.reassoc_ft_ies) &&
+		    (pSession->ftSmeContext.reassoc_ft_ies_length)) {
+			cdf_mem_free(pSession->ftSmeContext.reassoc_ft_ies);
+			pSession->ftSmeContext.reassoc_ft_ies_length = 0;
+			pSession->ftSmeContext.reassoc_ft_ies = NULL;
+		}
+
+		pSession->ftSmeContext.reassoc_ft_ies =
+			cdf_mem_malloc(ft_ies_length);
+		if (NULL == pSession->ftSmeContext.reassoc_ft_ies) {
+			sms_log(pMac, LOGE,
+				FL("Memory allocation failed for ft_ies"));
+			return;
+		} else {
+			/* Copy the RIC IEs to reassoc IEs */
+			cdf_mem_copy(((uint8_t *) pSession->ftSmeContext.
+				      reassoc_ft_ies),
+				     (uint8_t *) pFTPreAuthRsp->ric_ies,
+				     pFTPreAuthRsp->ric_ies_length);
+			pSession->ftSmeContext.reassoc_ft_ies_length =
+				ft_ies_length;
+			pSession->ftSmeContext.addMDIE = true;
+		}
+	}
+	/* Done with it, init it. */
+	pSession->ftSmeContext.psavedFTPreAuthRsp = NULL;
+}
+#endif
+
+
+/*
+   pBuf points to the beginning of the message
+   LIM packs disassoc rsp as below,
+      messageType - 2 bytes
+      messageLength - 2 bytes
+      sessionId - 1 byte
+      transactionId - 2 bytes (uint16_t)
+      reasonCode - 4 bytes (sizeof(tSirResultCodes))
+      peerMacAddr - 6 bytes
+      The rest is conditionally defined of (WNI_POLARIS_FW_PRODUCT == AP) and not used
+ */
+static void csr_ser_des_unpack_diassoc_rsp(uint8_t *pBuf, tSirSmeDisassocRsp *pRsp)
+{
+	if (pBuf && pRsp) {
+		pBuf += 4;      /* skip type and length */
+		pRsp->sessionId = *pBuf++;
+		cdf_get_u16(pBuf, (uint16_t *) &pRsp->transactionId);
+		pBuf += 2;
+		cdf_get_u32(pBuf, (uint32_t *) &pRsp->statusCode);
+		pBuf += 4;
+		cdf_mem_copy(pRsp->peerMacAddr, pBuf, 6);
+	}
+}
+
+/* Returns whether a session is in CDF_STA_MODE...or not */
+bool csr_roam_is_sta_mode(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	tCsrRoamSession *pSession = NULL;
+	pSession = CSR_GET_SESSION(pMac, sessionId);
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL(" %s: session %d not found "), __func__,
+			sessionId);
+		return false;
+	}
+	if (!CSR_IS_SESSION_VALID(pMac, sessionId)) {
+		sms_log(pMac, LOGE, FL(" %s: Inactive session"), __func__);
+		return false;
+	}
+	if (eCSR_BSS_TYPE_INFRASTRUCTURE != pSession->connectedProfile.BSSType) {
+		return false;
+	}
+	/* There is a possibility that the above check may fail,because
+	 * P2P CLI also uses the same BSSType (eCSR_BSS_TYPE_INFRASTRUCTURE)
+	 * when it is connected.So,we may sneak through the above check even
+	 * if we are not a STA mode INFRA station. So, if we sneak through
+	 * the above condition, we can use the following check if we are
+	 * really in STA Mode.*/
+
+	if (NULL != pSession->pCurRoamProfile) {
+		if (pSession->pCurRoamProfile->csrPersona == CDF_STA_MODE) {
+			return true;
+		} else {
+			sms_log(pMac, LOGE, FL(" %s: pCurRoamProfile is NULL\n"),
+				__func__);
+			return false;
+		}
+	}
+
+	return false;
+}
+
+CDF_STATUS csr_handoff_request(tpAniSirGlobal pMac,
+			       uint8_t sessionId,
+			       tCsrHandoffRequest *pHandoffInfo)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	cds_msg_t msg;
+
+	tAniHandoffReq *pMsg;
+	pMsg = cdf_mem_malloc(sizeof(tAniHandoffReq));
+	if (NULL == pMsg) {
+		sms_log(pMac, LOGE,
+			" csr_handoff_request: failed to allocate mem for req ");
+		return CDF_STATUS_E_NOMEM;
+	}
+	pMsg->msgType = eWNI_SME_HANDOFF_REQ;
+	pMsg->msgLen = (uint16_t) sizeof(tAniHandoffReq);
+	pMsg->sessionId = sessionId;
+	pMsg->channel = pHandoffInfo->channel;
+	pMsg->handoff_src = pHandoffInfo->src;
+	cdf_mem_copy(pMsg->bssid, pHandoffInfo->bssid.bytes, CDF_MAC_ADDR_SIZE);
+	msg.type = eWNI_SME_HANDOFF_REQ;
+	msg.bodyptr = pMsg;
+	msg.reserved = 0;
+	if (CDF_STATUS_SUCCESS != cds_mq_post_message(CDS_MQ_ID_SME, &msg)) {
+		sms_log(pMac, LOGE,
+			" csr_handoff_request failed to post msg to self ");
+		cdf_mem_free((void *)pMsg);
+		status = CDF_STATUS_E_FAILURE;
+	}
+	return status;
+}
+
+#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
+/* ---------------------------------------------------------------------------
+    \fn csr_set_cckm_ie
+    \brief  This function stores the CCKM IE passed by the supplicant
+    in a place holder data structure and this IE will be packed inside
+    reassociation request
+    \param  pMac - pMac global structure
+    \param  sessionId - Current session id
+    \param  pCckmIe - pointer to CCKM IE data
+    \param  ccKmIeLen - length of the CCKM IE
+   \- return Success or failure
+    -------------------------------------------------------------------------*/
+CDF_STATUS csr_set_cckm_ie(tpAniSirGlobal pMac, const uint8_t sessionId,
+			   const uint8_t *pCckmIe, const uint8_t ccKmIeLen)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("  session %d not found "), sessionId);
+		return CDF_STATUS_E_FAILURE;
+	}
+	cdf_mem_copy(pSession->suppCckmIeInfo.cckmIe, pCckmIe, ccKmIeLen);
+	pSession->suppCckmIeInfo.cckmIeLen = ccKmIeLen;
+	return status;
+}
+
+/* ---------------------------------------------------------------------------
+    \fn csr_roam_read_tsf
+    \brief  This function reads the TSF; and also add the time elapsed since
+    last beacon or probe response reception from the hand off AP to arrive at
+    the latest TSF value.
+    \param  pMac - pMac global structure
+    \param  pTimestamp - output TSF timestamp
+   \- return Success or failure
+    -------------------------------------------------------------------------*/
+CDF_STATUS csr_roam_read_tsf(tpAniSirGlobal pMac, uint8_t *pTimestamp,
+			     uint8_t sessionId)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tCsrNeighborRoamBSSInfo handoffNode;
+	uint32_t timer_diff = 0;
+	uint32_t timeStamp[2];
+	tpSirBssDescription pBssDescription = NULL;
+	csr_neighbor_roam_get_handoff_ap_info(pMac, &handoffNode, sessionId);
+	pBssDescription = handoffNode.pBssDescription;
+	/* Get the time diff in milli seconds */
+	timer_diff =
+		cdf_mc_timer_get_system_time() - pBssDescription->scanSysTimeMsec;
+	/* Convert msec to micro sec timer */
+	timer_diff = (uint32_t) (timer_diff * SYSTEM_TIME_MSEC_TO_USEC);
+	timeStamp[0] = pBssDescription->timeStamp[0];
+	timeStamp[1] = pBssDescription->timeStamp[1];
+	update_cckmtsf(&(timeStamp[0]), &(timeStamp[1]), &timer_diff);
+	cdf_mem_copy(pTimestamp, (void *)&timeStamp[0], sizeof(uint32_t) * 2);
+	return status;
+}
+#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
+
+/*
+ * Post Channel Change Request to LIM
+ * This API is primarily used to post
+ * Channel Change Req for SAP
+ */
+CDF_STATUS
+csr_roam_channel_change_req(tpAniSirGlobal pMac, struct cdf_mac_addr bssid,
+			    uint8_t cbMode, tCsrRoamProfile *profile)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tSirChanChangeRequest *pMsg;
+	tCsrRoamStartBssParams param;
+
+	csr_roam_get_bss_start_parms(pMac, profile, &param);
+	pMsg = cdf_mem_malloc(sizeof(tSirChanChangeRequest));
+	if (!pMsg) {
+		return CDF_STATUS_E_NOMEM;
+	}
+
+	cdf_mem_set((void *)pMsg, sizeof(tSirChanChangeRequest), 0);
+
+	pMsg->messageType = eWNI_SME_CHANNEL_CHANGE_REQ;
+	pMsg->messageLen = sizeof(tSirChanChangeRequest);
+	pMsg->targetChannel = profile->ChannelInfo.ChannelList[0];
+	pMsg->cbMode = cbMode;
+	pMsg->channel_width = profile->ch_params.ch_width;
+	pMsg->dot11mode = csr_translate_to_wni_cfg_dot11_mode(pMac,
+					pMac->roam.configParam.uCfgDot11Mode);
+	pMsg->center_freq_seg_0 = pMsg->targetChannel;
+	pMsg->center_freq_seg_1 = 0;
+	cdf_mem_copy(pMsg->bssid, bssid.bytes, CDF_MAC_ADDR_SIZE);
+	cdf_mem_copy(&pMsg->operational_rateset,
+		&param.operationalRateSet, sizeof(pMsg->operational_rateset));
+	cdf_mem_copy(&pMsg->extended_rateset,
+		&param.extendedRateSet, sizeof(pMsg->extended_rateset));
+	status = cds_send_mb_message_to_mac(pMsg);
+
+	return status;
+}
+
+/*
+ * Post Beacon Tx Start request to LIM
+ * immediately after SAP CAC WAIT is
+ * completed without any RADAR indications.
+ */
+CDF_STATUS csr_roam_start_beacon_req(tpAniSirGlobal pMac,
+				     struct cdf_mac_addr bssid,
+				     uint8_t dfsCacWaitStatus)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tSirStartBeaconIndication *pMsg;
+
+	pMsg = cdf_mem_malloc(sizeof(tSirStartBeaconIndication));
+
+	if (!pMsg) {
+		return CDF_STATUS_E_NOMEM;
+	}
+
+	cdf_mem_set((void *)pMsg, sizeof(tSirStartBeaconIndication), 0);
+	pMsg->messageType = eWNI_SME_START_BEACON_REQ;
+	pMsg->messageLen = sizeof(tSirStartBeaconIndication);
+	pMsg->beaconStartStatus = dfsCacWaitStatus;
+	cdf_mem_copy(pMsg->bssid, bssid.bytes, CDF_MAC_ADDR_SIZE);
+
+	status = cds_send_mb_message_to_mac(pMsg);
+
+	return status;
+}
+
+/*----------------------------------------------------------------------------
+   \fn csr_roam_modify_add_ies
+   \brief  This function sends msg to modify the additional IE buffers in PE
+   \param  pMac - pMac global structure
+   \param  pModifyIE - pointer to tSirModifyIE structure
+   \param  updateType - Type of buffer
+   \- return Success or failure
+   -----------------------------------------------------------------------------*/
+CDF_STATUS
+csr_roam_modify_add_ies(tpAniSirGlobal pMac,
+			 tSirModifyIE *pModifyIE, eUpdateIEsType updateType)
+{
+	tpSirModifyIEsInd pModifyAddIEInd = NULL;
+	uint8_t *pLocalBuffer = NULL;
+	CDF_STATUS status;
+
+	/* following buffer will be freed by consumer (PE) */
+	pLocalBuffer = cdf_mem_malloc(pModifyIE->ieBufferlength);
+
+	if (NULL == pLocalBuffer) {
+		sms_log(pMac, LOGE, FL("Memory Allocation Failure!!!"));
+		return CDF_STATUS_E_NOMEM;
+	}
+
+	pModifyAddIEInd = cdf_mem_malloc(sizeof(tSirModifyIEsInd));
+	if (NULL == pModifyAddIEInd) {
+		sms_log(pMac, LOGE, FL("Memory Allocation Failure!!!"));
+		cdf_mem_free(pLocalBuffer);
+		return CDF_STATUS_E_NOMEM;
+	}
+
+	/*copy the IE buffer */
+	cdf_mem_copy(pLocalBuffer, pModifyIE->pIEBuffer,
+		     pModifyIE->ieBufferlength);
+	cdf_mem_zero(pModifyAddIEInd, sizeof(tSirModifyIEsInd));
+
+	pModifyAddIEInd->msgType = eWNI_SME_MODIFY_ADDITIONAL_IES;
+	pModifyAddIEInd->msgLen = sizeof(tSirModifyIEsInd);
+
+	cdf_mem_copy(pModifyAddIEInd->modifyIE.bssid, pModifyIE->bssid,
+		     sizeof(tSirMacAddr));
+
+	pModifyAddIEInd->modifyIE.smeSessionId = pModifyIE->smeSessionId;
+	pModifyAddIEInd->modifyIE.notify = pModifyIE->notify;
+	pModifyAddIEInd->modifyIE.ieID = pModifyIE->ieID;
+	pModifyAddIEInd->modifyIE.ieIDLen = pModifyIE->ieIDLen;
+	pModifyAddIEInd->modifyIE.pIEBuffer = pLocalBuffer;
+	pModifyAddIEInd->modifyIE.ieBufferlength = pModifyIE->ieBufferlength;
+
+	pModifyAddIEInd->updateType = updateType;
+
+	status = cds_send_mb_message_to_mac(pModifyAddIEInd);
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		sms_log(pMac, LOGE,
+			FL("Failed to send eWNI_SME_UPDATE_ADDTIONAL_IES msg"
+			   "!!! status %d"), status);
+		cdf_mem_free(pLocalBuffer);
+	}
+	return status;
+}
+
+/*----------------------------------------------------------------------------
+   \fn csr_roam_update_add_ies
+   \brief  This function sends msg to updates the additional IE buffers in PE
+   \param  pMac - pMac global structure
+   \param  sessionId - SME session id
+   \param  bssid - BSSID
+   \param  additionIEBuffer - buffer containing addition IE from hostapd
+   \param  length - length of buffer
+   \param  updateType - Type of buffer
+   \param  append - append or replace completely
+   \- return Success or failure
+   -----------------------------------------------------------------------------*/
+CDF_STATUS
+csr_roam_update_add_ies(tpAniSirGlobal pMac,
+			 tSirUpdateIE *pUpdateIE, eUpdateIEsType updateType)
+{
+	tpSirUpdateIEsInd pUpdateAddIEs = NULL;
+	uint8_t *pLocalBuffer = NULL;
+	CDF_STATUS status;
+
+	if (pUpdateIE->ieBufferlength != 0) {
+		/* Following buffer will be freed by consumer (PE) */
+		pLocalBuffer = cdf_mem_malloc(pUpdateIE->ieBufferlength);
+		if (NULL == pLocalBuffer) {
+			sms_log(pMac, LOGE, FL("Memory Allocation Failure!!!"));
+			return CDF_STATUS_E_NOMEM;
+		}
+		cdf_mem_copy(pLocalBuffer, pUpdateIE->pAdditionIEBuffer,
+			     pUpdateIE->ieBufferlength);
+	}
+
+	pUpdateAddIEs = cdf_mem_malloc(sizeof(tSirUpdateIEsInd));
+	if (NULL == pUpdateAddIEs) {
+		sms_log(pMac, LOGE, FL("Memory Allocation Failure!!!"));
+		if (pLocalBuffer != NULL) {
+			cdf_mem_free(pLocalBuffer);
+		}
+		return CDF_STATUS_E_NOMEM;
+	}
+
+	cdf_mem_zero(pUpdateAddIEs, sizeof(tSirUpdateIEsInd));
+
+	pUpdateAddIEs->msgType = eWNI_SME_UPDATE_ADDITIONAL_IES;
+	pUpdateAddIEs->msgLen = sizeof(tSirUpdateIEsInd);
+
+	cdf_mem_copy(pUpdateAddIEs->updateIE.bssid, pUpdateIE->bssid,
+		     sizeof(tSirMacAddr));
+
+	pUpdateAddIEs->updateIE.smeSessionId = pUpdateIE->smeSessionId;
+	pUpdateAddIEs->updateIE.append = pUpdateIE->append;
+	pUpdateAddIEs->updateIE.notify = pUpdateIE->notify;
+	pUpdateAddIEs->updateIE.ieBufferlength = pUpdateIE->ieBufferlength;
+	pUpdateAddIEs->updateIE.pAdditionIEBuffer = pLocalBuffer;
+
+	pUpdateAddIEs->updateType = updateType;
+
+	status = cds_send_mb_message_to_mac(pUpdateAddIEs);
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		sms_log(pMac, LOGE,
+			FL("Failed to send eWNI_SME_UPDATE_ADDTIONAL_IES msg"
+			   "!!! status %d"), status);
+		cdf_mem_free(pLocalBuffer);
+	}
+	return status;
+}
+
+/**
+ * csr_roam_send_chan_sw_ie_request() - Request to transmit CSA IE
+ * @mac_ctx:        Global MAC context
+ * @bssid:          BSSID
+ * @target_channel: Channel on which to send the IE
+ * @csa_ie_reqd:    Include/Exclude CSA IE.
+ * @ch_bandwidth:   Channel offset
+ *
+ * This function sends request to transmit channel switch announcement
+ * IE to lower layers
+ *
+ * Return: success or failure
+ **/
+CDF_STATUS
+csr_roam_send_chan_sw_ie_request(tpAniSirGlobal mac_ctx,
+		struct cdf_mac_addr bssid, uint8_t target_channel,
+		uint8_t csa_ie_reqd, uint8_t ch_bandwidth)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tSirDfsCsaIeRequest *msg;
+
+	msg = cdf_mem_malloc(sizeof(tSirDfsCsaIeRequest));
+	if (!msg) {
+		return CDF_STATUS_E_NOMEM;
+	}
+
+	cdf_mem_set((void *)msg, sizeof(tSirDfsCsaIeRequest), 0);
+	msg->msgType = eWNI_SME_DFS_BEACON_CHAN_SW_IE_REQ;
+	msg->msgLen = sizeof(tSirDfsCsaIeRequest);
+
+	msg->targetChannel = target_channel;
+	msg->csaIeRequired = csa_ie_reqd;
+	cdf_mem_copy(msg->bssid, bssid.bytes, CDF_MAC_ADDR_SIZE);
+	msg->ch_bandwidth = ch_bandwidth;
+
+	status = cds_send_mb_message_to_mac(msg);
+
+	return status;
+}
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+/*----------------------------------------------------------------------------
+* fn     csr_process_roam_offload_synch_ind
+* brief  This will process the roam synch indication received from
+*        lower layers.This function also calls another API to
+*        parse the beacon IE and fill the appropriate fields
+* param  pMac - pMac global structure
+* param  pMsgBuf - Message buffer received from lower layers
+* --------------------------------------------------------------------------*/
+void csr_process_roam_offload_synch_ind(tHalHandle hHal,
+		roam_offload_synch_ind *roam_synch_ind_ptr)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	tCsrRoamSession *session_ptr = NULL;
+	uint8_t session_id = roam_synch_ind_ptr->roamedVdevId;
+	session_ptr =  CSR_GET_SESSION(pMac, roam_synch_ind_ptr->roamedVdevId);
+	if (!session_ptr) {
+		sms_log(pMac, LOGE, FL("LFR3: session %d not found "),
+				roam_synch_ind_ptr->roamedVdevId);
+		goto err_synch_rsp;
+	}
+	if (!CDF_IS_STATUS_SUCCESS(csr_scan_save_roam_offload_ap_to_scan_cache(
+					pMac, roam_synch_ind_ptr))) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+				"fail to save roam offload AP to scan cache");
+		goto err_synch_rsp;
+	}
+	session_ptr->roamOffloadSynchParams.rssi = roam_synch_ind_ptr->rssi;
+	session_ptr->roamOffloadSynchParams.roamReason =
+		roam_synch_ind_ptr->roamReason;
+	session_ptr->roamOffloadSynchParams.roamedVdevId =
+		roam_synch_ind_ptr->roamedVdevId;
+	cdf_mem_copy(session_ptr->roamOffloadSynchParams.bssid,
+			roam_synch_ind_ptr->bssId, sizeof(tSirMacAddr));
+	session_ptr->roamOffloadSynchParams.txMgmtPower =
+		roam_synch_ind_ptr->txMgmtPower;
+	session_ptr->roamOffloadSynchParams.authStatus =
+		roam_synch_ind_ptr->authStatus;
+	session_ptr->roamOffloadSynchParams.bRoamSynchInProgress = true;
+	/*Save the BSS descriptor for later use*/
+	session_ptr->roamOffloadSynchParams.bss_desc_ptr =
+		roam_synch_ind_ptr->bss_desc_ptr;
+	pMac->roam.reassocRespLen = roam_synch_ind_ptr->reassocRespLength;
+	pMac->roam.pReassocResp =
+		cdf_mem_malloc(pMac->roam.reassocRespLen);
+	if (NULL == pMac->roam.pReassocResp) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+				"Memory allocation for reassoc response failed");
+		goto err_synch_rsp;
+	}
+	cdf_mem_copy(pMac->roam.pReassocResp,
+			(uint8_t *)roam_synch_ind_ptr +
+			roam_synch_ind_ptr->reassocRespOffset,
+			pMac->roam.reassocRespLen);
+
+	CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
+			"LFR3:%s: the reassoc resp frame data:", __func__);
+	CDF_TRACE_HEX_DUMP(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
+			pMac->roam.pReassocResp, pMac->roam.reassocRespLen);
+
+	cdf_mem_copy(session_ptr->roamOffloadSynchParams.kck,
+			roam_synch_ind_ptr->kck, SIR_KCK_KEY_LEN);
+	cdf_mem_copy(session_ptr->roamOffloadSynchParams.kek,
+			roam_synch_ind_ptr->kek, SIR_KEK_KEY_LEN);
+	cdf_mem_copy(session_ptr->roamOffloadSynchParams.replay_ctr,
+			roam_synch_ind_ptr->replay_ctr, SIR_REPLAY_CTR_LEN);
+	if (CDF_STATUS_SUCCESS != csr_neighbor_roam_offload_update_preauth_list(
+					pMac, roam_synch_ind_ptr, session_id)) {
+		/**
+		 *Bail out if Roam Offload Synch Response was not even handled.
+		 **/
+		sms_log(pMac, LOGE, FL("Roam Offload Synch Response "
+					"was not processed"));
+		goto err_synch_rsp;
+	}
+
+	csr_neighbor_roam_request_handoff(pMac, session_id);
+
+err_synch_rsp:
+	cdf_mem_free(roam_synch_ind_ptr->bss_desc_ptr);
+	roam_synch_ind_ptr->bss_desc_ptr = NULL;
+}
+
+/*----------------------------------------------------------------------------
+* fn csr_process_ho_fail_ind
+* brief  This function will process the Hand Off Failure indication
+*        received from the firmware. It will trigger a disconnect on
+*        the session which the firmware reported a hand off failure
+* param  pMac global structure
+* param  pMsgBuf - Contains the session ID for which the handler should apply
+* --------------------------------------------------------------------------*/
+void csr_process_ho_fail_ind(tpAniSirGlobal pMac, void *pMsgBuf)
+{
+	tSirSmeHOFailureInd *pSmeHOFailInd = (tSirSmeHOFailureInd *) pMsgBuf;
+	uint32_t sessionId;
+
+	if (pSmeHOFailInd)
+		sessionId = pSmeHOFailInd->sessionId;
+	else {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+			  "LFR3: Hand-Off Failure Ind is NULL");
+		return;
+	}
+	/* Roaming is supported only on Infra STA Mode. */
+	if (!csr_roam_is_sta_mode(pMac, sessionId)) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+			  "LFR3:HO Fail cannot be handled for session %d",
+			  sessionId);
+		return;
+	}
+	csr_roam_synch_clean_up(pMac, sessionId);
+	CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+		  "LFR3:Issue Disconnect on session %d", sessionId);
+	csr_roam_disconnect(pMac, sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED);
+}
+#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
+
+/**
+ * csr_update_op_class_array() - update op class for each band
+ * @mac_ctx:          mac global context
+ * @op_classes:       out param, operating class array to update
+ * @channel_info:     channel info
+ * @ch_name:          channel band name to display in debug messages
+ * @i:                out param, stores number of operating classes
+ *
+ * Return: void
+ */
+static void
+csr_update_op_class_array(tpAniSirGlobal mac_ctx,
+			  uint8_t *op_classes,
+			  tCsrChannel *channel_info,
+			  char *ch_name,
+			  uint8_t *i)
+{
+	uint8_t j = 0, idx = 0, class = 0;
+	bool found = false;
+	uint8_t num_channels = channel_info->numChannels;
+
+	sms_log(mac_ctx, LOG1,
+		FL("Num of %s channels,  %d"),
+		ch_name, num_channels);
+
+	for (idx = 0; idx < num_channels
+		&& *i < (SIR_MAC_MAX_SUPP_OPER_CLASSES - 1); idx++) {
+		class = cds_regdm_get_opclass_from_channel(
+				mac_ctx->scan.countryCodeCurrent,
+				channel_info->channelList[idx],
+				BWALL);
+		sms_log(mac_ctx, LOG4, FL("for chan %d, op class: %d"),
+			channel_info->channelList[idx], class);
+
+		found = false;
+		for (j = 0; j < SIR_MAC_MAX_SUPP_OPER_CLASSES - 1; j++) {
+			if (op_classes[j] == class) {
+				found = true;
+				break;
+			}
+		}
+		if (!found) {
+			op_classes[*i] = class;
+			*i = *i + 1;
+		}
+	}
+}
+
+/**
+ * csr_update_op_class_array() - update op class for all bands
+ * @hHal:          global hal context
+ *
+ * Return: void
+ */
+void csr_init_operating_classes(tHalHandle hHal)
+{
+	uint8_t i = 0;
+	uint8_t j = 0;
+	uint8_t swap = 0;
+	uint8_t numClasses = 0;
+	uint8_t opClasses[SIR_MAC_MAX_SUPP_OPER_CLASSES] = {0,};
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	sms_log(pMac, LOG1, FL("Current Country = %c%c"),
+		pMac->scan.countryCodeCurrent[0],
+		pMac->scan.countryCodeCurrent[1]);
+
+	csr_update_op_class_array(pMac, opClasses,
+				  &pMac->scan.base_channels, "20MHz", &i);
+	csr_update_op_class_array(pMac, opClasses,
+				  &pMac->scan.base40MHzChannels, "40MHz", &i);
+	numClasses = i;
+
+	/* As per spec the operating classes should be in ascending order.
+	 * Bubble sort is fine since we don't have many classes
+	 */
+	for (i = 0; i < (numClasses - 1); i++) {
+		for (j = 0; j < (numClasses - i - 1); j++) {
+			/* For decreasing order use < */
+			if (opClasses[j] > opClasses[j + 1]) {
+				swap = opClasses[j];
+				opClasses[j] = opClasses[j + 1];
+				opClasses[j + 1] = swap;
+			}
+		}
+	}
+
+	sms_log(pMac, LOG1, FL("Number of unique supported op classes %d"),
+		numClasses);
+	for (i = 0; i < numClasses; i++) {
+		sms_log(pMac, LOG1, FL("supported opClasses[%d] = %d"), i,
+			opClasses[i]);
+	}
+
+	/* Set the ordered list of op classes in regdomain
+	 * for use by other modules
+	 */
+	cds_regdm_set_curr_opclasses(numClasses, &opClasses[0]);
+}
+
+/**
+ * csr_find_session_by_type() - This function will find given session type from
+ * all sessions.
+ * @mac_ctx: pointer to mac context.
+ * @type:    session type
+ *
+ * Return: session id for give session type.
+ **/
+static uint32_t
+csr_find_session_by_type(tpAniSirGlobal mac_ctx, tCDF_CON_MODE type)
+{
+	uint32_t i, session_id = CSR_SESSION_ID_INVALID;
+	tCsrRoamSession *session_ptr;
+	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
+		if (!CSR_IS_SESSION_VALID(mac_ctx, i))
+			continue;
+
+		session_ptr = CSR_GET_SESSION(mac_ctx, i);
+		if (type == session_ptr->bssParams.bssPersona) {
+			session_id = i;
+			break;
+		}
+	}
+	return session_id;
+}
+/**
+ * csr_is_conn_allow_2g_band() - This function will check if station's conn
+ * is allowed in 2.4Ghz band.
+ * @mac_ctx: pointer to mac context.
+ * @chnl: station's channel.
+ *
+ * This function will check if station's connection is allowed in 5Ghz band
+ * after comparing it with SAP's operating channel. If SAP's operating
+ * channel and Station's channel is different than this function will return
+ * false else true.
+ *
+ * Return: true or false.
+ **/
+static bool csr_is_conn_allow_2g_band(tpAniSirGlobal mac_ctx, uint32_t chnl)
+{
+	uint32_t sap_session_id;
+	tCsrRoamSession *sap_session;
+
+	if (0 == chnl) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+				FL("channel is zero, connection not allowed"));
+
+		return false;
+	}
+
+	sap_session_id = csr_find_session_by_type(mac_ctx, CDF_SAP_MODE);
+	if (CSR_SESSION_ID_INVALID != sap_session_id) {
+		sap_session = CSR_GET_SESSION(mac_ctx, sap_session_id);
+		if ((0 != sap_session->bssParams.operationChn) &&
+				(sap_session->bssParams.operationChn != chnl)) {
+
+			CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+				FL
+				("Can't allow STA to connect, chnls not same"));
+			return false;
+		}
+	}
+	return true;
+}
+
+/**
+ * csr_is_conn_allow_5g_band() - This function will check if station's conn
+ * is allowed in 5Ghz band.
+ * @mac_ctx: pointer to mac context.
+ * @chnl: station's channel.
+ *
+ * This function will check if station's connection is allowed in 5Ghz band
+ * after comparing it with P2PGO's operating channel. If P2PGO's operating
+ * channel and Station's channel is different than this function will return
+ * false else true.
+ *
+ * Return: true or false.
+ **/
+static bool csr_is_conn_allow_5g_band(tpAniSirGlobal mac_ctx, uint32_t chnl)
+{
+	uint32_t p2pgo_session_id;
+	tCsrRoamSession *p2pgo_session;
+
+	if (0 == chnl) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+				FL
+				("channel is zero, connection not allowed"));
+		return false;
+	}
+
+	p2pgo_session_id = csr_find_session_by_type(mac_ctx, CDF_P2P_GO_MODE);
+	if (CSR_SESSION_ID_INVALID != p2pgo_session_id) {
+		p2pgo_session = CSR_GET_SESSION(mac_ctx, p2pgo_session_id);
+		if ((0 != p2pgo_session->bssParams.operationChn) &&
+				(eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED !=
+				 p2pgo_session->connectState) &&
+				(p2pgo_session->bssParams.operationChn !=
+				 chnl)) {
+
+			CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+				FL
+				("Can't allow STA to connect, chnls not same"));
+			return false;
+		}
+	}
+	return true;
+}
+
+/**
+ * csr_clear_joinreq_param() - This function will clear station's params
+ * for stored join request to csr.
+ * @hal_handle: pointer to hal context.
+ * @session_id: station's session id.
+ *
+ * This function will clear station's allocated memory for cached join
+ * request.
+ *
+ * Return: true or false based on function's overall success.
+ **/
+bool csr_clear_joinreq_param(tpAniSirGlobal mac_ctx,
+		uint32_t session_id)
+{
+	tCsrRoamSession *sta_session;
+	tScanResultList *bss_list;
+
+	if (NULL == mac_ctx)
+		return false;
+
+	sta_session = CSR_GET_SESSION(mac_ctx, session_id);
+	if (NULL == sta_session)
+		return false;
+
+	/* Release the memory allocated by previous join request */
+	bss_list =
+		(tScanResultList *)&sta_session->stored_roam_profile.
+		bsslist_handle;
+	if (NULL != bss_list) {
+		csr_scan_result_purge(mac_ctx,
+			sta_session->stored_roam_profile.bsslist_handle);
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
+			FL("bss list is released for session %d"), session_id);
+		sta_session->stored_roam_profile.bsslist_handle = NULL;
+	}
+	sta_session->stored_roam_profile.bsslist_handle = NULL;
+	csr_release_profile(mac_ctx, &sta_session->stored_roam_profile.profile);
+	sta_session->stored_roam_profile.reason = 0;
+	sta_session->stored_roam_profile.roam_id = 0;
+	sta_session->stored_roam_profile.imediate_flag = false;
+	sta_session->stored_roam_profile.clear_flag = false;
+	return true;
+}
+
+/**
+ * csr_store_joinreq_param() - This function will store station's join
+ * request to that station's session.
+ * @mac_ctx: pointer to mac context.
+ * @profile: pointer to station's roam profile.
+ * @scan_cache: pointer to station's scan cache.
+ * @roam_id: reference to roam_id variable being passed.
+ * @session_id: station's session id.
+ *
+ * This function will store station's join request to one of the
+ * csr structure and add it to station's session.
+ *
+ * Return: true or false based on function's overall success.
+ **/
+bool csr_store_joinreq_param(tpAniSirGlobal mac_ctx,
+		tCsrRoamProfile *profile,
+		tScanResultHandle scan_cache,
+		uint32_t *roam_id,
+		uint32_t session_id)
+{
+	tCsrRoamSession *sta_session;
+
+	if (NULL == mac_ctx)
+		return false;
+
+	sta_session = CSR_GET_SESSION(mac_ctx, session_id);
+	if (NULL == sta_session)
+		return false;
+
+	sta_session->stored_roam_profile.session_id = session_id;
+	csr_roam_copy_profile(mac_ctx,
+			&sta_session->stored_roam_profile.profile, profile);
+	/* new bsslist_handle's memory will be relased later */
+	sta_session->stored_roam_profile.bsslist_handle = scan_cache;
+	sta_session->stored_roam_profile.reason = eCsrHddIssued;
+	sta_session->stored_roam_profile.roam_id = *roam_id;
+	sta_session->stored_roam_profile.imediate_flag = false;
+	sta_session->stored_roam_profile.clear_flag = false;
+
+	return true;
+}
+
+/**
+ * csr_issue_stored_joinreq() - This function will issues station's stored
+ * the join request.
+ * @mac_ctx: pointer to mac context.
+ * @roam_id: reference to roam_id variable being passed.
+ * @session_id: station's session id.
+ *
+ * This function will issue station's stored join request, from this point
+ * onwards the flow will be just like normal connect request.
+ *
+ * Return: CDF_STATUS_SUCCESS or CDF_STATUS_E_FAILURE.
+ **/
+CDF_STATUS csr_issue_stored_joinreq(tpAniSirGlobal mac_ctx,
+		uint32_t *roam_id,
+		uint32_t session_id)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tCsrRoamSession *sta_session;
+	uint32_t new_roam_id;
+
+	sta_session = CSR_GET_SESSION(mac_ctx, session_id);
+	if (NULL == sta_session)
+		return CDF_STATUS_E_FAILURE;
+	new_roam_id = GET_NEXT_ROAM_ID(&mac_ctx->roam);
+	*roam_id = new_roam_id;
+	status = csr_roam_issue_connect(mac_ctx,
+			sta_session->stored_roam_profile.session_id,
+			&sta_session->stored_roam_profile.profile,
+			sta_session->stored_roam_profile.bsslist_handle,
+			sta_session->stored_roam_profile.reason,
+			new_roam_id,
+			sta_session->stored_roam_profile.imediate_flag,
+			sta_session->stored_roam_profile.clear_flag);
+	if (CDF_STATUS_SUCCESS != status) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+			FL
+			("CSR failed issuing connect cmd with status = 0x%08X"),
+				status);
+		csr_clear_joinreq_param(mac_ctx, session_id);
+	}
+	return status;
+}
+
+/**
+ * csr_process_set_hw_mode() - Set HW mode command to PE
+ * @mac: Globacl MAC pointer
+ * @command: Command received from SME
+ *
+ * Posts the set HW mode command to PE. This message passing
+ * through PE is required for PE's internal management
+ *
+ * Return: None
+ */
+void csr_process_set_hw_mode(tpAniSirGlobal mac, tSmeCmd *command)
+{
+	uint32_t len;
+	struct s_sir_set_hw_mode *cmd;
+	CDF_STATUS status;
+	tSirMsgQ msg;
+	struct sir_set_hw_mode_resp *param;
+
+	/* Setting HW mode is for the entire system.
+	 * So, no need to check session
+	 */
+
+	if (!command) {
+		sms_log(mac, LOGE, FL("Set HW mode param is NULL"));
+		goto fail;
+	}
+
+	len = sizeof(*cmd);
+	cmd = cdf_mem_malloc(len);
+	if (!cmd) {
+		sms_log(mac, LOGE, FL("Memory allocation failed"));
+		/* Probably the fail response will also fail during malloc.
+		 * Still proceeding to send response!
+		 */
+		goto fail;
+	}
+
+	cdf_mem_set(cmd, len, 0);
+
+	cmd->messageType = eWNI_SME_SET_HW_MODE_REQ;
+	cmd->length = len;
+	cmd->set_hw.hw_mode_index = command->u.set_hw_mode_cmd.hw_mode_index;
+	/*
+	 * Below callback and context info are not needed for PE as of now.
+	 * Storing the passed value in the same s_sir_set_hw_mode format.
+	 */
+	cmd->set_hw.set_hw_mode_cb = command->u.set_hw_mode_cmd.set_hw_mode_cb;
+
+	sms_log(mac, LOG1,
+		FL("Posting eWNI_SME_SET_HW_MODE_REQ to PE"));
+
+	status = cds_send_mb_message_to_mac(cmd);
+	if (CDF_STATUS_SUCCESS != status) {
+		sms_log(mac, LOGE, FL("Posting to PE failed"));
+		return;
+	}
+	return;
+fail:
+	param = cdf_mem_malloc(sizeof(*param));
+	if (!param) {
+		sms_log(mac, LOGE,
+			FL("Malloc fail: Fail to send response to SME"));
+		return;
+	}
+	sms_log(mac, LOGE, FL("Sending set HW fail response to SME"));
+	param->status = SET_HW_MODE_STATUS_ECANCELED;
+	param->cfgd_hw_mode_index = 0;
+	param->num_vdev_mac_entries = 0;
+	msg.type = eWNI_SME_SET_HW_MODE_RESP;
+	msg.bodyptr = param;
+	msg.bodyval = 0;
+	sys_process_mmh_msg(mac, &msg);
+}
+
+/**
+ * csr_process_set_dual_mac_config() - Set HW mode command to PE
+ * @mac: Global MAC pointer
+ * @command: Command received from SME
+ *
+ * Posts the set dual mac config command to PE.
+ *
+ * Return: None
+ */
+void csr_process_set_dual_mac_config(tpAniSirGlobal mac, tSmeCmd *command)
+{
+	uint32_t len;
+	struct sir_set_dual_mac_cfg *cmd;
+	CDF_STATUS status;
+	tSirMsgQ msg;
+	struct sir_dual_mac_config_resp *param;
+
+	/* Setting MAC configuration is for the entire system.
+	 * So, no need to check session
+	 */
+
+	if (!command) {
+		sms_log(mac, LOGE, FL("Set HW mode param is NULL"));
+		goto fail;
+	}
+
+	len = sizeof(*cmd);
+	cmd = cdf_mem_malloc(len);
+	if (!cmd) {
+		sms_log(mac, LOGE, FL("Memory allocation failed"));
+		/* Probably the fail response will also fail during malloc.
+		 * Still proceeding to send response!
+		 */
+		goto fail;
+	}
+
+	cmd->message_type = eWNI_SME_SET_DUAL_MAC_CFG_REQ;
+	cmd->length = len;
+	cmd->set_dual_mac.scan_config = command->u.set_dual_mac_cmd.scan_config;
+	cmd->set_dual_mac.fw_mode_config =
+		command->u.set_dual_mac_cmd.fw_mode_config;
+	/*
+	 * Below callback and context info are not needed for PE as of now.
+	 * Storing the passed value in the same sir_set_dual_mac_cfg format.
+	 */
+	cmd->set_dual_mac.set_dual_mac_cb =
+		command->u.set_dual_mac_cmd.set_dual_mac_cb;
+
+	sms_log(mac, LOG1,
+		FL("Posting eWNI_SME_SET_DUAL_MAC_CFG_REQ to PE: %x %x"),
+		cmd->set_dual_mac.scan_config,
+		cmd->set_dual_mac.fw_mode_config);
+
+	status = cds_send_mb_message_to_mac(cmd);
+	if (CDF_STATUS_SUCCESS != status) {
+		sms_log(mac, LOGE, FL("Posting to PE failed"));
+		return;
+	}
+	return;
+fail:
+	param = cdf_mem_malloc(sizeof(*param));
+	if (!param) {
+		sms_log(mac, LOGE,
+			FL("Malloc fail: Fail to send response to SME"));
+		return;
+	}
+	sms_log(mac, LOGE, FL("Sending set dual mac fail response to SME"));
+	param->status = SET_HW_MODE_STATUS_ECANCELED;
+	msg.type = eWNI_SME_SET_DUAL_MAC_CFG_RESP;
+	msg.bodyptr = param;
+	msg.bodyval = 0;
+	sys_process_mmh_msg(mac, &msg);
+}
+
+/**
+ * csr_process_nss_update_req() - Update nss command to PE
+ * @mac: Globacl MAC pointer
+ * @command: Command received from SME
+ *
+ * Posts the nss update command to PE. This message passing
+ * through PE is required for PE's internal management
+ *
+ * Return: None
+ */
+void csr_process_nss_update_req(tpAniSirGlobal mac, tSmeCmd *command)
+{
+	uint32_t len;
+	struct sir_nss_update_request *msg;
+	CDF_STATUS status;
+	tSirMsgQ msg_return;
+	struct sir_beacon_tx_complete_rsp *param;
+
+	tCsrRoamSession *session =
+		CSR_GET_SESSION(mac, command->sessionId);
+
+	if (!session) {
+		sms_log(mac, LOGE, FL("Session not found"));
+		goto fail;
+	}
+
+	if (!command) {
+		sms_log(mac, LOGE, FL("nss update param is NULL"));
+		goto fail;
+	}
+
+	len = sizeof(*msg);
+	msg = cdf_mem_malloc(len);
+	if (!msg) {
+		sms_log(mac, LOGE, FL("Memory allocation failed"));
+		/* Probably the fail response is also fail during malloc.
+		 * Still proceeding to send response!
+		 */
+		goto fail;
+	}
+
+	cdf_mem_set((void *)msg, sizeof(*msg), 0);
+	msg->msgType = eWNI_SME_NSS_UPDATE_REQ;
+	msg->msgLen = sizeof(*msg);
+
+	msg->new_nss = command->u.nss_update_cmd.new_nss;
+	msg->vdev_id = command->u.nss_update_cmd.session_id;
+
+	sms_log(mac, LOG1,
+		FL("Posting eWNI_SME_NSS_UPDATE_REQ to PE"));
+
+	status = cds_send_mb_message_to_mac(msg);
+	if (CDF_STATUS_SUCCESS != status) {
+		sms_log(mac, LOGE, FL("Posting to PE failed"));
+		return;
+	}
+	return;
+fail:
+	param = cdf_mem_malloc(sizeof(*param));
+	if (!param) {
+		sms_log(mac, LOGE,
+			FL("Malloc fail: Fail to send response to SME"));
+		return;
+	}
+	sms_log(mac, LOGE, FL("Sending nss update fail response to SME"));
+	param->tx_status = CDF_STATUS_E_FAILURE;
+	param->session_id = command->u.nss_update_cmd.session_id;
+	msg_return.type = eWNI_SME_NSS_UPDATE_RSP;
+	msg_return.bodyptr = param;
+	msg_return.bodyval = 0;
+	sys_process_mmh_msg(mac, &msg_return);
+}
diff --git a/core/sme/src/csr/csr_api_scan.c b/core/sme/src/csr/csr_api_scan.c
new file mode 100644
index 0000000..68f0aee
--- /dev/null
+++ b/core/sme/src/csr/csr_api_scan.c
@@ -0,0 +1,6941 @@
+/*
+ * Copyright (c) 2011-2015 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 csr_api_scan.c
+
+    Implementation for the Common Scan interfaces.
+   ========================================================================== */
+
+#include "ani_global.h"
+
+#include "cds_mq.h"
+#include "csr_inside_api.h"
+#include "sme_inside.h"
+#include "sms_debug.h"
+
+#include "csr_support.h"
+
+#include "host_diag_core_log.h"
+#include "host_diag_core_event.h"
+
+#include "cds_reg_service.h"
+#include "wma_types.h"
+#include "cds_utils.h"
+#include "cfg_api.h"
+#include "lim_api.h"
+#include "wma.h"
+
+#include "cds_concurrency.h"
+#include "wlan_hdd_main.h"
+
+#define MIN_CHN_TIME_TO_FIND_GO 100
+#define MAX_CHN_TIME_TO_FIND_GO 100
+#define DIRECT_SSID_LEN 7
+
+/* Purpose of HIDDEN_TIMER
+** When we remove hidden ssid from the profile i.e., forget the SSID via GUI that SSID shouldn't see in the profile
+** For above requirement we used timer limit, logic is explained below
+** Timer value is initialsed to current time  when it receives corresponding probe response of hidden SSID (The probe request is
+** received regularly till SSID in the profile. Once it is removed from profile probe request is not sent.) when we receive probe response
+** for broadcast probe request, during update SSID with saved SSID we will diff current time with saved SSID time if it is greater than 1 min
+** then we are not updating with old one
+*/
+
+#define HIDDEN_TIMER (1*60*1000)
+#define CSR_SCAN_RESULT_RSSI_WEIGHT     80      /* must be less than 100, represent the persentage of new RSSI */
+
+#define MAX_ACTIVE_SCAN_FOR_ONE_CHANNEL 140
+#define MIN_ACTIVE_SCAN_FOR_ONE_CHANNEL 120
+
+#define MAX_ACTIVE_SCAN_FOR_ONE_CHANNEL_FASTREASSOC 30
+#define MIN_ACTIVE_SCAN_FOR_ONE_CHANNEL_FASTREASSOC 20
+
+#define PCL_ADVANTAGE 30
+#define PCL_RSSI_THRESHOLD -75
+
+#define CSR_SCAN_IS_OVER_BSS_LIMIT(pMac)  \
+	((pMac)->scan.nBssLimit <= (csr_ll_count(&(pMac)->scan.scanResultList)))
+
+void csr_scan_get_result_timer_handler(void *);
+static void csr_scan_result_cfg_aging_timer_handler(void *pv);
+static void csr_set_default_scan_timing(tpAniSirGlobal pMac, tSirScanType scanType,
+					tCsrScanRequest *pScanRequest);
+#ifdef WLAN_AP_STA_CONCURRENCY
+static void csr_sta_ap_conc_timer_handler(void *);
+#endif
+bool csr_is_supported_channel(tpAniSirGlobal pMac, uint8_t channelId);
+CDF_STATUS csr_scan_channels(tpAniSirGlobal pMac, tSmeCmd *pCommand);
+void csr_set_cfg_valid_channel_list(tpAniSirGlobal pMac, uint8_t *pChannelList,
+				    uint8_t NumChannels);
+void csr_save_tx_power_to_cfg(tpAniSirGlobal pMac, tDblLinkList *pList,
+			      uint32_t cfgId);
+void csr_set_cfg_country_code(tpAniSirGlobal pMac, uint8_t *countryCode);
+void csr_purge_channel_power(tpAniSirGlobal pMac, tDblLinkList *pChannelList);
+void csr_release_scan_command(tpAniSirGlobal pMac, tSmeCmd *pCommand,
+			      eCsrScanStatus scanStatus);
+static bool csr_scan_validate_scan_result(tpAniSirGlobal pMac, uint8_t *pChannels,
+					  uint8_t numChn,
+					  tSirBssDescription *pBssDesc,
+					  tDot11fBeaconIEs **ppIes);
+bool csr_roam_is_valid_channel(tpAniSirGlobal pMac, uint8_t channel);
+void csr_prune_channel_list_for_mode(tpAniSirGlobal pMac,
+				     tCsrChannel *pChannelList);
+
+#define CSR_IS_SOCIAL_CHANNEL(channel) \
+	(((channel) == 1) || ((channel) == 6) || ((channel) == 11))
+
+static void csr_release_scan_cmd_pending_list(tpAniSirGlobal pMac)
+{
+	tListElem *pEntry;
+	tSmeCmd *pCommand;
+
+	while ((pEntry =
+			csr_ll_remove_head(&pMac->scan.scanCmdPendingList,
+					   LL_ACCESS_LOCK)) != NULL) {
+		pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
+		if (eSmeCsrCommandMask & pCommand->command) {
+			csr_abort_command(pMac, pCommand, true);
+		} else {
+			sms_log(pMac, LOGE, FL("Error: Received command : %d"),
+				pCommand->command);
+		}
+	}
+}
+
+/* pResult is invalid calling this function. */
+void csr_free_scan_result_entry(tpAniSirGlobal pMac, tCsrScanResult *pResult)
+{
+	if (NULL != pResult->Result.pvIes) {
+		cdf_mem_free(pResult->Result.pvIes);
+	}
+	cdf_mem_free(pResult);
+}
+
+static CDF_STATUS csr_ll_scan_purge_result(tpAniSirGlobal pMac,
+					   tDblLinkList *pList)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tListElem *pEntry;
+	tCsrScanResult *pBssDesc;
+
+	csr_ll_lock(pList);
+
+	while ((pEntry = csr_ll_remove_head(pList, LL_ACCESS_NOLOCK)) != NULL) {
+		pBssDesc = GET_BASE_ADDR(pEntry, tCsrScanResult, Link);
+		csr_free_scan_result_entry(pMac, pBssDesc);
+	}
+
+	csr_ll_unlock(pList);
+
+	return status;
+}
+
+CDF_STATUS csr_scan_open(tpAniSirGlobal mac_ctx)
+{
+	CDF_STATUS status;
+
+	csr_ll_open(mac_ctx->hHdd, &mac_ctx->scan.scanResultList);
+	csr_ll_open(mac_ctx->hHdd, &mac_ctx->scan.tempScanResults);
+	csr_ll_open(mac_ctx->hHdd, &mac_ctx->scan.channelPowerInfoList24);
+	csr_ll_open(mac_ctx->hHdd, &mac_ctx->scan.channelPowerInfoList5G);
+#ifdef WLAN_AP_STA_CONCURRENCY
+	csr_ll_open(mac_ctx->hHdd, &mac_ctx->scan.scanCmdPendingList);
+#endif
+	mac_ctx->scan.fFullScanIssued = false;
+	mac_ctx->scan.nBssLimit = CSR_MAX_BSS_SUPPORT;
+#ifdef WLAN_AP_STA_CONCURRENCY
+	status = cdf_mc_timer_init(&mac_ctx->scan.hTimerStaApConcTimer,
+				   CDF_TIMER_TYPE_SW,
+				   csr_sta_ap_conc_timer_handler,
+				   mac_ctx);
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		sms_log(mac_ctx, LOGE,
+			FL("Mem Alloc failed for hTimerStaApConcTimer timer"));
+		return status;
+	}
+#endif
+	status = cdf_mc_timer_init(&mac_ctx->scan.hTimerResultCfgAging,
+				   CDF_TIMER_TYPE_SW,
+				   csr_scan_result_cfg_aging_timer_handler,
+				   mac_ctx);
+	if (!CDF_IS_STATUS_SUCCESS(status))
+		sms_log(mac_ctx, LOGE,
+			FL("Mem Alloc failed for CFG ResultAging timer"));
+
+	return status;
+}
+
+CDF_STATUS csr_scan_close(tpAniSirGlobal pMac)
+{
+	csr_ll_scan_purge_result(pMac, &pMac->scan.tempScanResults);
+	csr_ll_scan_purge_result(pMac, &pMac->scan.scanResultList);
+#ifdef WLAN_AP_STA_CONCURRENCY
+	csr_release_scan_cmd_pending_list(pMac);
+#endif
+	csr_ll_close(&pMac->scan.scanResultList);
+	csr_ll_close(&pMac->scan.tempScanResults);
+#ifdef WLAN_AP_STA_CONCURRENCY
+	csr_ll_close(&pMac->scan.scanCmdPendingList);
+#endif
+	csr_purge_channel_power(pMac, &pMac->scan.channelPowerInfoList24);
+	csr_purge_channel_power(pMac, &pMac->scan.channelPowerInfoList5G);
+	csr_ll_close(&pMac->scan.channelPowerInfoList24);
+	csr_ll_close(&pMac->scan.channelPowerInfoList5G);
+	csr_scan_disable(pMac);
+	cdf_mc_timer_destroy(&pMac->scan.hTimerResultCfgAging);
+#ifdef WLAN_AP_STA_CONCURRENCY
+	cdf_mc_timer_destroy(&pMac->scan.hTimerStaApConcTimer);
+#endif
+	return CDF_STATUS_SUCCESS;
+}
+
+CDF_STATUS csr_scan_enable(tpAniSirGlobal pMac)
+{
+
+	pMac->scan.fScanEnable = true;
+
+	return CDF_STATUS_SUCCESS;
+}
+
+CDF_STATUS csr_scan_disable(tpAniSirGlobal pMac)
+{
+
+	csr_scan_stop_timers(pMac);
+	pMac->scan.fScanEnable = false;
+
+	return CDF_STATUS_SUCCESS;
+}
+
+/* Set scan timing parameters according to state of other driver sessions */
+/* No validation of the parameters is performed. */
+static void csr_set_default_scan_timing(tpAniSirGlobal pMac, tSirScanType scanType,
+					tCsrScanRequest *pScanRequest)
+{
+#ifdef WLAN_AP_STA_CONCURRENCY
+	if (csr_is_any_session_connected(pMac)) {
+		/* Reset passive scan time as per ini parameter. */
+		cfg_set_int(pMac, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME,
+			    pMac->roam.configParam.nPassiveMaxChnTimeConc);
+		/* If multi-session, use the appropriate default scan times */
+		if (scanType == eSIR_ACTIVE_SCAN) {
+			pScanRequest->maxChnTime =
+				pMac->roam.configParam.nActiveMaxChnTimeConc;
+			pScanRequest->minChnTime =
+				pMac->roam.configParam.nActiveMinChnTimeConc;
+		} else {
+			pScanRequest->maxChnTime =
+				pMac->roam.configParam.nPassiveMaxChnTimeConc;
+			pScanRequest->minChnTime =
+				pMac->roam.configParam.nPassiveMinChnTimeConc;
+		}
+		pScanRequest->restTime = pMac->roam.configParam.nRestTimeConc;
+
+		/* Return so that fields set above will not be overwritten. */
+		return;
+	}
+#endif
+
+	/* This portion of the code executed if multi-session not supported */
+	/* (WLAN_AP_STA_CONCURRENCY not defined) or no multi-session. */
+	/* Use the "regular" (non-concurrency) default scan timing. */
+	cfg_set_int(pMac, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME,
+		    pMac->roam.configParam.nPassiveMaxChnTime);
+	if (pScanRequest->scanType == eSIR_ACTIVE_SCAN) {
+		pScanRequest->maxChnTime =
+			pMac->roam.configParam.nActiveMaxChnTime;
+		pScanRequest->minChnTime =
+			pMac->roam.configParam.nActiveMinChnTime;
+	} else {
+		pScanRequest->maxChnTime =
+			pMac->roam.configParam.nPassiveMaxChnTime;
+		pScanRequest->minChnTime =
+			pMac->roam.configParam.nPassiveMinChnTime;
+	}
+#ifdef WLAN_AP_STA_CONCURRENCY
+	/* No rest time if no sessions are connected. */
+	pScanRequest->restTime = 0;
+#endif
+}
+
+/**
+ * csr_scan_2g_only_request() - This function will update the scan request with
+ * only 2.4GHz valid channel list.
+ * @mac_ctx:      Pointer to Global MAC structure
+ * @scan_cmd      scan cmd
+ * @scan_req      scan req
+ *
+ * This function will update the scan request with  only 2.4GHz valid channel
+ * list.
+ *
+ * @Return: status of operation
+ */
+static CDF_STATUS
+csr_scan_2g_only_request(tpAniSirGlobal mac_ctx,
+			 tSmeCmd *scan_cmd,
+			 tCsrScanRequest *scan_req)
+{
+	uint8_t idx, lst_sz = 0;
+
+	CDF_ASSERT(scan_cmd && scan_req);
+	/* To silence the KW tool null check is added */
+	if ((scan_cmd == NULL) || (scan_req == NULL)) {
+		sms_log(mac_ctx, LOGE,
+			FL(" Scan Cmd or Scan Request is NULL "));
+		return CDF_STATUS_E_INVAL;
+	}
+
+	if (eCSR_SCAN_REQUEST_FULL_SCAN != scan_req->requestType)
+		return CDF_STATUS_SUCCESS;
+
+	sms_log(mac_ctx, LOG1,
+		FL("Scanning only 2G Channels during first scan"));
+
+	/* Contsruct valid Supported 2.4 GHz Channel List */
+	if (NULL == scan_req->ChannelInfo.ChannelList) {
+		scan_req->ChannelInfo.ChannelList =
+			cdf_mem_malloc(NUM_24GHZ_CHANNELS);
+		if (NULL == scan_req->ChannelInfo.ChannelList) {
+			sms_log(mac_ctx, LOGE, FL("Memory allocation failed."));
+			return CDF_STATUS_E_NOMEM;
+		}
+		for (idx = 1; idx <= NUM_24GHZ_CHANNELS; idx++) {
+			if (csr_is_supported_channel(mac_ctx, idx)) {
+				scan_req->ChannelInfo.ChannelList[lst_sz] = idx;
+				lst_sz++;
+			}
+		}
+	} else {
+		for (idx = 0;
+		     idx < scan_req->ChannelInfo.numOfChannels;
+		     idx++) {
+			if (scan_req->ChannelInfo.ChannelList[idx] <=
+				CDS_24_GHZ_CHANNEL_14
+			    && csr_is_supported_channel(mac_ctx,
+				scan_req->ChannelInfo.ChannelList[idx])) {
+				scan_req->ChannelInfo.ChannelList[lst_sz] =
+					scan_req->ChannelInfo.ChannelList[idx];
+				lst_sz++;
+			}
+		}
+	}
+	scan_req->ChannelInfo.numOfChannels = lst_sz;
+	return CDF_STATUS_SUCCESS;
+}
+
+static void
+csr_set_scan_reason(tSmeCmd *scan_cmd, eCsrRequestType req_type)
+{
+	switch (req_type) {
+	case eCSR_SCAN_REQUEST_11D_SCAN:
+		scan_cmd->u.scanCmd.reason = eCsrScan11d1;
+		break;
+#ifdef SOFTAP_CHANNEL_RANGE
+	case eCSR_SCAN_SOFTAP_CHANNEL_RANGE:
+#endif
+	case eCSR_SCAN_REQUEST_FULL_SCAN:
+	case eCSR_SCAN_P2P_DISCOVERY:
+		scan_cmd->u.scanCmd.reason = eCsrScanUserRequest;
+		break;
+	case eCSR_SCAN_HO_PROBE_SCAN:
+		scan_cmd->u.scanCmd.reason = eCsrScanProbeBss;
+		break;
+	case eCSR_SCAN_P2P_FIND_PEER:
+		scan_cmd->u.scanCmd.reason = eCsrScanP2PFindPeer;
+		break;
+	default:
+		break;
+	}
+}
+
+static CDF_STATUS
+csr_issue_11d_scan(tpAniSirGlobal mac_ctx, tSmeCmd *scan_cmd,
+		   tCsrScanRequest *scan_req, uint16_t session_id)
+{
+	CDF_STATUS status;
+	tSmeCmd *scan_11d_cmd = NULL;
+	tCsrScanRequest tmp_rq;
+	tCsrChannelInfo *pChnInfo = &tmp_rq.ChannelInfo;
+	uint32_t numChn = mac_ctx->scan.base_channels.numChannels;
+	tCsrRoamSession *csr_session = CSR_GET_SESSION(mac_ctx, session_id);
+
+	if (csr_session == NULL) {
+		sms_log(mac_ctx, LOGE, FL("session %d not found"),
+			session_id);
+		CDF_ASSERT(0);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	if (!(((false == mac_ctx->first_scan_done)
+	     && (eCSR_SCAN_REQUEST_11D_SCAN != scan_req->requestType))
+#ifdef SOFTAP_CHANNEL_RANGE
+	    && (eCSR_SCAN_SOFTAP_CHANNEL_RANGE != scan_req->requestType)
+#endif
+	    && (false == mac_ctx->scan.fEnableBypass11d)))
+		return CDF_STATUS_SUCCESS;
+
+	cdf_mem_set(&tmp_rq, sizeof(tCsrScanRequest), 0);
+	scan_11d_cmd = csr_get_command_buffer(mac_ctx);
+	if (!scan_11d_cmd) {
+		sms_log(mac_ctx, LOGE, FL("scan_11d_cmd failed"));
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	cdf_mem_set(&scan_11d_cmd->u.scanCmd, sizeof(tScanCmd), 0);
+	pChnInfo->ChannelList = cdf_mem_malloc(numChn);
+	if (NULL == pChnInfo->ChannelList) {
+		sms_log(mac_ctx, LOGE, FL("Failed to allocate memory"));
+		return CDF_STATUS_E_NOMEM;
+	}
+	cdf_mem_copy(pChnInfo->ChannelList,
+		     mac_ctx->scan.base_channels.channelList, numChn);
+
+	pChnInfo->numOfChannels = (uint8_t) numChn;
+	scan_11d_cmd->command = eSmeCommandScan;
+	scan_11d_cmd->u.scanCmd.callback = mac_ctx->scan.callback11dScanDone;
+	scan_11d_cmd->u.scanCmd.pContext = NULL;
+	wma_get_scan_id(&scan_11d_cmd->u.scanCmd.scanID);
+	tmp_rq.BSSType = eCSR_BSS_TYPE_ANY;
+	tmp_rq.scan_id = scan_11d_cmd->u.scanCmd.scanID;
+
+	status = cdf_mc_timer_init(&scan_cmd->u.scanCmd.csr_scan_timer,
+			CDF_TIMER_TYPE_SW,
+			csr_scan_active_list_timeout_handle, &scan_11d_cmd);
+
+	if (csr_is11d_supported(mac_ctx)) {
+		tmp_rq.bcnRptReqScan = scan_req->bcnRptReqScan;
+		if (scan_req->bcnRptReqScan)
+			tmp_rq.scanType = scan_req->scanType ?
+				eSIR_PASSIVE_SCAN : scan_req->scanType;
+		else
+			tmp_rq.scanType = eSIR_PASSIVE_SCAN;
+		tmp_rq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
+		scan_11d_cmd->u.scanCmd.reason = eCsrScan11d1;
+		tmp_rq.maxChnTime =
+			mac_ctx->roam.configParam.nPassiveMaxChnTime;
+		tmp_rq.minChnTime =
+			mac_ctx->roam.configParam.nPassiveMinChnTime;
+	} else {
+		tmp_rq.bcnRptReqScan = scan_req->bcnRptReqScan;
+		if (scan_req->bcnRptReqScan)
+			tmp_rq.scanType = scan_req->scanType;
+		else
+			tmp_rq.scanType = eSIR_ACTIVE_SCAN;
+		tmp_rq.requestType = scan_req->requestType;
+		scan_11d_cmd->u.scanCmd.reason = scan_cmd->u.scanCmd.reason;
+		tmp_rq.maxChnTime = mac_ctx->roam.configParam.nActiveMaxChnTime;
+		tmp_rq.minChnTime = mac_ctx->roam.configParam.nActiveMinChnTime;
+	}
+	if (mac_ctx->roam.configParam.nInitialDwellTime) {
+		tmp_rq.maxChnTime = mac_ctx->roam.configParam.nInitialDwellTime;
+		sms_log(mac_ctx, LOG1, FL("11d scan, updating dwell time for first scan %u"),
+			tmp_rq.maxChnTime);
+	}
+
+	status = csr_scan_copy_request(mac_ctx,
+			&scan_11d_cmd->u.scanCmd.u.scanRequest, &tmp_rq);
+	/* Free the channel list */
+	cdf_mem_free(pChnInfo->ChannelList);
+	pChnInfo->ChannelList = NULL;
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		sms_log(mac_ctx, LOGE, FL("csr_scan_copy_request failed"));
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	mac_ctx->scan.scanProfile.numOfChannels =
+		scan_11d_cmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels;
+
+
+	status = csr_queue_sme_command(mac_ctx, scan_11d_cmd, false);
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		sms_log(mac_ctx, LOGE, FL("Failed to send message status = %d"),
+			status);
+		return CDF_STATUS_E_FAILURE;
+	}
+	return CDF_STATUS_SUCCESS;
+}
+
+CDF_STATUS csr_scan_request(tpAniSirGlobal pMac, uint16_t sessionId,
+			    tCsrScanRequest *scan_req,
+			    csr_scan_completeCallback callback, void *pContext)
+{
+	CDF_STATUS status = CDF_STATUS_E_FAILURE;
+	tSmeCmd *scan_cmd = NULL;
+	tCsrScanRequest *pTempScanReq = NULL;
+	tCsrConfig *cfg_prm = &pMac->roam.configParam;
+
+	if (scan_req == NULL) {
+		sms_log(pMac, LOGE, FL("scan_req is NULL"));
+		CDF_ASSERT(0);
+		return status;
+	}
+
+	/*
+	 * During group formation, the P2P client scans for GO with the specific
+	 * SSID. There will be chances of GO switching to other channels because
+	 * of scan or to STA channel in case of STA+GO MCC scenario. So to
+	 * increase the possibility of client to find the GO, the dwell time of
+	 * scan is increased to 100ms.
+	 * If the scan request is for specific SSId the length of SSID will be
+	 * greater than 7 as SSID for p2p search contains "DIRECT-")
+	 */
+	if (scan_req->p2pSearch
+	    && scan_req->SSIDs.numOfSSIDs
+	    && (NULL != scan_req->SSIDs.SSIDList)
+	    && (scan_req->SSIDs.SSIDList->SSID.length > DIRECT_SSID_LEN)) {
+		sms_log(pMac, LOG1, FL("P2P: Increasing the min and max Dwell time to %d for specific SSID scan %.*s"),
+			MAX_CHN_TIME_TO_FIND_GO,
+			scan_req->SSIDs.SSIDList->SSID.length,
+			scan_req->SSIDs.SSIDList->SSID.ssId);
+		scan_req->maxChnTime = MAX_CHN_TIME_TO_FIND_GO;
+		scan_req->minChnTime = MIN_CHN_TIME_TO_FIND_GO;
+	}
+
+	if (!pMac->scan.fScanEnable) {
+		sms_log(pMac, LOGE, FL("SId: %d Scanning not enabled Scan type=%u, numOfSSIDs=%d P2P search=%d"),
+			sessionId, scan_req->requestType,
+			scan_req->SSIDs.numOfSSIDs,
+			scan_req->p2pSearch);
+		goto release_cmd;
+	}
+
+	scan_cmd = csr_get_command_buffer(pMac);
+	if (!scan_cmd) {
+		sms_log(pMac, LOGE, FL("scan_cmd is NULL"));
+		goto release_cmd;
+	}
+
+	cdf_mem_set(&scan_cmd->u.scanCmd, sizeof(tScanCmd), 0);
+	scan_cmd->command = eSmeCommandScan;
+	scan_cmd->sessionId = sessionId;
+	if (scan_cmd->sessionId >= CSR_ROAM_SESSION_MAX)
+		sms_log(pMac, LOGE, FL("Invalid Sme SessionID: %d"), sessionId);
+	scan_cmd->u.scanCmd.callback = callback;
+	scan_cmd->u.scanCmd.pContext = pContext;
+	csr_set_scan_reason(scan_cmd, scan_req->requestType);
+	if (scan_req->minChnTime == 0 && scan_req->maxChnTime == 0) {
+		/* The caller doesn't set the time correctly. Set it here */
+		csr_set_default_scan_timing(pMac, scan_req->scanType, scan_req);
+		sms_log(pMac, LOG1,
+			FL("Setting default min %d and max %d ChnTime"),
+			scan_req->minChnTime, scan_req->maxChnTime);
+	}
+#ifdef WLAN_AP_STA_CONCURRENCY
+	/* Need to set restTime only if at least one session is connected */
+	if (scan_req->restTime == 0 && csr_is_any_session_connected(pMac)) {
+		scan_req->restTime = cfg_prm->nRestTimeConc;
+		if (scan_req->scanType == eSIR_ACTIVE_SCAN) {
+			scan_req->maxChnTime = cfg_prm->nActiveMaxChnTimeConc;
+			scan_req->minChnTime = cfg_prm->nActiveMinChnTimeConc;
+		} else {
+			scan_req->maxChnTime = cfg_prm->nPassiveMaxChnTimeConc;
+			scan_req->minChnTime = cfg_prm->nPassiveMinChnTimeConc;
+		}
+	}
+#endif
+	/* Increase dwell time in case P2P Search and Miracast is not present */
+	if (scan_req->p2pSearch && scan_req->ChannelInfo.numOfChannels
+	    == P2P_SOCIAL_CHANNELS && (!(pMac->sme.miracast_value))) {
+		scan_req->maxChnTime += P2P_SEARCH_DWELL_TIME_INCREASE;
+	}
+	scan_cmd->u.scanCmd.scanID = scan_req->scan_id;
+	/*
+	 * If it is the first scan request from HDD, CSR checks if it is for 11d
+	 * If it is not, CSR will save the scan request in the pending cmd queue
+	 * & issue an 11d scan request to PE.
+	 */
+	status = csr_issue_11d_scan(pMac, scan_cmd, scan_req, sessionId);
+	if (status != CDF_STATUS_SUCCESS)
+		goto release_cmd;
+
+	/*
+	 * Scan only 2G Channels if set in ini file. This is mainly to reduce
+	 * the First Scan duration once we turn on Wifi
+	 */
+	if (pMac->scan.fFirstScanOnly2GChnl
+	    && false == pMac->first_scan_done) {
+		csr_scan_2g_only_request(pMac, scan_cmd, scan_req);
+		pMac->first_scan_done = true;
+	}
+
+
+	if (cfg_prm->nInitialDwellTime) {
+		scan_req->maxChnTime = cfg_prm->nInitialDwellTime;
+		cfg_prm->nInitialDwellTime = 0;
+		sms_log(pMac, LOG1, FL("updating dwell time for first scan %u"),
+			scan_req->maxChnTime);
+	}
+
+	status = csr_scan_copy_request(pMac, &scan_cmd->u.scanCmd.u.scanRequest,
+				       scan_req);
+	/*
+	 * Reset the variable after the first scan is  queued after loading the
+	 * driver. The purpose of this parameter is that DFS channels are
+	 * skipped during the first scan after loading the driver. The above API
+	 * builds the target scan request in which this variable is used.
+	 */
+	cfg_prm->initial_scan_no_dfs_chnl = 0;
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		sms_log(pMac, LOGE,
+			FL("fail to copy request status = %d"), status);
+		goto release_cmd;
+	}
+
+	pTempScanReq = &scan_cmd->u.scanCmd.u.scanRequest;
+	pMac->scan.scanProfile.numOfChannels =
+		pTempScanReq->ChannelInfo.numOfChannels;
+	status = cdf_mc_timer_init(&scan_cmd->u.scanCmd.csr_scan_timer,
+				CDF_TIMER_TYPE_SW,
+				csr_scan_active_list_timeout_handle, scan_cmd);
+	sms_log(pMac, LOG1,
+		FL("SId=%d scanId=%d Scan reason=%u numSSIDs=%d numChan=%d P2P search=%d minCT=%d maxCT=%d uIEFieldLen=%d"),
+		sessionId, scan_cmd->u.scanCmd.scanID,
+		scan_cmd->u.scanCmd.reason, pTempScanReq->SSIDs.numOfSSIDs,
+		pTempScanReq->ChannelInfo.numOfChannels,
+		pTempScanReq->p2pSearch, pTempScanReq->minChnTime,
+		pTempScanReq->maxChnTime, pTempScanReq->uIEFieldLen);
+
+	status = csr_queue_sme_command(pMac, scan_cmd, false);
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		sms_log(pMac, LOGE,
+			FL("fail to send message status = %d"), status);
+	}
+
+release_cmd:
+	if (!CDF_IS_STATUS_SUCCESS(status) && scan_cmd) {
+		sms_log(pMac, LOGE, FL(" SId: %d Failed with status=%d"
+				       " Scan reason=%u numOfSSIDs=%d"
+				       " P2P search=%d scanId=%d"),
+			sessionId, status, scan_cmd->u.scanCmd.reason,
+			scan_req->SSIDs.numOfSSIDs, scan_req->p2pSearch,
+			scan_cmd->u.scanCmd.scanID);
+		csr_release_command_scan(pMac, scan_cmd);
+	}
+
+	return status;
+}
+
+CDF_STATUS csr_issue_roam_after_lostlink_scan(tpAniSirGlobal pMac,
+					      uint32_t sessionId,
+					      eCsrRoamReason reason)
+{
+	CDF_STATUS status = CDF_STATUS_E_FAILURE;
+	tScanResultHandle hBSSList = NULL;
+	tCsrScanResultFilter *pScanFilter = NULL;
+	uint32_t roamId = 0;
+	tCsrRoamProfile *pProfile = NULL;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("session %d not found"), sessionId);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	sms_log(pMac, LOG1, FL("Entry"));
+	if (pSession->fCancelRoaming) {
+		sms_log(pMac, LOGW, FL("lost link roaming canceled"));
+		status = CDF_STATUS_SUCCESS;
+		goto free_filter;
+	}
+	/* Here is the profile we need to connect to */
+	pScanFilter = cdf_mem_malloc(sizeof(tCsrScanResultFilter));
+	if (NULL == pScanFilter) {
+		status = CDF_STATUS_E_NOMEM;
+		goto free_filter;
+	}
+	cdf_mem_set(pScanFilter, sizeof(tCsrScanResultFilter), 0);
+	if (NULL == pSession->pCurRoamProfile) {
+		pScanFilter->EncryptionType.numEntries = 1;
+		pScanFilter->EncryptionType.encryptionType[0] =
+			eCSR_ENCRYPT_TYPE_NONE;
+	} else {
+		/*
+		 * We have to make a copy of pCurRoamProfile because it will
+		 * be free inside csr_roam_issue_connect
+		 */
+		pProfile = cdf_mem_malloc(sizeof(tCsrRoamProfile));
+		if (NULL == pProfile) {
+			status = CDF_STATUS_E_NOMEM;
+			goto free_filter;
+		}
+		cdf_mem_set(pProfile, sizeof(tCsrRoamProfile), 0);
+		status = csr_roam_copy_profile(pMac, pProfile,
+					       pSession->pCurRoamProfile);
+		if (!CDF_IS_STATUS_SUCCESS(status))
+			goto free_filter;
+		status = csr_roam_prepare_filter_from_profile(pMac, pProfile,
+							      pScanFilter);
+	} /* We have a profile */
+	roamId = GET_NEXT_ROAM_ID(&pMac->roam);
+	if (!CDF_IS_STATUS_SUCCESS(status))
+		goto free_filter;
+
+	status = csr_scan_get_result(pMac, pScanFilter, &hBSSList);
+	if (!CDF_IS_STATUS_SUCCESS(status))
+		goto free_filter;
+
+	if (eCsrLostLink1 == reason) {
+		/* if possible put the last connected BSS in beginning */
+		csr_move_bss_to_head_from_bssid(pMac,
+				&pSession->connectedProfile.bssid, hBSSList);
+	}
+	status = csr_roam_issue_connect(pMac, sessionId, pProfile, hBSSList,
+					reason, roamId, true, true);
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		csr_scan_result_purge(pMac, hBSSList);
+	}
+
+free_filter:
+	if (pScanFilter) {
+		/* we need to free memory for filter if profile exists */
+		csr_free_scan_filter(pMac, pScanFilter);
+		cdf_mem_free(pScanFilter);
+	}
+	if (NULL != pProfile) {
+		csr_release_profile(pMac, pProfile);
+		cdf_mem_free(pProfile);
+	}
+	return status;
+}
+
+CDF_STATUS csr_scan_handle_failed_lostlink1(tpAniSirGlobal pMac,
+					    uint32_t sessionId)
+{
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("session %d not found"), sessionId);
+		return CDF_STATUS_E_FAILURE;
+	}
+	sms_log(pMac, LOGW, "Lost link scan 1 failed");
+	if (pSession->fCancelRoaming)
+		return CDF_STATUS_E_FAILURE;
+	if (!pSession->pCurRoamProfile)
+		return csr_scan_request_lost_link3(pMac, sessionId);
+	/*
+	 * We fail lostlink1 but there may be other BSS in the cached result
+	 * fit the profile. Give it a try first
+	 */
+	if (pSession->pCurRoamProfile->SSIDs.numOfSSIDs == 0 ||
+	    pSession->pCurRoamProfile->SSIDs.numOfSSIDs > 1)
+		/* try lostlink scan2 */
+		return csr_scan_request_lost_link2(pMac, sessionId);
+	if (!pSession->pCurRoamProfile->ChannelInfo.ChannelList
+	    || pSession->pCurRoamProfile->ChannelInfo.ChannelList[0] == 0) {
+		/* go straight to lostlink scan3 */
+		return csr_scan_request_lost_link3(pMac, sessionId);
+	}
+	return CDF_STATUS_SUCCESS;
+}
+
+CDF_STATUS csr_scan_handle_failed_lostlink2(tpAniSirGlobal pMac,
+					    uint32_t sessionId)
+{
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("session %d not found"), sessionId);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	sms_log(pMac, LOGW, "Lost link scan 2 failed");
+	if (pSession->fCancelRoaming)
+		return CDF_STATUS_E_FAILURE;
+
+	if (!pSession->pCurRoamProfile
+	    || !pSession->pCurRoamProfile->ChannelInfo.ChannelList
+	    || pSession->pCurRoamProfile->ChannelInfo.ChannelList[0] == 0) {
+		/* try lostlink scan3 */
+		return csr_scan_request_lost_link3(pMac, sessionId);
+	}
+	return CDF_STATUS_E_FAILURE;
+}
+
+CDF_STATUS csr_scan_handle_failed_lostlink3(tpAniSirGlobal pMac,
+					    uint32_t sessionId)
+{
+	sms_log(pMac, LOGW, "Lost link scan 3 failed");
+	return CDF_STATUS_SUCCESS;
+}
+
+static CDF_STATUS
+csr_update_lost_link1_cmd(tpAniSirGlobal mac_ctx, tSmeCmd *cmd,
+			  tCsrRoamSession *pSession, uint32_t session_id)
+{
+	uint8_t i, num_ch = 0;
+	tScanResultHandle bss_lst = NULL;
+	tCsrScanResultInfo *scan_result = NULL;
+	tCsrScanResultFilter *scan_filter = NULL;
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tCsrSSIDs *ssid_list = &cmd->u.scanCmd.u.scanRequest.SSIDs;
+	tCsrChannelInfo *ch_info = &cmd->u.scanCmd.u.scanRequest.ChannelInfo;
+
+	cmd->command = eSmeCommandScan;
+	cmd->sessionId = (uint8_t) session_id;
+	cmd->u.scanCmd.reason = eCsrScanLostLink1;
+	cmd->u.scanCmd.callback = NULL;
+	cmd->u.scanCmd.pContext = NULL;
+	cmd->u.scanCmd.u.scanRequest.maxChnTime =
+		mac_ctx->roam.configParam.nActiveMaxChnTime;
+	cmd->u.scanCmd.u.scanRequest.minChnTime =
+		mac_ctx->roam.configParam.nActiveMinChnTime;
+	cmd->u.scanCmd.u.scanRequest.scanType = eSIR_ACTIVE_SCAN;
+	wma_get_scan_id(&cmd->u.scanCmd.scanID);
+	status = cdf_mc_timer_init(&cmd->u.scanCmd.csr_scan_timer,
+			CDF_TIMER_TYPE_SW,
+			csr_scan_active_list_timeout_handle, &cmd);
+	cmd->u.scanCmd.u.scanRequest.scan_id =
+		cmd->u.scanCmd.scanID;
+
+	if (pSession->connectedProfile.SSID.length) {
+		/*
+		 * on error: following memory will be released by call to
+		 * csr_release_command_scan in the end
+		 */
+		ssid_list->SSIDList = cdf_mem_malloc(sizeof(tCsrSSIDInfo));
+		if (NULL == ssid_list->SSIDList)
+			return CDF_STATUS_E_NOMEM;
+		ssid_list->numOfSSIDs = 1;
+		cdf_mem_copy(&ssid_list->SSIDList[0].SSID,
+			     &pSession->connectedProfile.SSID,
+			     sizeof(tSirMacSSid));
+	} else {
+		ssid_list->numOfSSIDs = 0;
+	}
+
+	if (!pSession->pCurRoamProfile)
+		return CDF_STATUS_SUCCESS;
+
+	scan_filter = cdf_mem_malloc(sizeof(tCsrScanResultFilter));
+	if (NULL == scan_filter)
+		return CDF_STATUS_E_NOMEM;
+
+	cdf_mem_set(scan_filter, sizeof(tCsrScanResultFilter), 0);
+	status = csr_roam_prepare_filter_from_profile(mac_ctx,
+			pSession->pCurRoamProfile, scan_filter);
+	if (!CDF_IS_STATUS_SUCCESS(status))
+		goto free_lost_link1_local_mem;
+
+	if (!(CDF_IS_STATUS_SUCCESS(csr_scan_get_result(mac_ctx, scan_filter,
+		&bss_lst)) && bss_lst)) {
+		if (csr_roam_is_channel_valid(mac_ctx,
+			pSession->connectedProfile.operationChannel)) {
+			ch_info->ChannelList = cdf_mem_malloc(1);
+			if (NULL == ch_info->ChannelList) {
+				status = CDF_STATUS_E_NOMEM;
+				goto free_lost_link1_local_mem;
+			}
+			ch_info->ChannelList[0] =
+				pSession->connectedProfile.operationChannel;
+			ch_info->numOfChannels = 1;
+		}
+		return status;
+	}
+
+	/* on error: this mem will be released by csr_release_command_scan */
+	ch_info->ChannelList = cdf_mem_malloc(WNI_CFG_VALID_CHANNEL_LIST_LEN);
+	if (NULL == ch_info->ChannelList) {
+		status = CDF_STATUS_E_NOMEM;
+		goto free_lost_link1_local_mem;
+	}
+
+	scan_result = csr_scan_result_get_next(mac_ctx, bss_lst);
+	while (scan_result != NULL && num_ch < WNI_CFG_VALID_CHANNEL_LIST_LEN) {
+		for (i = 0; i < num_ch; i++) {
+			if (ch_info->ChannelList[i] ==
+				scan_result->BssDescriptor.channelId)
+				break;
+		}
+		if (i == num_ch)
+			ch_info->ChannelList[num_ch++] =
+				scan_result->BssDescriptor.channelId;
+		scan_result = csr_scan_result_get_next(mac_ctx, bss_lst);
+	}
+	/* Include the last connected BSS' channel */
+	if (csr_roam_is_channel_valid(mac_ctx,
+		pSession->connectedProfile.operationChannel)) {
+		for (i = 0; i < num_ch; i++) {
+			if (ch_info->ChannelList[i] ==
+				pSession->connectedProfile.operationChannel)
+				break;
+		}
+		if (i == num_ch)
+			ch_info->ChannelList[num_ch++] =
+				pSession->connectedProfile.operationChannel;
+	}
+	ch_info->numOfChannels = num_ch;
+free_lost_link1_local_mem:
+	if (scan_filter) {
+		csr_free_scan_filter(mac_ctx, scan_filter);
+		cdf_mem_free(scan_filter);
+	}
+	if (bss_lst)
+		csr_scan_result_purge(mac_ctx, bss_lst);
+	return status;
+}
+
+/**
+ * csr_scan_request_lost_link1() - start scan on link lost 1
+ * @mac_ctx:       mac global context
+ * @session_id:    session id
+ *
+ * Lostlink1 scan is to actively scan the last connected profile's SSID on all
+ * matched BSS channels. If no roam profile (it should not), it is like
+ * lostlinkscan3
+ *
+ * Return: status of operation
+ */
+CDF_STATUS
+csr_scan_request_lost_link1(tpAniSirGlobal mac_ctx, uint32_t session_id)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tSmeCmd *cmd = NULL;
+	tCsrRoamSession *session = CSR_GET_SESSION(mac_ctx, session_id);
+
+	if (!session) {
+		sms_log(mac_ctx, LOGE, FL("session %d not found"), session_id);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	sms_log(mac_ctx, LOGW, FL("Entry"));
+	cmd = csr_get_command_buffer(mac_ctx);
+	if (!cmd) {
+		status = CDF_STATUS_E_RESOURCES;
+		goto release_lost_link1_cmd;
+	}
+	cdf_mem_set(&cmd->u.scanCmd, sizeof(tScanCmd), 0);
+	status = csr_update_lost_link1_cmd(mac_ctx, cmd, session, session_id);
+	if (!CDF_IS_STATUS_SUCCESS(status))
+		goto release_lost_link1_cmd;
+
+	cdf_mem_set(&cmd->u.scanCmd.u.scanRequest.bssid,
+		    sizeof(struct cdf_mac_addr), 0xFF);
+	status = csr_queue_sme_command(mac_ctx, cmd, false);
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		sms_log(mac_ctx, LOGE,
+			FL("fail to send message status = %d"), status);
+	}
+
+release_lost_link1_cmd:
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		sms_log(mac_ctx, LOGW, FL("failed with status %d"), status);
+		if (cmd)
+			csr_release_command_scan(mac_ctx, cmd);
+		status = csr_scan_handle_failed_lostlink1(mac_ctx, session_id);
+	}
+	return status;
+}
+
+static CDF_STATUS
+csr_update_lost_link2_cmd(tpAniSirGlobal mac_ctx, tSmeCmd *cmd,
+			  uint32_t session_id, tCsrRoamSession *session)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	uint8_t i, num_ch = 0;
+	tScanResultHandle bss_lst = NULL;
+	tCsrScanResultInfo *scan_result = NULL;
+	tCsrScanResultFilter *scan_fltr = NULL;
+	tCsrChannelInfo *ch_info = &cmd->u.scanCmd.u.scanRequest.ChannelInfo;
+
+	cmd->command = eSmeCommandScan;
+	cmd->sessionId = (uint8_t) session_id;
+	cmd->u.scanCmd.reason = eCsrScanLostLink2;
+	cmd->u.scanCmd.callback = NULL;
+	cmd->u.scanCmd.pContext = NULL;
+	cmd->u.scanCmd.u.scanRequest.maxChnTime =
+		mac_ctx->roam.configParam.nActiveMaxChnTime;
+	cmd->u.scanCmd.u.scanRequest.minChnTime =
+		mac_ctx->roam.configParam.nActiveMinChnTime;
+	cmd->u.scanCmd.u.scanRequest.scanType = eSIR_ACTIVE_SCAN;
+	wma_get_scan_id(&cmd->u.scanCmd.scanID);
+	cmd->u.scanCmd.u.scanRequest.scan_id =
+		cmd->u.scanCmd.scanID;
+	if (!session->pCurRoamProfile)
+		return CDF_STATUS_SUCCESS;
+	status = cdf_mc_timer_init(&cmd->u.scanCmd.csr_scan_timer,
+			CDF_TIMER_TYPE_SW,
+			csr_scan_active_list_timeout_handle, &cmd);
+	scan_fltr = cdf_mem_malloc(sizeof(tCsrScanResultFilter));
+	if (NULL == scan_fltr)
+		return CDF_STATUS_E_NOMEM;
+
+	cdf_mem_set(scan_fltr, sizeof(tCsrScanResultFilter), 0);
+	status = csr_roam_prepare_filter_from_profile(mac_ctx,
+				session->pCurRoamProfile, scan_fltr);
+	if (!CDF_IS_STATUS_SUCCESS(status))
+		goto free_lost_link2_local_mem;
+
+	status = csr_scan_get_result(mac_ctx, scan_fltr, &bss_lst);
+	if (!CDF_IS_STATUS_SUCCESS(status))
+		goto free_lost_link2_local_mem;
+
+	if (!bss_lst)
+		goto free_lost_link2_local_mem;
+
+	ch_info->ChannelList = cdf_mem_malloc(WNI_CFG_VALID_CHANNEL_LIST_LEN);
+	if (NULL == ch_info->ChannelList) {
+		status = CDF_STATUS_E_NOMEM;
+		goto free_lost_link2_local_mem;
+	}
+	scan_result = csr_scan_result_get_next(mac_ctx, bss_lst);
+	while (scan_result != NULL && num_ch < WNI_CFG_VALID_CHANNEL_LIST_LEN) {
+		for (i = 0; i < num_ch; i++) {
+			if (ch_info->ChannelList[i] ==
+				scan_result->BssDescriptor.channelId)
+				break;
+		}
+		if (i == num_ch)
+			ch_info->ChannelList[num_ch++] =
+				scan_result->BssDescriptor.channelId;
+		scan_result = csr_scan_result_get_next(mac_ctx, bss_lst);
+	}
+	ch_info->numOfChannels = num_ch;
+
+free_lost_link2_local_mem:
+	if (scan_fltr) {
+		csr_free_scan_filter(mac_ctx, scan_fltr);
+		cdf_mem_free(scan_fltr);
+	}
+	if (bss_lst)
+		csr_scan_result_purge(mac_ctx, bss_lst);
+	return status;
+}
+
+/**
+ * csr_scan_request_lost_link2() - start scan on link lost 2
+ * @mac_ctx:       mac global context
+ * @session_id:    session id
+ *
+ * Lostlink2 scan is to actively scan the all SSIDs of the last roaming
+ * profile's on all matched BSS channels. Since MAC doesn't support multiple
+ * SSID, we scan all SSIDs and filter them afterwards
+ *
+ * Return: status of operation
+ */
+CDF_STATUS
+csr_scan_request_lost_link2(tpAniSirGlobal mac_ctx, uint32_t session_id)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tSmeCmd *cmd = NULL;
+	tCsrRoamSession *session = CSR_GET_SESSION(mac_ctx, session_id);
+
+	if (!session) {
+		sms_log(mac_ctx, LOGE, FL("session %d not found"), session_id);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	sms_log(mac_ctx, LOGW, FL(" called"));
+	cmd = csr_get_command_buffer(mac_ctx);
+	if (!cmd) {
+		status = CDF_STATUS_E_RESOURCES;
+		goto release_lost_link2_cmd;
+	}
+	cdf_mem_set(&cmd->u.scanCmd, sizeof(tScanCmd), 0);
+	status = csr_update_lost_link2_cmd(mac_ctx, cmd, session_id, session);
+	if (!CDF_IS_STATUS_SUCCESS(status))
+		goto release_lost_link2_cmd;
+
+	cdf_mem_set(&cmd->u.scanCmd.u.scanRequest.bssid,
+		    sizeof(struct cdf_mac_addr), 0xFF);
+	/* Put to the head in pending queue */
+	status = csr_queue_sme_command(mac_ctx, cmd, true);
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		sms_log(mac_ctx, LOGE,
+			FL("fail to send message status = %d"), status);
+		goto release_lost_link2_cmd;
+	}
+
+release_lost_link2_cmd:
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		sms_log(mac_ctx, LOGW, FL("failed with status %d"), status);
+		if (cmd)
+			csr_release_command_scan(mac_ctx, cmd);
+		status = csr_scan_handle_failed_lostlink2(mac_ctx, session_id);
+	}
+	return status;
+}
+
+/**
+ * csr_scan_request_lost_link3() - To actively scan all valid channels
+ * @mac_ctx:       mac global context
+ * @session_id:    session id
+ *
+ * Return: status of operation
+ */
+CDF_STATUS
+csr_scan_request_lost_link3(tpAniSirGlobal mac_ctx, uint32_t session_id)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tSmeCmd *cmd;
+
+	sms_log(mac_ctx, LOGW, FL(" called"));
+	do {
+		cmd = csr_get_command_buffer(mac_ctx);
+		if (!cmd) {
+			status = CDF_STATUS_E_RESOURCES;
+			break;
+		}
+		cdf_mem_set(&cmd->u.scanCmd, sizeof(tScanCmd), 0);
+		cmd->command = eSmeCommandScan;
+		cmd->sessionId = (uint8_t) session_id;
+		cmd->u.scanCmd.reason = eCsrScanLostLink3;
+		cmd->u.scanCmd.callback = NULL;
+		cmd->u.scanCmd.pContext = NULL;
+		cmd->u.scanCmd.u.scanRequest.maxChnTime =
+			mac_ctx->roam.configParam.nActiveMaxChnTime;
+		cmd->u.scanCmd.u.scanRequest.minChnTime =
+			mac_ctx->roam.configParam.nActiveMinChnTime;
+		cmd->u.scanCmd.u.scanRequest.scanType = eSIR_ACTIVE_SCAN;
+		wma_get_scan_id(&cmd->u.scanCmd.scanID);
+		status = cdf_mc_timer_init(&cmd->u.scanCmd.csr_scan_timer,
+			CDF_TIMER_TYPE_SW,
+			csr_scan_active_list_timeout_handle, &cmd);
+		cmd->u.scanCmd.u.scanRequest.scan_id =
+			cmd->u.scanCmd.scanID;
+		cdf_set_macaddr_broadcast(&cmd->u.scanCmd.u.scanRequest.bssid);
+		/* Put to the head of pending queue */
+		status = csr_queue_sme_command(mac_ctx, cmd, true);
+		if (!CDF_IS_STATUS_SUCCESS(status)) {
+			sms_log(mac_ctx, LOGE,
+				FL("fail to send message status = %d"), status);
+			break;
+		}
+	} while (0);
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		sms_log(mac_ctx, LOGW, FL("failed with status %d"), status);
+		if (cmd)
+			csr_release_command_scan(mac_ctx, cmd);
+	}
+
+	return status;
+}
+
+CDF_STATUS csr_scan_handle_search_for_ssid(tpAniSirGlobal pMac,
+					   tSmeCmd *pCommand)
+{
+	CDF_STATUS status = CDF_STATUS_E_FAILURE;
+	tScanResultHandle hBSSList = CSR_INVALID_SCANRESULT_HANDLE;
+	tCsrScanResultFilter *pScanFilter = NULL;
+	tCsrRoamProfile *pProfile = pCommand->u.scanCmd.pToRoamProfile;
+	uint32_t sessionId = pCommand->sessionId;
+
+	do {
+		/* If this scan is for LFR */
+		if (pMac->roam.neighborRoamInfo[sessionId].uOsRequestedHandoff) {
+			/* notify LFR state m/c */
+			status = csr_neighbor_roam_sssid_scan_done(pMac,
+						sessionId, CDF_STATUS_SUCCESS);
+			if (CDF_STATUS_SUCCESS != status)
+				csr_neighbor_roam_start_lfr_scan(pMac,
+								 sessionId);
+			status = CDF_STATUS_SUCCESS;
+			break;
+		}
+		/*
+		 * If there is roam command waiting, ignore this roam because
+		 * the newer roam command is the one to execute
+		 */
+		if (csr_is_roam_command_waiting_for_session(pMac, sessionId)) {
+			sms_log(pMac, LOGW,
+				FL("aborts because roam command waiting"));
+			break;
+		}
+		if (pProfile == NULL)
+			break;
+		pScanFilter = cdf_mem_malloc(sizeof(tCsrScanResultFilter));
+		if (NULL == pScanFilter) {
+			status = CDF_STATUS_E_NOMEM;
+			break;
+		}
+		cdf_mem_set(pScanFilter, sizeof(tCsrScanResultFilter), 0);
+		status = csr_roam_prepare_filter_from_profile(pMac, pProfile,
+							      pScanFilter);
+		if (!CDF_IS_STATUS_SUCCESS(status))
+			break;
+		status = csr_scan_get_result(pMac, pScanFilter, &hBSSList);
+		if (!CDF_IS_STATUS_SUCCESS(status))
+			break;
+		status = csr_roam_issue_connect(pMac, sessionId, pProfile,
+						hBSSList, eCsrHddIssued,
+						pCommand->u.scanCmd.roamId,
+						true, true);
+	} while (0);
+
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		if (CSR_INVALID_SCANRESULT_HANDLE != hBSSList) {
+			csr_scan_result_purge(pMac, hBSSList);
+		}
+		/* We haven't done anything to this profile */
+		csr_roam_call_callback(pMac, sessionId, NULL,
+				       pCommand->u.scanCmd.roamId,
+				       eCSR_ROAM_ASSOCIATION_FAILURE,
+				       eCSR_ROAM_RESULT_FAILURE);
+	}
+	if (pScanFilter) {
+		csr_free_scan_filter(pMac, pScanFilter);
+		cdf_mem_free(pScanFilter);
+	}
+	return status;
+}
+
+CDF_STATUS csr_scan_handle_search_for_ssid_failure(tpAniSirGlobal pMac,
+						   tSmeCmd *pCommand)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	uint32_t sessionId = pCommand->sessionId;
+	tCsrRoamProfile *pProfile = pCommand->u.scanCmd.pToRoamProfile;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+	eCsrRoamResult roam_result;
+
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("session %d not found"), sessionId);
+		return CDF_STATUS_E_FAILURE;
+	}
+	/* If this scan is for LFR */
+	if (pMac->roam.neighborRoamInfo[sessionId].uOsRequestedHandoff) {
+		/* notify LFR state m/c */
+		status = csr_neighbor_roam_sssid_scan_done(pMac, sessionId,
+							CDF_STATUS_E_FAILURE);
+		if (CDF_STATUS_SUCCESS != status)
+			csr_neighbor_roam_start_lfr_scan(pMac, sessionId);
+		return CDF_STATUS_SUCCESS;
+	}
+#ifdef WLAN_DEBUG
+	if (pCommand->u.scanCmd.u.scanRequest.SSIDs.numOfSSIDs == 1) {
+		char str[36];
+		tSirMacSSid *ptr_ssid =
+		&pCommand->u.scanCmd.u.scanRequest.SSIDs.SSIDList[0].SSID;
+		cdf_mem_copy(str, ptr_ssid->ssId, ptr_ssid->length);
+		str[ptr_ssid->length] = 0;
+		sms_log(pMac, LOGW, FL("SSID = %s"), str);
+	}
+#endif
+	/*
+	 * Check whether it is for start ibss. No need to do anything if it
+	 * is a JOIN request
+	 */
+	if (pProfile && CSR_IS_START_IBSS(pProfile)) {
+		status = csr_roam_issue_connect(pMac, sessionId, pProfile, NULL,
+				eCsrHddIssued, pCommand->u.scanCmd.roamId,
+				true, true);
+		if (!CDF_IS_STATUS_SUCCESS(status)) {
+			sms_log(pMac, LOGE,
+				FL("failed to issue startIBSS, status: 0x%08X"),
+				status);
+			csr_roam_call_callback(pMac, sessionId, NULL,
+				pCommand->u.scanCmd.roamId, eCSR_ROAM_FAILED,
+				eCSR_ROAM_RESULT_FAILURE);
+		}
+		return status;
+	}
+	roam_result = eCSR_ROAM_RESULT_FAILURE;
+	if (NULL != pProfile && csr_is_bss_type_ibss(pProfile->BSSType)) {
+		roam_result = eCSR_ROAM_RESULT_IBSS_START_FAILED;
+		goto roam_completion;
+	}
+	/* Only indicate assoc_completion if we indicate assoc_start. */
+	if (pSession->bRefAssocStartCnt > 0) {
+		tCsrRoamInfo *pRoamInfo = NULL, roamInfo;
+
+		cdf_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0);
+		pRoamInfo = &roamInfo;
+		if (pCommand->u.roamCmd.pRoamBssEntry) {
+			tCsrScanResult *pScanResult = GET_BASE_ADDR(
+				pCommand->u.roamCmd.pRoamBssEntry,
+				tCsrScanResult, Link);
+			roamInfo.pBssDesc = &pScanResult->Result.BssDescriptor;
+		}
+		roamInfo.statusCode = pSession->joinFailStatusCode.statusCode;
+		roamInfo.reasonCode = pSession->joinFailStatusCode.reasonCode;
+		pSession->bRefAssocStartCnt--;
+		csr_roam_call_callback(pMac, sessionId, pRoamInfo,
+				       pCommand->u.scanCmd.roamId,
+				       eCSR_ROAM_ASSOCIATION_COMPLETION,
+				       eCSR_ROAM_RESULT_FAILURE);
+	} else {
+		csr_roam_call_callback(pMac, sessionId, NULL,
+				       pCommand->u.scanCmd.roamId,
+				       eCSR_ROAM_ASSOCIATION_FAILURE,
+				       eCSR_ROAM_RESULT_FAILURE);
+	}
+roam_completion:
+	csr_roam_completion(pMac, sessionId, NULL, pCommand, roam_result,
+			    false);
+	return status;
+}
+
+CDF_STATUS csr_scan_result_purge(tpAniSirGlobal pMac,
+				 tScanResultHandle hScanList)
+{
+	CDF_STATUS status = CDF_STATUS_E_INVAL;
+	tScanResultList *pScanList = (tScanResultList *) hScanList;
+
+	if (pScanList) {
+		status = csr_ll_scan_purge_result(pMac, &pScanList->List);
+		csr_ll_close(&pScanList->List);
+		cdf_mem_free(pScanList);
+	}
+	return status;
+}
+
+/**
+ * csr_derive_prefer_value_from_rssi() - to derive prefer value
+ * @mac_ctx: Global MAC Context
+ * @rssi: RSSI of the BSS
+ *
+ * This routine will derive preferred value from given rssi
+ *
+ * Return: value between 0 to 14
+ */
+static int csr_derive_prefer_value_from_rssi(tpAniSirGlobal mac_ctx, int rssi)
+{
+	int i = CSR_NUM_RSSI_CAT - 1, pref_val = 0;
+	while (i >= 0) {
+		if (rssi >= mac_ctx->roam.configParam.RSSICat[i]) {
+			pref_val = mac_ctx->roam.configParam.BssPreferValue[i];
+			break;
+		}
+		i--;
+	};
+	return pref_val;
+}
+
+/**
+ * is_channel_found_in_pcl() - to check if channel is present in pcl
+ * @mac_ctx: Global MAC Context
+ * @channel_id: channel of bss
+ * @filter: pointer to filter created through profile
+ *
+ * to check if provided channel is present in pcl
+ *
+ * Return: true or false
+ */
+static bool is_channel_found_in_pcl(tpAniSirGlobal mac_ctx, int channel_id,
+		tCsrScanResultFilter *filter)
+{
+	int i;
+	bool status = false;
+
+	if (NULL == filter)
+		return status;
+
+	for (i = 0; i < filter->pcl_channels.numChannels; i++) {
+		if (filter->pcl_channels.channelList[i] == channel_id) {
+			status = true;
+			break;
+		}
+	}
+	return status;
+}
+/**
+ * csr_get_altered_rssi() - Artificially increase/decrease RSSI
+ * @mac_ctx:         Global MAC Context pointer.
+ * @rssi:            Actual RSSI of the AP.
+ * @channel_id:      Channel on which the AP is parked.
+ * @bssid:           BSSID of the AP to connect to.
+ *
+ * This routine will apply the boost and penalty parameters
+ * if the channel_id is of 5G band and it will also apply
+ * the preferred bssid score if there is a match between
+ * the bssid and the global preferred bssid list.
+ *
+ * Return:          The modified RSSI Value
+ */
+static int csr_get_altered_rssi(tpAniSirGlobal mac_ctx, int rssi,
+		uint8_t channel_id, struct cdf_mac_addr *bssid)
+{
+	int modified_rssi;
+	int boost_factor;
+	int penalty_factor;
+	int i;
+	struct roam_ext_params *roam_params;
+	struct cdf_mac_addr fav_bssid;
+	struct cdf_mac_addr local_bssid;
+
+	modified_rssi = rssi;
+	cdf_mem_zero(&local_bssid.bytes, CDF_MAC_ADDR_SIZE);
+	if (bssid)
+		cdf_mem_copy(local_bssid.bytes, bssid->bytes,
+				CDF_MAC_ADDR_SIZE);
+	roam_params = &mac_ctx->roam.configParam.roam_params;
+	/*
+	 * If the 5G pref feature is enabled, apply the roaming
+	 * parameters to boost or penalize the rssi.
+	 * Boost Factor = boost_factor * (Actual RSSI - boost Threshold)
+	 * Penalty Factor = penalty factor * (penalty threshold - Actual RSSI)
+	 */
+	if (CSR_IS_SELECT_5G_PREFERRED(mac_ctx) &&
+			CDS_IS_CHANNEL_5GHZ(channel_id)) {
+		if (rssi > roam_params->raise_rssi_thresh_5g) {
+			/* Check and boost the threshold*/
+			boost_factor = roam_params->raise_factor_5g *
+				(rssi - roam_params->raise_rssi_thresh_5g);
+			/* Check and penalize the threshold */
+			modified_rssi += CSR_MIN(roam_params->max_raise_rssi_5g,
+						boost_factor);
+		} else if (rssi < roam_params->drop_rssi_thresh_5g) {
+			penalty_factor = roam_params->drop_factor_5g *
+				(roam_params->drop_rssi_thresh_5g - rssi);
+			modified_rssi -= CSR_MAX(roam_params->max_drop_rssi_5g,
+						penalty_factor);
+		}
+		sms_log(mac_ctx, LOG2,
+			FL("5G BSSID"MAC_ADDRESS_STR" AR=%d, MR=%d, ch=%d"),
+			MAC_ADDR_ARRAY(local_bssid.bytes),
+			rssi, modified_rssi, channel_id);
+	}
+	/*
+	 * Check if there are preferred bssid and then apply the
+	 * preferred score
+	 */
+	cdf_mem_zero(&fav_bssid.bytes, CDF_MAC_ADDR_SIZE);
+	if (roam_params->num_bssid_favored) {
+		for (i = 0; i < roam_params->num_bssid_favored; i++) {
+			cdf_mem_copy(fav_bssid.bytes,
+					&roam_params->bssid_favored[i],
+					CDF_MAC_ADDR_SIZE);
+			if (!cdf_is_macaddr_equal(&fav_bssid, bssid))
+				continue;
+			modified_rssi += roam_params->bssid_favored_factor[i];
+			sms_log(mac_ctx, LOG2,
+				FL("Pref"MAC_ADDRESS_STR" AR=%d, MR=%d, ch=%d"),
+				MAC_ADDR_ARRAY(local_bssid.bytes),
+				rssi, modified_rssi, channel_id);
+		}
+	}
+	return modified_rssi;
+}
+
+/**
+ * csr_get_bss_prefer_value() - Get the preference value for BSS
+ * @mac_ctx:               Global MAC Context
+ * @rssi:                  RSSI of the BSS
+ * @bssid:                 BSSID to which the preference value is returned
+ * @channel_id:            Channel on which the AP is parked
+ *
+ * Each BSS descriptor should be assigned a preference value ranging from
+ * 14-0, which will be used as an RSSI bucket score while sorting the
+ * scan results.
+ *
+ * Return: Preference value for the BSSID
+ */
+static uint32_t csr_get_bss_prefer_value(tpAniSirGlobal mac_ctx, int rssi,
+		struct cdf_mac_addr *bssid, int channel_id)
+{
+	uint32_t ret = 0;
+	int modified_rssi;
+
+	/*
+	 * The RSSI does not get modified in case the 5G
+	 * preference or preferred BSSID is not applicable
+	 */
+	modified_rssi = csr_get_altered_rssi(mac_ctx, rssi, channel_id, bssid);
+	ret = csr_derive_prefer_value_from_rssi(mac_ctx, modified_rssi);
+
+	return ret;
+}
+
+/* Return a CapValue base on the capabilities of a BSS */
+static uint32_t csr_get_bss_cap_value(tpAniSirGlobal pMac,
+				      tSirBssDescription *pBssDesc,
+				      tDot11fBeaconIEs *pIes)
+{
+	uint32_t ret = CSR_BSS_CAP_VALUE_NONE;
+#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
+	if (CSR_IS_ROAM_PREFER_5GHZ(pMac) || CSR_IS_SELECT_5G_PREFERRED(pMac)) {
+		if ((pBssDesc) && CDS_IS_CHANNEL_5GHZ(pBssDesc->channelId)) {
+			ret += CSR_BSS_CAP_VALUE_5GHZ;
+		}
+	}
+#endif
+	/*
+	 * if strict select 5GHz is non-zero then ignore the capability checking
+	 */
+	if (pIes && !CSR_IS_SELECT_5GHZ_MARGIN(pMac)) {
+		/* We only care about 11N capability */
+		if (pIes->VHTCaps.present)
+			ret += CSR_BSS_CAP_VALUE_VHT;
+		else if (pIes->HTCaps.present)
+			ret += CSR_BSS_CAP_VALUE_HT;
+		if (CSR_IS_QOS_BSS(pIes)) {
+			ret += CSR_BSS_CAP_VALUE_WMM;
+			/* Give advantage to UAPSD */
+			if (CSR_IS_UAPSD_BSS(pIes)) {
+				ret += CSR_BSS_CAP_VALUE_UAPSD;
+			}
+		}
+	}
+
+	return ret;
+}
+
+/**
+ * csr_is_better_rssi() - Is bss1 better than bss2
+ * @mac_ctx:             Global MAC Context pointer.
+ * @bss1:                Pointer to the first BSS.
+ * @bss2:                Pointer to the second BSS.
+ *
+ * This routine helps in determining the preference value
+ * of a particular BSS in the scan result which is further
+ * used in the sorting logic of the final candidate AP's.
+ *
+ * Return:          true, if bss1 is better than bss2
+ *                  false, if bss2 is better than bss1.
+ */
+static bool csr_is_better_rssi(tpAniSirGlobal mac_ctx,
+		tCsrScanResult *bss1, tCsrScanResult *bss2)
+{
+	bool ret;
+	int rssi1, rssi2;
+	struct cdf_mac_addr local_mac;
+
+	rssi1 = bss1->Result.BssDescriptor.rssi;
+	rssi2 = bss2->Result.BssDescriptor.rssi;
+	/*
+	 * Apply the boost and penlty logic and check
+	 * which is the best RSSI
+	 */
+	cdf_mem_zero(&local_mac.bytes, CDF_MAC_ADDR_SIZE);
+	cdf_mem_copy(&local_mac.bytes,
+			&bss1->Result.BssDescriptor.bssId, CDF_MAC_ADDR_SIZE);
+	rssi1 = csr_get_altered_rssi(mac_ctx, rssi1,
+			bss1->Result.BssDescriptor.channelId,
+			&local_mac);
+	cdf_mem_copy(&local_mac.bytes,
+			&bss2->Result.BssDescriptor.bssId, CDF_MAC_ADDR_SIZE);
+	rssi2 = csr_get_altered_rssi(mac_ctx, rssi2,
+			bss2->Result.BssDescriptor.channelId,
+			&local_mac);
+	if (CSR_IS_BETTER_RSSI(rssi1, rssi2))
+		ret = true;
+	else
+		ret = false;
+	return ret;
+}
+
+/**
+ * csr_is_better_bss() - Is bss1 better than bss2
+ * @mac_ctx:             Global MAC Context pointer.
+ * @bss1:                Pointer to the first BSS.
+ * @bss2:                Pointer to the second BSS.
+ *
+ * This routine helps in determining the preference value
+ * of a particular BSS in the scan result which is further
+ * used in the sorting logic of the final candidate AP's.
+ *
+ * Return:          true, if bss1 is better than bss2
+ *                  false, if bss2 is better than bss1.
+ */
+static bool csr_is_better_bss(tpAniSirGlobal mac_ctx,
+	tCsrScanResult *bss1, tCsrScanResult *bss2)
+{
+	bool ret;
+
+	if (CSR_IS_BETTER_PREFER_VALUE(bss1->preferValue, bss2->preferValue)) {
+		ret = true;
+	} else if (CSR_IS_EQUAL_PREFER_VALUE
+			(bss1->preferValue, bss2->preferValue)) {
+		if (CSR_IS_BETTER_CAP_VALUE(bss1->capValue, bss2->capValue))
+			ret = true;
+		else if (CSR_IS_EQUAL_CAP_VALUE
+				(bss1->capValue, bss2->capValue)) {
+			if (csr_is_better_rssi(mac_ctx, bss1, bss2))
+				ret = true;
+			else
+				ret = false;
+		} else {
+			ret = false;
+		}
+	} else {
+		ret = false;
+	}
+
+	return ret;
+}
+
+#ifdef FEATURE_WLAN_LFR
+/* Add the channel to the occupiedChannels array */
+static void csr_scan_add_to_occupied_channels(tpAniSirGlobal pMac,
+					      tCsrScanResult *pResult,
+					      uint8_t sessionId,
+					      tCsrChannel *occupied_ch,
+					      tDot11fBeaconIEs *pIes)
+{
+	CDF_STATUS status;
+	uint8_t ch;
+	uint8_t num_occupied_ch = occupied_ch->numChannels;
+	uint8_t *occupied_ch_lst = occupied_ch->channelList;
+
+	ch = pResult->Result.BssDescriptor.channelId;
+	if (csr_is_channel_present_in_list(occupied_ch_lst, num_occupied_ch, ch)
+	    || !csr_neighbor_roam_connected_profile_match(pMac, sessionId,
+							  pResult, pIes))
+		return;
+
+	status = csr_add_to_channel_list_front(occupied_ch_lst,
+					       num_occupied_ch, ch);
+	if (CDF_IS_STATUS_SUCCESS(status)) {
+		occupied_ch->numChannels++;
+		sms_log(pMac, LOG2,
+			FL("Added channel %d to the list (count=%d)"),
+			ch, occupied_ch->numChannels);
+		if (occupied_ch->numChannels >
+		    CSR_BG_SCAN_OCCUPIED_CHANNEL_LIST_LEN)
+			occupied_ch->numChannels =
+				CSR_BG_SCAN_OCCUPIED_CHANNEL_LIST_LEN;
+	}
+}
+#endif
+
+/* Put the BSS into the scan result list */
+/* pIes can not be NULL */
+static void csr_scan_add_result(tpAniSirGlobal pMac, tCsrScanResult *pResult,
+				tDot11fBeaconIEs *pIes, uint32_t sessionId)
+{
+#ifdef FEATURE_WLAN_LFR
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+		&pMac->roam.neighborRoamInfo[sessionId];
+#endif
+
+	struct cdf_mac_addr bssid;
+	uint8_t channel_id = pResult->Result.BssDescriptor.channelId;
+	cdf_mem_zero(&bssid.bytes, CDF_MAC_ADDR_SIZE);
+	cdf_mem_copy(bssid.bytes, &pResult->Result.BssDescriptor.bssId,
+			CDF_MAC_ADDR_SIZE);
+	pResult->preferValue = csr_get_bss_prefer_value(pMac,
+				(int)pResult->Result.BssDescriptor.rssi,
+				&bssid, channel_id);
+	pResult->capValue = csr_get_bss_cap_value(pMac,
+				&pResult->Result.BssDescriptor, pIes);
+	csr_ll_insert_tail(&pMac->scan.scanResultList, &pResult->Link,
+			   LL_ACCESS_LOCK);
+#ifdef FEATURE_WLAN_LFR
+	if (0 == pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels) {
+		/*
+		 * Build the occupied channel list, only if
+		 * "gNeighborScanChannelList" is NOT set in the cfg.ini file
+		 */
+		csr_scan_add_to_occupied_channels(pMac, pResult, sessionId,
+				&pMac->scan.occupiedChannels[sessionId], pIes);
+	}
+#endif
+}
+
+static void
+csr_parser_scan_result_for_5ghz_preference(tpAniSirGlobal pMac,
+					   tCsrScanResultFilter *pFilter)
+{
+	bool fMatch;
+	CDF_STATUS status;
+	tListElem *pEntry;
+	tDot11fBeaconIEs *pIes;
+	tCsrScanResult *pBssDesc;
+	uint8_t i = 0;
+
+	/* Find out the best AP Rssi going thru the scan results */
+	pEntry = csr_ll_peek_head(&pMac->scan.scanResultList, LL_ACCESS_NOLOCK);
+	while (NULL != pEntry) {
+		pBssDesc = GET_BASE_ADDR(pEntry, tCsrScanResult, Link);
+		fMatch = false;
+
+		for (i = 0; pFilter && (i < pFilter->SSIDs.numOfSSIDs); i++) {
+			fMatch = csr_is_ssid_match(pMac,
+					pFilter->SSIDs.SSIDList[i].SSID.ssId,
+					pFilter->SSIDs.SSIDList[i].SSID.length,
+					pBssDesc->Result.ssId.ssId,
+					pBssDesc->Result.ssId.length, true);
+			if (!fMatch)
+				continue;
+
+			pIes = (tDot11fBeaconIEs *)(pBssDesc->Result.pvIes);
+			/* At this time, Result.pvIes may be NULL */
+			status = csr_get_parsed_bss_description_ies(pMac,
+					&pBssDesc->Result.BssDescriptor, &pIes);
+			if (!pIes && (!CDF_IS_STATUS_SUCCESS(status)))
+				continue;
+
+			sms_log(pMac, LOG1, FL("SSID Matched"));
+			if (pFilter->bOSENAssociation) {
+				fMatch = true;
+				sms_log(pMac, LOG1, FL("Security Matched"));
+				if ((pBssDesc->Result.pvIes == NULL) && pIes)
+					cdf_mem_free(pIes);
+				continue;
+			}
+#ifdef WLAN_FEATURE_11W
+			fMatch = csr_is_security_match(pMac, &pFilter->authType,
+					&pFilter->EncryptionType,
+					&pFilter->mcEncryptionType,
+					&pFilter->MFPEnabled,
+					&pFilter->MFPRequired,
+					&pFilter->MFPCapable,
+					&pBssDesc->Result.BssDescriptor,
+					pIes, NULL, NULL, NULL);
+#else
+			fMatch = csr_is_security_match(pMac, &pFilter->authType,
+					&pFilter->EncryptionType,
+					&pFilter->mcEncryptionType,
+					NULL, NULL, NULL,
+					&pBssDesc->Result.BssDescriptor,
+					pIes, NULL, NULL, NULL);
+#endif
+			if ((pBssDesc->Result.pvIes == NULL) && pIes)
+				cdf_mem_free(pIes);
+			if (fMatch)
+				sms_log(pMac, LOG1, FL("Security Matched"));
+		} /* for loop ends */
+
+		if (fMatch
+		    && (pBssDesc->Result.BssDescriptor.rssi >
+			pMac->scan.inScanResultBestAPRssi)) {
+			sms_log(pMac, LOG1,
+				FL("Best AP Rssi changed from %d to %d"),
+				pMac->scan.inScanResultBestAPRssi,
+				pBssDesc->Result.BssDescriptor.rssi);
+			pMac->scan.inScanResultBestAPRssi =
+				pBssDesc->Result.BssDescriptor.rssi;
+		}
+		pEntry = csr_ll_next(&pMac->scan.scanResultList, pEntry,
+				     LL_ACCESS_NOLOCK);
+	}
+}
+
+static void
+csr_prefer_5ghz(tpAniSirGlobal pMac, tCsrScanResultFilter *pFilter)
+{
+	tListElem *pEntry;
+	tCsrScanResult *pBssDesc;
+	struct roam_ext_params *roam_params = NULL;
+
+	if (!pMac->roam.configParam.nSelect5GHzMargin &&
+		!CSR_IS_SELECT_5G_PREFERRED(pMac))
+		return;
+
+	pMac->scan.inScanResultBestAPRssi = -128;
+	roam_params = &pMac->roam.configParam.roam_params;
+#ifdef WLAN_DEBUG_ROAM_OFFLOAD
+	CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
+		  FL("nSelect5GHzMargin"));
+#endif
+	csr_ll_lock(&pMac->scan.scanResultList);
+	/*
+	 * For 5G preference feature, there is no
+	 * need to check the filter match and also re-program the
+	 * RSSI bucket categories, since we use the RSSI values
+	 * while setting the preference value for the BSS.
+	 * There is no need to check the match for roaming since
+	 * it is already done.
+	 */
+	if (!CSR_IS_SELECT_5G_PREFERRED(pMac))
+		csr_parser_scan_result_for_5ghz_preference(pMac, pFilter);
+	if (-128 != pMac->scan.inScanResultBestAPRssi ||
+		CSR_IS_SELECT_5G_PREFERRED(pMac)) {
+		sms_log(pMac, LOG1, FL("Best AP Rssi is %d"),
+			pMac->scan.inScanResultBestAPRssi);
+		/* Modify Rssi category based on best AP Rssi */
+		if (-128 != pMac->scan.inScanResultBestAPRssi)
+			csr_assign_rssi_for_category(pMac,
+					pMac->scan.inScanResultBestAPRssi,
+					pMac->roam.configParam.bCatRssiOffset);
+		pEntry = csr_ll_peek_head(&pMac->scan.scanResultList,
+					  LL_ACCESS_NOLOCK);
+		while (NULL != pEntry) {
+			pBssDesc = GET_BASE_ADDR(pEntry, tCsrScanResult, Link);
+			/*
+			 * re-assign preference value based on modified
+			 * rssi bucket (or) 5G Preference feature.
+			 */
+			pBssDesc->preferValue = csr_get_bss_prefer_value(pMac,
+				(int)pBssDesc->Result.BssDescriptor.rssi,
+				(struct cdf_mac_addr *)
+				&pBssDesc->Result.BssDescriptor.bssId,
+				pBssDesc->Result.BssDescriptor.channelId);
+
+			sms_log(pMac, LOG2, FL("BSSID("MAC_ADDRESS_STR") Rssi(%d) Chnl(%d) PrefVal(%u) SSID=%.*s"),
+				MAC_ADDR_ARRAY(
+					pBssDesc->Result.BssDescriptor.bssId),
+				pBssDesc->Result.BssDescriptor.rssi,
+				pBssDesc->Result.BssDescriptor.channelId,
+				pBssDesc->preferValue,
+				pBssDesc->Result.ssId.length,
+				pBssDesc->Result.ssId.ssId);
+			pEntry = csr_ll_next(&pMac->scan.scanResultList, pEntry,
+					     LL_ACCESS_NOLOCK);
+		}
+	}
+	csr_ll_unlock(&pMac->scan.scanResultList);
+}
+
+static CDF_STATUS
+csr_save_ies(tpAniSirGlobal pMac,
+	     tCsrScanResultFilter *pFilter,
+	     tCsrScanResult *pBssDesc,
+	     tDot11fBeaconIEs **pNewIes,
+	     bool *fMatch,
+	     eCsrEncryptionType *uc,
+	     eCsrEncryptionType *mc,
+	     eCsrAuthType *auth)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tDot11fBeaconIEs *pIes = NULL;
+
+	if (!pFilter)
+		return status;
+	*fMatch = csr_match_bss(pMac, &pBssDesc->Result.BssDescriptor,
+			       pFilter, auth, uc, mc, &pIes);
+#ifdef WLAN_DEBUG_ROAM_OFFLOAD
+	CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
+		  FL("csr_match_bss fmatch %d"), *fMatch);
+#endif
+	if (NULL == pIes)
+		return status;
+	/* Only save it when matching */
+	if (!(*fMatch) && !pBssDesc->Result.pvIes) {
+		cdf_mem_free(pIes);
+		return status;
+	}
+	if (!pBssDesc->Result.pvIes) {
+		/*
+		 * csr_match_bss allocates the memory. Simply pass it and it
+		 * is freed later
+		 */
+		*pNewIes = pIes;
+		return status;
+	}
+	/*
+	 * The pIes is allocated by someone else. make a copy
+	 * Only to save parsed IEs if caller provides a filter. Most likely the
+	 * caller is using to for association, hence save the parsed IEs
+	 */
+	*pNewIes = cdf_mem_malloc(sizeof(tDot11fBeaconIEs));
+	if (NULL == *pNewIes) {
+		status = CDF_STATUS_E_NOMEM;
+		sms_log(pMac, LOGE, FL("fail to allocate memory for IEs"));
+		/* Need to free memory allocated by csr_match_bss */
+		if (!pBssDesc->Result.pvIes)
+			cdf_mem_free(pIes);
+		return status;
+	}
+	cdf_mem_copy(*pNewIes, pIes, sizeof(tDot11fBeaconIEs));
+	return status;
+}
+
+static CDF_STATUS
+csr_save_scan_entry(tpAniSirGlobal pMac,
+		    tCsrScanResultFilter *pFilter,
+		    bool fMatch,
+		    tCsrScanResult *pBssDesc,
+		    tDot11fBeaconIEs *pNewIes,
+		    tScanResultList *pRetList,
+		    uint32_t *count,
+		    eCsrEncryptionType uc,
+		    eCsrEncryptionType mc,
+		    eCsrAuthType *auth)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tCsrScanResult *pResult;
+	uint32_t bssLen, allocLen;
+	/* To sort the list */
+	tListElem *pTmpEntry;
+	tCsrScanResult *pTmpResult;
+
+	if (!(NULL == pFilter || fMatch))
+		return status;
+
+	bssLen = pBssDesc->Result.BssDescriptor.length +
+		sizeof(pBssDesc->Result.BssDescriptor.length);
+	allocLen = sizeof(tCsrScanResult) + bssLen;
+	pResult = cdf_mem_malloc(allocLen);
+	if (NULL == pResult) {
+		status = CDF_STATUS_E_NOMEM;
+		sms_log(pMac, LOGE,
+			FL("fail to allocate memory for scan result, len=%d"),
+			allocLen);
+		if (pNewIes)
+			cdf_mem_free(pNewIes);
+		return status;
+	}
+	cdf_mem_set(pResult, allocLen, 0);
+	pResult->capValue = pBssDesc->capValue;
+	pResult->preferValue = pBssDesc->preferValue;
+	pResult->ucEncryptionType = uc;
+	pResult->mcEncryptionType = mc;
+	pResult->authType = *auth;
+	pResult->Result.ssId = pBssDesc->Result.ssId;
+	pResult->Result.timer = pBssDesc->Result.timer;
+	/* save the pIes for later use */
+	pResult->Result.pvIes = pNewIes;
+	/* save bss description */
+	cdf_mem_copy(&pResult->Result.BssDescriptor,
+		     &pBssDesc->Result.BssDescriptor,
+		     bssLen);
+	/*
+	 * No need to lock pRetList because it is locally allocated and no
+	 * outside can access it at this time
+	 */
+	if (csr_ll_is_list_empty(&pRetList->List, LL_ACCESS_NOLOCK)) {
+		csr_ll_insert_tail(&pRetList->List, &pResult->Link,
+				   LL_ACCESS_NOLOCK);
+		(*count)++;
+		return status;
+	}
+
+	pTmpEntry = csr_ll_peek_head(&pRetList->List, LL_ACCESS_NOLOCK);
+	while (pTmpEntry) {
+		pTmpResult = GET_BASE_ADDR(pTmpEntry, tCsrScanResult, Link);
+		if (csr_is_better_bss(pMac, pResult, pTmpResult)) {
+			csr_ll_insert_entry(&pRetList->List, pTmpEntry,
+					    &pResult->Link, LL_ACCESS_NOLOCK);
+			/* To indicate we are done */
+			pResult = NULL;
+			break;
+		}
+		pTmpEntry = csr_ll_next(&pRetList->List,
+					pTmpEntry, LL_ACCESS_NOLOCK);
+	}
+	if (pResult != NULL) {
+		/* This one is not better than any one */
+		csr_ll_insert_tail(&pRetList->List, &pResult->Link,
+				   LL_ACCESS_NOLOCK);
+	}
+	(*count)++;
+	return status;
+}
+
+/**
+ * csr_calc_pref_val_by_pcl() - to calculate preferred value
+ * @mac_ctx: mac context
+ * @filter: filter to find match from scan result
+ * @bss_descr: pointer to bss descriptor
+ *
+ * this routine calculates the new preferred value to be given to
+ * provided bss if its channel falls under preferred channel list.
+ * Thump rule is higer the RSSI better the boost.
+ *
+ * Return: success or failure
+ */
+static CDF_STATUS csr_calc_pref_val_by_pcl(tpAniSirGlobal mac_ctx,
+			tCsrScanResultFilter *filter,
+			tCsrScanResult *bss_descr)
+{
+	int temp_rssi = 0, new_pref_val = 0;
+	int orig_pref_val = 0;
+
+	if (NULL == mac_ctx || NULL == bss_descr)
+		return CDF_STATUS_E_FAILURE;
+
+	if (mac_ctx->policy_manager_enabled &&
+		is_channel_found_in_pcl(mac_ctx,
+			bss_descr->Result.BssDescriptor.channelId, filter) &&
+		(bss_descr->Result.BssDescriptor.rssi > PCL_RSSI_THRESHOLD)) {
+		orig_pref_val = csr_derive_prefer_value_from_rssi(mac_ctx,
+					bss_descr->Result.BssDescriptor.rssi);
+		temp_rssi = bss_descr->Result.BssDescriptor.rssi +
+				(PCL_ADVANTAGE/(CSR_NUM_RSSI_CAT -
+							orig_pref_val));
+		if (temp_rssi > 0)
+			temp_rssi = 0;
+		new_pref_val = csr_derive_prefer_value_from_rssi(mac_ctx,
+					temp_rssi);
+
+		sms_log(mac_ctx, LOG1,
+			FL("%pM: rssi:%d org pref=%d temp rssi:%d new pref=%d pref=%d updated pref=%d"),
+			bss_descr->Result.BssDescriptor.bssId,
+			bss_descr->Result.BssDescriptor.rssi,
+			orig_pref_val, temp_rssi, new_pref_val,
+			bss_descr->preferValue,
+			CSR_MAX(new_pref_val, bss_descr->preferValue));
+
+		bss_descr->preferValue =
+			CSR_MAX(new_pref_val, bss_descr->preferValue);
+	}
+	return CDF_STATUS_SUCCESS;
+}
+
+static CDF_STATUS
+csr_parse_scan_results(tpAniSirGlobal pMac,
+		       tCsrScanResultFilter *pFilter,
+		       tScanResultList *pRetList,
+		       uint32_t *count)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tListElem *pEntry;
+	bool fMatch = false;
+	tCsrScanResult *pBssDesc = NULL;
+	tDot11fBeaconIEs *pIes, *pNewIes = NULL;
+	eCsrEncryptionType uc, mc;
+	eCsrAuthType auth = eCSR_AUTH_TYPE_OPEN_SYSTEM;
+	uint32_t len = 0;
+	enum cds_con_mode new_mode;
+
+
+	csr_ll_lock(&pMac->scan.scanResultList);
+
+	if (pFilter) {
+		if (cds_map_concurrency_mode(pMac->hHdd,
+					&pFilter->csrPersona, &new_mode)) {
+			status = cds_get_pcl(pMac->hHdd, new_mode,
+				&pFilter->pcl_channels.channelList[0], &len);
+			pFilter->pcl_channels.numChannels = (uint8_t)len;
+		}
+	}
+
+	if (CDF_STATUS_E_FAILURE == status)
+		sms_log(pMac, CDF_TRACE_LEVEL_ERROR,
+			FL("Retrieving pcl failed from HDD"));
+	pEntry = csr_ll_peek_head(&pMac->scan.scanResultList, LL_ACCESS_NOLOCK);
+	while (pEntry) {
+		pBssDesc = GET_BASE_ADDR(pEntry, tCsrScanResult, Link);
+		pIes = (tDot11fBeaconIEs *) (pBssDesc->Result.pvIes);
+		/*
+		 * if pBssDesc->Result.pvIes is NULL, we need to free any memory
+		 * allocated by csr_match_bss for any error condition,
+		 * otherwiase, it will be freed later
+		 */
+		fMatch = false;
+		pNewIes = NULL;
+		status = csr_save_ies(pMac, pFilter, pBssDesc, &pNewIes,
+				      &fMatch, &uc, &mc, &auth);
+		if (!CDF_IS_STATUS_SUCCESS(status))
+			break;
+		/*
+		 * Modify the prefer value to honor PCL list
+		 */
+		if (pFilter && pFilter->pcl_channels.numChannels > 0)
+			csr_calc_pref_val_by_pcl(pMac, pFilter, pBssDesc);
+		status = csr_save_scan_entry(pMac, pFilter, fMatch, pBssDesc,
+					     pNewIes, pRetList, count, uc, mc,
+					     &auth);
+		if (!CDF_IS_STATUS_SUCCESS(status))
+			break;
+		pEntry = csr_ll_next(&pMac->scan.scanResultList, pEntry,
+				     LL_ACCESS_NOLOCK);
+	} /* while */
+	csr_ll_unlock(&pMac->scan.scanResultList);
+	return status;
+}
+
+CDF_STATUS csr_scan_get_result(tpAniSirGlobal pMac,
+			       tCsrScanResultFilter *pFilter,
+			       tScanResultHandle *phResult)
+{
+	CDF_STATUS status;
+	tScanResultList *pRetList;
+	uint32_t count = 0;
+
+	if (phResult)
+		*phResult = CSR_INVALID_SCANRESULT_HANDLE;
+
+	csr_prefer_5ghz(pMac, pFilter);
+
+	pRetList = cdf_mem_malloc(sizeof(tScanResultList));
+	if (NULL == pRetList)
+		return CDF_STATUS_E_NOMEM;
+
+	cdf_mem_set(pRetList, sizeof(tScanResultList), 0);
+	csr_ll_open(pMac->hHdd, &pRetList->List);
+	pRetList->pCurEntry = NULL;
+	status = csr_parse_scan_results(pMac, pFilter, pRetList, &count);
+	sms_log(pMac, LOG2, FL("return %d BSS"), csr_ll_count(&pRetList->List));
+	if (!CDF_IS_STATUS_SUCCESS(status) || (phResult == NULL)) {
+		/* Fail or No one wants the result. */
+		csr_scan_result_purge(pMac, (tScanResultHandle) pRetList);
+	} else {
+		if (0 == count) {
+			/* We are here meaning the there is no match */
+			csr_ll_close(&pRetList->List);
+			cdf_mem_free(pRetList);
+			status = CDF_STATUS_E_NULL_VALUE;
+		} else if (phResult) {
+			*phResult = pRetList;
+		}
+	}
+	return status;
+}
+
+/*
+ * NOTE: This routine is being added to make
+ * sure that scan results are not being flushed
+ * while roaming. If the scan results are flushed,
+ * we are unable to recover from
+ * csr_roam_roaming_state_disassoc_rsp_processor.
+ * If it is needed to remove this routine,
+ * first ensure that we recover gracefully from
+ * csr_roam_roaming_state_disassoc_rsp_processor if
+ * csr_scan_get_result returns with a failure because
+ * of not being able to find the roaming BSS.
+ */
+bool csr_scan_flush_denied(tpAniSirGlobal pMac)
+{
+	uint8_t sessionId;
+
+	for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++) {
+		if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
+			if (csr_neighbor_middle_of_roaming(pMac, sessionId))
+				return 1;
+		}
+	}
+	return 0;
+}
+
+CDF_STATUS csr_scan_flush_result(tpAniSirGlobal pMac)
+{
+	bool isFlushDenied = csr_scan_flush_denied(pMac);
+
+	if (isFlushDenied) {
+		sms_log(pMac, LOGW, "%s: scan flush denied in roam state %d",
+			__func__, isFlushDenied);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	sms_log(pMac, LOG4, "%s: Flushing all scan results", __func__);
+	csr_ll_scan_purge_result(pMac, &pMac->scan.tempScanResults);
+	csr_ll_scan_purge_result(pMac, &pMac->scan.scanResultList);
+	return CDF_STATUS_SUCCESS;
+}
+
+CDF_STATUS csr_scan_flush_selective_result(tpAniSirGlobal pMac, bool flushP2P)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tListElem *pEntry, *pFreeElem;
+	tCsrScanResult *pBssDesc;
+	tDblLinkList *pList = &pMac->scan.scanResultList;
+
+	csr_ll_lock(pList);
+
+	pEntry = csr_ll_peek_head(pList, LL_ACCESS_NOLOCK);
+	while (pEntry != NULL) {
+		pBssDesc = GET_BASE_ADDR(pEntry, tCsrScanResult, Link);
+		if (flushP2P == cdf_mem_compare(pBssDesc->Result.ssId.ssId,
+						"DIRECT-", 7)) {
+			pFreeElem = pEntry;
+			pEntry = csr_ll_next(pList, pEntry, LL_ACCESS_NOLOCK);
+			csr_ll_remove_entry(pList, pFreeElem, LL_ACCESS_NOLOCK);
+			csr_free_scan_result_entry(pMac, pBssDesc);
+			continue;
+		}
+		pEntry = csr_ll_next(pList, pEntry, LL_ACCESS_NOLOCK);
+	}
+
+	csr_ll_unlock(pList);
+
+	return status;
+}
+
+void csr_scan_flush_bss_entry(tpAniSirGlobal pMac,
+			      tpSmeCsaOffloadInd pCsaOffloadInd)
+{
+	tListElem *pEntry, *pFreeElem;
+	tCsrScanResult *pBssDesc;
+	tDblLinkList *pList = &pMac->scan.scanResultList;
+
+	csr_ll_lock(pList);
+
+	pEntry = csr_ll_peek_head(pList, LL_ACCESS_NOLOCK);
+	while (pEntry != NULL) {
+		pBssDesc = GET_BASE_ADDR(pEntry, tCsrScanResult, Link);
+		if (cdf_mem_compare(pBssDesc->Result.BssDescriptor.bssId,
+			pCsaOffloadInd->bssId, sizeof(tSirMacAddr))) {
+			pFreeElem = pEntry;
+			pEntry = csr_ll_next(pList, pEntry, LL_ACCESS_NOLOCK);
+			csr_ll_remove_entry(pList, pFreeElem, LL_ACCESS_NOLOCK);
+			csr_free_scan_result_entry(pMac, pBssDesc);
+			sms_log(pMac, LOG1, FL("Removed BSS entry:%pM"),
+				pCsaOffloadInd->bssId);
+			continue;
+		}
+
+		pEntry = csr_ll_next(pList, pEntry, LL_ACCESS_NOLOCK);
+	}
+
+	csr_ll_unlock(pList);
+}
+
+/**
+ * csr_check11d_channel
+ *
+ ***FUNCTION:
+ * This function is called from csr_scan_filter_results function and
+ * compare channel number with given channel list.
+ *
+ ***LOGIC:
+ * Check Scan result channel number with CFG channel list
+ *
+ ***ASSUMPTIONS:
+ *
+ *
+ ***NOTE:
+ *
+ * @param  channelId      channel number
+ * @param  pChannelList   Pointer to channel list
+ * @param  numChannels    Number of channel in channel list
+ *
+ * @return Status
+ */
+
+CDF_STATUS csr_check11d_channel(uint8_t channelId, uint8_t *pChannelList,
+				uint32_t numChannels)
+{
+	CDF_STATUS status = CDF_STATUS_E_FAILURE;
+	uint8_t i = 0;
+
+	for (i = 0; i < numChannels; i++) {
+		if (pChannelList[i] == channelId) {
+			status = CDF_STATUS_SUCCESS;
+			break;
+		}
+	}
+	return status;
+}
+
+/**
+ * csr_scan_filter_results
+ *
+ ***FUNCTION:
+ * This function is called from csr_apply_country_information function and
+ * filter scan result based on valid channel list number.
+ *
+ ***LOGIC:
+ * Get scan result from scan list and Check Scan result channel number
+ * with 11d channel list if channel number is found in 11d channel list
+ * then do not remove scan result entry from scan list
+ *
+ ***ASSUMPTIONS:
+ *
+ *
+ ***NOTE:
+ *
+ * @param  pMac        Pointer to Global MAC structure
+ *
+ * @return Status
+ */
+
+CDF_STATUS csr_scan_filter_results(tpAniSirGlobal pMac)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tListElem *pEntry, *pTempEntry;
+	tCsrScanResult *pBssDesc;
+	uint32_t len = sizeof(pMac->roam.validChannelList);
+
+	/* Get valid channels list from CFG */
+	if (!CDF_IS_STATUS_SUCCESS(csr_get_cfg_valid_channels(pMac,
+							      pMac->roam.
+							      validChannelList,
+							      &len))) {
+		sms_log(pMac, LOGE, "Failed to get Channel list from CFG");
+	}
+
+	csr_ll_lock(&pMac->scan.scanResultList);
+	pEntry = csr_ll_peek_head(&pMac->scan.scanResultList, LL_ACCESS_NOLOCK);
+	while (pEntry) {
+		pBssDesc = GET_BASE_ADDR(pEntry, tCsrScanResult, Link);
+		pTempEntry = csr_ll_next(&pMac->scan.scanResultList, pEntry,
+					 LL_ACCESS_NOLOCK);
+		if (csr_check11d_channel(pBssDesc->Result.BssDescriptor.channelId,
+					 pMac->roam.validChannelList, len)) {
+			/* Remove Scan result which does not have 11d channel */
+			if (csr_ll_remove_entry(&pMac->scan.scanResultList,
+				 pEntry, LL_ACCESS_NOLOCK)) {
+				csr_free_scan_result_entry(pMac, pBssDesc);
+			}
+		} else {
+			sms_log(pMac, LOG1, FL("%d is a Valid channel"),
+				pBssDesc->Result.BssDescriptor.channelId);
+		}
+		pEntry = pTempEntry;
+	}
+
+	csr_ll_unlock(&pMac->scan.scanResultList);
+	csr_ll_lock(&pMac->scan.tempScanResults);
+
+	pEntry = csr_ll_peek_head(&pMac->scan.tempScanResults,
+					 LL_ACCESS_NOLOCK);
+	while (pEntry) {
+		pBssDesc = GET_BASE_ADDR(pEntry, tCsrScanResult, Link);
+		pTempEntry = csr_ll_next(&pMac->scan.tempScanResults, pEntry,
+					 LL_ACCESS_NOLOCK);
+		if (csr_check11d_channel(pBssDesc->Result.BssDescriptor.channelId,
+					 pMac->roam.validChannelList, len)) {
+			/* Remove Scan result which does not have 11d channel */
+			if (csr_ll_remove_entry
+				    (&pMac->scan.tempScanResults, pEntry,
+				    LL_ACCESS_NOLOCK)) {
+				csr_free_scan_result_entry(pMac, pBssDesc);
+			}
+		} else {
+			sms_log(pMac, LOG1, FL("%d is a Valid channel"),
+				pBssDesc->Result.BssDescriptor.channelId);
+		}
+		pEntry = pTempEntry;
+	}
+
+	csr_ll_unlock(&pMac->scan.tempScanResults);
+	return status;
+}
+
+CDF_STATUS csr_scan_copy_result_list(tpAniSirGlobal pMac, tScanResultHandle hIn,
+				     tScanResultHandle *phResult)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tScanResultList *pRetList, *pInList = (tScanResultList *) hIn;
+	tCsrScanResult *pResult, *pScanResult;
+	uint32_t count = 0;
+	tListElem *pEntry;
+	uint32_t bssLen, allocLen;
+
+	if (phResult) {
+		*phResult = CSR_INVALID_SCANRESULT_HANDLE;
+	}
+	pRetList = cdf_mem_malloc(sizeof(tScanResultList));
+	if (NULL == pRetList)
+		status = CDF_STATUS_E_NOMEM;
+	else {
+		cdf_mem_set(pRetList, sizeof(tScanResultList), 0);
+		csr_ll_open(pMac->hHdd, &pRetList->List);
+		pRetList->pCurEntry = NULL;
+		csr_ll_lock(&pMac->scan.scanResultList);
+		csr_ll_lock(&pInList->List);
+
+		pEntry = csr_ll_peek_head(&pInList->List, LL_ACCESS_NOLOCK);
+		while (pEntry) {
+			pScanResult =
+				GET_BASE_ADDR(pEntry, tCsrScanResult, Link);
+			bssLen =
+				pScanResult->Result.BssDescriptor.length +
+				sizeof(pScanResult->Result.BssDescriptor.length);
+			allocLen = sizeof(tCsrScanResult) + bssLen;
+			pResult = cdf_mem_malloc(allocLen);
+			if (NULL == pResult)
+				status = CDF_STATUS_E_NOMEM;
+			else
+				status = CDF_STATUS_SUCCESS;
+			if (!CDF_IS_STATUS_SUCCESS(status)) {
+				csr_scan_result_purge(pMac,
+						      (tScanResultHandle *)
+						      pRetList);
+				count = 0;
+				break;
+			}
+			cdf_mem_set(pResult, allocLen, 0);
+			cdf_mem_copy(&pResult->Result.BssDescriptor,
+				     &pScanResult->Result.BssDescriptor,
+				     bssLen);
+			if (pScanResult->Result.pvIes) {
+				pResult->Result.pvIes =
+					cdf_mem_malloc(sizeof(tDot11fBeaconIEs));
+				if (NULL == pResult->Result.pvIes)
+					status = CDF_STATUS_E_NOMEM;
+				else
+					status = CDF_STATUS_SUCCESS;
+				if (!CDF_IS_STATUS_SUCCESS(status)) {
+					/* Free the memory we allocate above first */
+					cdf_mem_free(pResult);
+					csr_scan_result_purge(pMac,
+							      (tScanResultHandle *)
+							      pRetList);
+					count = 0;
+					break;
+				}
+				cdf_mem_copy(pResult->Result.pvIes,
+					     pScanResult->Result.pvIes,
+					     sizeof(tDot11fBeaconIEs));
+			}
+			csr_ll_insert_tail(&pRetList->List, &pResult->Link,
+					   LL_ACCESS_LOCK);
+			count++;
+			pEntry =
+				csr_ll_next(&pInList->List, pEntry, LL_ACCESS_NOLOCK);
+		} /* while */
+		csr_ll_unlock(&pInList->List);
+		csr_ll_unlock(&pMac->scan.scanResultList);
+
+		if (CDF_IS_STATUS_SUCCESS(status)) {
+			if (0 == count) {
+				csr_ll_close(&pRetList->List);
+				cdf_mem_free(pRetList);
+				status = CDF_STATUS_E_NULL_VALUE;
+			} else if (phResult) {
+				*phResult = pRetList;
+			}
+		}
+	} /* Allocated pRetList */
+
+	return status;
+}
+
+CDF_STATUS csr_scanning_state_msg_processor(tpAniSirGlobal pMac,
+	void *pMsgBuf)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tSirMbMsg *pMsg = (tSirMbMsg *) pMsgBuf;
+	tCsrRoamSession *pSession;
+	tSirSmeAssocIndToUpperLayerCnf *pUpperLayerAssocCnf;
+	tCsrRoamInfo roamInfo;
+	tCsrRoamInfo *pRoamInfo = NULL;
+	uint32_t sessionId;
+
+	if (eWNI_SME_SCAN_RSP == pMsg->type)
+		return csr_scan_sme_scan_response(pMac, pMsgBuf);
+
+	if (pMsg->type != eWNI_SME_UPPER_LAYER_ASSOC_CNF) {
+		if (csr_is_any_session_in_connect_state(pMac)) {
+			/*
+			 * In case of we are connected, we need to check whether
+			 * connect status changes because scan may also run
+			 * while connected.
+			 */
+			csr_roam_check_for_link_status_change(pMac,
+						(tSirSmeRsp *) pMsgBuf);
+		} else {
+			sms_log(pMac, LOGW,
+				FL("Message [0x%04x] received in wrong state"),
+				pMsg->type);
+		}
+		return status;
+	}
+
+	sms_log(pMac, LOG1,
+		FL("Scanning: ASSOC cnf can be given to upper layer"));
+	cdf_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0);
+	pRoamInfo = &roamInfo;
+	pUpperLayerAssocCnf = (tSirSmeAssocIndToUpperLayerCnf *) pMsgBuf;
+	status = csr_roam_get_session_id_from_bssid(pMac,
+			(struct cdf_mac_addr *)pUpperLayerAssocCnf->bssId, &sessionId);
+	pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("session %d not found"), sessionId);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	/* send the status code as Success */
+	pRoamInfo->statusCode = eSIR_SME_SUCCESS;
+	pRoamInfo->u.pConnectedProfile = &pSession->connectedProfile;
+	pRoamInfo->staId = (uint8_t) pUpperLayerAssocCnf->aid;
+	pRoamInfo->rsnIELen = (uint8_t) pUpperLayerAssocCnf->rsnIE.length;
+	pRoamInfo->prsnIE = pUpperLayerAssocCnf->rsnIE.rsnIEdata;
+	pRoamInfo->addIELen = (uint8_t) pUpperLayerAssocCnf->addIE.length;
+	pRoamInfo->paddIE = pUpperLayerAssocCnf->addIE.addIEdata;
+	cdf_mem_copy(pRoamInfo->peerMac.bytes,
+			pUpperLayerAssocCnf->peerMacAddr,
+			CDF_MAC_ADDR_SIZE);
+	cdf_mem_copy(&pRoamInfo->bssid.bytes, pUpperLayerAssocCnf->bssId,
+		     CDF_MAC_ADDR_SIZE);
+	pRoamInfo->wmmEnabledSta = pUpperLayerAssocCnf->wmmEnabledSta;
+	if (CSR_IS_INFRA_AP(pRoamInfo->u.pConnectedProfile)) {
+		pMac->roam.roamSession[sessionId].connectState =
+			eCSR_ASSOC_STATE_TYPE_INFRA_CONNECTED;
+		pRoamInfo->fReassocReq = pUpperLayerAssocCnf->reassocReq;
+		status = csr_roam_call_callback(pMac, sessionId,
+					pRoamInfo, 0,
+					eCSR_ROAM_INFRA_IND,
+					eCSR_ROAM_RESULT_INFRA_ASSOCIATION_CNF);
+	}
+	if (CSR_IS_WDS_AP(pRoamInfo->u.pConnectedProfile)) {
+		cdf_sleep(100);
+		pMac->roam.roamSession[sessionId].connectState =
+			eCSR_ASSOC_STATE_TYPE_WDS_CONNECTED;
+		status = csr_roam_call_callback(pMac, sessionId, pRoamInfo, 0,
+				eCSR_ROAM_WDS_IND,
+				eCSR_ROAM_RESULT_WDS_ASSOCIATION_IND);
+	}
+	return status;
+}
+
+void csr_check_n_save_wsc_ie(tpAniSirGlobal pMac, tSirBssDescription *pNewBssDescr,
+			     tSirBssDescription *pOldBssDescr)
+{
+	int idx, len;
+	uint8_t *pbIe;
+
+	/* If failed to remove, assuming someone else got it. */
+	if ((pNewBssDescr->fProbeRsp != pOldBssDescr->fProbeRsp) &&
+	    (0 == pNewBssDescr->WscIeLen)) {
+		idx = 0;
+		len = pOldBssDescr->length - sizeof(tSirBssDescription) +
+		      sizeof(uint16_t) + sizeof(uint32_t) -
+		      DOT11F_IE_WSCPROBERES_MIN_LEN - 2;
+		pbIe = (uint8_t *) pOldBssDescr->ieFields;
+		/* Save WPS IE if it exists */
+		pNewBssDescr->WscIeLen = 0;
+		while (idx < len) {
+			if ((DOT11F_EID_WSCPROBERES == pbIe[0]) &&
+			    (0x00 == pbIe[2]) && (0x50 == pbIe[3])
+			    && (0xf2 == pbIe[4]) && (0x04 == pbIe[5])) {
+				/* Founrd it */
+				if ((DOT11F_IE_WSCPROBERES_MAX_LEN - 2) >=
+				    pbIe[1]) {
+					cdf_mem_copy(pNewBssDescr->
+						     WscIeProbeRsp, pbIe,
+						     pbIe[1] + 2);
+					pNewBssDescr->WscIeLen = pbIe[1] + 2;
+				}
+				break;
+			}
+			idx += pbIe[1] + 2;
+			pbIe += pbIe[1] + 2;
+		}
+	}
+}
+
+/* pIes may be NULL */
+bool csr_remove_dup_bss_description(tpAniSirGlobal pMac,
+				    tSirBssDescription *bss_dscp,
+				    tDot11fBeaconIEs *pIes, tAniSSID *pSsid,
+				    v_TIME_t *timer, bool fForced)
+{
+	tListElem *pEntry;
+	tCsrScanResult *scan_entry;
+	bool fRC = false;
+	int8_t scan_entry_rssi = 0;
+
+	/*
+	 * Walk through all the chained BssDescriptions. If we find a chained
+	 * BssDescription that matches the BssID of the BssDescription passed
+	 * in, then these must be duplicate scan results for this Bss. In that
+	 * case, remove the 'old' Bss description from the linked list.
+	 */
+	csr_ll_lock(&pMac->scan.scanResultList);
+	pEntry = csr_ll_peek_head(&pMac->scan.scanResultList, LL_ACCESS_NOLOCK);
+
+	while (pEntry) {
+		scan_entry = GET_BASE_ADDR(pEntry, tCsrScanResult, Link);
+		/*
+		 * we have a duplicate scan results only when BSSID, SSID,
+		 * Channel and NetworkType matches
+		 */
+		if (csr_is_duplicate_bss_description(pMac,
+			&scan_entry->Result.BssDescriptor,
+			bss_dscp, pIes, fForced)) {
+			/*
+			 * Following is mathematically a = (aX + b(100-X))/100
+			 * where:
+			 * a = bss_dscp->rssi, b = scan_entry_rssi
+			 * and X = CSR_SCAN_RESULT_RSSI_WEIGHT
+			 */
+			scan_entry_rssi = scan_entry->Result.BssDescriptor.rssi;
+			bss_dscp->rssi = (int8_t) ((((int32_t) bss_dscp->rssi *
+						CSR_SCAN_RESULT_RSSI_WEIGHT) +
+				((int32_t) scan_entry_rssi *
+				 (100 - CSR_SCAN_RESULT_RSSI_WEIGHT))) / 100);
+			/* Remove the old entry from the list */
+			if (csr_ll_remove_entry
+				    (&pMac->scan.scanResultList, pEntry,
+				    LL_ACCESS_NOLOCK)) {
+				/*
+				 * we need to free the memory associated with
+				 * this node. If failed to remove, assuming
+				 * someone else got it.
+				 */
+				*pSsid = scan_entry->Result.ssId;
+				*timer = scan_entry->Result.timer;
+				csr_check_n_save_wsc_ie(pMac, bss_dscp,
+							&scan_entry->Result.
+							BssDescriptor);
+				csr_free_scan_result_entry(pMac, scan_entry);
+			} else {
+				sms_log(pMac, LOGW, FL("fail to remove entry"));
+			}
+			fRC = true;
+			/*
+			 * If we found a match, we can stop looking through
+			 * the list.
+			 */
+			break;
+		}
+		pEntry = csr_ll_next(&pMac->scan.scanResultList, pEntry,
+				     LL_ACCESS_NOLOCK);
+	}
+
+	csr_ll_unlock(&pMac->scan.scanResultList);
+	return fRC;
+}
+
+CDF_STATUS csr_add_pmkid_candidate_list(tpAniSirGlobal pMac, uint32_t sessionId,
+					tSirBssDescription *pBssDesc,
+					tDot11fBeaconIEs *pIes)
+{
+	CDF_STATUS status = CDF_STATUS_E_FAILURE;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+	tPmkidCandidateInfo *pmkid_info = NULL;
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+	WLAN_HOST_DIAG_EVENT_DEF(secEvent,
+				 host_event_wlan_security_payload_type);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("  session %d not found "), sessionId);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	sms_log(pMac, LOGW, FL("NumPmkidCandidate = %d"),
+		pSession->NumPmkidCandidate);
+	if (!pIes)
+		return status;
+		/* check if this is a RSN BSS */
+	if (!pIes->RSN.present)
+		return status;
+
+	if (pSession->NumPmkidCandidate >= CSR_MAX_PMKID_ALLOWED)
+		return CDF_STATUS_E_FAILURE;
+
+	/* BSS is capable of doing pre-authentication */
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+	cdf_mem_set(&secEvent, sizeof(host_event_wlan_security_payload_type),
+		    0);
+	secEvent.eventId = WLAN_SECURITY_EVENT_PMKID_CANDIDATE_FOUND;
+	secEvent.encryptionModeMulticast = (uint8_t)diag_enc_type_from_csr_type(
+				pSession->connectedProfile.mcEncryptionType);
+	secEvent.encryptionModeUnicast = (uint8_t)diag_enc_type_from_csr_type(
+				pSession->connectedProfile.EncryptionType);
+	cdf_mem_copy(secEvent.bssid, pSession->connectedProfile.bssid.bytes,
+			CDF_MAC_ADDR_SIZE);
+	secEvent.authMode = (uint8_t)diag_auth_type_from_csr_type(
+				pSession->connectedProfile.AuthType);
+	WLAN_HOST_DIAG_EVENT_REPORT(&secEvent, EVENT_WLAN_SECURITY);
+#endif /* #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR */
+
+	pmkid_info = &pSession->PmkidCandidateInfo[pSession->NumPmkidCandidate];
+	/* if yes, then add to PMKIDCandidateList */
+	cdf_mem_copy(pmkid_info->BSSID.bytes, pBssDesc->bssId,
+			CDF_MAC_ADDR_SIZE);
+	/* Bit 0 offirst byte - PreAuthentication Capability */
+	if ((pIes->RSN.RSN_Cap[0] >> 0) & 0x1)
+		pmkid_info->preAuthSupported = true;
+	else
+		pmkid_info->preAuthSupported = false;
+	pSession->NumPmkidCandidate++;
+	return status;
+}
+
+/*
+ * This function checks whether new AP is found for the current connected
+ * profile. If it is found, it return the sessionId, else it return invalid
+ * sessionID
+ */
+CDF_STATUS csr_process_bss_desc_for_pmkid_list(tpAniSirGlobal pMac,
+					       tSirBssDescription *pBssDesc,
+					       tDot11fBeaconIEs *pIes,
+					       uint8_t sessionId)
+{
+	tCsrRoamSession *pSession;
+	tDot11fBeaconIEs *pIesLocal = pIes;
+	CDF_STATUS status = CDF_STATUS_E_FAILURE;
+
+	if (!(pIesLocal ||
+	    CDF_IS_STATUS_SUCCESS(
+		csr_get_parsed_bss_description_ies(pMac, pBssDesc,
+						   &pIesLocal))))
+		return status;
+
+	if (!CSR_IS_SESSION_VALID(pMac, sessionId)) {
+		if (!pIes)
+			cdf_mem_free(pIesLocal);
+		return status;
+	}
+
+	pSession = CSR_GET_SESSION(pMac, sessionId);
+	if (csr_is_conn_state_connected_infra(pMac, sessionId)
+	    && (eCSR_AUTH_TYPE_RSN == pSession->connectedProfile.AuthType)
+	    && csr_match_bss_to_connect_profile(pMac,
+				&pSession->connectedProfile,
+				pBssDesc, pIesLocal)) {
+		/* This new BSS fits the current profile connected */
+		status = csr_add_pmkid_candidate_list(pMac, sessionId,
+						      pBssDesc, pIesLocal);
+		if (!CDF_IS_STATUS_SUCCESS(status))
+			sms_log(pMac, LOGE,
+				FL("csr_add_pmkid_candidate_list failed"));
+		else
+			status = CDF_STATUS_SUCCESS;
+	}
+
+	if (!pIes)
+		cdf_mem_free(pIesLocal);
+
+	return status;
+}
+
+#ifdef FEATURE_WLAN_WAPI
+CDF_STATUS csr_add_bkid_candidate_list(tpAniSirGlobal pMac, uint32_t sessionId,
+				       tSirBssDescription *pBssDesc,
+				       tDot11fBeaconIEs *pIes)
+{
+	CDF_STATUS status = CDF_STATUS_E_FAILURE;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("  session %d not found "), sessionId);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	sms_log(pMac, LOGW,
+		"csr_add_bkid_candidate_list called pMac->scan.NumBkidCandidate = %d",
+		pSession->NumBkidCandidate);
+	if (pIes) {
+		/* check if this is a WAPI BSS */
+		if (pIes->WAPI.present) {
+			/* Check if the BSS is capable of doing pre-authentication */
+			if (pSession->NumBkidCandidate < CSR_MAX_BKID_ALLOWED) {
+
+				/* if yes, then add to BKIDCandidateList */
+				cdf_mem_copy(pSession->
+					     BkidCandidateInfo[pSession->
+							       NumBkidCandidate].
+					     BSSID.bytes, pBssDesc->bssId,
+					     CDF_MAC_ADDR_SIZE);
+				if (pIes->WAPI.preauth) {
+					pSession->BkidCandidateInfo[pSession->
+								    NumBkidCandidate].
+					preAuthSupported = true;
+				} else {
+					pSession->BkidCandidateInfo[pSession->
+								    NumBkidCandidate].
+					preAuthSupported = false;
+				}
+				pSession->NumBkidCandidate++;
+			} else {
+				status = CDF_STATUS_E_FAILURE;
+			}
+		}
+	}
+
+	return status;
+}
+
+/*
+ * This function checks whether new AP is found for the current connected
+ * profile, if so add to BKIDCandidateList
+ */
+bool csr_process_bss_desc_for_bkid_list(tpAniSirGlobal pMac,
+					tSirBssDescription *pBssDesc,
+					tDot11fBeaconIEs *pIes)
+{
+	bool fRC = false;
+	tDot11fBeaconIEs *pIesLocal = pIes;
+	uint32_t sessionId;
+	tCsrRoamSession *pSession;
+	CDF_STATUS status;
+
+	if (!(pIesLocal ||
+	    CDF_IS_STATUS_SUCCESS(
+		csr_get_parsed_bss_description_ies(pMac, pBssDesc,
+						   &pIesLocal))))
+		return fRC;
+
+	for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++) {
+		if (!CSR_IS_SESSION_VALID(pMac, sessionId))
+			continue;
+		pSession = CSR_GET_SESSION(pMac, sessionId);
+		if (csr_is_conn_state_connected_infra(pMac, sessionId)
+		    && (eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE ==
+			pSession->connectedProfile.AuthType)
+		    && csr_match_bss_to_connect_profile(pMac,
+				&pSession->connectedProfile,
+				pBssDesc, pIesLocal)) {
+			/* this new BSS fits the current profile connected */
+			status = csr_add_bkid_candidate_list(pMac, sessionId,
+							pBssDesc, pIesLocal);
+			if (CDF_IS_STATUS_SUCCESS(status))
+				fRC = true;
+		}
+	}
+	if (!pIes)
+		cdf_mem_free(pIesLocal);
+	return fRC;
+}
+
+#endif
+
+static void
+csr_remove_from_tmp_list(tpAniSirGlobal mac_ctx,
+			 uint8_t reason,
+			 uint8_t session_id)
+{
+	CDF_STATUS status;
+	tListElem *entry;
+	tCsrScanResult *bss_dscp;
+	tDot11fBeaconIEs *local_ie = NULL;
+	bool dup_bss;
+	tAniSSID tmpSsid;
+	v_TIME_t timer = 0;
+
+	tmpSsid.length = 0;
+	while ((entry = csr_ll_remove_tail(&mac_ctx->scan.tempScanResults,
+					   LL_ACCESS_LOCK)) != NULL) {
+		bss_dscp = GET_BASE_ADDR(entry, tCsrScanResult, Link);
+		sms_log(mac_ctx, LOG2,
+			FL("...Bssid= "MAC_ADDRESS_STR" chan= %d, rssi = -%d"),
+			MAC_ADDR_ARRAY(bss_dscp->Result.BssDescriptor.
+				       bssId),
+			bss_dscp->Result.BssDescriptor.channelId,
+			bss_dscp->Result.BssDescriptor.rssi * (-1));
+
+		/* At this time, bss_dscp->Result.pvIes may be NULL */
+		local_ie = (tDot11fBeaconIEs *)(bss_dscp->Result.pvIes);
+		status = csr_get_parsed_bss_description_ies(mac_ctx,
+				&bss_dscp->Result.BssDescriptor, &local_ie);
+		if (!(local_ie || CDF_IS_STATUS_SUCCESS(status))) {
+			sms_log(mac_ctx, LOGE, FL("Cannot pared IEs"));
+			csr_free_scan_result_entry(mac_ctx, bss_dscp);
+			continue;
+		}
+		dup_bss = csr_remove_dup_bss_description(mac_ctx,
+				&bss_dscp->Result.BssDescriptor,
+				local_ie, &tmpSsid, &timer, false);
+		/*
+		 * Check whether we have reach out limit, but don't lose the
+		 * LFR candidates came from FW
+		 */
+		if (CSR_SCAN_IS_OVER_BSS_LIMIT(mac_ctx)) {
+			sms_log(mac_ctx, LOGW, FL("BSS limit reached"));
+			if ((bss_dscp->Result.pvIes == NULL) && local_ie)
+				cdf_mem_free(local_ie);
+			csr_free_scan_result_entry(mac_ctx, bss_dscp);
+			/* Continue because there may be duplicated BSS */
+			continue;
+		}
+		/* check for duplicate scan results */
+		if (!dup_bss) {
+			status = csr_process_bss_desc_for_pmkid_list(mac_ctx,
+					&bss_dscp->Result.BssDescriptor,
+					local_ie, session_id);
+			if (CDF_IS_STATUS_SUCCESS(status)) {
+				/* Found a new BSS */
+				csr_roam_call_callback(mac_ctx, session_id,
+					NULL, 0, eCSR_ROAM_SCAN_FOUND_NEW_BSS,
+					eCSR_ROAM_RESULT_NONE);
+			}
+		} else {
+			/*
+			 * Check if the new one has SSID it it, if not, use
+			 * the older SSID if it exists.
+			 *
+			 * New BSS has a hidden SSID and old one has the SSID.
+			 * Keep the SSID only if diff of saved SSID time and
+			 * current time is less than 1 min to avoid side effect
+			 * of saving SSID with old one is that if AP changes
+			 * its SSID while remain hidden, we may never see it
+			 * and also to address the requirement of When we remove
+			 * hidden ssid from the profile i.e., forget the SSID
+			 * via GUI that SSID shouldn't see in the profile
+			 */
+			v_TIME_t time_gap = cdf_mc_timer_get_system_time() -
+									timer;
+			if ((0 == bss_dscp->Result.ssId.length)
+			    && (time_gap <= HIDDEN_TIMER)
+			    && tmpSsid.length) {
+				bss_dscp->Result.timer = timer;
+				bss_dscp->Result.ssId = tmpSsid;
+			}
+		}
+
+		if (csr_is11d_supported(mac_ctx)
+		    && local_ie->Country.present) {
+			csr_add_vote_for_country_info(mac_ctx,
+						local_ie->Country.country);
+			sms_log(mac_ctx, LOGW,
+				FL("11d AP Bssid "MAC_ADDRESS_STR
+				   " chan= %d, rssi = -%d, countryCode %c%c"),
+				MAC_ADDR_ARRAY(
+					bss_dscp->Result.BssDescriptor.bssId),
+				bss_dscp->Result.BssDescriptor.channelId,
+				bss_dscp->Result.BssDescriptor.rssi * (-1),
+				local_ie->Country.country[0],
+				local_ie->Country.country[1]);
+		}
+		/* append to main list */
+		csr_scan_add_result(mac_ctx, bss_dscp, local_ie, session_id);
+		if ((bss_dscp->Result.pvIes == NULL) && local_ie)
+			cdf_mem_free(local_ie);
+	} /* end of loop */
+}
+
+static void csr_move_temp_scan_results_to_main_list(tpAniSirGlobal pMac,
+						    uint8_t reason,
+						    uint8_t sessionId)
+{
+	tCsrRoamSession *pSession;
+	uint32_t i;
+
+	/* remove the BSS descriptions from temporary list */
+	csr_remove_from_tmp_list(pMac, reason, sessionId);
+	/*
+	 * We don't need to update CC while connected to an AP which is
+	 * advertising CC already
+	 */
+	if (!csr_is11d_supported(pMac))
+		return;
+
+	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
+		if (!CSR_IS_SESSION_VALID(pMac, i))
+			continue;
+		pSession = CSR_GET_SESSION(pMac, i);
+		if (csr_is_conn_state_connected(pMac, i)) {
+			sms_log(pMac, LOGW,
+				FL("No need to update CC in connected state"));
+			return;
+		}
+	}
+	csr_elected_country_info(pMac);
+	csr_learn_11dcountry_information(pMac, NULL, NULL, true);
+}
+
+static tCsrScanResult *csr_scan_save_bss_description(tpAniSirGlobal pMac,
+						     tSirBssDescription *
+						     pBSSDescription,
+						     tDot11fBeaconIEs *pIes,
+						     uint8_t sessionId)
+{
+	tCsrScanResult *pCsrBssDescription = NULL;
+	uint32_t cbBSSDesc;
+	uint32_t cbAllocated;
+
+	/* figure out how big the BSS description is (the BSSDesc->length does NOT */
+	/* include the size of the length field itself). */
+	cbBSSDesc = pBSSDescription->length + sizeof(pBSSDescription->length);
+
+	cbAllocated = sizeof(tCsrScanResult) + cbBSSDesc;
+
+	pCsrBssDescription = cdf_mem_malloc(cbAllocated);
+	if (NULL != pCsrBssDescription) {
+		cdf_mem_set(pCsrBssDescription, cbAllocated, 0);
+		pCsrBssDescription->AgingCount =
+			(int32_t) pMac->roam.configParam.agingCount;
+		sms_log(pMac, LOGW,
+			FL(" Set Aging Count = %d for BSS " MAC_ADDRESS_STR " "),
+			pCsrBssDescription->AgingCount,
+			MAC_ADDR_ARRAY(pCsrBssDescription->Result.BssDescriptor.
+				       bssId));
+		cdf_mem_copy(&pCsrBssDescription->Result.BssDescriptor,
+			     pBSSDescription, cbBSSDesc);
+#if defined(CDF_ENSBALED)
+		if (NULL != pCsrBssDescription->Result.pvIes) {
+			CDF_ASSERT(pCsrBssDescription->Result.pvIes == NULL);
+			return NULL;
+		}
+#endif
+		csr_scan_add_result(pMac, pCsrBssDescription, pIes, sessionId);
+	}
+
+	return pCsrBssDescription;
+}
+
+/* Append a Bss Description... */
+tCsrScanResult *csr_scan_append_bss_description(tpAniSirGlobal pMac,
+						tSirBssDescription *
+						pSirBssDescription,
+						tDot11fBeaconIEs *pIes,
+						bool fForced, uint8_t sessionId)
+{
+	tCsrScanResult *pCsrBssDescription = NULL;
+	tAniSSID tmpSsid;
+	v_TIME_t timer = 0;
+	int result;
+
+	tmpSsid.length = 0;
+	result = csr_remove_dup_bss_description(pMac, pSirBssDescription,
+						pIes, &tmpSsid, &timer,
+						fForced);
+	pCsrBssDescription = csr_scan_save_bss_description(pMac,
+					pSirBssDescription, pIes, sessionId);
+	if (result && (pCsrBssDescription != NULL)) {
+		/*
+		* Check if the new one has SSID it it, if not, use the older
+		* SSID if it exists.
+		*/
+		if ((0 == pCsrBssDescription->Result.ssId.length)
+		    && tmpSsid.length) {
+			/*
+			 * New BSS has a hidden SSID and old one has the SSID.
+			 * Keep the SSID only if diff of saved SSID time and
+			 * current time is less than 1 min to avoid side effect
+			 * of saving SSID with old one is that if AP changes its
+			 * SSID while remain hidden, we may never see it and
+			 * also to address the requirement of. When we remove
+			 * hidden ssid from the profile i.e., forget the SSID
+			 * via GUI that SSID shouldn't see in the profile
+			 */
+			if ((cdf_mc_timer_get_system_time() - timer) <=
+			    HIDDEN_TIMER) {
+				pCsrBssDescription->Result.ssId = tmpSsid;
+				pCsrBssDescription->Result.timer = timer;
+			}
+		}
+	}
+
+	return pCsrBssDescription;
+}
+
+void csr_purge_channel_power(tpAniSirGlobal pMac, tDblLinkList *pChannelList)
+{
+	tCsrChannelPowerInfo *pChannelSet;
+	tListElem *pEntry;
+
+	csr_ll_lock(pChannelList);
+	/*
+	* Remove the channel sets from the learned list and put them
+	* in the free list
+	*/
+	while ((pEntry = csr_ll_remove_head(pChannelList,
+					    LL_ACCESS_NOLOCK)) != NULL) {
+		pChannelSet = GET_BASE_ADDR(pEntry, tCsrChannelPowerInfo, link);
+		if (pChannelSet)
+			cdf_mem_free(pChannelSet);
+	}
+	csr_ll_unlock(pChannelList);
+	return;
+}
+
+/*
+ * Save the channelList into the ultimate storage as the final stage of channel
+ * Input: pCountryInfo -- the country code (e.g. "USI"), channel list, and power
+ * limit are all stored inside this data structure
+ */
+CDF_STATUS csr_save_to_channel_power2_g_5_g(tpAniSirGlobal pMac,
+					    uint32_t tableSize,
+					    tSirMacChanInfo *channelTable)
+{
+	uint32_t i = tableSize / sizeof(tSirMacChanInfo);
+	tSirMacChanInfo *pChannelInfo;
+	tCsrChannelPowerInfo *pChannelSet;
+	bool f2GHzInfoFound = false;
+	bool f2GListPurged = false, f5GListPurged = false;
+
+	pChannelInfo = channelTable;
+	/* atleast 3 bytes have to be remaining  -- from "countryString" */
+	while (i--) {
+		pChannelSet = cdf_mem_malloc(sizeof(tCsrChannelPowerInfo));
+		if (NULL == pChannelSet) {
+			pChannelInfo++;
+			continue;
+		}
+		cdf_mem_set(pChannelSet, sizeof(tCsrChannelPowerInfo), 0);
+		pChannelSet->firstChannel = pChannelInfo->firstChanNum;
+		pChannelSet->numChannels = pChannelInfo->numChannels;
+		/*
+		 * Now set the inter-channel offset based on the frequency band
+		 * the channel set lies in
+		 */
+		if ((CDS_IS_CHANNEL_24GHZ(pChannelSet->firstChannel)) &&
+		    ((pChannelSet->firstChannel +
+		      (pChannelSet->numChannels - 1)) <=
+		     CDS_MAX_24GHz_CHANNEL_NUMBER)) {
+			pChannelSet->interChannelOffset = 1;
+			f2GHzInfoFound = true;
+		} else if ((CDS_IS_CHANNEL_5GHZ(pChannelSet->firstChannel))
+		    && ((pChannelSet->firstChannel +
+		      ((pChannelSet->numChannels - 1) * 4)) <=
+		     CDS_MAX_5GHz_CHANNEL_NUMBER)) {
+			pChannelSet->interChannelOffset = 4;
+			f2GHzInfoFound = false;
+		} else {
+			sms_log(pMac, LOGW,
+				FL("Invalid Channel %d Present in Country IE"),
+				pChannelSet->firstChannel);
+			cdf_mem_free(pChannelSet);
+			return CDF_STATUS_E_FAILURE;
+		}
+		pChannelSet->txPower = CDF_MIN(pChannelInfo->maxTxPower,
+					pMac->roam.configParam.nTxPowerCap);
+		if (f2GHzInfoFound) {
+			if (!f2GListPurged) {
+				/* purge previous results if found new */
+				csr_purge_channel_power(pMac,
+							&pMac->scan.
+							channelPowerInfoList24);
+				f2GListPurged = true;
+			}
+			if (CSR_IS_OPERATING_BG_BAND(pMac)) {
+				/* add to the list of 2.4 GHz channel sets */
+				csr_ll_insert_tail(&pMac->scan.
+						   channelPowerInfoList24,
+						   &pChannelSet->link,
+						   LL_ACCESS_LOCK);
+			} else {
+				sms_log(pMac, LOGW,
+					FL("Adding 11B/G ch in 11A. 1st ch %d"),
+					pChannelSet->firstChannel);
+				cdf_mem_free(pChannelSet);
+			}
+		} else {
+			/* 5GHz info found */
+			if (!f5GListPurged) {
+				/* purge previous results if found new */
+				csr_purge_channel_power(pMac,
+							&pMac->scan.
+							channelPowerInfoList5G);
+				f5GListPurged = true;
+			}
+			if (CSR_IS_OPERATING_A_BAND(pMac)) {
+				/* add to the list of 5GHz channel sets */
+				csr_ll_insert_tail(&pMac->scan.
+						   channelPowerInfoList5G,
+						   &pChannelSet->link,
+						   LL_ACCESS_LOCK);
+			} else {
+				sms_log(pMac, LOGW,
+					FL("Adding 11A ch in B/G. 1st ch %d"),
+					pChannelSet->firstChannel);
+				cdf_mem_free(pChannelSet);
+			}
+		}
+		pChannelInfo++; /* move to next entry */
+	}
+	return CDF_STATUS_SUCCESS;
+}
+
+static void csr_clear_dfs_channel_list(tpAniSirGlobal pMac)
+{
+	tSirMbMsg *pMsg;
+	uint16_t msgLen;
+
+	msgLen = (uint16_t) (sizeof(tSirMbMsg));
+	pMsg = cdf_mem_malloc(msgLen);
+	if (NULL != pMsg) {
+		cdf_mem_set((void *)pMsg, msgLen, 0);
+		pMsg->type = eWNI_SME_CLEAR_DFS_CHANNEL_LIST;
+		pMsg->msgLen = msgLen;
+		cds_send_mb_message_to_mac(pMsg);
+	}
+}
+
+void csr_apply_power2_current(tpAniSirGlobal pMac)
+{
+	sms_log(pMac, LOG3, FL(" Updating Cfg with power settings"));
+	csr_save_tx_power_to_cfg(pMac, &pMac->scan.channelPowerInfoList24,
+				 WNI_CFG_MAX_TX_POWER_2_4);
+	csr_save_tx_power_to_cfg(pMac, &pMac->scan.channelPowerInfoList5G,
+				 WNI_CFG_MAX_TX_POWER_5);
+}
+
+void csr_apply_channel_power_info_to_fw(tpAniSirGlobal mac_ctx,
+					  tCsrChannel *ch_lst,
+					  uint8_t *countryCode)
+{
+	int i;
+	uint8_t num_ch = 0;
+	uint8_t tempNumChannels = 0;
+	tCsrChannel tmp_ch_lst;
+
+	if (ch_lst->numChannels) {
+		tempNumChannels = CSR_MIN(ch_lst->numChannels,
+					  WNI_CFG_VALID_CHANNEL_LIST_LEN);
+		for (i = 0; i < tempNumChannels; i++) {
+			tmp_ch_lst.channelList[num_ch] = ch_lst->channelList[i];
+			num_ch++;
+		}
+		tmp_ch_lst.numChannels = num_ch;
+		/* Store the channel+power info in the global place: Cfg */
+		csr_apply_power2_current(mac_ctx);
+		csr_set_cfg_valid_channel_list(mac_ctx, tmp_ch_lst.channelList,
+					       tmp_ch_lst.numChannels);
+		/*
+		 * extend scan capability, build a scan list based on the
+		 * channel list : channel# + active/passive scan
+		 */
+		csr_set_cfg_scan_control_list(mac_ctx, countryCode,
+					      &tmp_ch_lst);
+		/* Send msg to Lim to clear DFS channel list */
+		csr_clear_dfs_channel_list(mac_ctx);
+	} else {
+		sms_log(mac_ctx, LOGE, FL("11D channel list is empty"));
+	}
+	csr_set_cfg_country_code(mac_ctx, countryCode);
+}
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+static void csr_diag_reset_country_information(tpAniSirGlobal pMac)
+{
+
+	host_log_802_11d_pkt_type *p11dLog;
+	int Index;
+	WLAN_HOST_DIAG_LOG_ALLOC(p11dLog, host_log_802_11d_pkt_type,
+				 LOG_WLAN_80211D_C);
+	if (!p11dLog)
+		return;
+
+	p11dLog->eventId = WLAN_80211D_EVENT_RESET;
+	cdf_mem_copy(p11dLog->countryCode, pMac->scan.countryCodeCurrent, 3);
+	p11dLog->numChannel = pMac->scan.base_channels.numChannels;
+	if (p11dLog->numChannel <= HOST_LOG_MAX_NUM_CHANNEL) {
+		cdf_mem_copy(p11dLog->Channels,
+			     pMac->scan.base_channels.channelList,
+			     p11dLog->numChannel);
+		for (Index = 0;
+		     Index < pMac->scan.base_channels.numChannels;
+		     Index++) {
+			p11dLog->TxPwr[Index] = CDF_MIN(
+				pMac->scan.defaultPowerTable[Index].pwr,
+				pMac->roam.configParam.nTxPowerCap);
+		}
+	}
+	if (!pMac->roam.configParam.Is11dSupportEnabled)
+		p11dLog->supportMultipleDomain = WLAN_80211D_DISABLED;
+	else
+		p11dLog->supportMultipleDomain =
+			WLAN_80211D_SUPPORT_MULTI_DOMAIN;
+	WLAN_HOST_DIAG_LOG_REPORT(p11dLog);
+}
+#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
+
+/**
+ * csr_apply_channel_power_info_wrapper() - sends channel info to fw
+ * @pMac: main MAC data structure
+ *
+ * This function sends the channel power info to firmware
+ *
+ * Return: none
+ */
+void csr_apply_channel_power_info_wrapper(tpAniSirGlobal pMac)
+{
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+	csr_diag_reset_country_information(pMac);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
+	csr_prune_channel_list_for_mode(pMac, &pMac->scan.base_channels);
+	csr_save_channel_power_for_band(pMac, false);
+	csr_save_channel_power_for_band(pMac, true);
+	/* apply the channel list, power settings, and the country code. */
+	csr_apply_channel_power_info_to_fw(pMac,
+		&pMac->scan.base_channels, pMac->scan.countryCodeCurrent);
+	/* clear the 11d channel list */
+	cdf_mem_set(&pMac->scan.channels11d, sizeof(pMac->scan.channels11d), 0);
+}
+
+void csr_clear_votes_for_country_info(tpAniSirGlobal pMac)
+{
+	pMac->scan.countryCodeCount = 0;
+	cdf_mem_set(pMac->scan.votes11d,
+		    sizeof(tCsrVotes11d) * CSR_MAX_NUM_COUNTRY_CODE, 0);
+}
+
+void csr_add_vote_for_country_info(tpAniSirGlobal pMac, uint8_t *pCountryCode)
+{
+	bool match = false;
+	uint8_t i;
+
+	/* convert to UPPER here so we are assured
+	 * the strings are always in upper case.
+	 */
+	for (i = 0; i < 3; i++) {
+		pCountryCode[i] = (uint8_t) csr_to_upper(pCountryCode[i]);
+	}
+
+	/* Some of the 'old' Cisco 350 series AP's advertise NA as the
+	 * country code (for North America ??). NA is not a valid country code
+	 * or domain so let's allow this by changing it to the proper
+	 * country code (which is US).  We've also seen some NETGEAR AP's
+	 * that have "XX " as the country code with valid 2.4 GHz US channel
+	 * information.  If we cannot find the country code advertised in the
+	 * 11d information element, let's default to US.
+	 */
+
+	if (!CDF_IS_STATUS_SUCCESS(csr_get_regulatory_domain_for_country(pMac,
+						pCountryCode, NULL,
+						COUNTRY_QUERY))) {
+		pCountryCode[0] = '0';
+		pCountryCode[1] = '0';
+	}
+
+	/* We've seen some of the AP's improperly put a 0 for the
+	 * third character of the country code. spec says valid charcters are
+	 * 'O' (for outdoor), 'I' for Indoor, or ' ' (space; for either).
+	 * if we see a 0 in this third character, let's change it to a ' '.
+	 */
+	if (0 == pCountryCode[2]) {
+		pCountryCode[2] = ' ';
+	}
+
+	for (i = 0; i < pMac->scan.countryCodeCount; i++) {
+		match = (cdf_mem_compare(pMac->scan.votes11d[i].countryCode,
+					 pCountryCode, 2));
+		if (match) {
+			break;
+		}
+	}
+
+	if (match) {
+		pMac->scan.votes11d[i].votes++;
+	} else {
+		cdf_mem_copy(pMac->scan.votes11d[pMac->scan.countryCodeCount].
+			     countryCode, pCountryCode, 3);
+		pMac->scan.votes11d[pMac->scan.countryCodeCount].votes = 1;
+		pMac->scan.countryCodeCount++;
+	}
+
+	return;
+}
+
+bool csr_elected_country_info(tpAniSirGlobal pMac)
+{
+	bool fRet = false;
+	uint8_t maxVotes = 0;
+	uint8_t i, j = 0;
+
+	if (!pMac->scan.countryCodeCount) {
+		return fRet;
+	}
+	maxVotes = pMac->scan.votes11d[0].votes;
+	fRet = true;
+
+	for (i = 1; i < pMac->scan.countryCodeCount; i++) {
+		/* If we have a tie for max votes for 2 different country codes,
+		 * pick random.we can put some more intelligence - TBD
+		 */
+		if (maxVotes < pMac->scan.votes11d[i].votes) {
+			CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
+				  " Votes for Country %c%c : %d\n",
+				  pMac->scan.votes11d[i].countryCode[0],
+				  pMac->scan.votes11d[i].countryCode[1],
+				  pMac->scan.votes11d[i].votes);
+
+			maxVotes = pMac->scan.votes11d[i].votes;
+			j = i;
+			fRet = true;
+		}
+
+	}
+	if (fRet) {
+		cdf_mem_copy(pMac->scan.countryCodeElected,
+		       pMac->scan.votes11d[j].countryCode,
+		       WNI_CFG_COUNTRY_CODE_LEN);
+		cdf_mem_copy(pMac->scan.countryCode11d,
+		       pMac->scan.votes11d[j].countryCode,
+		       WNI_CFG_COUNTRY_CODE_LEN);
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
+			  "Selected Country is %c%c With count %d\n",
+			  pMac->scan.votes11d[j].countryCode[0],
+			  pMac->scan.votes11d[j].countryCode[1],
+			  pMac->scan.votes11d[j].votes);
+	}
+	return fRet;
+}
+
+/**
+ * csr_set_country_code() - Set country code
+ * @pMac: main MAC data structure
+ * @pCountry: ptr to Country Code
+ *
+ * This function sends the channel power info to firmware
+ *
+ * Return: none
+ */
+CDF_STATUS csr_set_country_code(tpAniSirGlobal pMac, uint8_t *pCountry)
+{
+	CDF_STATUS status = CDF_STATUS_E_INVAL;
+	v_REGDOMAIN_t domainId;
+
+	if (pCountry) {
+
+		status = csr_get_regulatory_domain_for_country(pMac, pCountry,
+							       &domainId,
+							       COUNTRY_USER);
+		if (CDF_IS_STATUS_SUCCESS(status)) {
+			cdf_mem_copy(pMac->scan.countryCodeCurrent,
+				     pCountry,
+				     WNI_CFG_COUNTRY_CODE_LEN);
+			csr_set_cfg_country_code(pMac, pCountry);
+		}
+	}
+	return status;
+}
+
+/* caller allocated memory for pNumChn and pChnPowerInfo */
+/* As input, *pNumChn has the size of the array of pChnPowerInfo */
+/* Upon return, *pNumChn has the number of channels assigned. */
+void csr_get_channel_power_info(tpAniSirGlobal pMac, tDblLinkList *list,
+				uint32_t *num_ch,
+				tChannelListWithPower *chn_pwr_info)
+{
+	tListElem *entry;
+	uint32_t chn_idx = 0, idx;
+	tCsrChannelPowerInfo *ch_set;
+
+	/* Get 2.4Ghz first */
+	entry = csr_ll_peek_head(list, LL_ACCESS_LOCK);
+	while (entry && (chn_idx < *num_ch)) {
+		ch_set = GET_BASE_ADDR(entry, tCsrChannelPowerInfo, link);
+		for (idx = 0; (idx < ch_set->numChannels)
+				&& (chn_idx < *num_ch); idx++) {
+			chn_pwr_info[chn_idx].chanId =
+				(uint8_t) (ch_set->firstChannel
+				 + (idx * ch_set->interChannelOffset));
+			chn_pwr_info[chn_idx++].pwr = ch_set->txPower;
+		}
+		entry = csr_ll_next(list, entry, LL_ACCESS_LOCK);
+	}
+	*num_ch = chn_idx;
+
+	return;
+}
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+void csr_diag_apply_country_info(tpAniSirGlobal mac_ctx)
+{
+	host_log_802_11d_pkt_type *p11dLog;
+	tChannelListWithPower chnPwrInfo[WNI_CFG_VALID_CHANNEL_LIST_LEN];
+	uint32_t nChnInfo = WNI_CFG_VALID_CHANNEL_LIST_LEN, nTmp;
+
+	WLAN_HOST_DIAG_LOG_ALLOC(p11dLog, host_log_802_11d_pkt_type,
+				 LOG_WLAN_80211D_C);
+	if (!p11dLog)
+		return;
+
+	p11dLog->eventId = WLAN_80211D_EVENT_COUNTRY_SET;
+	cdf_mem_copy(p11dLog->countryCode, mac_ctx->scan.countryCode11d, 3);
+	p11dLog->numChannel = mac_ctx->scan.channels11d.numChannels;
+	if (p11dLog->numChannel > HOST_LOG_MAX_NUM_CHANNEL)
+		goto diag_end;
+
+	cdf_mem_copy(p11dLog->Channels,
+		     mac_ctx->scan.channels11d.channelList,
+		     p11dLog->numChannel);
+	csr_get_channel_power_info(mac_ctx,
+				&mac_ctx->scan.channelPowerInfoList24,
+				&nChnInfo, chnPwrInfo);
+	nTmp = nChnInfo;
+	nChnInfo = WNI_CFG_VALID_CHANNEL_LIST_LEN - nTmp;
+	csr_get_channel_power_info(mac_ctx,
+				&mac_ctx->scan.channelPowerInfoList5G,
+				&nChnInfo, &chnPwrInfo[nTmp]);
+	for (nTmp = 0; nTmp < p11dLog->numChannel; nTmp++) {
+		for (nChnInfo = 0;
+		     nChnInfo < WNI_CFG_VALID_CHANNEL_LIST_LEN;
+		     nChnInfo++) {
+			if (p11dLog->Channels[nTmp] ==
+			    chnPwrInfo[nChnInfo].chanId) {
+				p11dLog->TxPwr[nTmp] =
+					chnPwrInfo[nChnInfo].pwr;
+				break;
+			}
+		}
+	}
+diag_end:
+	if (!mac_ctx->roam.configParam.Is11dSupportEnabled)
+		p11dLog->supportMultipleDomain = WLAN_80211D_DISABLED;
+	else
+		p11dLog->supportMultipleDomain =
+				WLAN_80211D_SUPPORT_MULTI_DOMAIN;
+	WLAN_HOST_DIAG_LOG_REPORT(p11dLog);
+}
+#endif /* #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR */
+
+/**
+ * csr_apply_country_information() - apply country code information
+ * @pMac: core MAC data structure
+ *
+ * This function programs the new country code
+ *
+ * Return: none
+ */
+void csr_apply_country_information(tpAniSirGlobal pMac)
+{
+	v_REGDOMAIN_t domainId;
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+
+	if (!csr_is11d_supported(pMac)
+	    || 0 == pMac->scan.channelOf11dInfo)
+		return;
+	status = csr_get_regulatory_domain_for_country(pMac,
+			pMac->scan.countryCode11d, &domainId, COUNTRY_QUERY);
+	if (!CDF_IS_STATUS_SUCCESS(status))
+		return;
+	/* Check whether we need to enforce default domain */
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+	csr_diag_apply_country_info(pMac);
+#endif /* #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR */
+
+	if (pMac->scan.domainIdCurrent != domainId)
+		return;
+	if (pMac->scan.domainIdCurrent != domainId) {
+		sms_log(pMac, LOGW, FL("Domain Changed Old %d, new %d"),
+			pMac->scan.domainIdCurrent, domainId);
+		status = wma_set_reg_domain(pMac, domainId);
+	}
+	if (status != CDF_STATUS_SUCCESS)
+		sms_log(pMac, LOGE, FL("fail to set regId %d"), domainId);
+	pMac->scan.domainIdCurrent = domainId;
+	/* switch to active scans using this new channel list */
+	pMac->scan.curScanType = eSIR_ACTIVE_SCAN;
+}
+
+void csr_save_channel_power_for_band(tpAniSirGlobal pMac, bool fill_5f)
+{
+	uint32_t idx, count = 0;
+	tSirMacChanInfo *chan_info;
+	tSirMacChanInfo *ch_info_start;
+	int32_t max_ch_idx;
+	bool tmp_bool;
+	uint8_t ch = 0;
+
+	max_ch_idx =
+		(pMac->scan.base_channels.numChannels <
+		WNI_CFG_VALID_CHANNEL_LIST_LEN) ?
+		pMac->scan.base_channels.numChannels :
+		WNI_CFG_VALID_CHANNEL_LIST_LEN;
+
+	chan_info = cdf_mem_malloc(sizeof(tSirMacChanInfo) *
+				   WNI_CFG_VALID_CHANNEL_LIST_LEN);
+	if (NULL == chan_info)
+		return;
+
+	cdf_mem_set(chan_info, sizeof(tSirMacChanInfo) *
+		    WNI_CFG_VALID_CHANNEL_LIST_LEN, 0);
+	ch_info_start = chan_info;
+	for (idx = 0; idx < max_ch_idx; idx++) {
+		ch = pMac->scan.defaultPowerTable[idx].chanId;
+		tmp_bool =  (fill_5f && CDS_IS_CHANNEL_5GHZ(ch))
+			|| (!fill_5f && CDS_IS_CHANNEL_24GHZ(ch));
+		if (!tmp_bool)
+			continue;
+
+		if (count >= WNI_CFG_VALID_CHANNEL_LIST_LEN) {
+			sms_log(pMac, LOGW, FL("count(%d) exceeded"), count);
+			break;
+		}
+
+		chan_info->firstChanNum =
+			pMac->scan.defaultPowerTable[idx].chanId;
+		chan_info->numChannels = 1;
+		chan_info->maxTxPower =
+			CDF_MIN(pMac->scan.defaultPowerTable[idx].pwr,
+				pMac->roam.configParam.nTxPowerCap);
+		chan_info++;
+		count++;
+	}
+	if (count) {
+		csr_save_to_channel_power2_g_5_g(pMac,
+				count * sizeof(tSirMacChanInfo), ch_info_start);
+	}
+	cdf_mem_free(ch_info_start);
+}
+
+bool csr_is_supported_channel(tpAniSirGlobal pMac, uint8_t channelId)
+{
+	bool fRet = false;
+	uint32_t i;
+
+	for (i = 0; i < pMac->scan.base_channels.numChannels; i++) {
+		if (channelId ==
+		    pMac->scan.base_channels.channelList[i]) {
+			fRet = true;
+			break;
+		}
+	}
+
+	return fRet;
+}
+
+/*
+ * 802.11D only: Gather 11d IE via beacon or Probe response and store them in pAdapter->channels11d
+ */
+bool csr_learn_11dcountry_information(tpAniSirGlobal pMac,
+				   tSirBssDescription *pSirBssDesc,
+				   tDot11fBeaconIEs *pIes, bool fForce)
+{
+	CDF_STATUS status;
+	uint8_t *pCountryCodeSelected;
+	bool fRet = false;
+	v_REGDOMAIN_t domainId;
+	tDot11fBeaconIEs *pIesLocal = pIes;
+	bool useVoting = false;
+
+	if (CDF_SAP_MODE == cds_get_conparam())
+		return CDF_STATUS_SUCCESS;
+
+	if ((NULL == pSirBssDesc) && (NULL == pIes))
+		useVoting = true;
+
+	/* check if .11d support is enabled */
+	if (!csr_is11d_supported(pMac))
+		goto free_ie;
+
+	if (false == useVoting) {
+		if (!pIesLocal &&
+		   (!CDF_IS_STATUS_SUCCESS(
+			csr_get_parsed_bss_description_ies(
+				pMac, pSirBssDesc, &pIesLocal))))
+			goto free_ie;
+		/* check if country information element is present */
+		if (!pIesLocal->Country.present)
+			/* No country info */
+			goto free_ie;
+		status = csr_get_regulatory_domain_for_country(pMac,
+				pIesLocal->Country.country, &domainId,
+				COUNTRY_QUERY);
+		if (CDF_IS_STATUS_SUCCESS(status)
+		    && (domainId == REGDOMAIN_WORLD))
+			goto free_ie;
+	} /* useVoting == false */
+
+	if (false == useVoting)
+		pCountryCodeSelected = pIesLocal->Country.country;
+	else
+		pCountryCodeSelected = pMac->scan.countryCodeElected;
+
+	status = csr_get_regulatory_domain_for_country(pMac,
+				pCountryCodeSelected, &domainId, COUNTRY_IE);
+	if (status != CDF_STATUS_SUCCESS) {
+		sms_log(pMac, LOGE, FL("fail to get regId %d"), domainId);
+		fRet = false;
+		goto free_ie;
+	}
+
+	/* updating 11d Country Code with Country code selected. */
+	cdf_mem_copy(pMac->scan.countryCode11d, pCountryCodeSelected,
+		     WNI_CFG_COUNTRY_CODE_LEN);
+	fRet = true;
+free_ie:
+	if (!pIes && pIesLocal) {
+		/* locally allocated */
+		cdf_mem_free(pIesLocal);
+	}
+	return fRet;
+}
+
+void csr_save_scan_results(tpAniSirGlobal pMac, uint8_t reason,
+				  uint8_t sessionId)
+{
+	sms_log(pMac, LOG4, "%s: Saving scan results", __func__);
+
+	/* initialize this to false. profMoveInterimScanResultsToMainList() routine */
+	/* will set this to the channel where an .11d beacon is seen */
+	pMac->scan.channelOf11dInfo = 0;
+	/* move the scan results from interim list to the main scan list */
+	csr_move_temp_scan_results_to_main_list(pMac, reason, sessionId);
+
+	/* Now check if we gathered any domain/country specific information */
+	/* If so, we should update channel list and apply Tx power settings */
+	if (csr_is11d_supported(pMac)) {
+		csr_apply_country_information(pMac);
+	}
+}
+
+void csr_reinit_scan_cmd(tpAniSirGlobal pMac, tSmeCmd *pCommand)
+{
+	switch (pCommand->u.scanCmd.reason) {
+	case eCsrScanAbortNormalScan:
+	default:
+		csr_scan_free_request(pMac, &pCommand->u.scanCmd.u.scanRequest);
+		break;
+	}
+	if (pCommand->u.scanCmd.pToRoamProfile) {
+		csr_release_profile(pMac, pCommand->u.scanCmd.pToRoamProfile);
+		cdf_mem_free(pCommand->u.scanCmd.pToRoamProfile);
+	}
+	cdf_mem_set(&pCommand->u.scanCmd, sizeof(tScanCmd), 0);
+}
+
+eCsrScanCompleteNextCommand csr_scan_get_next_command_state(tpAniSirGlobal pMac,
+							    tSmeCmd *pCommand,
+							    bool fSuccess)
+{
+	eCsrScanCompleteNextCommand NextCommand = eCsrNextScanNothing;
+
+	switch (pCommand->u.scanCmd.reason) {
+	case eCsrScan11d1:
+		NextCommand =
+			(fSuccess) ? eCsrNext11dScan1Success :
+			eCsrNext11dScan1Failure;
+		break;
+	case eCsrScan11d2:
+		NextCommand =
+			(fSuccess) ? eCsrNext11dScan2Success :
+			eCsrNext11dScan2Failure;
+		break;
+	case eCsrScan11dDone:
+		NextCommand = eCsrNext11dScanComplete;
+		break;
+	case eCsrScanLostLink1:
+		NextCommand =
+			(fSuccess) ? eCsrNextLostLinkScan1Success :
+			eCsrNextLostLinkScan1Failed;
+		break;
+	case eCsrScanLostLink2:
+		NextCommand =
+			(fSuccess) ? eCsrNextLostLinkScan2Success :
+			eCsrNextLostLinkScan2Failed;
+		break;
+	case eCsrScanLostLink3:
+		NextCommand =
+			(fSuccess) ? eCsrNextLostLinkScan3Success :
+			eCsrNextLostLinkScan3Failed;
+		break;
+	case eCsrScanForSsid:
+		NextCommand =
+			(fSuccess) ? eCsrNexteScanForSsidSuccess :
+			eCsrNexteScanForSsidFailure;
+		break;
+	default:
+		NextCommand = eCsrNextScanNothing;
+		break;
+	}
+	return NextCommand;
+}
+
+/* Return whether the pCommand is finished. */
+bool csr_handle_scan11d1_failure(tpAniSirGlobal pMac, tSmeCmd *pCommand)
+{
+	bool fRet = true;
+
+	/* Apply back the default setting and passively scan one more time. */
+	csr_apply_channel_power_info_wrapper(pMac);
+	pCommand->u.scanCmd.reason = eCsrScan11d2;
+	if (CDF_IS_STATUS_SUCCESS(csr_scan_channels(pMac, pCommand))) {
+		fRet = false;
+	}
+
+	return fRet;
+}
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+static void
+csr_diag_scan_complete(tpAniSirGlobal pMac,
+		       tSmeCmd *pCommand,
+		       tSirSmeScanRsp *pScanRsp)
+{
+	host_log_scan_pkt_type *pScanLog = NULL;
+	tScanResultHandle hScanResult;
+	tCsrScanResultInfo *pScanResult;
+	tDot11fBeaconIEs *pIes;
+	int n = 0, c = 0;
+	CDF_STATUS status;
+
+	WLAN_HOST_DIAG_LOG_ALLOC(pScanLog,
+				 host_log_scan_pkt_type,
+				 LOG_WLAN_SCAN_C);
+	if (!pScanLog)
+		return;
+
+	if (eCsrScanProbeBss == pCommand->u.scanCmd.reason) {
+		pScanLog->eventId = WLAN_SCAN_EVENT_HO_SCAN_RSP;
+	} else {
+		if (eSIR_PASSIVE_SCAN != pMac->scan.curScanType)
+			pScanLog->eventId = WLAN_SCAN_EVENT_ACTIVE_SCAN_RSP;
+		else
+			pScanLog->eventId = WLAN_SCAN_EVENT_PASSIVE_SCAN_RSP;
+	}
+	if (eSIR_SME_SUCCESS != pScanRsp->statusCode) {
+		pScanLog->status = WLAN_SCAN_STATUS_FAILURE;
+		WLAN_HOST_DIAG_LOG_REPORT(pScanLog);
+		return;
+	}
+
+	status = csr_scan_get_result(pMac, NULL, &hScanResult);
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		WLAN_HOST_DIAG_LOG_REPORT(pScanLog);
+		return;
+	}
+
+	pScanResult = csr_scan_result_get_next(pMac, hScanResult);
+	while (pScanResult != NULL) {
+		if (n < HOST_LOG_MAX_NUM_BSSID) {
+			status = csr_get_parsed_bss_description_ies(pMac,
+					&pScanResult->BssDescriptor, &pIes);
+			if (!CDF_IS_STATUS_SUCCESS(status)) {
+				sms_log(pMac, LOGE, FL("fail to parse IEs"));
+				break;
+			}
+			cdf_mem_copy(pScanLog->bssid[n],
+				pScanResult->BssDescriptor.bssId, 6);
+			if (pIes && pIes->SSID.present &&
+			    HOST_LOG_MAX_SSID_SIZE >= pIes->SSID.num_ssid) {
+				cdf_mem_copy(pScanLog->ssid[n],
+					pIes->SSID.ssid,
+					pIes->SSID.num_ssid);
+			}
+			cdf_mem_free(pIes);
+			n++;
+		}
+		c++;
+		pScanResult = csr_scan_result_get_next(pMac, hScanResult);
+	}
+	pScanLog->numSsid = (uint8_t) n;
+	pScanLog->totalSsid = (uint8_t) c;
+	csr_scan_result_purge(pMac, hScanResult);
+	WLAN_HOST_DIAG_LOG_REPORT(pScanLog);
+
+	csr_diag_event_report(pMac, eCSR_EVENT_SCAN_COMPLETE, eSIR_SUCCESS,
+			      eSIR_SUCCESS);
+	if (c > 0)
+		csr_diag_event_report(pMac, eCSR_EVENT_SCAN_RES_FOUND,
+				      eSIR_SUCCESS, eSIR_SUCCESS);
+}
+#endif /* #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR */
+
+static void
+csr_handle_nxt_cmd(tpAniSirGlobal mac_ctx, tSmeCmd *pCommand,
+		   eCsrScanCompleteNextCommand *nxt_cmd,
+		   bool *remove_cmd, uint32_t session_id)
+{
+	CDF_STATUS status;
+	switch (*nxt_cmd) {
+	case eCsrNext11dScan1Success:
+	case eCsrNext11dScan2Success:
+		sms_log(mac_ctx, LOG2,
+			FL("11dScan1/3 produced results. Reissue Active scan"));
+		/*
+		 * if we found country information, no need to continue scanning
+		 * further, bail out
+		 */
+		*remove_cmd = true;
+		*nxt_cmd = eCsrNext11dScanComplete;
+		break;
+	case eCsrNext11dScan1Failure:
+		/*
+		 * We are not done yet. 11d scan fail once. We will try to reset
+		 * anything and do it over again. The only meaningful thing for
+		 * this retry is that we cannot find 11d information after a
+		 * reset so we clear the "old" 11d info and give it once more
+		 * chance
+		 */
+		*remove_cmd = csr_handle_scan11d1_failure(mac_ctx, pCommand);
+		if (*remove_cmd)
+			*nxt_cmd = eCsrNext11dScanComplete;
+		break;
+	case eCsrNextLostLinkScan1Success:
+		status = csr_issue_roam_after_lostlink_scan(mac_ctx, session_id,
+							    eCsrLostLink1);
+		if (!CDF_IS_STATUS_SUCCESS(status))
+			csr_scan_handle_failed_lostlink1(mac_ctx, session_id);
+		break;
+	case eCsrNextLostLinkScan2Success:
+		status = csr_issue_roam_after_lostlink_scan(mac_ctx, session_id,
+							    eCsrLostLink2);
+		if (!CDF_IS_STATUS_SUCCESS(status))
+			csr_scan_handle_failed_lostlink2(mac_ctx, session_id);
+		break;
+	case eCsrNextLostLinkScan3Success:
+		status = csr_issue_roam_after_lostlink_scan(mac_ctx, session_id,
+							    eCsrLostLink3);
+		if (!CDF_IS_STATUS_SUCCESS(status))
+			csr_scan_handle_failed_lostlink3(mac_ctx, session_id);
+		break;
+	case eCsrNextLostLinkScan1Failed:
+		csr_scan_handle_failed_lostlink1(mac_ctx, session_id);
+		break;
+	case eCsrNextLostLinkScan2Failed:
+		csr_scan_handle_failed_lostlink2(mac_ctx, session_id);
+		break;
+	case eCsrNextLostLinkScan3Failed:
+		csr_scan_handle_failed_lostlink3(mac_ctx, session_id);
+		break;
+	case eCsrNexteScanForSsidSuccess:
+		csr_scan_handle_search_for_ssid(mac_ctx, pCommand);
+		break;
+	case eCsrNexteScanForSsidFailure:
+		csr_scan_handle_search_for_ssid_failure(mac_ctx, pCommand);
+		break;
+	default:
+		break;
+	}
+}
+
+/**
+ * csr_get_active_scan_entry() - To get scan entry from active command list
+ *
+ * @mac_ctx - MAC context
+ * @scan_id - Scan identifier of the scan request
+ * @entry - scan entry returned.
+ *
+ * Scan entry in the active scan list mapping to the sent scan id
+ * is returned to the caller.
+ *
+ * Return: CDF_STATUS.
+ */
+CDF_STATUS csr_get_active_scan_entry(tpAniSirGlobal mac_ctx,
+	uint32_t scan_id, tListElem **entry)
+{
+	CDF_STATUS status = CDF_STATUS_E_FAILURE;
+	tListElem *localentry;
+	tSmeCmd *cmd;
+	uint32_t cmd_scan_id = 0;
+
+	csr_ll_lock(&mac_ctx->sme.smeScanCmdActiveList);
+
+	if (csr_ll_is_list_empty(&mac_ctx->sme.smeScanCmdActiveList,
+			LL_ACCESS_NOLOCK)) {
+		sms_log(mac_ctx, LOGE,
+			FL(" Active list Empty scanId: %d"), scan_id);
+		return CDF_STATUS_SUCCESS;
+	}
+	localentry = csr_ll_peek_head(&mac_ctx->sme.smeScanCmdActiveList,
+			LL_ACCESS_NOLOCK);
+	do {
+		cmd = GET_BASE_ADDR(localentry, tSmeCmd, Link);
+		if (cmd->command == eSmeCommandScan)
+			cmd_scan_id = cmd->u.scanCmd.u.scanRequest.scan_id;
+		else if (cmd->command == eSmeCommandRemainOnChannel)
+			cmd_scan_id = cmd->u.remainChlCmd.scan_id;
+		if (cmd_scan_id == scan_id) {
+			sms_log(mac_ctx, LOG1, FL(" scanId Matched %d"),
+					scan_id);
+			*entry = localentry;
+			csr_ll_unlock(&mac_ctx->sme.smeScanCmdActiveList);
+			return CDF_STATUS_SUCCESS;
+		}
+		localentry = csr_ll_next(&mac_ctx->sme.smeScanCmdActiveList,
+				localentry, LL_ACCESS_NOLOCK);
+	} while (localentry);
+	csr_ll_unlock(&mac_ctx->sme.smeScanCmdActiveList);
+	return status;
+}
+
+/* Return whether the command should be removed */
+bool csr_scan_complete(tpAniSirGlobal pMac, tSirSmeScanRsp *pScanRsp)
+{
+	eCsrScanCompleteNextCommand NextCommand = eCsrNextScanNothing;
+	tListElem *pEntry = NULL;
+	tSmeCmd *pCommand;
+	bool fRemoveCommand = true;
+	bool fSuccess;
+	uint32_t sessionId = 0;
+
+	csr_get_active_scan_entry(pMac, pScanRsp->scan_id, &pEntry);
+	if (!pEntry) {
+		sms_log(pMac, LOGE,
+			FL("Scan Completion called but NO cmd ACTIVE ..."));
+		return false;
+	}
+
+	pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
+	/*
+	 * If the head of the queue is Active and it is a SCAN command, remove
+	 * and put this on the Free queue.
+	 */
+	if (eSmeCommandScan != pCommand->command) {
+		sms_log(pMac, LOGW,
+			FL("Scan Completion called, but active SCAN cmd"));
+		return false;
+	}
+
+	sessionId = pCommand->sessionId;
+	if (eSIR_SME_SUCCESS != pScanRsp->statusCode) {
+		fSuccess = false;
+	} else {
+		/*
+		 * pMac->scan.tempScanResults is not empty meaning the scan
+		 * found something. This check only valid here because
+		 * csrSaveScanresults is not yet called
+		 */
+		fSuccess = (!csr_ll_is_list_empty(&pMac->scan.tempScanResults,
+						  LL_ACCESS_LOCK));
+	}
+	if (pCommand->u.scanCmd.abortScanDueToBandChange) {
+		/*
+		 * Scan aborted due to band change
+		 * The scan results need to be flushed
+		 */
+		if (pCommand->u.scanCmd.callback
+		    != pMac->scan.callback11dScanDone) {
+			sms_log(pMac, LOG1, FL("Filtering the scan results"));
+			csr_scan_filter_results(pMac);
+		} else {
+			sms_log(pMac, LOG1,
+				FL("11d_scan_done, flushing the scan results"));
+		}
+		pCommand->u.scanCmd.abortScanDueToBandChange = false;
+	}
+	csr_save_scan_results(pMac, pCommand->u.scanCmd.reason, sessionId);
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+	csr_diag_scan_complete(pMac, pCommand, pScanRsp);
+#endif /* #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR */
+	NextCommand = csr_scan_get_next_command_state(pMac, pCommand, fSuccess);
+	/* We reuse the command here instead reissue a new command */
+	csr_handle_nxt_cmd(pMac, pCommand, &NextCommand,
+			   &fRemoveCommand, sessionId);
+	return fRemoveCommand;
+}
+
+static void
+csr_scan_remove_dup_bss_description_from_interim_list(tpAniSirGlobal mac_ctx,
+					tSirBssDescription *bss_dscp,
+					tDot11fBeaconIEs *pIes)
+{
+	tListElem *pEntry;
+	tCsrScanResult *scan_bss_dscp;
+	int8_t scan_entry_rssi = 0;
+	/*
+	 * Walk through all the chained BssDescriptions. If we find a chained
+	 * BssDescription that matches the BssID of the BssDescription passed
+	 * in, then these must be duplicate scan results for this Bss. In that
+	 * case, remove the 'old' Bss description from the linked list.
+	 */
+	sms_log(mac_ctx, LOG4, FL(" for BSS " MAC_ADDRESS_STR " "),
+		MAC_ADDR_ARRAY(bss_dscp->bssId));
+	csr_ll_lock(&mac_ctx->scan.tempScanResults);
+	pEntry = csr_ll_peek_head(&mac_ctx->scan.tempScanResults,
+				 LL_ACCESS_NOLOCK);
+	while (pEntry) {
+		scan_bss_dscp = GET_BASE_ADDR(pEntry, tCsrScanResult, Link);
+		/*
+		 * we have a duplicate scan results only when BSSID, SSID,
+		 * Channel and NetworkType matches
+		 */
+		scan_entry_rssi = scan_bss_dscp->Result.BssDescriptor.rssi;
+		if (csr_is_duplicate_bss_description(mac_ctx,
+			&scan_bss_dscp->Result.BssDescriptor, bss_dscp,
+			pIes, false)) {
+			/*
+			 * Following is mathematically a = (aX + b(100-X))/100
+			 * where:
+			 * a = bss_dscp->rssi, b = scan_entry_rssi
+			 * and X = CSR_SCAN_RESULT_RSSI_WEIGHT
+			 */
+			bss_dscp->rssi = (int8_t) ((((int32_t) bss_dscp->rssi *
+				CSR_SCAN_RESULT_RSSI_WEIGHT) +
+				((int32_t) scan_entry_rssi *
+				 (100 - CSR_SCAN_RESULT_RSSI_WEIGHT))) / 100);
+			/* Remove the 'old' entry from the list */
+			if (csr_ll_remove_entry(&mac_ctx->scan.tempScanResults,
+				pEntry, LL_ACCESS_NOLOCK)) {
+				csr_check_n_save_wsc_ie(mac_ctx, bss_dscp,
+							&scan_bss_dscp->Result.
+							BssDescriptor);
+				/*
+				 * we need to free the memory associated with
+				 * this node
+				 */
+				csr_free_scan_result_entry(mac_ctx,
+							   scan_bss_dscp);
+			}
+			/*
+			 * If we found a match, we can stop looking through
+			 * the list.
+			 */
+			break;
+		}
+		pEntry = csr_ll_next(&mac_ctx->scan.tempScanResults, pEntry,
+				     LL_ACCESS_NOLOCK);
+	}
+
+	csr_ll_unlock(&mac_ctx->scan.tempScanResults);
+}
+
+/* Caller allocated memory pfNewBssForConn to return whether new candidate for */
+/* current connection is found. Cannot be NULL */
+tCsrScanResult *csr_scan_save_bss_description_to_interim_list(tpAniSirGlobal pMac,
+							      tSirBssDescription *
+							      pBSSDescription,
+							      tDot11fBeaconIEs *pIes)
+{
+	tCsrScanResult *pCsrBssDescription = NULL;
+	uint32_t cbBSSDesc;
+	uint32_t cbAllocated;
+
+	/* figure out how big the BSS description is (the BSSDesc->length does NOT */
+	/* include the size of the length field itself). */
+	cbBSSDesc = pBSSDescription->length + sizeof(pBSSDescription->length);
+
+	cbAllocated = sizeof(tCsrScanResult) + cbBSSDesc;
+
+	sms_log(pMac, LOG4, FL("new BSS description, length %d, cbBSSDesc %d"),
+		cbAllocated, cbBSSDesc);
+	pCsrBssDescription = cdf_mem_malloc(cbAllocated);
+	if (NULL != pCsrBssDescription) {
+		cdf_mem_set(pCsrBssDescription, cbAllocated, 0);
+		cdf_mem_copy(&pCsrBssDescription->Result.BssDescriptor,
+			     pBSSDescription, cbBSSDesc);
+		pCsrBssDescription->AgingCount =
+			(int32_t) pMac->roam.configParam.agingCount;
+		sms_log(pMac, LOG4,
+			FL(" Set Aging Count = %d for BSS " MAC_ADDRESS_STR " "),
+			pCsrBssDescription->AgingCount,
+			MAC_ADDR_ARRAY(pCsrBssDescription->Result.BssDescriptor.
+				       bssId));
+		/* Save SSID separately for later use */
+		if (pIes->SSID.present
+		    && !csr_is_nullssid(pIes->SSID.ssid, pIes->SSID.num_ssid)) {
+			/* SSID not hidden */
+			uint32_t len = pIes->SSID.num_ssid;
+			if (len > SIR_MAC_MAX_SSID_LENGTH) {
+				/* truncate to fit in our struct */
+				len = SIR_MAC_MAX_SSID_LENGTH;
+			}
+			pCsrBssDescription->Result.ssId.length = len;
+			pCsrBssDescription->Result.timer =
+				cdf_mc_timer_get_system_time();
+			cdf_mem_copy(pCsrBssDescription->Result.ssId.ssId,
+				     pIes->SSID.ssid, len);
+		}
+		csr_ll_insert_tail(&pMac->scan.tempScanResults,
+				   &pCsrBssDescription->Link, LL_ACCESS_LOCK);
+	}
+
+	return pCsrBssDescription;
+}
+
+bool csr_is_duplicate_bss_description(tpAniSirGlobal pMac,
+				      tSirBssDescription *pSirBssDesc1,
+				      tSirBssDescription *pSirBssDesc2,
+				      tDot11fBeaconIEs *pIes2, bool fForced)
+{
+	bool fMatch = false;
+	tSirMacCapabilityInfo *pCap1, *pCap2;
+	tDot11fBeaconIEs *pIes1 = NULL;
+	tDot11fBeaconIEs *pIesTemp = pIes2;
+	CDF_STATUS status;
+
+	pCap1 = (tSirMacCapabilityInfo *) &pSirBssDesc1->capabilityInfo;
+	pCap2 = (tSirMacCapabilityInfo *) &pSirBssDesc2->capabilityInfo;
+
+	if (pCap1->ess != pCap2->ess)
+		goto free_ies;
+
+	if (pCap1->ess &&
+	    cdf_is_macaddr_equal((struct cdf_mac_addr *) pSirBssDesc1->bssId,
+				 (struct cdf_mac_addr *) pSirBssDesc2->bssId)
+	    && (fForced
+		|| (cds_chan_to_band(pSirBssDesc1->channelId) ==
+		    cds_chan_to_band((pSirBssDesc2->channelId))))) {
+		fMatch = true;
+		/* Check for SSID match, if exists */
+		status = csr_get_parsed_bss_description_ies(pMac, pSirBssDesc1,
+							    &pIes1);
+		if (!CDF_IS_STATUS_SUCCESS(status))
+			goto free_ies;
+
+		if (NULL == pIesTemp) {
+			status = csr_get_parsed_bss_description_ies(pMac,
+						pSirBssDesc2, &pIesTemp);
+			if (!CDF_IS_STATUS_SUCCESS(status))
+				goto free_ies;
+		}
+		if (pIes1->SSID.present && pIesTemp->SSID.present) {
+			fMatch = csr_is_ssid_match(pMac, pIes1->SSID.ssid,
+						   pIes1->SSID.num_ssid,
+						   pIesTemp->SSID.ssid,
+						   pIesTemp->SSID.num_ssid,
+						   true);
+		}
+	} else if (pCap1->ibss && (pSirBssDesc1->channelId ==
+					pSirBssDesc2->channelId)) {
+		status = csr_get_parsed_bss_description_ies(pMac, pSirBssDesc1,
+							    &pIes1);
+		if (!CDF_IS_STATUS_SUCCESS(status))
+			goto free_ies;
+
+		if (NULL == pIesTemp) {
+			status = csr_get_parsed_bss_description_ies(pMac,
+						pSirBssDesc2, &pIesTemp);
+			if (!CDF_IS_STATUS_SUCCESS(status))
+				goto free_ies;
+		}
+
+		/* Same channel cannot have same SSID for different IBSS */
+		if (pIes1->SSID.present && pIesTemp->SSID.present) {
+			fMatch = csr_is_ssid_match(pMac, pIes1->SSID.ssid,
+						   pIes1->SSID.num_ssid,
+						   pIesTemp->SSID.ssid,
+						   pIesTemp->SSID.num_ssid,
+						   true);
+		}
+	}
+	/* In case of P2P devices, ess and ibss will be set to zero */
+	else if (!pCap1->ess &&
+		cdf_is_macaddr_equal(
+			(struct cdf_mac_addr *) pSirBssDesc1->bssId,
+			(struct cdf_mac_addr *) pSirBssDesc2->bssId)) {
+		fMatch = true;
+	}
+
+free_ies:
+	if (pIes1)
+		cdf_mem_free(pIes1);
+	if ((NULL == pIes2) && pIesTemp)
+		/* locally allocated */
+		cdf_mem_free(pIesTemp);
+	return fMatch;
+}
+
+bool csr_is_network_type_equal(tSirBssDescription *pSirBssDesc1,
+			       tSirBssDescription *pSirBssDesc2)
+{
+	return pSirBssDesc1->nwType == pSirBssDesc2->nwType;
+}
+
+/* to check whether the BSS matches the dot11Mode */
+static bool csr_scan_is_bss_allowed(tpAniSirGlobal pMac,
+				    tSirBssDescription *pBssDesc,
+				    tDot11fBeaconIEs *pIes)
+{
+	bool fAllowed = false;
+	eCsrPhyMode phyMode;
+
+	if (CDF_IS_STATUS_SUCCESS
+		    (csr_get_phy_mode_from_bss(pMac, pBssDesc, &phyMode, pIes))) {
+		switch (pMac->roam.configParam.phyMode) {
+		case eCSR_DOT11_MODE_11b:
+			fAllowed = (bool) (eCSR_DOT11_MODE_11a != phyMode);
+			break;
+		case eCSR_DOT11_MODE_11g:
+			fAllowed = (bool) (eCSR_DOT11_MODE_11a != phyMode);
+			break;
+		case eCSR_DOT11_MODE_11g_ONLY:
+			fAllowed = (bool) (eCSR_DOT11_MODE_11g == phyMode);
+			break;
+		case eCSR_DOT11_MODE_11a:
+			fAllowed = (bool) ((eCSR_DOT11_MODE_11b != phyMode)
+					   && (eCSR_DOT11_MODE_11g != phyMode));
+			break;
+		case eCSR_DOT11_MODE_11n_ONLY:
+			fAllowed = (bool) ((eCSR_DOT11_MODE_11n == phyMode));
+			break;
+
+#ifdef WLAN_FEATURE_11AC
+		case eCSR_DOT11_MODE_11ac_ONLY:
+			fAllowed = (bool) ((eCSR_DOT11_MODE_11ac == phyMode));
+			break;
+#endif
+		case eCSR_DOT11_MODE_11b_ONLY:
+			fAllowed = (bool) (eCSR_DOT11_MODE_11b == phyMode);
+			break;
+		case eCSR_DOT11_MODE_11n:
+#ifdef WLAN_FEATURE_11AC
+		case eCSR_DOT11_MODE_11ac:
+#endif
+		default:
+			fAllowed = true;
+			break;
+		}
+	}
+
+	return fAllowed;
+}
+
+/* Return pIes to caller for future use when returning true. */
+static bool csr_scan_validate_scan_result(tpAniSirGlobal pMac,
+					  uint8_t *pChannels,
+					  uint8_t numChn,
+					  tSirBssDescription *pBssDesc,
+					  tDot11fBeaconIEs **ppIes)
+{
+	bool valid = false;
+	tDot11fBeaconIEs *pIes = NULL;
+	uint8_t index;
+	CDF_STATUS status;
+
+	for (index = 0; index < numChn; index++) {
+		/*
+		 * This check relies on the fact that a single BSS description
+		 * is returned in each ScanRsp call, which is the way LIM
+		 * implemented the scan req/rsp funtions. We changed to this
+		 * model when we ran with a large number of APs. If this were to
+		 * change, then this check would have to mess with removing the
+		 * bssDescription from somewhere in an arbitrary index in the
+		 * bssDescription array.
+		 */
+		if (pChannels[index] == pBssDesc->channelId) {
+			valid = true;
+			break;
+		}
+	}
+	*ppIes = NULL;
+	if (valid) {
+		status = csr_get_parsed_bss_description_ies(pMac, pBssDesc,
+							    &pIes);
+		if (!CDF_IS_STATUS_SUCCESS(status))
+			return false;
+
+		valid = csr_scan_is_bss_allowed(pMac, pBssDesc, pIes);
+		if (valid)
+			*ppIes = pIes;
+		else
+			cdf_mem_free(pIes);
+	}
+	return valid;
+}
+
+static void csr_update_scantype(tpAniSirGlobal pMac, tDot11fBeaconIEs *pIes,
+				uint8_t channelId)
+{
+	if (eSIR_PASSIVE_SCAN != pMac->scan.curScanType)
+		return;
+
+	if (csr_is11d_supported(pMac)) {
+		/* Check whether the BSS is acceptable based on
+		 * 11d info and our config.
+		 */
+		if (!csr_match_country_code(pMac, NULL, pIes))
+			return;
+
+		/* check if channel is acceptable by config */
+		if (csr_is_supported_channel(pMac, channelId))
+			pMac->scan.curScanType = eSIR_ACTIVE_SCAN;
+
+	} else
+		pMac->scan.curScanType = eSIR_ACTIVE_SCAN;
+
+}
+
+/* Return whether last scan result is received */
+static bool csr_scan_process_scan_results(tpAniSirGlobal pMac, tSmeCmd *pCommand,
+					  tSirSmeScanRsp *pScanRsp,
+					  bool *pfRemoveCommand)
+{
+	bool fRet = false, fRemoveCommand = false;
+
+	sms_log(pMac, LOG1, FL("scan reason = %d, response status code = %d"),
+		pCommand->u.scanCmd.reason, pScanRsp->statusCode);
+	fRemoveCommand = csr_scan_complete(pMac, pScanRsp);
+	fRet = true;
+	if (pfRemoveCommand) {
+		*pfRemoveCommand = fRemoveCommand;
+	}
+	return fRet;
+}
+
+/* csr_scan_process_single_bssdescr() - Add a bssdescriptor to scan table
+ *
+ * @mac_ctx - MAC context
+ * @bssdescr - Pointer to BSS description structure that contains
+ *             everything from beacon/probe response frame and additional
+ *             information.
+ * @scan_id - Scan identifier of the scan request that was running
+ *            when this beacon was received. Reserved for future when
+ *            firmware provides that information.
+ * @flags - Reserved for future use.
+ *
+ * Callback routine called by LIM when it receives a beacon or probe response
+ * from the device. 802.11 frame is already converted to internal
+ * tSirBssDescription data structure.
+ *
+ * Return: 0 or other error codes.
+ */
+
+CDF_STATUS csr_scan_process_single_bssdescr(tpAniSirGlobal mac_ctx,
+					tSirBssDescription *bssdescr,
+					uint32_t scan_id, uint32_t flags)
+{
+	tDot11fBeaconIEs *ies = NULL;
+	uint8_t *chanlist = NULL;
+	uint8_t cnt_channels = 0;
+	uint32_t len = sizeof(mac_ctx->roam.validChannelList);
+
+	sms_log(mac_ctx, LOG4, "CSR: Processing single bssdescr");
+	if (CDF_IS_STATUS_SUCCESS(
+		csr_get_cfg_valid_channels(mac_ctx,
+			(uint8_t *) mac_ctx->roam.validChannelList,
+			&len))) {
+		chanlist = mac_ctx->roam.validChannelList;
+		cnt_channels = (uint8_t) len;
+	} else {
+		/* Cannot continue */
+		sms_log(mac_ctx, LOGW,
+			FL("Received results on invalid channel"));
+		return CDF_STATUS_E_INVAL;
+	}
+
+	if (csr_scan_validate_scan_result(mac_ctx, chanlist,
+			cnt_channels, bssdescr, &ies)) {
+		csr_scan_remove_dup_bss_description_from_interim_list
+			(mac_ctx, bssdescr, ies);
+		csr_scan_save_bss_description_to_interim_list
+			(mac_ctx, bssdescr, ies);
+		csr_update_scantype(mac_ctx, ies, bssdescr->channelId);
+		/* Free the resource */
+		if (ies != NULL)
+			cdf_mem_free(ies);
+	}
+	return CDF_STATUS_SUCCESS;
+}
+
+
+bool csr_scan_is_wild_card_scan(tpAniSirGlobal pMac, tSmeCmd *pCommand)
+{
+	uint8_t bssid[CDF_MAC_ADDR_SIZE] = {0};
+	bool f = cdf_mem_compare(pCommand->u.scanCmd.u.scanRequest.bssid.bytes,
+				 bssid, sizeof(struct cdf_mac_addr));
+	/*
+	 * It is not a wild card scan if the bssid is not broadcast and
+	 * the number of SSID is 1.
+	 */
+	return (f || (0xff == pCommand->u.scanCmd.u.scanRequest.bssid.bytes[0]))
+		&& (pCommand->u.scanCmd.u.scanRequest.SSIDs.numOfSSIDs != 1);
+}
+
+CDF_STATUS csr_scan_sme_scan_response(tpAniSirGlobal pMac,
+		void *pMsgBuf)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tListElem *pEntry = NULL;
+	tSmeCmd *pCommand;
+	eCsrScanStatus scanStatus;
+	tSirSmeScanRsp *pScanRsp = (tSirSmeScanRsp *)pMsgBuf;
+	bool fRemoveCommand = true;
+	eCsrScanReason reason = eCsrScanOther;
+
+	csr_get_active_scan_entry(pMac, pScanRsp->scan_id, &pEntry);
+	if (!pEntry)
+		goto error_handling;
+
+	sms_log(pMac, LOG1, FL("Scan completion called:scan_id %d, entry = %p"),
+		pScanRsp->scan_id, pEntry);
+
+	pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
+	if (eSmeCommandScan != pCommand->command)
+		goto error_handling;
+
+	scanStatus = (eSIR_SME_SUCCESS == pScanRsp->statusCode) ?
+			eCSR_SCAN_SUCCESS : eCSR_SCAN_FAILURE;
+	reason = pCommand->u.scanCmd.reason;
+	switch (pCommand->u.scanCmd.reason) {
+	case eCsrScanAbortNormalScan:
+		break;
+	case eCsrScanP2PFindPeer:
+		scanStatus = (eSIR_SME_SUCCESS == pScanRsp->statusCode) ?
+				eCSR_SCAN_FOUND_PEER : eCSR_SCAN_FAILURE;
+		csr_scan_process_scan_results(pMac, pCommand, pScanRsp, NULL);
+		break;
+	default:
+		if (csr_scan_process_scan_results(pMac, pCommand, pScanRsp,
+						  &fRemoveCommand)
+		    && csr_scan_is_wild_card_scan(pMac, pCommand)
+		    && !pCommand->u.scanCmd.u.scanRequest.p2pSearch) {
+
+		/* Age out logic will be taken care by the age out timer */
+		}
+		break;
+	}
+	if (fRemoveCommand)
+		csr_release_scan_command(pMac, pCommand, scanStatus);
+	sme_process_pending_queue(pMac);
+	return status;
+
+error_handling:
+#ifdef FEATURE_WLAN_SCAN_PNO
+	if (pMac->pnoOffload && pScanRsp->statusCode == eSIR_PNO_SCAN_SUCCESS) {
+		sms_log(pMac, LOGE, FL("PNO Scan completion called."));
+		csr_save_scan_results(pMac, eCsrScanCandidateFound,
+				      pScanRsp->sessionId);
+		return CDF_STATUS_SUCCESS;
+	} else {
+		/*
+		 * Scan completion was called, PNO is active, but scan
+		 * response was not PNO
+		 */
+		sms_log(pMac, LOGE,
+			FL("Scan completion called, scan rsp was not PNO."));
+		return CDF_STATUS_E_FAILURE;
+	}
+#endif
+	sms_log(pMac, LOGE, FL("Scan completion called, but no active SCAN command."));
+	return CDF_STATUS_E_FAILURE;
+}
+
+tCsrScanResultInfo *csr_scan_result_get_first(tpAniSirGlobal pMac,
+					      tScanResultHandle hScanResult)
+{
+	tListElem *pEntry;
+	tCsrScanResult *pResult;
+	tCsrScanResultInfo *pRet = NULL;
+	tScanResultList *pResultList = (tScanResultList *) hScanResult;
+
+	if (pResultList) {
+		csr_ll_lock(&pResultList->List);
+		pEntry = csr_ll_peek_head(&pResultList->List, LL_ACCESS_NOLOCK);
+		if (pEntry) {
+			pResult = GET_BASE_ADDR(pEntry, tCsrScanResult, Link);
+			pRet = &pResult->Result;
+		}
+		pResultList->pCurEntry = pEntry;
+		csr_ll_unlock(&pResultList->List);
+	}
+
+	return pRet;
+}
+
+tCsrScanResultInfo *csr_scan_result_get_next(tpAniSirGlobal pMac,
+					     tScanResultHandle hScanResult)
+{
+	tListElem *pEntry = NULL;
+	tCsrScanResult *pResult = NULL;
+	tCsrScanResultInfo *pRet = NULL;
+	tScanResultList *pResultList = (tScanResultList *) hScanResult;
+
+	if (!pResultList)
+		return NULL;
+
+	csr_ll_lock(&pResultList->List);
+	if (NULL == pResultList->pCurEntry) {
+		pEntry = csr_ll_peek_head(&pResultList->List, LL_ACCESS_NOLOCK);
+	} else {
+		pEntry = csr_ll_next(&pResultList->List, pResultList->pCurEntry,
+				     LL_ACCESS_NOLOCK);
+	}
+	if (pEntry) {
+		pResult = GET_BASE_ADDR(pEntry, tCsrScanResult, Link);
+		pRet = &pResult->Result;
+	}
+	pResultList->pCurEntry = pEntry;
+	csr_ll_unlock(&pResultList->List);
+	return pRet;
+}
+
+/*
+ * This function moves the first BSS that matches the bssid to the
+ * head of the result
+ */
+CDF_STATUS csr_move_bss_to_head_from_bssid(tpAniSirGlobal pMac,
+					   struct cdf_mac_addr *bssid,
+					   tScanResultHandle hScanResult)
+{
+	CDF_STATUS status = CDF_STATUS_E_FAILURE;
+	tScanResultList *pResultList = (tScanResultList *) hScanResult;
+	tCsrScanResult *pResult = NULL;
+	tListElem *pEntry = NULL;
+
+	if (!(pResultList && bssid))
+		return status;
+
+	csr_ll_lock(&pResultList->List);
+	pEntry = csr_ll_peek_head(&pResultList->List, LL_ACCESS_NOLOCK);
+	while (pEntry) {
+		pResult = GET_BASE_ADDR(pEntry, tCsrScanResult, Link);
+		if (cdf_mem_compare(bssid, pResult->Result.BssDescriptor.bssId,
+				    sizeof(struct cdf_mac_addr))) {
+			status = CDF_STATUS_SUCCESS;
+			csr_ll_remove_entry(&pResultList->List, pEntry,
+					    LL_ACCESS_NOLOCK);
+			csr_ll_insert_head(&pResultList->List, pEntry,
+					   LL_ACCESS_NOLOCK);
+			break;
+		}
+		pEntry = csr_ll_next(&pResultList->List, pResultList->pCurEntry,
+				     LL_ACCESS_NOLOCK);
+	}
+	csr_ll_unlock(&pResultList->List);
+	return status;
+}
+
+/* Remove the BSS if possible. */
+/* Return -- true == the BSS is remove. False == Fail to remove it */
+/* This function is called when list lock is held. Be caution what functions it can call. */
+bool csr_scan_age_out_bss(tpAniSirGlobal pMac, tCsrScanResult *pResult)
+{
+	bool fRet = false;
+	uint32_t i;
+	tCsrRoamSession *pSession;
+	bool isConnBssfound = false;
+
+	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
+		if (!CSR_IS_SESSION_VALID(pMac, i))
+			continue;
+		pSession = CSR_GET_SESSION(pMac, i);
+		/* Not to remove the BSS we are connected to. */
+		if (csr_is_conn_state_connected_infra(pMac, i)
+		    && (NULL != pSession->pConnectBssDesc)
+		    && (csr_is_duplicate_bss_description(pMac,
+			&pResult->Result.BssDescriptor,
+			pSession->pConnectBssDesc, NULL, false))) {
+			isConnBssfound = true;
+			break;
+		}
+	}
+	if (isConnBssfound) {
+		/*
+		 * Reset the counter so that aging out of connected BSS won't
+		 * hapeen too soon
+		 */
+		pResult->AgingCount =
+			(int32_t) pMac->roam.configParam.agingCount;
+		sms_log(pMac, LOGW,
+			FL("Connected BSS, Set Aging Count=%d for BSS "
+			   MAC_ADDRESS_STR), pResult->AgingCount,
+			MAC_ADDR_ARRAY(pResult->Result.BssDescriptor.bssId));
+		pResult->Result.BssDescriptor.nReceivedTime =
+			(uint32_t) cdf_mc_timer_get_system_ticks();
+		return fRet;
+	}
+	sms_log(pMac, LOGW,
+		"Aging out BSS " MAC_ADDRESS_STR " Channel %d",
+		MAC_ADDR_ARRAY(pResult->Result.BssDescriptor.bssId),
+		pResult->Result.BssDescriptor.channelId);
+	/*
+	 * No need to hold the spin lock because caller should hold the lock for
+	 * pMac->scan.scanResultList
+	 */
+	if (csr_ll_remove_entry(&pMac->scan.scanResultList, &pResult->Link,
+				LL_ACCESS_NOLOCK)) {
+		if (cdf_is_macaddr_equal(
+			(struct cdf_mac_addr *) &pResult->Result.BssDescriptor.bssId,
+			(struct cdf_mac_addr *) &pMac->scan.currentCountryBssid)) {
+			sms_log(pMac, LOGW,
+				FL("Aging out 11d BSS " MAC_ADDRESS_STR),
+				MAC_ADDR_ARRAY(
+					pResult->Result.BssDescriptor.bssId));
+			pMac->scan.currentCountryRSSI = -128;
+		}
+		csr_free_scan_result_entry(pMac, pResult);
+		fRet = true;
+	}
+	return fRet;
+}
+
+CDF_STATUS csr_scan_age_results(tpAniSirGlobal pMac,
+				tSmeGetScanChnRsp *pScanChnInfo)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tListElem *pEntry, *tmpEntry;
+	tCsrScanResult *pResult;
+	tLimScanChn *pChnInfo;
+	uint8_t i;
+
+	csr_ll_lock(&pMac->scan.scanResultList);
+	for (i = 0; i < pScanChnInfo->numChn; i++) {
+		pChnInfo = &pScanChnInfo->scanChn[i];
+		pEntry =
+			csr_ll_peek_head(&pMac->scan.scanResultList, LL_ACCESS_NOLOCK);
+		while (pEntry) {
+			tmpEntry =
+				csr_ll_next(&pMac->scan.scanResultList, pEntry,
+					    LL_ACCESS_NOLOCK);
+			pResult = GET_BASE_ADDR(pEntry, tCsrScanResult, Link);
+			if (pResult->Result.BssDescriptor.channelId ==
+			    pChnInfo->channelId) {
+				if (pResult->AgingCount <= 0) {
+					sms_log(pMac, LOGW,
+						" age out due to ref count");
+					csr_scan_age_out_bss(pMac, pResult);
+				} else {
+					pResult->AgingCount--;
+					sms_log(pMac, LOGW,
+						FL
+							("Decremented AgingCount=%d for BSS "
+							MAC_ADDRESS_STR ""),
+						pResult->AgingCount,
+						MAC_ADDR_ARRAY(pResult->Result.
+							       BssDescriptor.
+							       bssId));
+				}
+			}
+			pEntry = tmpEntry;
+		}
+	}
+	csr_ll_unlock(&pMac->scan.scanResultList);
+
+	return status;
+}
+
+CDF_STATUS csr_send_mb_scan_req(tpAniSirGlobal pMac, uint16_t sessionId,
+				tCsrScanRequest *pScanReq,
+				tScanReqParam *pScanReqParam)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tSirSmeScanReq *pMsg;
+	uint16_t msgLen;
+	tSirScanType scanType = pScanReq->scanType;
+	uint32_t minChnTime;    /* in units of milliseconds */
+	uint32_t maxChnTime;    /* in units of milliseconds */
+	uint32_t i;
+	uint8_t selfMacAddr[CDF_MAC_ADDR_SIZE];
+	uint8_t *pSelfMac = NULL;
+
+	msgLen = (uint16_t) (sizeof(tSirSmeScanReq) -
+		 sizeof(pMsg->channelList.channelNumber) +
+		 (sizeof(pMsg->channelList.channelNumber) *
+		 pScanReq->ChannelInfo.numOfChannels)) +
+		 (pScanReq->uIEFieldLen);
+
+	pMsg = cdf_mem_malloc(msgLen);
+	if (NULL == pMsg) {
+		sms_log(pMac, LOGE, FL("memory allocation failed"));
+		sms_log(pMac, LOG1, FL("Failed: SId: %d FirstMatch = %d"
+				       " UniqueResult = %d freshScan = %d hiddenSsid = %d"),
+			sessionId, pScanReqParam->bReturnAfter1stMatch,
+			pScanReqParam->fUniqueResult, pScanReqParam->freshScan,
+			pScanReqParam->hiddenSsid);
+		sms_log(pMac, LOG1,
+			FL("scanType = %u BSSType = %u numOfSSIDs = %d"
+			   " numOfChannels = %d requestType = %d p2pSearch = %d\n"),
+			pScanReq->scanType, pScanReq->BSSType,
+			pScanReq->SSIDs.numOfSSIDs,
+			pScanReq->ChannelInfo.numOfChannels,
+			pScanReq->requestType, pScanReq->p2pSearch);
+		return CDF_STATUS_E_NOMEM;
+	}
+
+	cdf_mem_set(pMsg, msgLen, 0);
+	pMsg->messageType = eWNI_SME_SCAN_REQ;
+	pMsg->length = msgLen;
+	/* ToDO: Fill in session info when we need to do scan base on session */
+	if ((sessionId != CSR_SESSION_ID_INVALID)) {
+		pMsg->sessionId = sessionId;
+	} else {
+		/* if sessionId == CSR_SESSION_ID_INVALID, then send the scan
+		   request on first available session */
+		pMsg->sessionId = 0;
+	}
+	if (pMsg->sessionId >= CSR_ROAM_SESSION_MAX)
+		sms_log(pMac, LOGE, FL(" Invalid Sme Session ID = %d"),
+			pMsg->sessionId);
+	pMsg->transactionId = 0;
+	pMsg->dot11mode = (uint8_t) csr_translate_to_wni_cfg_dot11_mode(pMac,
+				csr_find_best_phy_mode(pMac,
+					pMac->roam.configParam.phyMode));
+	pMsg->bssType = csr_translate_bsstype_to_mac_type(pScanReq->BSSType);
+
+	if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
+		pSelfMac = (uint8_t *)
+			&pMac->roam.roamSession[sessionId].selfMacAddr;
+	} else {
+		/*
+		 * Since we don't have session for the scanning, we find a valid
+		 * session. In case we fail to do so, get the WNI_CFG_STA_ID
+		 */
+		for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
+			if (CSR_IS_SESSION_VALID(pMac, i)) {
+				pSelfMac = (uint8_t *)
+					&pMac->roam.roamSession[i].selfMacAddr;
+				break;
+			}
+		}
+		if (CSR_ROAM_SESSION_MAX == i) {
+			uint32_t len = CDF_MAC_ADDR_SIZE;
+			pSelfMac = selfMacAddr;
+			status = wlan_cfg_get_str(pMac, WNI_CFG_STA_ID,
+						  pSelfMac, &len);
+			if (!CDF_IS_STATUS_SUCCESS(status)
+			    || (len < CDF_MAC_ADDR_SIZE)) {
+				sms_log(pMac, LOGE,
+					FL("Can't get self MAC address = %d"),
+					status);
+				/* Force failed status */
+				status = CDF_STATUS_E_FAILURE;
+				goto send_scan_req;
+			}
+		}
+	}
+	cdf_mem_copy((uint8_t *) pMsg->selfMacAddr,
+		     pSelfMac, sizeof(tSirMacAddr));
+
+	/* sir_copy_mac_addr */
+	cdf_mem_copy(pMsg->bssId, &pScanReq->bssid, sizeof(tSirMacAddr));
+	if (cdf_is_macaddr_zero(&pScanReq->bssid))
+		cdf_mem_set(pMsg->bssId, sizeof(tSirMacAddr), 0xff);
+	else
+		cdf_mem_copy(pMsg->bssId, pScanReq->bssid.bytes,
+				CDF_MAC_ADDR_SIZE);
+	minChnTime = pScanReq->minChnTime;
+	maxChnTime = pScanReq->maxChnTime;
+
+	/*
+	 * Verify the scan type first, if the scan is active scan, we need to
+	 * make sure we are allowed to do so. if 11d is enabled & we don't see
+	 * any beacon around, scan type falls back to passive. But in BT AMP STA
+	 * mode we need to send out a directed probe
+	 */
+	if ((eSIR_PASSIVE_SCAN != scanType)
+	    && (eCSR_SCAN_P2P_DISCOVERY !=
+		pScanReq->requestType)
+	    && (eCSR_BSS_TYPE_WDS_STA != pScanReq->BSSType)
+	    && (false == pMac->scan.fEnableBypass11d)) {
+		scanType = pMac->scan.curScanType;
+		if (eSIR_PASSIVE_SCAN == pMac->scan.curScanType) {
+			if (minChnTime <
+			    pMac->roam.configParam.nPassiveMinChnTime) {
+				minChnTime =
+				    pMac->roam.configParam.nPassiveMinChnTime;
+			}
+			if (maxChnTime <
+			    pMac->roam.configParam.nPassiveMaxChnTime) {
+				maxChnTime =
+				    pMac->roam.configParam.nPassiveMaxChnTime;
+			}
+		}
+	}
+	pMsg->scanType = scanType;
+
+	pMsg->numSsid = (pScanReq->SSIDs.numOfSSIDs < SIR_SCAN_MAX_NUM_SSID) ?
+			 pScanReq->SSIDs.numOfSSIDs : SIR_SCAN_MAX_NUM_SSID;
+	if ((pScanReq->SSIDs.numOfSSIDs != 0)
+	    && (eSIR_PASSIVE_SCAN != scanType)) {
+		for (i = 0; i < pMsg->numSsid; i++) {
+			cdf_mem_copy(&pMsg->ssId[i],
+				     &pScanReq->SSIDs.SSIDList[i].SSID,
+				     sizeof(tSirMacSSid));
+		}
+	} else {
+		/* Otherwise we scan all SSID and let the result filter later */
+		for (i = 0; i < SIR_SCAN_MAX_NUM_SSID; i++)
+			pMsg->ssId[i].length = 0;
+	}
+
+	pMsg->minChannelTime = minChnTime;
+	pMsg->maxChannelTime = maxChnTime;
+	/* hidden SSID option */
+	pMsg->hiddenSsid = pScanReqParam->hiddenSsid;
+	/* rest time */
+	pMsg->restTime = pScanReq->restTime;
+	pMsg->returnAfterFirstMatch = pScanReqParam->bReturnAfter1stMatch;
+	/* All the scan results caching will be done by Roaming */
+	/* We do not want LIM to do any caching of scan results, */
+	/* so delete the LIM cache on all scan requests */
+	pMsg->returnFreshResults = pScanReqParam->freshScan;
+	/* Always ask for unique result */
+	pMsg->returnUniqueResults = pScanReqParam->fUniqueResult;
+	pMsg->channelList.numChannels =
+		(uint8_t) pScanReq->ChannelInfo.numOfChannels;
+	if (pScanReq->ChannelInfo.numOfChannels) {
+		/* Assuming the channelNumber is uint8_t (1 byte) */
+		cdf_mem_copy(pMsg->channelList.channelNumber,
+			     pScanReq->ChannelInfo.ChannelList,
+			     pScanReq->ChannelInfo.numOfChannels);
+	}
+
+	pMsg->uIEFieldLen = (uint16_t) pScanReq->uIEFieldLen;
+	pMsg->uIEFieldOffset = (uint16_t) (sizeof(tSirSmeScanReq) -
+			sizeof(pMsg->channelList.channelNumber) +
+			(sizeof(pMsg->channelList.channelNumber) *
+			 pScanReq->ChannelInfo.numOfChannels));
+	if (pScanReq->uIEFieldLen != 0) {
+		cdf_mem_copy((uint8_t *) pMsg + pMsg->uIEFieldOffset,
+			     pScanReq->pIEField, pScanReq->uIEFieldLen);
+	}
+	pMsg->p2pSearch = pScanReq->p2pSearch;
+	pMsg->scan_id = pScanReq->scan_id;
+
+send_scan_req:
+	sms_log(pMac, LOG1,
+		FL("scanId %d domainIdCurrent %d scanType %d bssType %d requestType %d numChannels %d"),
+		pMsg->scan_id, pMac->scan.domainIdCurrent, pMsg->scanType,
+		pMsg->bssType, pScanReq->requestType,
+		pMsg->channelList.numChannels);
+
+	for (i = 0; i < pMsg->channelList.numChannels; i++) {
+		sms_log(pMac, LOG1, FL("channelNumber[%d]= %d"), i,
+			pMsg->channelList.channelNumber[i]);
+	}
+
+	if (CDF_IS_STATUS_SUCCESS(status)) {
+		status = cds_send_mb_message_to_mac(pMsg);
+	} else {
+		sms_log(pMac, LOGE,
+			FL("failed to send down scan req with status = %d"),
+			status);
+		cdf_mem_free(pMsg);
+	}
+	return status;
+}
+
+CDF_STATUS csr_send_mb_scan_result_req(tpAniSirGlobal pMac,
+				       uint32_t sessionId,
+				       tScanReqParam *pScanReqParam)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tSirSmeScanReq *pMsg;
+	uint16_t msgLen;
+
+	msgLen = (uint16_t) (sizeof(tSirSmeScanReq));
+	pMsg = cdf_mem_malloc(msgLen);
+	if (NULL == pMsg)
+		return CDF_STATUS_E_NOMEM;
+
+	cdf_mem_set(pMsg, msgLen, 0);
+	pMsg->messageType = eWNI_SME_SCAN_REQ;
+	pMsg->length = msgLen;
+	pMsg->sessionId = sessionId;
+	pMsg->transactionId = 0;
+	pMsg->returnFreshResults = pScanReqParam->freshScan;
+	/* Always ask for unique result */
+	pMsg->returnUniqueResults = pScanReqParam->fUniqueResult;
+	pMsg->returnAfterFirstMatch =
+		pScanReqParam->bReturnAfter1stMatch;
+	status = cds_send_mb_message_to_mac(pMsg);
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		sms_log(pMac, LOGE,
+			FL("Failed to send down scan req with status = %d\n"),
+			status);
+	}
+	return status;
+}
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+static void csr_diag_scan_channels(tpAniSirGlobal pMac, tSmeCmd *pCommand)
+{
+	host_log_scan_pkt_type *pScanLog = NULL;
+
+	WLAN_HOST_DIAG_LOG_ALLOC(pScanLog,
+				 host_log_scan_pkt_type,
+				 LOG_WLAN_SCAN_C);
+	if (!pScanLog)
+		return;
+
+	if (eCsrScanProbeBss == pCommand->u.scanCmd.reason) {
+		pScanLog->eventId = WLAN_SCAN_EVENT_HO_SCAN_REQ;
+	} else {
+		if ((eSIR_PASSIVE_SCAN !=
+			pCommand->u.scanCmd.u.scanRequest.scanType)
+		    && (eSIR_PASSIVE_SCAN != pMac->scan.curScanType)) {
+			pScanLog->eventId = WLAN_SCAN_EVENT_ACTIVE_SCAN_REQ;
+		} else {
+			pScanLog->eventId = WLAN_SCAN_EVENT_PASSIVE_SCAN_REQ;
+		}
+	}
+	pScanLog->minChnTime =
+		(uint8_t) pCommand->u.scanCmd.u.scanRequest.minChnTime;
+	pScanLog->maxChnTime =
+		(uint8_t) pCommand->u.scanCmd.u.scanRequest.maxChnTime;
+	pScanLog->numChannel =
+	(uint8_t) pCommand->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels;
+	if (pScanLog->numChannel &&
+	    (pScanLog->numChannel < HOST_LOG_MAX_NUM_CHANNEL)) {
+		cdf_mem_copy(pScanLog->channels,
+		      pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList,
+		      pScanLog->numChannel);
+	}
+	WLAN_HOST_DIAG_LOG_REPORT(pScanLog);
+}
+#else
+#define csr_diag_scan_channels(tpAniSirGlobal pMac, tSmeCmd *pCommand) (void)0;
+#endif /* #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR */
+
+CDF_STATUS csr_scan_channels(tpAniSirGlobal pMac, tSmeCmd *pCommand)
+{
+	CDF_STATUS status = CDF_STATUS_E_FAILURE;
+	tScanReqParam scanReq;
+
+	/*
+	 * Don't delete cached results. Rome rssi based scan candidates may land
+	 * up in scan cache instead of LFR cache. They will be deleted upon
+	 * query
+	 */
+	scanReq.freshScan = SIR_BG_SCAN_RETURN_FRESH_RESULTS;
+	scanReq.fUniqueResult = true;
+	scanReq.hiddenSsid = SIR_SCAN_NO_HIDDEN_SSID;
+	if (eCsrScanForSsid == pCommand->u.scanCmd.reason) {
+		scanReq.bReturnAfter1stMatch =
+			CSR_SCAN_RETURN_AFTER_FIRST_MATCH;
+	} else {
+		/*
+		 * Basically do scan on all channels even for 11D 1st scan case
+		 */
+		scanReq.bReturnAfter1stMatch =
+			CSR_SCAN_RETURN_AFTER_ALL_CHANNELS;
+	}
+	if (eCsrScanProbeBss == pCommand->u.scanCmd.reason)
+		scanReq.hiddenSsid = SIR_SCAN_HIDDEN_SSID_PE_DECISION;
+	csr_diag_scan_channels(pMac, pCommand);
+	csr_clear_votes_for_country_info(pMac);
+	status = csr_send_mb_scan_req(pMac, pCommand->sessionId,
+				      &pCommand->u.scanCmd.u.scanRequest,
+				      &scanReq);
+	return status;
+}
+
+static CDF_STATUS
+csr_issue_user_scan(tpAniSirGlobal mac_ctx, tSmeCmd *cmd)
+{
+	int i, j;
+	CDF_STATUS status;
+	uint32_t len = 0;
+	uint8_t *ch_lst = NULL;
+	tCsrChannelInfo new_ch_info = { 0, NULL };
+
+	if (!mac_ctx->roam.configParam.fScanTwice)
+		return csr_scan_channels(mac_ctx, cmd);
+
+	/* We scan 2.4 channel twice */
+	if (cmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels
+	    && (NULL != cmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList)) {
+		len = cmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels;
+		/* allocate twice the channel */
+		new_ch_info.ChannelList = (uint8_t *) cdf_mem_malloc(len * 2);
+		ch_lst = cmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList;
+	} else {
+		/* get the valid channel list to scan all. */
+		len = sizeof(mac_ctx->roam.validChannelList);
+		status = csr_get_cfg_valid_channels(mac_ctx,
+			    (uint8_t *) mac_ctx->roam.validChannelList, &len);
+		if (CDF_IS_STATUS_SUCCESS(status)) {
+			/* allocate twice the channel */
+			new_ch_info.ChannelList =
+				(uint8_t *) cdf_mem_malloc(len * 2);
+			ch_lst = mac_ctx->roam.validChannelList;
+		}
+	}
+	if (NULL == new_ch_info.ChannelList) {
+		new_ch_info.numOfChannels = 0;
+	} else {
+		j = 0;
+		for (i = 0; i < len; i++) {
+			new_ch_info.ChannelList[j++] = ch_lst[i];
+			if (CDS_MAX_24GHz_CHANNEL_NUMBER >= ch_lst[i])
+				new_ch_info.ChannelList[j++] = ch_lst[i];
+		}
+		if (NULL !=
+		    cmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList) {
+			/*
+			 * ch_lst points to the channellist from the command,
+			 * free it.
+			 */
+			cdf_mem_free(
+			  cmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList);
+			cmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList =
+			  NULL;
+		}
+		cmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = j;
+		cmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList =
+							new_ch_info.ChannelList;
+	}
+
+	return csr_scan_channels(mac_ctx, cmd);
+}
+
+CDF_STATUS csr_process_scan_command(tpAniSirGlobal pMac, tSmeCmd *pCommand)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+
+	sms_log(pMac, LOG3,
+			FL("starting SCAN cmd in %d state. reason %d"),
+			pCommand->u.scanCmd.lastRoamState[pCommand->sessionId],
+			pCommand->u.scanCmd.reason);
+
+	switch (pCommand->u.scanCmd.reason) {
+	case eCsrScanUserRequest:
+		status = csr_issue_user_scan(pMac, pCommand);
+		break;
+	default:
+		status = csr_scan_channels(pMac, pCommand);
+		break;
+	}
+
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		csr_release_scan_command(pMac, pCommand, eCSR_SCAN_FAILURE);
+	}
+
+	return status;
+}
+
+/**
+ * csr_scan_copy_request_valid_channels_only() - scan request of valid channels
+ * @mac_ctx : pointer to Global Mac Structure
+ * @dst_req: pointer to tCsrScanRequest
+ * @skip_dfs_chnl: 1 - skip dfs channel, 0 - don't skip dfs channel
+ * @src_req: pointer to tCsrScanRequest
+ *
+ * This function makes a copy of scan request with valid channels
+ *
+ * Return: none
+ */
+static void csr_scan_copy_request_valid_channels_only(tpAniSirGlobal mac_ctx,
+				tCsrScanRequest *dst_req, uint8_t skip_dfs_chnl,
+				tCsrScanRequest *src_req)
+{
+	uint32_t index = 0;
+	uint32_t new_index = 0;
+
+	for (index = 0; index < src_req->ChannelInfo.numOfChannels; index++) {
+		/* Allow scan on valid channels only.
+		 * If it is p2p scan and valid channel list doesnt contain
+		 * social channels, enforce scan on social channels because
+		 * that is the only way to find p2p peers.
+		 * This can happen only if band is set to 5Ghz mode.
+		 */
+		if (src_req->ChannelInfo.ChannelList[index] < MIN_11P_CHANNEL &&
+			((csr_roam_is_valid_channel(mac_ctx,
+			src_req->ChannelInfo.ChannelList[index])) ||
+			((eCSR_SCAN_P2P_DISCOVERY == src_req->requestType) &&
+			CSR_IS_SOCIAL_CHANNEL(
+				src_req->ChannelInfo.ChannelList[index])))) {
+			if (((src_req->skipDfsChnlInP2pSearch || skip_dfs_chnl)
+				&& (CHANNEL_STATE_DFS ==
+				cds_get_channel_state(src_req->
+							ChannelInfo.
+							ChannelList
+							[index])))
+			) {
+#ifdef FEATURE_WLAN_LFR
+				sms_log(mac_ctx, LOG2,
+					FL(" reqType=%d, numOfChannels=%d, ignoring DFS channel %d"),
+					src_req->requestType,
+					src_req->ChannelInfo.numOfChannels,
+					src_req->ChannelInfo.ChannelList
+						[index]);
+#endif
+				continue;
+			}
+
+			dst_req->ChannelInfo.ChannelList[new_index] =
+				src_req->ChannelInfo.ChannelList[index];
+			new_index++;
+		}
+	}
+	dst_req->ChannelInfo.numOfChannels = new_index;
+}
+
+/**
+ * csr_scan_copy_request() - Function to copy scan request
+ * @mac_ctx : pointer to Global Mac Structure
+ * @dst_req: pointer to tCsrScanRequest
+ * @src_req: pointer to tCsrScanRequest
+ *
+ * This function makes a copy of scan request
+ *
+ * Return: 0 - Success, Error number - Failure
+ */
+CDF_STATUS csr_scan_copy_request(tpAniSirGlobal mac_ctx,
+				tCsrScanRequest *dst_req,
+				tCsrScanRequest *src_req)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	uint32_t len = sizeof(mac_ctx->roam.validChannelList);
+	uint32_t index = 0;
+	uint32_t new_index = 0;
+	CHANNEL_STATE channel_state;
+	bool skip_dfs_chnl =
+			mac_ctx->roam.configParam.initial_scan_no_dfs_chnl ||
+				!mac_ctx->scan.fEnableDFSChnlScan;
+
+	status = csr_scan_free_request(mac_ctx, dst_req);
+	if (!CDF_IS_STATUS_SUCCESS(status))
+		goto complete;
+	cdf_mem_copy(dst_req, src_req, sizeof(tCsrScanRequest));
+	/* Re-initialize the pointers to NULL since we did a copy */
+	dst_req->pIEField = NULL;
+	dst_req->ChannelInfo.ChannelList = NULL;
+	dst_req->SSIDs.SSIDList = NULL;
+
+	if (src_req->uIEFieldLen) {
+		dst_req->pIEField =
+			cdf_mem_malloc(src_req->uIEFieldLen);
+		if (NULL == dst_req->pIEField) {
+			status = CDF_STATUS_E_NOMEM;
+			sms_log(mac_ctx, LOGE,
+					FL("No memory for scanning IE fields"));
+			goto complete;
+		} else {
+			status = CDF_STATUS_SUCCESS;
+			cdf_mem_copy(dst_req->pIEField, src_req->pIEField,
+				src_req->uIEFieldLen);
+			dst_req->uIEFieldLen = src_req->uIEFieldLen;
+		}
+	}
+
+	/* Allocate memory for IE field */
+	if (src_req->ChannelInfo.numOfChannels == 0) {
+		dst_req->ChannelInfo.ChannelList = NULL;
+		dst_req->ChannelInfo.numOfChannels = 0;
+	} else {
+		dst_req->ChannelInfo.ChannelList =
+			cdf_mem_malloc(src_req->ChannelInfo.numOfChannels *
+				sizeof(*dst_req->ChannelInfo.ChannelList));
+		if (NULL == dst_req->ChannelInfo.ChannelList) {
+			status = CDF_STATUS_E_NOMEM;
+			dst_req->ChannelInfo.numOfChannels = 0;
+			sms_log(mac_ctx, LOGE,
+				FL("No memory for scanning Channel List"));
+			goto complete;
+		}
+
+		if ((src_req->scanType == eSIR_PASSIVE_SCAN) &&
+			(src_req->requestType == eCSR_SCAN_REQUEST_11D_SCAN)) {
+			for (index = 0; index < src_req->ChannelInfo.
+						numOfChannels; index++) {
+				channel_state =
+					cds_get_channel_state(src_req->
+							ChannelInfo.
+							ChannelList[index]);
+				if (src_req->ChannelInfo.ChannelList[index] <
+						MIN_11P_CHANNEL &&
+					((CHANNEL_STATE_ENABLE ==
+						channel_state) ||
+					((CHANNEL_STATE_DFS == channel_state) &&
+					!skip_dfs_chnl))) {
+					dst_req->ChannelInfo.ChannelList
+							[new_index] =
+								src_req->
+								ChannelInfo.
+								ChannelList
+								[index];
+					new_index++;
+				}
+			}
+			dst_req->ChannelInfo.numOfChannels = new_index;
+		} else if (CDF_IS_STATUS_SUCCESS(
+				csr_get_cfg_valid_channels(mac_ctx,
+						mac_ctx->roam.validChannelList,
+						&len))) {
+			new_index = 0;
+			mac_ctx->roam.numValidChannels = len;
+			csr_scan_copy_request_valid_channels_only(mac_ctx,
+							dst_req, skip_dfs_chnl,
+							src_req);
+		} else {
+			sms_log(mac_ctx, LOGE,
+				FL("Couldn't get the valid Channel List, keeping requester's list"));
+			new_index = 0;
+			for (index = 0; index < src_req->ChannelInfo.
+					numOfChannels; index++) {
+				if (src_req->ChannelInfo.ChannelList[index] <
+						MIN_11P_CHANNEL) {
+					dst_req->ChannelInfo.
+						ChannelList[new_index] =
+						src_req->ChannelInfo.
+						ChannelList[index];
+					new_index++;
+				}
+			}
+			dst_req->ChannelInfo.numOfChannels =
+				new_index;
+		}
+	} /* Allocate memory for Channel List */
+	if (src_req->SSIDs.numOfSSIDs == 0) {
+		dst_req->SSIDs.numOfSSIDs = 0;
+		dst_req->SSIDs.SSIDList = NULL;
+	} else {
+		dst_req->SSIDs.SSIDList =
+			cdf_mem_malloc(src_req->SSIDs.numOfSSIDs *
+					sizeof(*dst_req->SSIDs.SSIDList));
+		if (NULL == dst_req->SSIDs.SSIDList)
+			status = CDF_STATUS_E_NOMEM;
+		else
+			status = CDF_STATUS_SUCCESS;
+		if (CDF_IS_STATUS_SUCCESS(status)) {
+			dst_req->SSIDs.numOfSSIDs =
+				src_req->SSIDs.numOfSSIDs;
+			cdf_mem_copy(dst_req->SSIDs.SSIDList,
+				src_req->SSIDs.SSIDList,
+				src_req->SSIDs.numOfSSIDs *
+				sizeof(*dst_req->SSIDs.SSIDList));
+		} else {
+			dst_req->SSIDs.numOfSSIDs = 0;
+			sms_log(mac_ctx, LOGE,
+					FL("No memory for scanning SSID List"));
+			goto complete;
+		}
+	} /* Allocate memory for SSID List */
+	dst_req->p2pSearch = src_req->p2pSearch;
+	dst_req->skipDfsChnlInP2pSearch =
+		src_req->skipDfsChnlInP2pSearch;
+	dst_req->scan_id = src_req->scan_id;
+	dst_req->timestamp = src_req->timestamp;
+
+complete:
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		csr_scan_free_request(mac_ctx, dst_req);
+	}
+
+	return status;
+}
+
+CDF_STATUS csr_scan_free_request(tpAniSirGlobal pMac, tCsrScanRequest *pReq)
+{
+
+	if (pReq->ChannelInfo.ChannelList) {
+		cdf_mem_free(pReq->ChannelInfo.ChannelList);
+		pReq->ChannelInfo.ChannelList = NULL;
+	}
+	pReq->ChannelInfo.numOfChannels = 0;
+	if (pReq->pIEField) {
+		cdf_mem_free(pReq->pIEField);
+		pReq->pIEField = NULL;
+	}
+	pReq->uIEFieldLen = 0;
+	if (pReq->SSIDs.SSIDList) {
+		cdf_mem_free(pReq->SSIDs.SSIDList);
+		pReq->SSIDs.SSIDList = NULL;
+	}
+	pReq->SSIDs.numOfSSIDs = 0;
+
+	return CDF_STATUS_SUCCESS;
+}
+
+void csr_scan_call_callback(tpAniSirGlobal pMac, tSmeCmd *pCommand,
+			    eCsrScanStatus scanStatus)
+{
+	if (pCommand->u.scanCmd.callback) {
+		pCommand->u.scanCmd.callback(pMac, pCommand->u.scanCmd.pContext,
+					     pCommand->sessionId,
+					     pCommand->u.scanCmd.scanID,
+					     scanStatus);
+	} else {
+		sms_log(pMac, LOG2, "%s:%d - Callback NULL!!!", __func__,
+			__LINE__);
+	}
+}
+
+void csr_scan_stop_timers(tpAniSirGlobal pMac)
+{
+	if (0 != pMac->scan.scanResultCfgAgingTime) {
+		csr_scan_stop_result_cfg_aging_timer(pMac);
+	}
+
+}
+
+#ifdef WLAN_AP_STA_CONCURRENCY
+/**
+ * csr_sta_ap_conc_timer_handler - Function to handle STA,AP concurrency timer
+ * @pv: pointer variable
+ *
+ * Function handles STA,AP concurrency timer
+ *
+ * Return: none
+ */
+static void csr_sta_ap_conc_timer_handler(void *pv)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(pv);
+	tListElem *entry;
+	tSmeCmd *scan_cmd;
+	uint32_t session_id = CSR_SESSION_ID_INVALID;
+	tCsrScanRequest scan_req;
+	tSmeCmd *send_scancmd = NULL;
+	uint8_t num_chn = 0;
+	uint8_t numchan_combinedconc = 0;
+	uint8_t i, j;
+	tCsrChannelInfo *chn_info = NULL;
+	uint8_t channel_to_scan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
+	CDF_STATUS status;
+
+	csr_ll_lock(&mac_ctx->scan.scanCmdPendingList);
+
+	entry = csr_ll_peek_head(&mac_ctx->scan.scanCmdPendingList,
+			LL_ACCESS_NOLOCK);
+
+	if (NULL == entry) {
+		csr_ll_unlock(&mac_ctx->scan.scanCmdPendingList);
+		return;
+	}
+
+
+	chn_info = &scan_req.ChannelInfo;
+	scan_cmd = GET_BASE_ADDR(entry, tSmeCmd, Link);
+	num_chn =
+		scan_cmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels;
+	session_id = scan_cmd->sessionId;
+
+	/*
+	 * if any session is connected and the number of channels to scan is
+	 * greater than 1 then split the scan into multiple scan operations
+	 * on each individual channel else continue to perform scan on all
+	 * specified channels */
+
+	/*
+	 * split scan if number of channels to scan is greater than 1 and
+	 * any one of the following:
+	 * - STA session is connected and the scan is not a P2P search
+	 * - any P2P session is connected
+	 * Do not split scans if no concurrent infra connections are
+	 * active and if the scan is a BG scan triggered by LFR (OR)
+	 * any scan if LFR is in the middle of a BG scan. Splitting
+	 * the scan is delaying the time it takes for LFR to find
+	 * candidates and resulting in disconnects.
+	 */
+
+	if ((csr_is_sta_session_connected(mac_ctx) &&
+		!csr_is_p2p_session_connected(mac_ctx)))
+		numchan_combinedconc =
+			mac_ctx->roam.configParam.nNumStaChanCombinedConc;
+	else if (csr_is_p2p_session_connected(mac_ctx))
+		numchan_combinedconc =
+			mac_ctx->roam.configParam.nNumP2PChanCombinedConc;
+
+	if ((num_chn > numchan_combinedconc) &&
+		((csr_is_sta_session_connected(mac_ctx) &&
+#ifdef FEATURE_WLAN_LFR
+		(csr_is_concurrent_infra_connected(mac_ctx)) &&
+#endif
+		(scan_cmd->u.scanCmd.u.scanRequest.p2pSearch != 1)) ||
+		(csr_is_p2p_session_connected(mac_ctx)))) {
+			cdf_mem_set(&scan_req, sizeof(tCsrScanRequest), 0);
+
+		/* optimize this to use 2 command buffer only */
+		send_scancmd = csr_get_command_buffer(mac_ctx);
+		if (!send_scancmd) {
+			sms_log(mac_ctx, LOGE,
+				FL(" Failed to get Queue command buffer"));
+			csr_ll_unlock(&mac_ctx->scan.scanCmdPendingList);
+			return;
+		}
+		send_scancmd->command = scan_cmd->command;
+		send_scancmd->sessionId = scan_cmd->sessionId;
+		send_scancmd->u.scanCmd.callback = NULL;
+		send_scancmd->u.scanCmd.pContext =
+		scan_cmd->u.scanCmd.pContext;
+		send_scancmd->u.scanCmd.reason =
+				scan_cmd->u.scanCmd.reason;
+		/* let it wrap around */
+		wma_get_scan_id(&send_scancmd->u.scanCmd.scanID);
+
+		/*
+		 * First copy all the parameters to local variable of scan
+		 * request
+		 */
+		csr_scan_copy_request(mac_ctx, &scan_req,
+					&scan_cmd->u.scanCmd.u.scanRequest);
+
+		/*
+		 * Now modify the elements of local var scan request required
+		 * to be modified for split scan
+		 */
+		if (scan_req.ChannelInfo.ChannelList != NULL) {
+				cdf_mem_free(scan_req.ChannelInfo.ChannelList);
+			scan_req.ChannelInfo.ChannelList = NULL;
+		}
+
+		chn_info->numOfChannels = numchan_combinedconc;
+		cdf_mem_copy(&channel_to_scan[0],
+				&scan_cmd->u.scanCmd.u.scanRequest.ChannelInfo.
+				ChannelList[0], chn_info->numOfChannels
+				* sizeof(uint8_t));
+		chn_info->ChannelList = &channel_to_scan[0];
+
+		for (i = 0, j = numchan_combinedconc;
+				i < (num_chn - numchan_combinedconc);
+						i++, j++) {
+			/* Move all the channels one step */
+			scan_cmd->u.scanCmd.u.scanRequest.ChannelInfo.
+					ChannelList[i] =
+					scan_cmd->u.scanCmd.u.scanRequest.
+					ChannelInfo.ChannelList[j];
+		}
+
+		/* reduce outstanding # of channels to be scanned */
+		scan_cmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels =
+				num_chn - numchan_combinedconc;
+
+		scan_req.BSSType = eCSR_BSS_TYPE_ANY;
+		/* Modify callers parameters in case of concurrency */
+		scan_req.scanType = eSIR_ACTIVE_SCAN;
+		/* Use concurrency values for min/maxChnTime. */
+		csr_set_default_scan_timing(mac_ctx, scan_req.scanType,
+						&scan_req);
+
+		status = csr_scan_copy_request(mac_ctx,
+						&send_scancmd->u.scanCmd.u.
+						scanRequest, &scan_req);
+		if (!CDF_IS_STATUS_SUCCESS(status)) {
+			sms_log(mac_ctx, LOGE,
+				FL(" Failed to get copy csr_scan_request = %d"),
+				status);
+			csr_ll_unlock(&mac_ctx->scan.scanCmdPendingList);
+			return;
+		}
+		/* Clean the local scan variable */
+		scan_req.ChannelInfo.ChannelList = NULL;
+		scan_req.ChannelInfo.numOfChannels = 0;
+		csr_scan_free_request(mac_ctx, &scan_req);
+	} else {
+		/*
+		 * no active connected session present or numChn == 1
+		 * scan all remaining channels
+		 */
+		send_scancmd = scan_cmd;
+		/* remove this command from pending list */
+		if (csr_ll_remove_head(&mac_ctx->scan.scanCmdPendingList,
+			/*
+			 * In case between PeekHead and here, the entry
+			 * got removed by another thread.
+			 */
+					LL_ACCESS_NOLOCK) == NULL) {
+			sms_log(mac_ctx, LOGE,
+				FL(" Failed to remove entry from scanCmdPendingList"));
+		}
+
+	}
+	csr_queue_sme_command(mac_ctx, send_scancmd, false);
+
+
+	csr_ll_unlock(&mac_ctx->scan.scanCmdPendingList);
+
+}
+#endif
+
+CDF_STATUS csr_scan_start_result_cfg_aging_timer(tpAniSirGlobal pMac)
+{
+	CDF_STATUS status = CDF_STATUS_E_FAILURE;
+
+	if (pMac->scan.fScanEnable) {
+		status =
+			cdf_mc_timer_start(&pMac->scan.hTimerResultCfgAging,
+					   CSR_SCAN_RESULT_CFG_AGING_INTERVAL /
+					   CDF_MC_TIMER_TO_MS_UNIT);
+	}
+	return status;
+}
+
+CDF_STATUS csr_scan_stop_result_cfg_aging_timer(tpAniSirGlobal pMac)
+{
+	return cdf_mc_timer_stop(&pMac->scan.hTimerResultCfgAging);
+}
+
+/**
+ * csr_scan_result_cfg_aging_timer_handler() - Time based scan aging handler
+ * @pv: Global context
+ *
+ * This routine is to handle scan aging based on user configured timer value.
+ *
+ * Return: None
+ */
+static void csr_scan_result_cfg_aging_timer_handler(void *pv)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(pv);
+	tListElem *entry, *tmp_entry;
+	tCsrScanResult *result;
+	uint32_t ageout_time =
+		mac_ctx->scan.scanResultCfgAgingTime * CDF_TICKS_PER_SECOND/10;
+	uint32_t cur_time = (uint32_t) cdf_mc_timer_get_system_ticks();
+	uint8_t *bssId;
+
+	csr_ll_lock(&mac_ctx->scan.scanResultList);
+	entry = csr_ll_peek_head(&mac_ctx->scan.scanResultList, LL_ACCESS_NOLOCK);
+	while (entry) {
+		tmp_entry = csr_ll_next(&mac_ctx->scan.scanResultList, entry,
+					LL_ACCESS_NOLOCK);
+		result = GET_BASE_ADDR(entry, tCsrScanResult, Link);
+		/*
+		 * cdf_mc_timer_get_system_ticks() returns in 10ms interval.
+		 * so ageout time value also updated to 10ms interval value.
+		 */
+		if ((cur_time - result->Result.BssDescriptor.nReceivedTime) >
+			    ageout_time) {
+			bssId = result->Result.BssDescriptor.bssId;
+			sms_log(mac_ctx, LOGW,
+				FL("age out due to time out"MAC_ADDRESS_STR),
+				MAC_ADDR_ARRAY(bssId));
+			csr_scan_age_out_bss(mac_ctx, result);
+		}
+		entry = tmp_entry;
+	}
+	csr_ll_unlock(&mac_ctx->scan.scanResultList);
+	cdf_mc_timer_start(&mac_ctx->scan.hTimerResultCfgAging,
+			   CSR_SCAN_RESULT_CFG_AGING_INTERVAL /
+			   CDF_MC_TIMER_TO_MS_UNIT);
+}
+
+bool csr_scan_remove_fresh_scan_command(tpAniSirGlobal pMac, uint8_t sessionId)
+{
+	bool fRet = false;
+	tListElem *pEntry, *pEntryTmp;
+	tSmeCmd *pCommand;
+	tDblLinkList localList;
+	tDblLinkList *pCmdList;
+
+	cdf_mem_zero(&localList, sizeof(tDblLinkList));
+	if (!CDF_IS_STATUS_SUCCESS(csr_ll_open(pMac->hHdd, &localList))) {
+		sms_log(pMac, LOGE, FL(" failed to open list"));
+		return fRet;
+	}
+
+	pCmdList = &pMac->sme.smeScanCmdPendingList;
+
+	csr_ll_lock(pCmdList);
+	pEntry = csr_ll_peek_head(pCmdList, LL_ACCESS_NOLOCK);
+	while (pEntry) {
+		pEntryTmp = csr_ll_next(pCmdList, pEntry, LL_ACCESS_NOLOCK);
+		pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
+		if (!((eSmeCommandScan == pCommand->command)
+		    && (sessionId == pCommand->sessionId))) {
+			pEntry = pEntryTmp;
+			continue;
+		}
+		sms_log(pMac, LOGW,
+			FL("-------- abort scan command reason = %d"),
+			pCommand->u.scanCmd.reason);
+		/* The rest are fresh scan requests */
+		if (csr_ll_remove_entry(pCmdList, pEntry,
+					LL_ACCESS_NOLOCK)) {
+			csr_ll_insert_tail(&localList, pEntry,
+					   LL_ACCESS_NOLOCK);
+		}
+		fRet = true;
+		pEntry = pEntryTmp;
+	}
+
+	csr_ll_unlock(pCmdList);
+
+	while ((pEntry = csr_ll_remove_head(&localList, LL_ACCESS_NOLOCK))) {
+		pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
+		if (pCommand->u.scanCmd.callback) {
+			/*
+			 * User scan request is pending, send response with
+			 * status eCSR_SCAN_ABORT
+			 */
+			pCommand->u.scanCmd.callback(pMac,
+				pCommand->u.scanCmd.pContext, sessionId,
+				pCommand->u.scanCmd.scanID, eCSR_SCAN_ABORT);
+		}
+		csr_release_command_scan(pMac, pCommand);
+	}
+	csr_ll_close(&localList);
+
+	return fRet;
+}
+
+void csr_release_scan_command(tpAniSirGlobal pMac, tSmeCmd *pCommand,
+			      eCsrScanStatus scanStatus)
+{
+	eCsrScanReason reason = pCommand->u.scanCmd.reason;
+	bool status;
+	tDblLinkList *cmd_list = NULL;
+
+	csr_scan_call_callback(pMac, pCommand, scanStatus);
+	sms_log(pMac, LOG1, FL("Remove Scan command reason = %d, scan_id %d"),
+		reason, pCommand->u.scanCmd.scanID);
+	cmd_list = &pMac->sme.smeScanCmdActiveList;
+	status = csr_ll_remove_entry(cmd_list, &pCommand->Link, LL_ACCESS_LOCK);
+	if (!status) {
+		sms_log(pMac, LOGE,
+			FL("cannot release command reason %d scan_id %d"),
+			pCommand->u.scanCmd.reason,
+			pCommand->u.scanCmd.scanID);
+		return;
+	}
+	csr_release_command_scan(pMac, pCommand);
+}
+
+CDF_STATUS csr_scan_get_pmkid_candidate_list(tpAniSirGlobal pMac,
+					     uint32_t sessionId,
+					     tPmkidCandidateInfo *pPmkidList,
+					     uint32_t *pNumItems)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+	tCsrScanResultFilter *pScanFilter;
+	tCsrScanResultInfo *pScanResult;
+	tScanResultHandle hBSSList;
+	uint32_t nItems = *pNumItems;
+
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("  session %d not found "), sessionId);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	sms_log(pMac, LOGW, FL("pMac->scan.NumPmkidCandidate = %d"),
+		pSession->NumPmkidCandidate);
+	csr_reset_pmkid_candidate_list(pMac, sessionId);
+	if (!(csr_is_conn_state_connected(pMac, sessionId)
+	    && pSession->pCurRoamProfile))
+		return status;
+
+	*pNumItems = 0;
+	pScanFilter = cdf_mem_malloc(sizeof(tCsrScanResultFilter));
+	if (NULL == pScanFilter)
+		return CDF_STATUS_E_NOMEM;
+
+	cdf_mem_set(pScanFilter, sizeof(tCsrScanResultFilter), 0);
+	/* Here is the profile we need to connect to */
+	status = csr_roam_prepare_filter_from_profile(pMac,
+					pSession->pCurRoamProfile, pScanFilter);
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		cdf_mem_free(pScanFilter);
+		return status;
+	}
+
+	status = csr_scan_get_result(pMac, pScanFilter, &hBSSList);
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		csr_free_scan_filter(pMac, pScanFilter);
+		cdf_mem_free(pScanFilter);
+		return status;
+	}
+
+	if (pSession->NumPmkidCandidate < nItems) {
+		pScanResult = csr_scan_result_get_next(pMac, hBSSList);
+		while (pScanResult != NULL) {
+			/* NumPmkidCandidate adds up here */
+			csr_process_bss_desc_for_pmkid_list(pMac,
+				&pScanResult->BssDescriptor,
+				(tDot11fBeaconIEs *)(pScanResult->pvIes),
+				sessionId);
+			pScanResult = csr_scan_result_get_next(pMac, hBSSList);
+		}
+	}
+
+	if (pSession->NumPmkidCandidate) {
+		*pNumItems = pSession->NumPmkidCandidate;
+		cdf_mem_copy(pPmkidList, pSession->PmkidCandidateInfo,
+			     pSession->NumPmkidCandidate *
+			     sizeof(tPmkidCandidateInfo));
+	}
+
+	csr_scan_result_purge(pMac, hBSSList);
+	csr_free_scan_filter(pMac, pScanFilter);
+	cdf_mem_free(pScanFilter);
+	return status;
+}
+
+#ifdef FEATURE_WLAN_WAPI
+CDF_STATUS csr_scan_get_bkid_candidate_list(tpAniSirGlobal pMac,
+					    uint32_t sessionId,
+					    tBkidCandidateInfo *pBkidList,
+					    uint32_t *pNumItems)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+	tCsrScanResultFilter *pScanFilter;
+	tCsrScanResultInfo *pScanResult;
+	tScanResultHandle hBSSList;
+	uint32_t nItems = *pNumItems;
+
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("  session %d not found "), sessionId);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	sms_log(pMac, LOGW, FL("pMac->scan.NumBkidCandidate = %d"),
+		pSession->NumBkidCandidate);
+	csr_reset_bkid_candidate_list(pMac, sessionId);
+	if (!(csr_is_conn_state_connected(pMac, sessionId)
+	    && pSession->pCurRoamProfile))
+		return status;
+
+	*pNumItems = 0;
+	pScanFilter = cdf_mem_malloc(sizeof(tCsrScanResultFilter));
+	if (NULL == pScanFilter)
+		return CDF_STATUS_E_NOMEM;
+
+	cdf_mem_set(pScanFilter, sizeof(tCsrScanResultFilter), 0);
+	/* Here is the profile we need to connect to */
+	status = csr_roam_prepare_filter_from_profile(pMac,
+					pSession->pCurRoamProfile, pScanFilter);
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		cdf_mem_free(pScanFilter);
+		return status;
+	}
+
+	status = csr_scan_get_result(pMac, pScanFilter, &hBSSList);
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		csr_free_scan_filter(pMac, pScanFilter);
+		cdf_mem_free(pScanFilter);
+		return status;
+	}
+
+	if (pSession->NumBkidCandidate < nItems) {
+		pScanResult = csr_scan_result_get_next(pMac, hBSSList);
+		while (pScanResult != NULL) {
+			/* pMac->scan.NumBkidCandidate adds up here */
+			csr_process_bss_desc_for_bkid_list(pMac,
+				&pScanResult->BssDescriptor,
+				(tDot11fBeaconIEs *)(pScanResult->pvIes));
+			pScanResult = csr_scan_result_get_next(pMac, hBSSList);
+		}
+	}
+
+	if (pSession->NumBkidCandidate) {
+		*pNumItems = pSession->NumBkidCandidate;
+		cdf_mem_copy(pBkidList, pSession->BkidCandidateInfo,
+			     pSession->NumBkidCandidate *
+			     sizeof(tBkidCandidateInfo));
+	}
+
+	csr_scan_result_purge(pMac, hBSSList);
+	csr_free_scan_filter(pMac, pScanFilter);
+	cdf_mem_free(pScanFilter);
+	return status;
+}
+#endif /* FEATURE_WLAN_WAPI */
+
+/**
+ * csr_roam_copy_channellist() - Function to copy channel list
+ * @mac_ctx: pointer to Global Mac structure
+ * @profile: pointer to tCsrRoamProfile
+ * @scan_cmd: pointer to tSmeCmd
+ * @index: index for channellist
+ *
+ * Function copies channel list
+ *
+ * Return: none
+ */
+static void csr_roam_copy_channellist(tpAniSirGlobal mac_ctx,
+				tCsrRoamProfile *profile,
+				tSmeCmd *scan_cmd, uint8_t index)
+{
+	tCsrChannelInfo *channel_info =
+		&scan_cmd->u.scanCmd.u.scanRequest.ChannelInfo;
+
+	for (index = 0; index < profile->ChannelInfo.numOfChannels;
+			index++) {
+		if (!csr_roam_is_valid_channel(mac_ctx,
+			profile->ChannelInfo.ChannelList[index])) {
+			sms_log(mac_ctx, LOGW,
+				FL("process a channel (%d) that is invalid"),
+			profile->ChannelInfo.ChannelList[index]);
+			continue;
+		}
+		channel_info->ChannelList[channel_info->numOfChannels] =
+			profile->ChannelInfo.ChannelList[index];
+		scan_cmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels++;
+	}
+}
+
+/**
+ * csr_scan_for_ssid() -  Function usually used for BSSs that suppresses SSID
+ * @mac_ctx: Pointer to Global Mac structure
+ * @profile: pointer to tCsrRoamProfile
+ * @roam_id: variable representing roam id
+ * @notify: boolean variable
+ *
+ * Function is usually used for BSSs that suppresses SSID so the profile
+ * shall have one and only one SSID.
+ *
+ * Return: Success - CDF_STATUS_SUCCESS, Failure - error number
+ */
+CDF_STATUS csr_scan_for_ssid(tpAniSirGlobal mac_ctx, uint32_t session_id,
+			tCsrRoamProfile *profile, uint32_t roam_id,
+			bool notify)
+{
+	CDF_STATUS status = CDF_STATUS_E_INVAL;
+	tSmeCmd *scan_cmd = NULL;
+	tCsrScanRequest *scan_req = NULL;
+	uint8_t index = 0;
+	uint32_t num_ssid = profile->SSIDs.numOfSSIDs;
+	tpCsrNeighborRoamControlInfo neighbor_roaminfo =
+		&mac_ctx->roam.neighborRoamInfo[session_id];
+	tCsrSSIDs *ssids = NULL;
+
+	sms_log(mac_ctx, LOG2, FL("called"));
+
+	/* For WDS, we use the index 0. There must be at least one in there */
+	if (CSR_IS_WDS_STA(profile) && num_ssid)
+		num_ssid = 1;
+
+	if (!(mac_ctx->scan.fScanEnable) && (num_ssid != 1)) {
+		sms_log(mac_ctx, LOGE,
+			FL("cannot scan because scanEnable (%d) or numSSID (%d) is invalid"),
+			mac_ctx->scan.fScanEnable, profile->SSIDs.numOfSSIDs);
+		return status;
+	}
+
+	scan_cmd = csr_get_command_buffer(mac_ctx);
+
+	if (!scan_cmd) {
+		sms_log(mac_ctx, LOGE,
+			FL("failed to allocate command buffer"));
+		goto error;
+	}
+
+	cdf_mem_set(&scan_cmd->u.scanCmd, sizeof(tScanCmd), 0);
+	scan_cmd->u.scanCmd.pToRoamProfile =
+			cdf_mem_malloc(sizeof(tCsrRoamProfile));
+
+	if (NULL == scan_cmd->u.scanCmd.pToRoamProfile)
+		status = CDF_STATUS_E_NOMEM;
+	else
+		status = csr_roam_copy_profile(mac_ctx,
+					scan_cmd->u.scanCmd.pToRoamProfile,
+					profile);
+
+	if (!CDF_IS_STATUS_SUCCESS(status))
+		goto error;
+
+	scan_cmd->u.scanCmd.roamId = roam_id;
+	scan_cmd->command = eSmeCommandScan;
+	scan_cmd->sessionId = (uint8_t) session_id;
+	scan_cmd->u.scanCmd.callback = NULL;
+	scan_cmd->u.scanCmd.pContext = NULL;
+	scan_cmd->u.scanCmd.reason = eCsrScanForSsid;
+
+	/* let it wrap around */
+	wma_get_scan_id(&scan_cmd->u.scanCmd.scanID);
+	cdf_mem_set(&scan_cmd->u.scanCmd.u.scanRequest,
+			sizeof(tCsrScanRequest), 0);
+	status = cdf_mc_timer_init(&scan_cmd->u.scanCmd.csr_scan_timer,
+			CDF_TIMER_TYPE_SW,
+			csr_scan_active_list_timeout_handle, &scan_cmd);
+	scan_req = &scan_cmd->u.scanCmd.u.scanRequest;
+	scan_req->scanType = eSIR_ACTIVE_SCAN;
+	scan_req->BSSType = profile->BSSType;
+	scan_req->scan_id = scan_cmd->u.scanCmd.scanID;
+	/*
+	 * To avoid 11b rate in probe request Set p2pSearch
+	 * flag as 1 for P2P Client Mode
+	 */
+	if (CDF_P2P_CLIENT_MODE == profile->csrPersona)
+		scan_req->p2pSearch = 1;
+
+	/* Allocate memory for IE field */
+	if (profile->pAddIEScan) {
+		scan_req->pIEField =
+			cdf_mem_malloc(profile->nAddIEScanLength);
+
+		if (NULL == scan_req->pIEField)
+			status = CDF_STATUS_E_NOMEM;
+		else
+			status = CDF_STATUS_SUCCESS;
+
+		cdf_mem_set(scan_req->pIEField,
+				profile->nAddIEScanLength, 0);
+
+		if (CDF_IS_STATUS_SUCCESS(status)) {
+			cdf_mem_copy(scan_req->pIEField,
+					profile->pAddIEScan,
+					profile->nAddIEScanLength);
+			scan_req->uIEFieldLen = profile->nAddIEScanLength;
+		} else {
+			sms_log(mac_ctx, LOGE,
+				"No memory for scanning IE fields");
+		}
+	} else
+		scan_req->uIEFieldLen = 0;
+
+	/*
+	 * For one channel be good enpugh time to receive beacon
+	 * atleast
+	 */
+	if (1 == profile->ChannelInfo.numOfChannels) {
+		if (neighbor_roaminfo->handoffReqInfo.src ==
+					FASTREASSOC) {
+			scan_req->maxChnTime =
+				MAX_ACTIVE_SCAN_FOR_ONE_CHANNEL_FASTREASSOC;
+			scan_req->minChnTime =
+				MIN_ACTIVE_SCAN_FOR_ONE_CHANNEL_FASTREASSOC;
+			/* Reset this value */
+			neighbor_roaminfo->handoffReqInfo.src = 0;
+		} else {
+			scan_req->maxChnTime =
+					MAX_ACTIVE_SCAN_FOR_ONE_CHANNEL;
+			scan_req->minChnTime =
+					MIN_ACTIVE_SCAN_FOR_ONE_CHANNEL;
+		}
+	} else {
+		scan_req->maxChnTime =
+			mac_ctx->roam.configParam.nActiveMaxChnTime;
+		scan_req->minChnTime =
+			mac_ctx->roam.configParam.nActiveMinChnTime;
+	}
+
+	if (profile->BSSIDs.numOfBSSIDs == 1)
+		cdf_copy_macaddr(&scan_req->bssid,
+				profile->BSSIDs.bssid);
+	else
+		cdf_set_macaddr_broadcast(&scan_req->bssid);
+
+	if (profile->ChannelInfo.numOfChannels) {
+		scan_req->ChannelInfo.ChannelList =
+		    cdf_mem_malloc(sizeof(*scan_req->ChannelInfo.ChannelList) *
+					profile->ChannelInfo.numOfChannels);
+
+		if (NULL == scan_req->ChannelInfo.ChannelList)
+			status = CDF_STATUS_E_NOMEM;
+		else
+			status = CDF_STATUS_SUCCESS;
+
+		scan_req->ChannelInfo.numOfChannels = 0;
+
+		if (CDF_IS_STATUS_SUCCESS(status)) {
+			csr_roam_is_channel_valid(mac_ctx,
+				profile->ChannelInfo.ChannelList[0]);
+			csr_roam_copy_channellist(mac_ctx,
+				profile, scan_cmd, index);
+		} else {
+			goto error;
+		}
+	} else {
+		scan_req->ChannelInfo.numOfChannels = 0;
+	}
+
+	if (profile->SSIDs.numOfSSIDs) {
+		scan_req->SSIDs.SSIDList =
+			cdf_mem_malloc(profile->SSIDs.numOfSSIDs *
+					sizeof(tCsrSSIDInfo));
+
+		if (NULL == scan_req->SSIDs.SSIDList)
+			status = CDF_STATUS_E_NOMEM;
+		else
+			status = CDF_STATUS_SUCCESS;
+
+		if (!CDF_IS_STATUS_SUCCESS(status))
+			goto error;
+
+		ssids = &scan_req->SSIDs;
+		ssids->numOfSSIDs =  1;
+
+		cdf_mem_copy(scan_req->SSIDs.SSIDList,
+				profile->SSIDs.SSIDList,
+				sizeof(tCsrSSIDInfo));
+	}
+
+	/* Start process the command */
+	status = csr_queue_sme_command(mac_ctx, scan_cmd, false);
+error:
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		sms_log(mac_ctx, LOGE,
+			FL(" failed to iniate scan with status = %d"), status);
+		if (scan_cmd)
+			csr_release_command_scan(mac_ctx, scan_cmd);
+		if (notify)
+			csr_roam_call_callback(mac_ctx, session_id, NULL,
+					roam_id, eCSR_ROAM_FAILED,
+					eCSR_ROAM_RESULT_FAILURE);
+	}
+	return status;
+}
+
+void csr_set_cfg_valid_channel_list(tpAniSirGlobal pMac, uint8_t *pChannelList,
+				    uint8_t NumChannels)
+{
+	uint32_t dataLen = sizeof(uint8_t) * NumChannels;
+	CDF_STATUS status;
+
+	CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
+		  "%s: dump valid channel list(NumChannels(%d))",
+		  __func__, NumChannels);
+	CDF_TRACE_HEX_DUMP(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
+			   pChannelList, NumChannels);
+	cfg_set_str(pMac, WNI_CFG_VALID_CHANNEL_LIST, pChannelList,
+			dataLen);
+
+	CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
+		  "Scan offload is enabled, update default chan list");
+	/*
+	 * disable fcc constraint since new country code
+	 * is being set
+	 */
+	pMac->scan.fcc_constraint = false;
+	status = csr_update_channel_list(pMac);
+	if (CDF_STATUS_SUCCESS != status) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+			  "failed to update the supported channel list");
+	}
+	return;
+}
+
+/*
+ * The Tx power limits are saved in the cfg for future usage.
+ */
+void csr_save_tx_power_to_cfg(tpAniSirGlobal pMac, tDblLinkList *pList,
+			      uint32_t cfgId)
+{
+	tListElem *pEntry;
+	uint32_t cbLen = 0, dataLen, tmp_len;
+	tCsrChannelPowerInfo *ch_set;
+	uint32_t idx;
+	tSirMacChanInfo *ch_pwr_set;
+	uint8_t *pBuf = NULL;
+
+	/* allocate maximum space for all channels */
+	dataLen = WNI_CFG_VALID_CHANNEL_LIST_LEN * sizeof(tSirMacChanInfo);
+	pBuf = cdf_mem_malloc(dataLen);
+	if (pBuf == NULL)
+		return;
+
+	cdf_mem_set(pBuf, dataLen, 0);
+	ch_pwr_set = (tSirMacChanInfo *) (pBuf);
+	pEntry = csr_ll_peek_head(pList, LL_ACCESS_LOCK);
+	/*
+	 * write the tuples (startChan, numChan, txPower) for each channel found
+	 * in the channel power list.
+	 */
+	while (pEntry) {
+		ch_set = GET_BASE_ADDR(pEntry, tCsrChannelPowerInfo, link);
+		if (1 != ch_set->interChannelOffset) {
+			/*
+			 * we keep the 5G channel sets internally with an
+			 * interchannel offset of 4. Expand these to the right
+			 * format. (inter channel offset of 1 is the only option
+			 * for the triplets that 11d advertises.
+			 */
+			tmp_len = cbLen + (ch_set->numChannels *
+						sizeof(tSirMacChanInfo));
+			if (tmp_len >= dataLen) {
+				/*
+				 * expanding this entry will overflow our
+				 * allocation
+				 */
+				sms_log(pMac, LOGE,
+					FL("Buffer overflow, start %d, num %d, offset %d"),
+					ch_set->firstChannel,
+					ch_set->numChannels,
+					ch_set->interChannelOffset);
+				break;
+			}
+
+			for (idx = 0; idx < ch_set->numChannels; idx++) {
+				ch_pwr_set->firstChanNum = (tSirMacChanNum)
+					(ch_set->firstChannel + (idx *
+						ch_set->interChannelOffset));
+				sms_log(pMac, LOG3,
+					FL("Setting Channel Number %d"),
+					ch_pwr_set->firstChanNum);
+				ch_pwr_set->numChannels = 1;
+				ch_pwr_set->maxTxPower =
+					CDF_MIN(ch_set->txPower,
+					pMac->roam.configParam.nTxPowerCap);
+				sms_log(pMac, LOG3,
+					FL("Setting Max Transmit Power %d"),
+					ch_pwr_set->maxTxPower);
+				cbLen += sizeof(tSirMacChanInfo);
+				ch_pwr_set++;
+			}
+		} else {
+			if (cbLen >= dataLen) {
+				/* this entry will overflow our allocation */
+				sms_log(pMac, LOGE,
+					FL("Buffer overflow, start %d, num %d, offset %d"),
+					ch_set->firstChannel,
+					ch_set->numChannels,
+					ch_set->interChannelOffset);
+				break;
+			}
+			ch_pwr_set->firstChanNum = ch_set->firstChannel;
+			sms_log(pMac, LOG3, FL("Setting Channel Number %d"),
+				ch_pwr_set->firstChanNum);
+			ch_pwr_set->numChannels = ch_set->numChannels;
+			ch_pwr_set->maxTxPower = CDF_MIN(ch_set->txPower,
+					pMac->roam.configParam.nTxPowerCap);
+			sms_log(pMac, LOG3,
+				FL("Setting Max Tx Power %d, nTxPower %d"),
+				ch_pwr_set->maxTxPower,
+				pMac->roam.configParam.nTxPowerCap);
+			cbLen += sizeof(tSirMacChanInfo);
+			ch_pwr_set++;
+		}
+		pEntry = csr_ll_next(pList, pEntry, LL_ACCESS_LOCK);
+	}
+	if (cbLen)
+		cfg_set_str(pMac, cfgId, (uint8_t *) pBuf, cbLen);
+
+	cdf_mem_free(pBuf);
+}
+
+void csr_set_cfg_country_code(tpAniSirGlobal pMac, uint8_t *countryCode)
+{
+	uint8_t cc[WNI_CFG_COUNTRY_CODE_LEN];
+	/* v_REGDOMAIN_t DomainId */
+
+	sms_log(pMac, LOG3, FL("Setting Country Code in Cfg %s"), countryCode);
+	cdf_mem_copy(cc, countryCode, WNI_CFG_COUNTRY_CODE_LEN);
+
+	/*
+	* don't program the bogus country codes that we created for Korea in the
+	* MAC. if we see the bogus country codes, program the MAC with the right
+	* country code.
+	*/
+	if (('K' == countryCode[0] && '1' == countryCode[1]) ||
+	    ('K' == countryCode[0] && '2' == countryCode[1]) ||
+	    ('K' == countryCode[0] && '3' == countryCode[1]) ||
+	    ('K' == countryCode[0] && '4' == countryCode[1])) {
+		/*
+		 * replace the alternate Korea country codes, 'K1', 'K2', ..
+		 * with 'KR' for Korea
+		 */
+		cc[1] = 'R';
+	}
+	cfg_set_str(pMac, WNI_CFG_COUNTRY_CODE, cc, WNI_CFG_COUNTRY_CODE_LEN);
+
+	/*
+	 * Need to let HALPHY know about the current domain so it can apply some
+	 * domain-specific settings (TX filter...)
+	 */
+	/*
+	if(CDF_IS_STATUS_SUCCESS(csr_get_regulatory_domain_for_country(
+		pMac, cc, &DomainId))) {
+		halPhySetRegDomain(pMac, DomainId);
+	} */
+}
+
+CDF_STATUS csr_get_country_code(tpAniSirGlobal pMac, uint8_t *pBuf,
+				uint8_t *pbLen)
+{
+	CDF_STATUS status = CDF_STATUS_E_INVAL;
+	uint32_t len;
+
+	if (pBuf && pbLen && (*pbLen >= WNI_CFG_COUNTRY_CODE_LEN)) {
+		len = *pbLen;
+		status = wlan_cfg_get_str(pMac, WNI_CFG_COUNTRY_CODE, pBuf, &len);
+		if (CDF_IS_STATUS_SUCCESS(status)) {
+			*pbLen = (uint8_t) len;
+		}
+	}
+
+	return status;
+}
+
+void csr_set_cfg_scan_control_list(tpAniSirGlobal pMac, uint8_t *countryCode,
+				   tCsrChannel *pChannelList)
+{
+	uint8_t i, j;
+	bool found = false;
+	uint8_t *pControlList = NULL;
+	uint32_t len = WNI_CFG_SCAN_CONTROL_LIST_LEN;
+
+	pControlList = cdf_mem_malloc(WNI_CFG_SCAN_CONTROL_LIST_LEN);
+	if (pControlList != NULL) {
+		cdf_mem_set((void *)pControlList, WNI_CFG_SCAN_CONTROL_LIST_LEN,
+			    0);
+		if (IS_SIR_STATUS_SUCCESS(wlan_cfg_get_str(pMac,
+					WNI_CFG_SCAN_CONTROL_LIST,
+					pControlList, &len))) {
+			for (i = 0; i < pChannelList->numChannels; i++) {
+				for (j = 0; j < len; j += 2) {
+					if (pControlList[j] ==
+					    pChannelList->channelList[i]) {
+						found = true;
+						break;
+					}
+				}
+
+				if (found) {
+					/* insert a pair(channel#, flag) */
+					pControlList[j + 1] =
+						csr_get_scan_type(pMac,
+								  pControlList[j]);
+					found = false;  /* reset the flag */
+				}
+
+			}
+			CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
+				  "%s: dump scan control list", __func__);
+			CDF_TRACE_HEX_DUMP(CDF_MODULE_ID_SME,
+					   CDF_TRACE_LEVEL_INFO, pControlList,
+					   len);
+
+			cfg_set_str(pMac, WNI_CFG_SCAN_CONTROL_LIST,
+					pControlList, len);
+		} /* Successfully getting scan control list */
+		cdf_mem_free(pControlList);
+	} /* AllocateMemory */
+}
+
+CDF_STATUS csr_scan_abort_mac_scan(tpAniSirGlobal pMac, uint8_t sessionId,
+				   eCsrAbortReason reason)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+
+	pMac->scan.fDropScanCmd = true;
+	csr_remove_cmd_with_session_id_from_pending_list(pMac,
+			sessionId, &pMac->sme.smeScanCmdPendingList,
+			eSmeCommandScan);
+	pMac->scan.fDropScanCmd = false;
+	csr_abort_scan_from_active_list(pMac,
+			 &pMac->sme.smeScanCmdActiveList, sessionId,
+			eSmeCommandScan, reason);
+
+	return status;
+}
+
+void csr_remove_cmd_with_session_id_from_pending_list(tpAniSirGlobal pMac,
+						uint8_t sessionId,
+						tDblLinkList *pList,
+						eSmeCommandType commandType)
+{
+	tDblLinkList localList;
+	tListElem *pEntry;
+	tSmeCmd *pCommand;
+	tListElem *pEntryToRemove;
+
+	cdf_mem_zero(&localList, sizeof(tDblLinkList));
+	if (!CDF_IS_STATUS_SUCCESS(csr_ll_open(pMac->hHdd, &localList))) {
+		sms_log(pMac, LOGE, FL("failed to open list"));
+		return;
+	}
+
+	csr_ll_lock(pList);
+	pEntry = csr_ll_peek_head(pList, LL_ACCESS_NOLOCK);
+	if (pEntry) {
+		/*
+		 * Have to make sure we don't loop back to the head of the list,
+		 * which will happen if the entry is NOT on the list
+		 */
+		while (pEntry) {
+			pEntryToRemove = pEntry;
+			pEntry = csr_ll_next(pList, pEntry, LL_ACCESS_NOLOCK);
+			pCommand = GET_BASE_ADDR(pEntryToRemove, tSmeCmd, Link);
+
+			if (!((pCommand->command == commandType) &&
+			    (pCommand->sessionId == sessionId)))
+				continue;
+			/* Remove that entry only */
+			if (csr_ll_remove_entry(pList, pEntryToRemove,
+						LL_ACCESS_NOLOCK)) {
+				csr_ll_insert_tail(&localList, pEntryToRemove,
+						   LL_ACCESS_NOLOCK);
+			}
+		}
+	}
+	csr_ll_unlock(pList);
+
+	while ((pEntry = csr_ll_remove_head(&localList, LL_ACCESS_NOLOCK))) {
+		pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
+		sms_log(pMac, LOG1, FL("Sending abort for scan command ID %d"),
+			pCommand->u.scanCmd.scanID);
+		csr_abort_command(pMac, pCommand, false);
+	}
+
+	csr_ll_close(&localList);
+}
+
+void csr_remove_cmd_from_pending_list(tpAniSirGlobal pMac,
+				      tDblLinkList *pList,
+				      eSmeCommandType commandType)
+{
+	tDblLinkList localList;
+	tListElem *pEntry;
+	tSmeCmd *pCommand;
+	tListElem *pEntryToRemove;
+
+	cdf_mem_zero(&localList, sizeof(tDblLinkList));
+	if (!CDF_IS_STATUS_SUCCESS(csr_ll_open(pMac->hHdd, &localList))) {
+		sms_log(pMac, LOGE, FL(" failed to open list"));
+		return;
+	}
+
+	csr_ll_lock(pList);
+	if (!csr_ll_is_list_empty(pList, LL_ACCESS_NOLOCK)) {
+		pEntry = csr_ll_peek_head(pList, LL_ACCESS_NOLOCK);
+		/*
+		 * Have to make sure we don't loop back to the head of the list,
+		 * which will happen if the entry is NOT on the list...
+		 */
+		while (pEntry) {
+			pEntryToRemove = pEntry;
+			pEntry = csr_ll_next(pList, pEntry, LL_ACCESS_NOLOCK);
+			pCommand = GET_BASE_ADDR(pEntryToRemove, tSmeCmd, Link);
+			/* Remove that entry only that matches cmd type */
+			if (pCommand->command == commandType &&
+			    csr_ll_remove_entry(pList, pEntryToRemove,
+						LL_ACCESS_NOLOCK)) {
+				csr_ll_insert_tail(&localList, pEntryToRemove,
+						   LL_ACCESS_NOLOCK);
+			}
+		}
+	}
+	csr_ll_unlock(pList);
+
+	while ((pEntry = csr_ll_remove_head(&localList, LL_ACCESS_NOLOCK))) {
+		pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
+		csr_abort_command(pMac, pCommand, false);
+	}
+	csr_ll_close(&localList);
+
+}
+
+CDF_STATUS csr_scan_abort_scan_for_ssid(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+
+	pMac->scan.fDropScanCmd = true;
+	csr_remove_scan_for_ssid_from_pending_list(pMac,
+			&pMac->sme.smeScanCmdPendingList, sessionId);
+	pMac->scan.fDropScanCmd = false;
+	csr_abort_scan_from_active_list(pMac, &pMac->sme.smeScanCmdActiveList,
+		sessionId, eSmeCommandScan, eCSR_SCAN_ABORT_SSID_ONLY);
+	return status;
+}
+
+void csr_remove_scan_for_ssid_from_pending_list(tpAniSirGlobal pMac,
+						tDblLinkList *pList,
+						uint32_t sessionId)
+{
+	tDblLinkList localList;
+	tListElem *pEntry;
+	tSmeCmd *pCommand;
+	tListElem *pEntryToRemove;
+
+	cdf_mem_zero(&localList, sizeof(tDblLinkList));
+	if (!CDF_IS_STATUS_SUCCESS(csr_ll_open(pMac->hHdd, &localList))) {
+		sms_log(pMac, LOGE, FL(" failed to open list"));
+		return;
+	}
+	csr_ll_lock(pList);
+	if (!csr_ll_is_list_empty(pList, LL_ACCESS_NOLOCK)) {
+		pEntry = csr_ll_peek_head(pList, LL_ACCESS_NOLOCK);
+		/*
+		 * Have to make sure we don't loop back to the head of the list,
+		 * which will happen if the entry is NOT on the list...
+		 */
+		while (pEntry) {
+			pEntryToRemove = pEntry;
+			pEntry = csr_ll_next(pList, pEntry, LL_ACCESS_NOLOCK);
+			pCommand = GET_BASE_ADDR(pEntryToRemove, tSmeCmd, Link);
+
+			if (!((eSmeCommandScan == pCommand->command) &&
+			    (sessionId == pCommand->sessionId)))
+				continue;
+			if (eCsrScanForSsid != pCommand->u.scanCmd.reason)
+				continue;
+			/* Remove that entry only */
+			if (csr_ll_remove_entry(pList, pEntryToRemove,
+						LL_ACCESS_NOLOCK)) {
+				csr_ll_insert_tail(&localList, pEntryToRemove,
+						   LL_ACCESS_NOLOCK);
+			}
+		}
+	}
+	csr_ll_unlock(pList);
+	while ((pEntry = csr_ll_remove_head(&localList, LL_ACCESS_NOLOCK))) {
+		pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
+		csr_abort_command(pMac, pCommand, false);
+	}
+	csr_ll_close(&localList);
+}
+
+
+/**
+ * csr_send_scan_abort() -  Sends scan abort command to firmware
+ * @mac_ctx: Pointer to Global Mac structure
+ * @session_id: CSR session identification
+ * @scan_id: scan identifier
+ *
+ * .Sends scan abort command to firmware
+ *
+ * Return: None
+ */
+static void csr_send_scan_abort(tpAniSirGlobal mac_ctx,
+	uint32_t session_id, uint32_t scan_id)
+{
+	tSirSmeScanAbortReq *msg;
+	uint16_t msg_len;
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+
+	msg_len = (uint16_t)(sizeof(tSirSmeScanAbortReq));
+	msg = cdf_mem_malloc(msg_len);
+	if (NULL == msg) {
+		sms_log(mac_ctx, LOGE,
+			FL("Failed to alloc memory for SmeScanAbortReq"));
+		return;
+	}
+	cdf_mem_zero((void *)msg, msg_len);
+	msg->type = eWNI_SME_SCAN_ABORT_IND;
+	msg->msgLen = msg_len;
+	msg->sessionId = session_id;
+	msg->scan_id = scan_id;
+	sms_log(mac_ctx, LOG2,
+		FL("Abort scan sent to Firmware scan_id %d session %d"),
+		scan_id, session_id);
+	status = cds_send_mb_message_to_mac(msg);
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		cdf_mem_free(msg);
+		sms_log(mac_ctx, LOGE,
+			FL("Failed to send abort scan.scan_id %d session %d"),
+			scan_id, session_id);
+	}
+	return;
+}
+
+/**
+ * csr_abort_scan_from_active_list() -  Remove Scan command from active list
+ * @mac_ctx: Pointer to Global Mac structure
+ * @list: pointer to scan active list
+ * @session_id: CSR session identification
+ * @scan_cmd_type: scan command type
+ * @abort_reason: abort reason
+ *
+ * .Remove Scan command from active scan list
+ *
+ * Return: Success - CDF_STATUS_SUCCESS, Failure - error number
+ */
+CDF_STATUS csr_abort_scan_from_active_list(tpAniSirGlobal mac_ctx,
+		tDblLinkList *list, uint32_t session_id,
+		eSmeCommandType scan_cmd_type, eCsrAbortReason abort_reason)
+{
+	tListElem *entry;
+	tSmeCmd *cmd;
+	tListElem *entry_remove;
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+
+	csr_ll_lock(list);
+	if (!csr_ll_is_list_empty(list, LL_ACCESS_NOLOCK)) {
+		entry = csr_ll_peek_head(list, LL_ACCESS_NOLOCK);
+		while (entry) {
+			entry_remove = entry;
+			entry = csr_ll_next(list, entry, LL_ACCESS_NOLOCK);
+			cmd = GET_BASE_ADDR(entry_remove, tSmeCmd, Link);
+
+			/* Skip if command and session id not matched */
+			if (!((scan_cmd_type == cmd->command) &&
+				(session_id == cmd->sessionId)))
+				continue;
+			/*skip if abort reason is for SSID*/
+			if ((abort_reason == eCSR_SCAN_ABORT_SSID_ONLY) &&
+				(eCsrScanForSsid != cmd->u.scanCmd.reason))
+					continue;
+			if (abort_reason == eCSR_SCAN_ABORT_DUE_TO_BAND_CHANGE)
+				cmd->u.scanCmd.abortScanDueToBandChange =
+					true;
+			csr_send_scan_abort(mac_ctx, cmd->sessionId,
+						cmd->u.scanCmd.scanID);
+		}
+	}
+	csr_ll_unlock(list);
+
+	return status;
+}
+
+
+CDF_STATUS csr_scan_abort_mac_scan_not_for_connect(tpAniSirGlobal pMac,
+						   uint8_t sessionId)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	if (!csr_is_scan_for_roam_command_active(pMac)) {
+		/*
+		 * Only abort the scan if it is not used for other roam/connect
+		 * purpose
+		 */
+		status = csr_scan_abort_mac_scan(pMac, sessionId,
+						 eCSR_SCAN_ABORT_DEFAULT);
+	}
+	return status;
+}
+bool csr_roam_is_valid_channel(tpAniSirGlobal pMac, uint8_t channel)
+{
+	bool fValid = false;
+	uint32_t idx_valid_ch;
+	uint32_t len = pMac->roam.numValidChannels;
+
+	for (idx_valid_ch = 0; (idx_valid_ch < len); idx_valid_ch++) {
+		if (channel == pMac->roam.validChannelList[idx_valid_ch]) {
+			fValid = true;
+			break;
+		}
+	}
+	return fValid;
+}
+
+#ifdef FEATURE_WLAN_SCAN_PNO
+CDF_STATUS csr_scan_save_preferred_network_found(tpAniSirGlobal pMac,
+						 tSirPrefNetworkFoundInd *
+						 pPrefNetworkFoundInd)
+{
+	uint32_t uLen = 0;
+	tpSirProbeRespBeacon parsed_frm;
+	tCsrScanResult *pScanResult = NULL;
+	tSirBssDescription *pBssDescr = NULL;
+	bool fDupBss;
+	tDot11fBeaconIEs *local_ie = NULL;
+	tAniSSID tmpSsid;
+	v_TIME_t timer = 0;
+	CDF_STATUS status;
+
+	tpSirMacMgmtHdr macHeader =
+		(tpSirMacMgmtHdr) pPrefNetworkFoundInd->data;
+	parsed_frm =
+	    (tpSirProbeRespBeacon) cdf_mem_malloc(sizeof(tSirProbeRespBeacon));
+
+	if (NULL == parsed_frm) {
+		sms_log(pMac, LOGE, FL("fail to allocate memory for frame"));
+		return CDF_STATUS_E_NOMEM;
+	}
+	if (pPrefNetworkFoundInd->frameLength <= SIR_MAC_HDR_LEN_3A) {
+		sms_log(pMac, LOGE,
+			FL("Incorrect len(%d)"),
+			pPrefNetworkFoundInd->frameLength);
+		cdf_mem_free(parsed_frm);
+		return CDF_STATUS_E_FAILURE;
+	}
+	if (sir_convert_probe_frame2_struct(pMac,
+		&pPrefNetworkFoundInd->data[SIR_MAC_HDR_LEN_3A],
+		pPrefNetworkFoundInd->frameLength - SIR_MAC_HDR_LEN_3A,
+		parsed_frm) != eSIR_SUCCESS
+	    || !parsed_frm->ssidPresent) {
+		sms_log(pMac, LOGE, FL("Parse error ProbeResponse, length=%d"),
+			pPrefNetworkFoundInd->frameLength);
+		cdf_mem_free(parsed_frm);
+		return CDF_STATUS_E_FAILURE;
+	}
+	/* 24 byte MAC header and 12 byte to ssid IE */
+	if (pPrefNetworkFoundInd->frameLength >
+	    (SIR_MAC_HDR_LEN_3A + SIR_MAC_B_PR_SSID_OFFSET)) {
+		uLen = pPrefNetworkFoundInd->frameLength -
+		       (SIR_MAC_HDR_LEN_3A + SIR_MAC_B_PR_SSID_OFFSET);
+	}
+	pScanResult = cdf_mem_malloc(sizeof(tCsrScanResult) + uLen);
+	if (NULL == pScanResult) {
+		sms_log(pMac, LOGE, FL("fail to allocate memory for frame"));
+		cdf_mem_free(parsed_frm);
+		return CDF_STATUS_E_NOMEM;
+	}
+	cdf_mem_set(pScanResult, sizeof(tCsrScanResult) + uLen, 0);
+	pBssDescr = &pScanResult->Result.BssDescriptor;
+	/*
+	 * Length of BSS desription is without length of length itself and
+	 * length of pointer that holds the next BSS description
+	 */
+	pBssDescr->length = (uint16_t) (sizeof(tSirBssDescription) -
+		sizeof(uint16_t) - sizeof(uint32_t) + uLen);
+	if (parsed_frm->dsParamsPresent)
+		pBssDescr->channelId = parsed_frm->channelNumber;
+	else if (parsed_frm->HTInfo.present)
+		pBssDescr->channelId = parsed_frm->HTInfo.primaryChannel;
+	else
+		pBssDescr->channelId = parsed_frm->channelNumber;
+
+	if ((pBssDescr->channelId > 0) && (pBssDescr->channelId < 15)) {
+		int i;
+		/* 11b or 11g packet */
+		/* 11g iff extended Rate IE is present or */
+		/* if there is an A rate in suppRate IE */
+		for (i = 0; i < parsed_frm->supportedRates.numRates; i++) {
+			if (sirIsArate(parsed_frm->supportedRates.rate[i]
+				       & 0x7f)) {
+				pBssDescr->nwType = eSIR_11G_NW_TYPE;
+				break;
+			}
+		}
+		if (parsed_frm->extendedRatesPresent)
+			pBssDescr->nwType = eSIR_11G_NW_TYPE;
+	} else {
+		/* 11a packet */
+		pBssDescr->nwType = eSIR_11A_NW_TYPE;
+	}
+	pBssDescr->sinr = 0;
+	pBssDescr->rssi = -1 * pPrefNetworkFoundInd->rssi;
+	pBssDescr->beaconInterval = parsed_frm->beaconInterval;
+	if (!pBssDescr->beaconInterval) {
+		sms_log(pMac, LOGW, FL("Bcn Interval is Zero , default to 100"
+			MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pBssDescr->bssId));
+		pBssDescr->beaconInterval = 100;
+	}
+	pBssDescr->timeStamp[0] = parsed_frm->timeStamp[0];
+	pBssDescr->timeStamp[1] = parsed_frm->timeStamp[1];
+	pBssDescr->capabilityInfo = *((uint16_t *)&parsed_frm->capabilityInfo);
+	cdf_mem_copy((uint8_t *) &pBssDescr->bssId,
+		     (uint8_t *) macHeader->bssId, sizeof(tSirMacAddr));
+	pBssDescr->nReceivedTime = (uint32_t) cdf_mc_timer_get_system_ticks();
+	sms_log(pMac, LOG2, FL("Bssid= "MAC_ADDRESS_STR" chan= %d, rssi = %d"),
+		MAC_ADDR_ARRAY(pBssDescr->bssId), pBssDescr->channelId,
+		pBssDescr->rssi);
+	/* IEs */
+	if (uLen) {
+		cdf_mem_copy(&pBssDescr->ieFields,
+			pPrefNetworkFoundInd->data + (SIR_MAC_HDR_LEN_3A +
+			SIR_MAC_B_PR_SSID_OFFSET), uLen);
+	}
+	local_ie = (tDot11fBeaconIEs *) (pScanResult->Result.pvIes);
+	status = csr_get_parsed_bss_description_ies(pMac,
+			&pScanResult->Result.BssDescriptor, &local_ie);
+	if (!(local_ie || CDF_IS_STATUS_SUCCESS(status))) {
+		sms_log(pMac, LOGE, FL("Cannot parse IEs"));
+		csr_free_scan_result_entry(pMac, pScanResult);
+		cdf_mem_free(parsed_frm);
+		return CDF_STATUS_E_RESOURCES;
+	}
+
+	fDupBss = csr_remove_dup_bss_description(pMac,
+			&pScanResult->Result.BssDescriptor,
+			local_ie, &tmpSsid, &timer, false);
+	/* Check whether we have reach out limit */
+	if (CSR_SCAN_IS_OVER_BSS_LIMIT(pMac)) {
+		/* Limit reach */
+		sms_log(pMac, LOGE, FL("BSS limit reached"));
+		/* Free the resources */
+		if ((pScanResult->Result.pvIes == NULL) && local_ie)
+			cdf_mem_free(local_ie);
+		csr_free_scan_result_entry(pMac, pScanResult);
+		cdf_mem_free(parsed_frm);
+		return CDF_STATUS_E_RESOURCES;
+	}
+	/* Add to scan cache */
+	csr_scan_add_result(pMac, pScanResult, local_ie,
+			    pPrefNetworkFoundInd->sessionId);
+
+	if ((pScanResult->Result.pvIes == NULL) && local_ie)
+		cdf_mem_free(local_ie);
+	cdf_mem_free(parsed_frm);
+	return CDF_STATUS_SUCCESS;
+}
+#endif /* FEATURE_WLAN_SCAN_PNO */
+
+#ifdef FEATURE_WLAN_LFR
+void csr_init_occupied_channels_list(tpAniSirGlobal pMac, uint8_t sessionId)
+{
+	tListElem *pEntry = NULL;
+	tCsrScanResult *pBssDesc = NULL;
+	tDot11fBeaconIEs *pIes = NULL;
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+		&pMac->roam.neighborRoamInfo[sessionId];
+
+	if (0 != pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels) {
+		/*
+		 * Ini file contains neighbor scan channel list, hence NO need
+		 * to build occupied channel list"
+		 */
+		sms_log(pMac, LOG1, FL("Ini contains neighbor scan ch list"));
+		return;
+	}
+
+	if (!csr_neighbor_roam_is_new_connected_profile(pMac, sessionId)) {
+		/*
+		 * Do not flush occupied list since current roam profile matches
+		 * previous
+		 */
+		sms_log(pMac, LOG2, FL("Current roam profile matches prev"));
+		return;
+	}
+
+	/* Empty occupied channels here */
+	pMac->scan.occupiedChannels[sessionId].numChannels = 0;
+
+	csr_ll_lock(&pMac->scan.scanResultList);
+	pEntry = csr_ll_peek_head(&pMac->scan.scanResultList, LL_ACCESS_NOLOCK);
+	while (pEntry) {
+		pBssDesc = GET_BASE_ADDR(pEntry, tCsrScanResult, Link);
+		pIes = (tDot11fBeaconIEs *) (pBssDesc->Result.pvIes);
+		/* At this time, pBssDescription->Result.pvIes may be NULL */
+		if (!pIes && !CDF_IS_STATUS_SUCCESS(
+			csr_get_parsed_bss_description_ies(pMac,
+				&pBssDesc->Result.BssDescriptor, &pIes)))
+			continue;
+		csr_scan_add_to_occupied_channels(pMac, pBssDesc, sessionId,
+				&pMac->scan.occupiedChannels[sessionId], pIes);
+		/*
+		 * Free the memory allocated for pIes in
+		 * csr_get_parsed_bss_description_ies
+		 */
+		if ((pBssDesc->Result.pvIes == NULL) && pIes)
+			cdf_mem_free(pIes);
+		pEntry = csr_ll_next(&pMac->scan.scanResultList, pEntry,
+				     LL_ACCESS_NOLOCK);
+	} /* while */
+	csr_ll_unlock(&pMac->scan.scanResultList);
+}
+#endif
+
+CDF_STATUS csr_scan_create_entry_in_scan_cache(tpAniSirGlobal pMac,
+					       uint32_t sessionId,
+					       struct cdf_mac_addr bssid,
+					       uint8_t channel)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tDot11fBeaconIEs *pNewIes = NULL;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+	tSirBssDescription *pNewBssDescriptor = NULL;
+	uint32_t size = 0;
+
+	if (NULL == pSession) {
+		status = CDF_STATUS_E_FAILURE;
+		return status;
+	}
+	sms_log(pMac, LOG2, FL("Current bssid::"MAC_ADDRESS_STR),
+		MAC_ADDR_ARRAY(pSession->pConnectBssDesc->bssId));
+	sms_log(pMac, LOG2, FL("My bssid::"MAC_ADDRESS_STR" channel %d"),
+		MAC_ADDR_ARRAY(bssid.bytes), channel);
+
+	if (!CDF_IS_STATUS_SUCCESS(csr_get_parsed_bss_description_ies(
+					pMac, pSession->pConnectBssDesc,
+					&pNewIes))) {
+		sms_log(pMac, LOGE, FL("Failed to parse IEs"));
+		status = CDF_STATUS_E_FAILURE;
+		goto free_mem;
+	}
+	size = pSession->pConnectBssDesc->length +
+		sizeof(pSession->pConnectBssDesc->length);
+	if (!size) {
+		sms_log(pMac, LOGE, FL("length of bss descriptor is 0"));
+		status = CDF_STATUS_E_FAILURE;
+		goto free_mem;
+	}
+	pNewBssDescriptor = cdf_mem_malloc(size);
+	if (NULL == pNewBssDescriptor) {
+		sms_log(pMac, LOGE, FL("memory allocation failed"));
+		status = CDF_STATUS_E_FAILURE;
+		goto free_mem;
+	}
+	cdf_mem_copy(pNewBssDescriptor, pSession->pConnectBssDesc, size);
+	/* change the BSSID & channel as passed */
+	cdf_mem_copy(pNewBssDescriptor->bssId, bssid.bytes,
+			sizeof(tSirMacAddr));
+	pNewBssDescriptor->channelId = channel;
+	if (NULL == csr_scan_append_bss_description(pMac, pNewBssDescriptor,
+						pNewIes, true, sessionId)) {
+		sms_log(pMac, LOGE,
+			FL("csr_scan_append_bss_description failed"));
+		status = CDF_STATUS_E_FAILURE;
+		goto free_mem;
+	}
+	sms_log(pMac, LOGE, FL("entry successfully added in scan cache"));
+
+free_mem:
+	if (pNewIes) {
+		cdf_mem_free(pNewIes);
+	}
+	if (pNewBssDescriptor) {
+		cdf_mem_free(pNewBssDescriptor);
+	}
+	return status;
+}
+
+#ifdef FEATURE_WLAN_ESE
+/*  Update the TSF with the difference in system time */
+void update_cckmtsf(uint32_t *timeStamp0, uint32_t *timeStamp1,
+		    uint32_t *incr)
+{
+	uint64_t timeStamp64 = ((uint64_t) *timeStamp1 << 32) | (*timeStamp0);
+	timeStamp64 = (uint64_t) (timeStamp64 + (uint64_t) *incr);
+	*timeStamp0 = (uint32_t) (timeStamp64 & 0xffffffff);
+	*timeStamp1 = (uint32_t) ((timeStamp64 >> 32) & 0xffffffff);
+}
+#endif
+
+/**
+ * csr_scan_save_roam_offload_ap_to_scan_cache
+ * This function parses the received beacon/probe response
+ * from the firmware as part of the roam synch indication.
+ * The beacon or the probe response is parsed and is also
+ * saved into the scan cache
+ *
+ * @param  pMac Pointer to Global Mac
+ * @param  roam_sync_ind_ptr Roam Synch Indication from
+ *         firmware which also contains the beacon/probe
+ *         response
+ * @return Status
+ */
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+CDF_STATUS csr_scan_save_roam_offload_ap_to_scan_cache(tpAniSirGlobal pMac,
+				roam_offload_synch_ind *roam_sync_ind_ptr)
+{
+	uint32_t length = 0;
+	bool dup_bss;
+	tDot11fBeaconIEs *ies_local_ptr = NULL;
+	tAniSSID tmpSsid;
+	v_TIME_t timer = 0;
+	tCsrScanResult *scan_res_ptr = NULL;
+	uint8_t session_id = roam_sync_ind_ptr->roamedVdevId;
+
+	length = roam_sync_ind_ptr->beaconProbeRespLength -
+		(SIR_MAC_HDR_LEN_3A + SIR_MAC_B_PR_SSID_OFFSET);
+	scan_res_ptr = cdf_mem_malloc(sizeof(tCsrScanResult) + length);
+	if (scan_res_ptr == NULL) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+				" fail to allocate memory for frame");
+		return CDF_STATUS_E_NOMEM;
+	}
+
+	cdf_mem_zero(scan_res_ptr, sizeof(tCsrScanResult) + length);
+	cdf_mem_copy(&scan_res_ptr->Result.BssDescriptor,
+			roam_sync_ind_ptr->bss_desc_ptr,
+			(sizeof(tSirBssDescription) + length));
+	ies_local_ptr = (tDot11fBeaconIEs *)(scan_res_ptr->Result.pvIes);
+	if (!ies_local_ptr &&
+		(!CDF_IS_STATUS_SUCCESS(csr_get_parsed_bss_description_ies(
+						pMac, &scan_res_ptr->Result.
+						BssDescriptor,
+						&ies_local_ptr)))) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+				"%s:Cannot Parse IEs", __func__);
+		csr_free_scan_result_entry(pMac, scan_res_ptr);
+		return CDF_STATUS_E_RESOURCES;
+	}
+
+	dup_bss = csr_remove_dup_bss_description(pMac,
+			&scan_res_ptr->Result.BssDescriptor,
+			ies_local_ptr, &tmpSsid, &timer, true);
+	if (CSR_SCAN_IS_OVER_BSS_LIMIT(pMac)) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+				"%s:BSS Limit Exceed", __func__);
+		if ((scan_res_ptr->Result.pvIes == NULL) && ies_local_ptr)
+			cdf_mem_free(ies_local_ptr);
+
+		csr_free_scan_result_entry(pMac, scan_res_ptr);
+		return CDF_STATUS_E_RESOURCES;
+	}
+	csr_scan_add_result(pMac, scan_res_ptr, ies_local_ptr, session_id);
+	return CDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * csr_get_bssdescr_from_scan_handle() - This function to extract
+ *                                       first bss description from scan handle
+ * @result_handle: an object for the result.
+ *
+ * This function is written to extract first bss from scan handle.
+ *
+ * Return: first bss descriptor from the scan handle.
+ */
+tSirBssDescription*
+csr_get_bssdescr_from_scan_handle(tScanResultHandle result_handle,
+				tSirBssDescription *bss_descr)
+{
+	tListElem *first_element = NULL;
+	tCsrScanResult *scan_result = NULL;
+	tScanResultList *bss_list = (tScanResultList *)result_handle;
+
+	if (NULL == bss_list) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+				FL("Empty bss_list"));
+		return NULL;
+	}
+	if (csr_ll_is_list_empty(&bss_list->List, LL_ACCESS_NOLOCK)) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+				FL("bss_list->List is empty"));
+		cdf_mem_free(bss_list);
+		return NULL;
+	}
+	first_element = csr_ll_peek_head(&bss_list->List, LL_ACCESS_NOLOCK);
+	if (first_element) {
+		scan_result = GET_BASE_ADDR(first_element,
+				tCsrScanResult,
+				Link);
+		cdf_mem_copy(bss_descr,
+				&scan_result->Result.BssDescriptor,
+				sizeof(tSirBssDescription));
+	}
+	return bss_descr;
+}
+
+/**
+ * scan_active_list_cmd_timeout_handle() - To handle scan active command timeout
+ * @userData: scan context
+ *
+ * This routine is to handle scan active command timeout
+ *
+ * Return: None
+ */
+void csr_scan_active_list_timeout_handle(void *userData)
+{
+	tSmeCmd *scan_cmd = (tSmeCmd *) userData;
+	tHalHandle *hal_ctx = cds_get_context(CDF_MODULE_ID_PE);
+	tpAniSirGlobal mac_ctx;
+	uint16_t scan_id;
+	tSirSmeScanAbortReq *msg;
+	uint16_t msg_len;
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+
+	if (scan_cmd == NULL) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+			FL("Scan Timeout: Scan command is NULL"));
+		return;
+	}
+	mac_ctx = PMAC_STRUCT(hal_ctx);
+	scan_id = scan_cmd->u.scanCmd.scanID;
+	sms_log(mac_ctx, LOGE,
+		FL("Scan Timeout:Sending abort to Firmware ID %d session %d "),
+		scan_id, scan_cmd->sessionId);
+	msg_len = (uint16_t)(sizeof(tSirSmeScanAbortReq));
+	msg = cdf_mem_malloc(msg_len);
+	if (NULL == msg) {
+		sms_log(mac_ctx, LOGE,
+			FL("Failed to alloc memory for SmeScanAbortReq"));
+		return;
+	}
+	cdf_mem_zero((void *)msg, msg_len);
+	msg->type = eWNI_SME_SCAN_ABORT_IND;
+	msg->msgLen = msg_len;
+	msg->sessionId = scan_cmd->sessionId;
+	msg->scan_id = scan_id;
+	status = cds_send_mb_message_to_mac(msg);
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		sms_log(mac_ctx, LOGE,
+			FL(" Failed to post message to LIM"));
+		cdf_mem_free(msg);
+	}
+	csr_release_scan_command(mac_ctx, scan_cmd, eCSR_SCAN_FAILURE);
+	return;
+}
diff --git a/core/sme/src/csr/csr_cmd_process.c b/core/sme/src/csr/csr_cmd_process.c
new file mode 100644
index 0000000..7fa7ec8
--- /dev/null
+++ b/core/sme/src/csr/csr_cmd_process.c
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2011-2015 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 csr_cmd_process.c
+
+    Implementation for processing various commands.
+   ========================================================================== */
+
+#include "ani_global.h"
+
+#include "csr_inside_api.h"
+#include "sme_inside.h"
+#include "sms_debug.h"
+#include "mac_trace.h"
+
+/**
+ * csr_msg_processor() - To process all csr msg
+ * @mac_ctx: mac context
+ * @msg_buf: message buffer
+ *
+ * This routine will handle all the message for csr to process
+ *
+ * Return: CDF_STATUS
+ */
+CDF_STATUS csr_msg_processor(tpAniSirGlobal mac_ctx, void *msg_buf)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tSirSmeRsp *sme_rsp = (tSirSmeRsp *) msg_buf;
+#ifdef FEATURE_WLAN_SCAN_PNO
+	tSirMbMsg *msg = (tSirMbMsg *) msg_buf;
+	tCsrRoamSession *session;
+#endif
+	uint8_t session_id = sme_rsp->sessionId;
+	eCsrRoamState cur_state = mac_ctx->roam.curState[session_id];
+
+	sms_log(mac_ctx, LOG2,
+		FL("msg %d[0x%04X] recvd in curstate %s & substate %s id(%d)"),
+		sme_rsp->messageType, sme_rsp->messageType,
+		mac_trace_getcsr_roam_state(cur_state),
+		mac_trace_getcsr_roam_sub_state(
+			mac_ctx->roam.curSubState[session_id]),
+		session_id);
+
+#ifdef FEATURE_WLAN_SCAN_PNO
+	/*
+	 * PNO scan responses have to be handled irrespective of CSR roam state.
+	 * Check if PNO has been started & only then process the PNO scan result
+	 * Also note that normal scan isn't allowed when PNO scan is in progress
+	 * and so the scan responses reaching here when PNO is started must be
+	 * PNO responses. For normal scan, the PNO started flag will be false
+	 * and it'll be processed as usual based on the current CSR roam state.
+	 */
+	session = CSR_GET_SESSION(mac_ctx, session_id);
+	if (!session) {
+		sms_log(mac_ctx, LOGE, FL("session %d not found, msgType : %d"),
+			session_id, msg->type);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	if (eWNI_SME_SCAN_RSP == msg->type) {
+		status = csr_scanning_state_msg_processor(mac_ctx, msg_buf);
+		if (CDF_STATUS_SUCCESS != status)
+			sms_log(mac_ctx, LOGE,
+				FL("handling PNO scan resp 0x%X CSR state %d"),
+				sme_rsp->messageType, cur_state);
+		return status;
+	}
+#endif
+
+	/* Process the message based on the state of the roaming states... */
+#if defined(ANI_RTT_DEBUG)
+	if (!pAdapter->fRttModeEnabled) {
+#endif
+		switch (cur_state) {
+		case eCSR_ROAMING_STATE_JOINED:
+			/* are we in joined state */
+			csr_roam_joined_state_msg_processor(mac_ctx, msg_buf);
+			break;
+		case eCSR_ROAMING_STATE_JOINING:
+			/* are we in roaming states */
+#if defined(ANI_EMUL_ASSOC)
+			emulRoamingStateMsgProcessor(pAdapter, pMBBufHdr);
+#endif
+			csr_roaming_state_msg_processor(mac_ctx, msg_buf);
+			break;
+
+		default:
+			/*
+			 * For all other messages, we ignore it
+			 * To work-around an issue where checking for set/remove
+			 * key base on connection state is no longer workable
+			 * due to failure or finding the condition meets both
+			 * SAP and infra/IBSS requirement.
+			 */
+			if (eWNI_SME_SETCONTEXT_RSP == sme_rsp->messageType) {
+				sms_log(mac_ctx, LOGW,
+					FL("handling msg 0x%X CSR state is %d"),
+					sme_rsp->messageType, cur_state);
+				csr_roam_check_for_link_status_change(mac_ctx,
+						sme_rsp);
+			} else if (eWNI_SME_GET_RSSI_REQ ==
+					sme_rsp->messageType) {
+				tAniGetRssiReq *pGetRssiReq =
+					(tAniGetRssiReq *) msg_buf;
+				if (NULL == pGetRssiReq->rssiCallback) {
+					sms_log(mac_ctx, LOGE,
+						FL("rssiCallback is NULL"));
+					return status;
+				}
+				sms_log(mac_ctx, LOGW,
+						FL("msg eWNI_SME_GET_RSSI_REQ is not handled by CSR in state %d. calling RSSI callback"),
+						cur_state);
+				((tCsrRssiCallback)(pGetRssiReq->rssiCallback))(
+						pGetRssiReq->lastRSSI,
+						pGetRssiReq->staId,
+						pGetRssiReq->pDevContext);
+			} else {
+				sms_log(mac_ctx, LOGE,
+					FL("Message 0x%04X is not handled by CSR state is %d session Id %d"),
+					sme_rsp->messageType, cur_state,
+					session_id);
+
+				if (eWNI_SME_FT_PRE_AUTH_RSP ==
+						sme_rsp->messageType) {
+					sms_log(mac_ctx, LOGE,
+						FL("Dequeue eSmeCommandRoam command with reason eCsrPerformPreauth"));
+					csr_dequeue_roam_command(mac_ctx,
+						eCsrPerformPreauth);
+				} else if (eWNI_SME_REASSOC_RSP ==
+						sme_rsp->messageType) {
+					sms_log(mac_ctx, LOGE,
+						FL("Dequeue eSmeCommandRoam command with reason eCsrSmeIssuedFTReassoc"));
+					csr_dequeue_roam_command(mac_ctx,
+						eCsrSmeIssuedFTReassoc);
+				}
+			}
+			break;
+		} /* switch */
+#if defined(ANI_RTT_DEBUG)
+	}
+#endif
+	return status;
+}
+
+bool csr_check_ps_ready(void *pv)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(pv);
+
+	if (pMac->roam.sPendingCommands < 0) {
+		CDF_ASSERT(pMac->roam.sPendingCommands >= 0);
+		return 0;
+	}
+	return pMac->roam.sPendingCommands == 0;
+}
+
+bool csr_check_ps_offload_ready(void *pv, uint32_t sessionId)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(pv);
+
+	CDF_ASSERT(pMac->roam.sPendingCommands >= 0);
+	return pMac->roam.sPendingCommands == 0;
+}
+
diff --git a/core/sme/src/csr/csr_inside_api.h b/core/sme/src/csr/csr_inside_api.h
new file mode 100644
index 0000000..1679784
--- /dev/null
+++ b/core/sme/src/csr/csr_inside_api.h
@@ -0,0 +1,1070 @@
+/*
+ * Copyright (c) 2011-2015 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 csr_inside_api.h
+
+    Define interface only used by CSR.
+   ========================================================================== */
+#ifndef CSR_INSIDE_API_H__
+#define CSR_INSIDE_API_H__
+
+#include "csr_support.h"
+#include "sme_inside.h"
+#include "cds_reg_service.h"
+
+#define CSR_PASSIVE_MAX_CHANNEL_TIME   110
+#define CSR_PASSIVE_MIN_CHANNEL_TIME   60
+
+#define CSR_ACTIVE_MAX_CHANNEL_TIME    40
+#define CSR_ACTIVE_MIN_CHANNEL_TIME    20
+
+#ifdef WLAN_AP_STA_CONCURRENCY
+#define CSR_PASSIVE_MAX_CHANNEL_TIME_CONC   110
+#define CSR_PASSIVE_MIN_CHANNEL_TIME_CONC   60
+
+#define CSR_ACTIVE_MAX_CHANNEL_TIME_CONC    27
+#define CSR_ACTIVE_MIN_CHANNEL_TIME_CONC    20
+
+#define CSR_REST_TIME_CONC                  100
+
+#define CSR_NUM_STA_CHAN_COMBINED_CONC      3
+#define CSR_NUM_P2P_CHAN_COMBINED_CONC      1
+#endif
+
+#define CSR_MAX_NUM_SUPPORTED_CHANNELS 55
+
+#define CSR_MAX_2_4_GHZ_SUPPORTED_CHANNELS 14
+
+#define CSR_MAX_BSS_SUPPORT            300
+#define SYSTEM_TIME_MSEC_TO_USEC      1000
+
+/* This number minus 1 means the number of times a channel is scanned before a BSS is remvoed from */
+/* cache scan result */
+#define CSR_AGING_COUNT     3
+#define CSR_SCAN_GET_RESULT_INTERVAL    (5 * CDF_MC_TIMER_TO_SEC_UNIT)  /* 5 seconds */
+#define CSR_MIC_ERROR_TIMEOUT  (60 * CDF_MC_TIMER_TO_SEC_UNIT)  /* 60 seconds */
+#define CSR_TKIP_COUNTER_MEASURE_TIMEOUT  (60 * CDF_MC_TIMER_TO_SEC_UNIT)       /* 60 seconds */
+
+#define CSR_SCAN_RESULT_CFG_AGING_INTERVAL    (CDF_MC_TIMER_TO_SEC_UNIT)        /* 1  second */
+/* the following defines are NOT used by palTimer */
+#define CSR_SCAN_AGING_TIME_NOT_CONNECT_NO_PS 50        /* 50 seconds */
+#define CSR_SCAN_AGING_TIME_NOT_CONNECT_W_PS 300        /* 300 seconds */
+#define CSR_SCAN_AGING_TIME_CONNECT_NO_PS 150   /* 150 seconds */
+#define CSR_SCAN_AGING_TIME_CONNECT_W_PS 600    /* 600 seconds */
+#define CSR_JOIN_FAILURE_TIMEOUT_DEFAULT (3000)
+#define CSR_JOIN_FAILURE_TIMEOUT_MIN   (1000)   /* minimal value */
+/* These are going against the signed RSSI (int8_t) so it is between -+127 */
+#define CSR_BEST_RSSI_VALUE         (-30)       /* RSSI >= this is in CAT4 */
+#define CSR_DEFAULT_RSSI_DB_GAP     30  /* every 30 dbm for one category */
+#define CSR_BSS_CAP_VALUE_NONE  0       /* not much value */
+#define CSR_BSS_CAP_VALUE_HT    1
+#define CSR_BSS_CAP_VALUE_VHT    2
+#define CSR_BSS_CAP_VALUE_WMM   1
+#define CSR_BSS_CAP_VALUE_UAPSD 1
+#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
+#define CSR_BSS_CAP_VALUE_5GHZ  2
+#endif
+#define CSR_DEFAULT_ROAMING_TIME 10     /* 10 seconds */
+
+#define CSR_ROAMING_DFS_CHANNEL_DISABLED           (0)
+#define CSR_ROAMING_DFS_CHANNEL_ENABLED_NORMAL     (1)
+#define CSR_ROAMING_DFS_CHANNEL_ENABLED_ACTIVE     (2)
+
+/* ***************************************************************************
+ * The MAX BSSID Count should be lower than the command timeout value and it
+ * can be of a fraction of 3/4 of the total command timeout value.
+ * ***************************************************************************/
+#define CSR_ACTIVE_LIST_CMD_TIMEOUT_VALUE (1000*30*4)
+#define CSR_ACTIVE_SCAN_LIST_CMD_TIMEOUT (1000*30)
+
+#define CSR_MAX_BSSID_COUNT     ((CSR_ACTIVE_LIST_CMD_TIMEOUT_VALUE/4000) * 3)
+#define CSR_CUSTOM_CONC_GO_BI    100
+#define MIN_11P_CHANNEL (rf_channels[MIN_5_9GHZ_CHANNEL].channelNum)
+
+typedef enum {
+	eCsrNextScanNothing,
+	eCsrNextLostLinkScan1Success,
+	eCsrNextLostLinkScan1Failed,
+	eCsrNextLostLinkScan2Success,
+	eCsrNextLostLinkScan2Failed,
+	eCsrNextLostLinkScan3Success,
+	eCsrNexteScanForSsidSuccess,
+	eCsrNextLostLinkScan3Failed,
+	eCsrNext11dScan1Failure,
+	eCsrNext11dScan1Success,
+	eCsrNext11dScan2Failure,
+	eCsrNext11dScan2Success,
+	eCsrNext11dScanComplete,
+	eCsrNexteScanForSsidFailure,
+
+} eCsrScanCompleteNextCommand;
+
+typedef enum {
+	eCsrJoinSuccess,
+	eCsrJoinFailure,
+	eCsrReassocSuccess,
+	eCsrReassocFailure,
+	eCsrNothingToJoin,
+	eCsrStartBssSuccess,
+	eCsrStartBssFailure,
+	eCsrSilentlyStopRoaming,
+	eCsrSilentlyStopRoamingSaveState,
+	eCsrJoinWdsFailure,
+	eCsrJoinFailureDueToConcurrency,
+
+} eCsrRoamCompleteResult;
+
+typedef struct tagScanReqParam {
+	uint8_t bReturnAfter1stMatch;
+	uint8_t fUniqueResult;
+	uint8_t freshScan;
+	uint8_t hiddenSsid;
+	uint8_t reserved;
+} tScanReqParam;
+
+typedef struct tagCsrScanResult {
+	tListElem Link;
+	int32_t AgingCount;     /* This BSS is removed when it reaches 0 or less */
+	uint32_t preferValue;   /* The bigger the number, the better the BSS. This value override capValue */
+	uint32_t capValue;      /* The biggger the better. This value is in use only if we have equal preferValue */
+	/* This member must be the last in the structure because the end of tSirBssDescription (inside) is an */
+	/*    array with nonknown size at this time */
+
+	eCsrEncryptionType ucEncryptionType;    /* Preferred Encryption type that matched with profile. */
+	eCsrEncryptionType mcEncryptionType;
+	eCsrAuthType authType;  /* Preferred auth type that matched with the profile. */
+
+	tCsrScanResultInfo Result;
+} tCsrScanResult;
+
+typedef struct {
+	tDblLinkList List;
+	tListElem *pCurEntry;
+} tScanResultList;
+
+#define CSR_IS_ROAM_REASON(pCmd, reason) ((reason) == (pCmd)->roamCmd.roamReason)
+#define CSR_IS_BETTER_PREFER_VALUE(v1, v2)   ((v1) > (v2))
+#define CSR_IS_EQUAL_PREFER_VALUE(v1, v2)   ((v1) == (v2))
+#define CSR_IS_BETTER_CAP_VALUE(v1, v2)     ((v1) > (v2))
+#define CSR_IS_EQUAL_CAP_VALUE(v1, v2)  ((v1) == (v2))
+#define CSR_IS_BETTER_RSSI(v1, v2)   ((v1) > (v2))
+#define CSR_IS_ENC_TYPE_STATIC(encType) ((eCSR_ENCRYPT_TYPE_NONE == (encType)) || \
+					    (eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == (encType)) || \
+					    (eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == (encType)))
+#define CSR_IS_WAIT_FOR_KEY(pMac, sessionId) \
+		 (CSR_IS_ROAM_JOINED(pMac, sessionId) && \
+		  CSR_IS_ROAM_SUBSTATE_WAITFORKEY(pMac, sessionId))
+/* WIFI has a test case for not using HT rates with TKIP as encryption */
+/* We may need to add WEP but for now, TKIP only. */
+
+#define CSR_IS_11n_ALLOWED(encType) ((eCSR_ENCRYPT_TYPE_TKIP != (encType)) && \
+				       (eCSR_ENCRYPT_TYPE_WEP40_STATICKEY != (encType)) && \
+				       (eCSR_ENCRYPT_TYPE_WEP104_STATICKEY != (encType)) && \
+				       (eCSR_ENCRYPT_TYPE_WEP40 != (encType)) && \
+				       (eCSR_ENCRYPT_TYPE_WEP104 != (encType)))
+
+#define CSR_IS_DISCONNECT_COMMAND(pCommand) ((eSmeCommandRoam == (pCommand)->command) && \
+					      ((eCsrForcedDisassoc == (pCommand)->u.roamCmd.roamReason) || \
+						(eCsrForcedDeauth == (pCommand)->u.roamCmd.roamReason) || \
+						(eCsrSmeIssuedDisassocForHandoff == \
+						  (pCommand)->u.roamCmd.roamReason) ||	\
+						(eCsrForcedDisassocMICFailure == \
+						  (pCommand)->u.roamCmd.roamReason)))
+
+extern const tRfChannelProps rf_channels[NUM_RF_CHANNELS];
+eCsrRoamState csr_roam_state_change(tpAniSirGlobal pMac,
+				    eCsrRoamState NewRoamState, uint8_t sessionId);
+CDF_STATUS csr_scanning_state_msg_processor(tpAniSirGlobal pMac, void *pMsgBuf);
+void csr_roaming_state_msg_processor(tpAniSirGlobal pMac, void *pMsgBuf);
+void csr_roam_joined_state_msg_processor(tpAniSirGlobal pMac, void *pMsgBuf);
+bool csr_scan_complete(tpAniSirGlobal pMac, tSirSmeScanRsp *pScanRsp);
+void csr_release_command_roam(tpAniSirGlobal pMac, tSmeCmd *pCommand);
+void csr_release_command_scan(tpAniSirGlobal pMac, tSmeCmd *pCommand);
+void csr_release_command_wm_status_change(tpAniSirGlobal pMac, tSmeCmd *pCommand);
+extern void csr_release_roc_req_cmd(tpAniSirGlobal mac_ctx);
+
+bool csr_is_duplicate_bss_description(tpAniSirGlobal pMac,
+				      tSirBssDescription *pSirBssDesc1,
+				      tSirBssDescription *pSirBssDesc2,
+				      tDot11fBeaconIEs *pIes2, bool fForced);
+CDF_STATUS csr_roam_save_connected_bss_desc(tpAniSirGlobal pMac, uint32_t sessionId,
+					    tSirBssDescription *pBssDesc);
+bool csr_is_network_type_equal(tSirBssDescription *pSirBssDesc1,
+			       tSirBssDescription *pSirBssDesc2);
+CDF_STATUS csr_scan_sme_scan_response(tpAniSirGlobal pMac, void *pMsgBuf);
+/*
+   Prepare a filter base on a profile for parsing the scan results.
+   Upon successful return, caller MUST call csr_free_scan_filter on
+   pScanFilter when it is done with the filter.
+ */
+CDF_STATUS csr_roam_prepare_filter_from_profile(tpAniSirGlobal pMac,
+						tCsrRoamProfile *pProfile,
+						tCsrScanResultFilter *pScanFilter);
+CDF_STATUS csr_roam_copy_profile(tpAniSirGlobal pMac,
+				 tCsrRoamProfile *pDstProfile,
+				 tCsrRoamProfile *pSrcProfile);
+CDF_STATUS csr_roam_start(tpAniSirGlobal pMac);
+void csr_roam_stop(tpAniSirGlobal pMac, uint32_t sessionId);
+void csr_roam_startMICFailureTimer(tpAniSirGlobal pMac);
+void csr_roam_stopMICFailureTimer(tpAniSirGlobal pMac);
+void csr_roam_startTKIPCounterMeasureTimer(tpAniSirGlobal pMac);
+void csr_roam_stopTKIPCounterMeasureTimer(tpAniSirGlobal pMac);
+
+CDF_STATUS csr_scan_open(tpAniSirGlobal pMac);
+CDF_STATUS csr_scan_close(tpAniSirGlobal pMac);
+CDF_STATUS csr_scan_request_lost_link1(tpAniSirGlobal pMac, uint32_t sessionId);
+CDF_STATUS csr_scan_request_lost_link2(tpAniSirGlobal pMac, uint32_t sessionId);
+CDF_STATUS csr_scan_request_lost_link3(tpAniSirGlobal pMac, uint32_t sessionId);
+CDF_STATUS csr_scan_handle_failed_lostlink1(tpAniSirGlobal pMac,
+					    uint32_t sessionId);
+CDF_STATUS csr_scan_handle_failed_lostlink2(tpAniSirGlobal pMac,
+					    uint32_t sessionId);
+CDF_STATUS csr_scan_handle_failed_lostlink3(tpAniSirGlobal pMac,
+					    uint32_t sessionId);
+tCsrScanResult *csr_scan_append_bss_description(tpAniSirGlobal pMac,
+						tSirBssDescription *
+						pSirBssDescription,
+						tDot11fBeaconIEs *pIes,
+						bool fForced, uint8_t sessionId);
+void csr_scan_call_callback(tpAniSirGlobal pMac, tSmeCmd *pCommand,
+			    eCsrScanStatus scanStatus);
+CDF_STATUS csr_scan_copy_request(tpAniSirGlobal pMac, tCsrScanRequest *pDstReq,
+				 tCsrScanRequest *pSrcReq);
+CDF_STATUS csr_scan_free_request(tpAniSirGlobal pMac, tCsrScanRequest *pReq);
+CDF_STATUS csr_scan_copy_result_list(tpAniSirGlobal pMac, tScanResultHandle hIn,
+				     tScanResultHandle *phResult);
+CDF_STATUS csr_scan_for_ssid(tpAniSirGlobal pMac, uint32_t sessionId,
+			     tCsrRoamProfile *pProfile, uint32_t roamId,
+			     bool notify);
+CDF_STATUS csr_scan_start_result_cfg_aging_timer(tpAniSirGlobal pMac);
+CDF_STATUS csr_scan_stop_result_cfg_aging_timer(tpAniSirGlobal pMac);
+void csr_scan_stop_timers(tpAniSirGlobal pMac);
+/* To remove fresh scan commands from the pending queue */
+bool csr_scan_remove_fresh_scan_command(tpAniSirGlobal pMac, uint8_t sessionId);
+CDF_STATUS csr_scan_abort_mac_scan(tpAniSirGlobal pMac, uint8_t sessionId,
+				   eCsrAbortReason reason);
+void csr_remove_cmd_from_pending_list(tpAniSirGlobal pMac, tDblLinkList *pList,
+				      eSmeCommandType commandType);
+void csr_remove_cmd_with_session_id_from_pending_list(tpAniSirGlobal pMac,
+						      uint8_t sessionId,
+						      tDblLinkList *pList,
+						      eSmeCommandType commandType);
+CDF_STATUS csr_scan_abort_mac_scan_not_for_connect(tpAniSirGlobal pMac,
+						   uint8_t sessionId);
+CDF_STATUS csr_scan_abort_scan_for_ssid(tpAniSirGlobal pMac, uint32_t sessionId);
+void csr_remove_scan_for_ssid_from_pending_list(tpAniSirGlobal pMac,
+						tDblLinkList *pList,
+						uint32_t sessionId);
+
+CDF_STATUS csr_abort_scan_from_active_list(tpAniSirGlobal pMac,
+		tDblLinkList *pList, uint32_t sessionId,
+		eSmeCommandType scan_cmd_type, eCsrAbortReason abort_reason);
+
+/* To age out scan results base. tSmeGetScanChnRsp is a pointer returned by LIM that */
+/* has the information regarding scanned channels. */
+/* The logic is that whenever CSR add a BSS to scan result, it set the age count to */
+/* a value. This function deduct the age count if channelId matches the BSS' channelId */
+/* The BSS is remove if the count reaches 0. */
+CDF_STATUS csr_scan_age_results(tpAniSirGlobal pMac,
+				tSmeGetScanChnRsp *pScanChnInfo);
+
+/* If fForce is true we will save the new String that is learn't. */
+/* Typically it will be true in case of Join or user initiated ioctl */
+bool csr_learn_11dcountry_information(tpAniSirGlobal pMac,
+				   tSirBssDescription *pSirBssDesc,
+				   tDot11fBeaconIEs *pIes, bool fForce);
+void csr_apply_country_information(tpAniSirGlobal pMac);
+void csr_set_cfg_scan_control_list(tpAniSirGlobal pMac, uint8_t *countryCode,
+				   tCsrChannel *pChannelList);
+void csr_reinit_scan_cmd(tpAniSirGlobal pMac, tSmeCmd *pCommand);
+void csr_free_scan_result_entry(tpAniSirGlobal pMac, tCsrScanResult *pResult);
+
+CDF_STATUS csr_roam_call_callback(tpAniSirGlobal pMac, uint32_t sessionId,
+				  tCsrRoamInfo *pRoamInfo, uint32_t roamId,
+				  eRoamCmdStatus u1, eCsrRoamResult u2);
+CDF_STATUS csr_roam_issue_connect(tpAniSirGlobal pMac, uint32_t sessionId,
+				  tCsrRoamProfile *pProfile,
+				  tScanResultHandle hBSSList,
+				  eCsrRoamReason reason, uint32_t roamId,
+				  bool fImediate, bool fClearScan);
+CDF_STATUS csr_roam_issue_reassoc(tpAniSirGlobal pMac, uint32_t sessionId,
+				  tCsrRoamProfile *pProfile,
+				  tCsrRoamModifyProfileFields *pModProfileFields,
+				  eCsrRoamReason reason, uint32_t roamId,
+				  bool fImediate);
+void csr_roam_complete(tpAniSirGlobal pMac, eCsrRoamCompleteResult Result,
+		       void *Context);
+CDF_STATUS csr_roam_issue_set_context_req(tpAniSirGlobal pMac, uint32_t sessionId,
+					  eCsrEncryptionType EncryptType,
+					  tSirBssDescription *pBssDescription,
+					  tSirMacAddr *bssId, bool addKey,
+					  bool fUnicast,
+					  tAniKeyDirection aniKeyDirection,
+					  uint8_t keyId, uint16_t keyLength,
+					  uint8_t *pKey, uint8_t paeRole);
+CDF_STATUS csr_roam_process_disassoc_deauth(tpAniSirGlobal pMac, tSmeCmd *pCommand,
+					    bool fDisassoc, bool fMICFailure);
+CDF_STATUS csr_roam_save_connected_infomation(tpAniSirGlobal pMac,
+					      uint32_t sessionId,
+					      tCsrRoamProfile *pProfile,
+					      tSirBssDescription *pSirBssDesc,
+					      tDot11fBeaconIEs *pIes);
+void csr_roam_check_for_link_status_change(tpAniSirGlobal pMac, tSirSmeRsp *pSirMsg);
+void csr_roam_stats_rsp_processor(tpAniSirGlobal pMac, tSirSmeRsp *pSirMsg);
+CDF_STATUS csr_roam_issue_start_bss(tpAniSirGlobal pMac, uint32_t sessionId,
+				    tCsrRoamStartBssParams *pParam,
+				    tCsrRoamProfile *pProfile,
+				    tSirBssDescription *pBssDesc, uint32_t roamId);
+CDF_STATUS csr_roam_issue_stop_bss(tpAniSirGlobal pMac, uint32_t sessionId,
+				   eCsrRoamSubState NewSubstate);
+bool csr_is_same_profile(tpAniSirGlobal pMac, tCsrRoamConnectedProfile *pProfile1,
+			 tCsrRoamProfile *pProfile2);
+bool csr_is_roam_command_waiting(tpAniSirGlobal pMac);
+bool csr_is_roam_command_waiting_for_session(tpAniSirGlobal pMac, uint32_t sessionId);
+bool csr_is_scan_for_roam_command_active(tpAniSirGlobal pMac);
+eRoamCmdStatus csr_get_roam_complete_status(tpAniSirGlobal pMac,
+					    uint32_t sessionId);
+/* pBand can be NULL if caller doesn't need to get it */
+CDF_STATUS csr_roam_issue_disassociate_cmd(tpAniSirGlobal pMac, uint32_t sessionId,
+					   eCsrRoamDisconnectReason reason);
+CDF_STATUS csr_roam_disconnect_internal(tpAniSirGlobal pMac, uint32_t sessionId,
+					eCsrRoamDisconnectReason reason);
+/* pCommand may be NULL */
+void csr_roam_remove_duplicate_command(tpAniSirGlobal pMac, uint32_t sessionId,
+				       tSmeCmd *pCommand,
+				       eCsrRoamReason eRoamReason);
+
+CDF_STATUS csr_send_join_req_msg(tpAniSirGlobal pMac, uint32_t sessionId,
+				 tSirBssDescription *pBssDescription,
+				 tCsrRoamProfile *pProfile,
+				 tDot11fBeaconIEs *pIes, uint16_t messageType);
+CDF_STATUS csr_send_mb_disassoc_req_msg(tpAniSirGlobal pMac, uint32_t sessionId,
+					tSirMacAddr bssId, uint16_t reasonCode);
+CDF_STATUS csr_send_mb_deauth_req_msg(tpAniSirGlobal pMac, uint32_t sessionId,
+				      tSirMacAddr bssId, uint16_t reasonCode);
+CDF_STATUS csr_send_mb_disassoc_cnf_msg(tpAniSirGlobal pMac,
+					tpSirSmeDisassocInd pDisassocInd);
+CDF_STATUS csr_send_mb_deauth_cnf_msg(tpAniSirGlobal pMac,
+				      tpSirSmeDeauthInd pDeauthInd);
+CDF_STATUS csr_send_assoc_cnf_msg(tpAniSirGlobal pMac, tpSirSmeAssocInd pAssocInd,
+				  CDF_STATUS status);
+CDF_STATUS csr_send_assoc_ind_to_upper_layer_cnf_msg(tpAniSirGlobal pMac,
+						     tpSirSmeAssocInd pAssocInd,
+						     CDF_STATUS Halstatus,
+						     uint8_t sessionId);
+CDF_STATUS csr_send_mb_start_bss_req_msg(tpAniSirGlobal pMac, uint32_t sessionId,
+					 eCsrRoamBssType bssType,
+					 tCsrRoamStartBssParams *pParam,
+					 tSirBssDescription *pBssDesc);
+CDF_STATUS csr_send_mb_stop_bss_req_msg(tpAniSirGlobal pMac, uint32_t sessionId);
+
+/* Caller should put the BSS' ssid to fiedl bssSsid when comparing SSID for a BSS. */
+bool csr_is_ssid_match(tpAniSirGlobal pMac, uint8_t *ssid1, uint8_t ssid1Len,
+		       uint8_t *bssSsid, uint8_t bssSsidLen, bool fSsidRequired);
+bool csr_is_phy_mode_match(tpAniSirGlobal pMac, uint32_t phyMode,
+			   tSirBssDescription *pSirBssDesc,
+			   tCsrRoamProfile *pProfile,
+			   eCsrCfgDot11Mode *pReturnCfgDot11Mode,
+			   tDot11fBeaconIEs *pIes);
+bool csr_roam_is_channel_valid(tpAniSirGlobal pMac, uint8_t channel);
+
+/* pNumChan is a caller allocated space with the sizeof pChannels */
+CDF_STATUS csr_get_cfg_valid_channels(tpAniSirGlobal pMac, uint8_t *pChannels,
+				      uint32_t *pNumChan);
+void csr_roam_ccm_cfg_set_callback(tpAniSirGlobal pMac, int32_t result);
+
+tPowerdBm csr_get_cfg_max_tx_power(tpAniSirGlobal pMac, uint8_t channel);
+
+/* To free the last roaming profile */
+void csr_free_roam_profile(tpAniSirGlobal pMac, uint32_t sessionId);
+void csr_free_connect_bss_desc(tpAniSirGlobal pMac, uint32_t sessionId);
+CDF_STATUS csr_move_bss_to_head_from_bssid(tpAniSirGlobal pMac,
+					   struct cdf_mac_addr *bssid,
+					   tScanResultHandle hScanResult);
+bool csr_check_ps_ready(void *pv);
+bool csr_check_ps_offload_ready(void *pv, uint32_t sessionId);
+
+/* to free memory allocated inside the profile structure */
+void csr_release_profile(tpAniSirGlobal pMac, tCsrRoamProfile *pProfile);
+/* To free memory allocated inside scanFilter */
+void csr_free_scan_filter(tpAniSirGlobal pMac, tCsrScanResultFilter *pScanFilter);
+eCsrCfgDot11Mode csr_get_cfg_dot11_mode_from_csr_phy_mode(tCsrRoamProfile *pProfile,
+							  eCsrPhyMode phyMode,
+							  bool fProprietary);
+uint32_t csr_translate_to_wni_cfg_dot11_mode(tpAniSirGlobal pMac,
+					     eCsrCfgDot11Mode csrDot11Mode);
+void csr_save_channel_power_for_band(tpAniSirGlobal pMac, bool fPopulate5GBand);
+void csr_apply_channel_power_info_to_fw(tpAniSirGlobal pMac,
+					tCsrChannel *pChannelList,
+					uint8_t *countryCode);
+void csr_apply_power2_current(tpAniSirGlobal pMac);
+void csr_assign_rssi_for_category(tpAniSirGlobal pMac, int8_t bestApRssi,
+				  uint8_t catOffset);
+CDF_STATUS csr_roam_remove_connected_bss_from_scan_cache(tpAniSirGlobal pMac,
+							 tCsrRoamConnectedProfile *
+							 pConnProfile);
+CDF_STATUS csr_roam_start_roaming(tpAniSirGlobal pMac, uint32_t sessionId,
+				  eCsrRoamingReason roamingReason);
+/* return a bool to indicate whether roaming completed or continue. */
+bool csr_roam_complete_roaming(tpAniSirGlobal pMac, uint32_t sessionId,
+			       bool fForce, eCsrRoamResult roamResult);
+void csr_roam_completion(tpAniSirGlobal pMac, uint32_t sessionId,
+			 tCsrRoamInfo *pRoamInfo, tSmeCmd *pCommand,
+			 eCsrRoamResult roamResult, bool fSuccess);
+void csr_roam_cancel_roaming(tpAniSirGlobal pMac, uint32_t sessionId);
+void csr_apply_channel_power_info_wrapper(tpAniSirGlobal pMac);
+void csr_reset_pmkid_candidate_list(tpAniSirGlobal pMac, uint32_t sessionId);
+#ifdef FEATURE_WLAN_WAPI
+void csr_reset_bkid_candidate_list(tpAniSirGlobal pMac, uint32_t sessionId);
+#endif /* FEATURE_WLAN_WAPI */
+CDF_STATUS csr_save_to_channel_power2_g_5_g(tpAniSirGlobal pMac, uint32_t tableSize,
+					    tSirMacChanInfo *channelTable);
+
+/* To check whether a country code matches the one in the IE */
+/* Only check the first two characters, ignoring in/outdoor */
+/* pCountry -- caller allocated buffer contain the country code that is checking against */
+/* the one in pIes. It can be NULL. */
+/* caller must provide pIes, it cannot be NULL */
+/* This function always return true if 11d support is not turned on. */
+/* pIes cannot be NULL */
+bool csr_match_country_code(tpAniSirGlobal pMac, uint8_t *pCountry,
+			    tDot11fBeaconIEs *pIes);
+CDF_STATUS csr_roam_set_key(tpAniSirGlobal pMac, uint32_t sessionId,
+			    tCsrRoamSetKey *pSetKey, uint32_t roamId);
+CDF_STATUS csr_roam_open_session(tpAniSirGlobal pMac,
+				 csr_roam_completeCallback callback, void *pContext,
+				 uint8_t *pSelfMacAddr, uint8_t *pbSessionId,
+				 uint32_t type, uint32_t subType);
+/* fSync: true means cleanupneeds to handle synchronously. */
+CDF_STATUS csr_roam_close_session(tpAniSirGlobal pMac, uint32_t sessionId,
+				  bool fSync,
+				  csr_roamSessionCloseCallback callback,
+				  void *pContext);
+void csr_cleanup_session(tpAniSirGlobal pMac, uint32_t sessionId);
+CDF_STATUS csr_roam_get_session_id_from_bssid(tpAniSirGlobal pMac, struct cdf_mac_addr *bssid,
+					      uint32_t *pSessionId);
+eCsrCfgDot11Mode csr_find_best_phy_mode(tpAniSirGlobal pMac, uint32_t phyMode);
+
+/* ---------------------------------------------------------------------------
+    \fn csr_scan_enable
+    \brief Enable the scanning feature of CSR. It must be called before any scan request can be performed.
+    \param tHalHandle - HAL context handle
+    \return CDF_STATUS
+   -------------------------------------------------------------------------------*/
+CDF_STATUS csr_scan_enable(tpAniSirGlobal);
+
+/* ---------------------------------------------------------------------------
+    \fn csr_scan_disable
+    \brief Disableing the scanning feature of CSR. After this function return success, no scan is performed until
+   a successfull to csr_scan_enable
+    \param tHalHandle - HAL context handle
+    \return CDF_STATUS
+   -------------------------------------------------------------------------------*/
+CDF_STATUS csr_scan_disable(tpAniSirGlobal);
+/* ---------------------------------------------------------------------------
+    \fn csr_scan_request
+    \brief Request a 11d or full scan.
+    \param callback - a callback function that scan calls upon finish, will not be called if csr_scan_request returns error
+    \param pContext - a pointer passed in for the callback
+    \return CDF_STATUS
+   -------------------------------------------------------------------------------*/
+CDF_STATUS csr_scan_request(tpAniSirGlobal, uint16_t, tCsrScanRequest *,
+			csr_scan_completeCallback callback, void *pContext);
+
+/* ---------------------------------------------------------------------------
+    \fn csrScanAbort
+    \brief If a scan request is abort, the scan complete callback will be called first before csrScanAbort returns.
+    \param pScanRequestID - The request ID returned from csr_scan_request
+    \return CDF_STATUS
+   -------------------------------------------------------------------------------*/
+CDF_STATUS csrScanAbort(tpAniSirGlobal, uint32_t scanRequestID);
+
+/* ---------------------------------------------------------------------------
+    \fn csr_scan_get_result
+    \brief Return scan results.
+    \param pFilter - If pFilter is NULL, all cached results are returned
+    \param phResult - an object for the result.
+    \return CDF_STATUS
+   -------------------------------------------------------------------------------*/
+CDF_STATUS csr_scan_get_result(tpAniSirGlobal, tCsrScanResultFilter *pFilter,
+			       tScanResultHandle *phResult);
+
+/* ---------------------------------------------------------------------------
+    \fn csr_scan_flush_result
+    \brief Clear scan results.
+    \param pMac - pMac global pointer
+    \param sessionId - Session Identifier
+    \return CDF_STATUS
+   -------------------------------------------------------------------------------*/
+CDF_STATUS csr_scan_flush_result(tpAniSirGlobal);
+/* ---------------------------------------------------------------------------
+ *  \fn csr_scan_filter_results
+ *  \brief Filter scan results based on valid channel list.
+ *  \param  pMac - Pointer to Global MAC structure
+ *  \return CDF_STATUS
+ ***-------------------------------------------------------------------------------
+ */
+CDF_STATUS csr_scan_filter_results(tpAniSirGlobal pMac);
+
+void csr_save_scan_results(tpAniSirGlobal pMac, uint8_t reason,
+				  uint8_t sessionId);
+
+CDF_STATUS csr_scan_flush_selective_result(tpAniSirGlobal, bool flushP2P);
+
+/* ---------------------------------------------------------------------------
+    \fn csr_scan_result_get_first
+    \brief Returns the first element of scan result.
+    \param hScanResult - returned from csr_scan_get_result
+    \return tCsrScanResultInfo * - NULL if no result
+   -------------------------------------------------------------------------------*/
+tCsrScanResultInfo *csr_scan_result_get_first(tpAniSirGlobal,
+					      tScanResultHandle hScanResult);
+/* ---------------------------------------------------------------------------
+    \fn csr_scan_result_get_next
+    \brief Returns the next element of scan result. It can be called without calling csr_scan_result_get_first first
+    \param hScanResult - returned from csr_scan_get_result
+    \return Null if no result or reach the end
+   -------------------------------------------------------------------------------*/
+tCsrScanResultInfo *csr_scan_result_get_next(tpAniSirGlobal,
+					     tScanResultHandle hScanResult);
+
+/* ---------------------------------------------------------------------------
+    \fn csr_get_country_code
+    \brief this function is to get the country code current being used
+    \param pBuf - Caller allocated buffer with at least 3 bytes, upon success return, this has the country code
+    \param pbLen - Caller allocated, as input, it indicates the length of pBuf. Upon success return,
+    this contains the length of the data in pBuf
+    \return CDF_STATUS
+   -------------------------------------------------------------------------------*/
+CDF_STATUS csr_get_country_code(tpAniSirGlobal pMac, uint8_t *pBuf,
+				uint8_t *pbLen);
+
+/* ---------------------------------------------------------------------------
+    \fn csr_set_country_code
+    \brief this function is to set the country code so channel/power setting matches the countrycode and
+    the domain it belongs to.
+    \param pCountry - Caller allocated buffer with at least 3 bytes specifying the country code
+    \return CDF_STATUS
+   -------------------------------------------------------------------------------*/
+CDF_STATUS csr_set_country_code(tpAniSirGlobal pMac, uint8_t *pCountry);
+
+/* ---------------------------------------------------------------------------
+    \fn csr_get_regulatory_domain_for_country
+    \brief this function is to get the regulatory domain for a country.
+    This function must be called after CFG is downloaded and all the band/mode setting already passed into
+    CSR.
+    \param pCountry - Caller allocated buffer with at least 3 bytes specifying the country code
+    \param pDomainId - Caller allocated buffer to get the return domain ID upon success return. Can be NULL.
+    \param source - the source of country information.
+    \return CDF_STATUS
+   -------------------------------------------------------------------------------*/
+CDF_STATUS csr_get_regulatory_domain_for_country(tpAniSirGlobal pMac,
+						 uint8_t *pCountry,
+						 v_REGDOMAIN_t *pDomainId,
+						 v_CountryInfoSource_t source);
+
+/* some support functions */
+bool csr_is11d_supported(tpAniSirGlobal pMac);
+bool csr_is11h_supported(tpAniSirGlobal pMac);
+bool csr_is11e_supported(tpAniSirGlobal pMac);
+bool csr_is_wmm_supported(tpAniSirGlobal pMac);
+bool csr_is_mcc_supported(tpAniSirGlobal pMac);
+
+/* Return SUCCESS is the command is queued, failed */
+CDF_STATUS csr_queue_sme_command(tpAniSirGlobal pMac, tSmeCmd *pCommand,
+				 bool fHighPriority);
+tSmeCmd *csr_get_command_buffer(tpAniSirGlobal pMac);
+void csr_release_command(tpAniSirGlobal pMac, tSmeCmd *pCommand);
+void csr_scan_flush_bss_entry(tpAniSirGlobal pMac,
+			      tpSmeCsaOffloadInd pCsaOffloadInd);
+CDF_STATUS csr_get_active_scan_entry(tpAniSirGlobal mac, uint32_t scan_id,
+	tListElem **entry);
+
+#ifdef FEATURE_WLAN_WAPI
+bool csr_is_profile_wapi(tCsrRoamProfile *pProfile);
+#endif /* FEATURE_WLAN_WAPI */
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
+
+/* Security */
+#define WLAN_SECURITY_EVENT_SET_PTK_REQ     1
+#define WLAN_SECURITY_EVENT_SET_PTK_RSP     2
+#define WLAN_SECURITY_EVENT_SET_GTK_REQ     3
+#define WLAN_SECURITY_EVENT_SET_GTK_RSP     4
+#define WLAN_SECURITY_EVENT_REMOVE_KEY_REQ  5
+#define WLAN_SECURITY_EVENT_REMOVE_KEY_RSP  6
+#define WLAN_SECURITY_EVENT_PMKID_CANDIDATE_FOUND  7
+#define WLAN_SECURITY_EVENT_PMKID_UPDATE    8
+#define WLAN_SECURITY_EVENT_MIC_ERROR       9
+
+#define AUTH_OPEN       0
+#define AUTH_SHARED     1
+#define AUTH_WPA_EAP    2
+#define AUTH_WPA_PSK    3
+#define AUTH_WPA2_EAP   4
+#define AUTH_WPA2_PSK   5
+#ifdef FEATURE_WLAN_WAPI
+#define AUTH_WAPI_CERT  6
+#define AUTH_WAPI_PSK   7
+#endif /* FEATURE_WLAN_WAPI */
+
+#define ENC_MODE_OPEN   0
+#define ENC_MODE_WEP40  1
+#define ENC_MODE_WEP104 2
+#define ENC_MODE_TKIP   3
+#define ENC_MODE_AES    4
+#ifdef FEATURE_WLAN_WAPI
+#define ENC_MODE_SMS4   5       /* WAPI */
+#endif /* FEATURE_WLAN_WAPI */
+
+#define NO_MATCH    0
+#define MATCH       1
+
+#define WLAN_SECURITY_STATUS_SUCCESS        0
+#define WLAN_SECURITY_STATUS_FAILURE        1
+
+/* Scan */
+#define WLAN_SCAN_EVENT_ACTIVE_SCAN_REQ     1
+#define WLAN_SCAN_EVENT_ACTIVE_SCAN_RSP     2
+#define WLAN_SCAN_EVENT_PASSIVE_SCAN_REQ    3
+#define WLAN_SCAN_EVENT_PASSIVE_SCAN_RSP    4
+#define WLAN_SCAN_EVENT_HO_SCAN_REQ         5
+#define WLAN_SCAN_EVENT_HO_SCAN_RSP         6
+
+#define WLAN_SCAN_STATUS_SUCCESS        0
+#define WLAN_SCAN_STATUS_FAILURE        1
+#define WLAN_SCAN_STATUS_ABORT          2
+
+/* Ibss */
+#define WLAN_IBSS_EVENT_START_IBSS_REQ      0
+#define WLAN_IBSS_EVENT_START_IBSS_RSP      1
+#define WLAN_IBSS_EVENT_JOIN_IBSS_REQ       2
+#define WLAN_IBSS_EVENT_JOIN_IBSS_RSP       3
+#define WLAN_IBSS_EVENT_COALESCING          4
+#define WLAN_IBSS_EVENT_PEER_JOIN           5
+#define WLAN_IBSS_EVENT_PEER_LEAVE          6
+#define WLAN_IBSS_EVENT_STOP_REQ            7
+#define WLAN_IBSS_EVENT_STOP_RSP            8
+
+#define AUTO_PICK       0
+#define SPECIFIED       1
+
+#define WLAN_IBSS_STATUS_SUCCESS        0
+#define WLAN_IBSS_STATUS_FAILURE        1
+
+/* 11d */
+#define WLAN_80211D_EVENT_COUNTRY_SET   0
+#define WLAN_80211D_EVENT_RESET         1
+
+#define WLAN_80211D_DISABLED         0
+#define WLAN_80211D_SUPPORT_MULTI_DOMAIN     1
+#define WLAN_80211D_NOT_SUPPORT_MULTI_DOMAIN     2
+
+int diag_auth_type_from_csr_type(eCsrAuthType authType);
+int diag_enc_type_from_csr_type(eCsrEncryptionType encType);
+#endif /* #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR */
+/* ---------------------------------------------------------------------------
+    \fn csr_scan_result_purge
+    \brief remove all items(tCsrScanResult) in the list and free memory for each item
+    \param hScanResult - returned from csr_scan_get_result. hScanResult is considered gone by
+    calling this function and even before this function reutrns.
+    \return CDF_STATUS
+   -------------------------------------------------------------------------------*/
+CDF_STATUS csr_scan_result_purge(tpAniSirGlobal pMac,
+				 tScanResultHandle hScanResult);
+
+/* /////////////////////////////////////////Common Scan ends */
+
+/* ---------------------------------------------------------------------------
+    \fn csr_roam_connect
+    \brief To inititiate an association
+    \param pProfile - can be NULL to join to any open ones
+    \param pRoamId - to get back the request ID
+    \return CDF_STATUS
+   -------------------------------------------------------------------------------*/
+CDF_STATUS csr_roam_connect(tpAniSirGlobal pMac, uint32_t sessionId,
+			    tCsrRoamProfile *pProfile,
+			    uint32_t *pRoamId);
+
+/* ---------------------------------------------------------------------------
+    \fn csr_roam_reassoc
+    \brief To inititiate a re-association
+    \param pProfile - can be NULL to join the currently connected AP. In that
+    case modProfileFields should carry the modified field(s) which could trigger
+    reassoc
+    \param modProfileFields - fields which are part of tCsrRoamConnectedProfile
+    that might need modification dynamically once STA is up & running and this
+    could trigger a reassoc
+    \param pRoamId - to get back the request ID
+    \return CDF_STATUS
+   -------------------------------------------------------------------------------*/
+CDF_STATUS csr_roam_reassoc(tpAniSirGlobal pMac, uint32_t sessionId,
+			    tCsrRoamProfile *pProfile,
+			    tCsrRoamModifyProfileFields modProfileFields,
+			    uint32_t *pRoamId);
+
+/* ---------------------------------------------------------------------------
+    \fn csr_roam_reconnect
+    \brief To disconnect and reconnect with the same profile
+    \return CDF_STATUS. It returns fail if currently not connected
+   -------------------------------------------------------------------------------*/
+CDF_STATUS csr_roam_reconnect(tpAniSirGlobal pMac, uint32_t sessionId);
+
+/* ---------------------------------------------------------------------------
+    \fn csr_roam_set_pmkid_cache
+    \brief return the PMKID candidate list
+    \param pPMKIDCache - caller allocated buffer point to an array of tPmkidCacheInfo
+    \param numItems - a variable that has the number of tPmkidCacheInfo allocated
+    when retruning, this is either the number needed or number of items put into pPMKIDCache
+    \return CDF_STATUS - when fail, it usually means the buffer allocated is not big enough and pNumItems
+    has the number of tPmkidCacheInfo.
+    \Note: pNumItems is a number of tPmkidCacheInfo, not sizeof(tPmkidCacheInfo) * something
+   -------------------------------------------------------------------------------*/
+CDF_STATUS csr_roam_set_pmkid_cache(tpAniSirGlobal pMac, uint32_t sessionId,
+				    tPmkidCacheInfo *pPMKIDCache,
+				    uint32_t numItems, bool update_entire_cache);
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+/* ---------------------------------------------------------------------------
+   *\fn csr_roam_set_psk_pmk
+   *\brief store PSK/PMK
+   *\param pMac  - pointer to global structure for MAC
+   *\param sessionId - Sme session id
+   *\param pPSK_PMK - pointer to an array of Psk/Pmk
+   *\return CDF_STATUS - usually it succeed unless sessionId is not found
+   *\Note:
+ *-------------------------------------------------------------------------------*/
+CDF_STATUS csr_roam_set_psk_pmk(tpAniSirGlobal pMac, uint32_t sessionId,
+				uint8_t *pPSK_PMK, size_t pmk_len);
+
+/* ---------------------------------------------------------------------------
+   *\fn csr_roam_set_key_mgmt_offload
+   *\brief sets nRoamKeyMgmtOffloadEnabled
+   *\param pMac  - pointer to global structure for MAC
+   *\param sessionId - Sme session id
+   *\param nRoamKeyMgmtOffloadEnabled - value of key mgmt offload enable
+   *\return CDF_STATUS - usually it succeed unless sessionId is not found
+   *\Note:
+ *-------------------------------------------------------------------------------*/
+CDF_STATUS csr_roam_set_key_mgmt_offload(tpAniSirGlobal pMac,
+					 uint32_t sessionId,
+					 bool nRoamKeyMgmtOffloadEnabled);
+#endif
+/* ---------------------------------------------------------------------------
+    \fn csr_roam_get_wpa_rsn_req_ie
+    \brief return the WPA or RSN IE CSR passes to PE to JOIN request or START_BSS request
+    \param pLen - caller allocated memory that has the length of pBuf as input. Upon returned, *pLen has the
+    needed or IE length in pBuf.
+    \param pBuf - Caller allocated memory that contain the IE field, if any, upon return
+    \return CDF_STATUS - when fail, it usually means the buffer allocated is not big enough
+   -------------------------------------------------------------------------------*/
+CDF_STATUS csr_roam_get_wpa_rsn_req_ie(tpAniSirGlobal pMac, uint32_t sessionId,
+				       uint32_t *pLen, uint8_t *pBuf);
+
+/* ---------------------------------------------------------------------------
+    \fn csr_roam_get_wpa_rsn_rsp_ie
+    \brief return the WPA or RSN IE from the beacon or probe rsp if connected
+    \param pLen - caller allocated memory that has the length of pBuf as input. Upon returned, *pLen has the
+    needed or IE length in pBuf.
+    \param pBuf - Caller allocated memory that contain the IE field, if any, upon return
+    \return CDF_STATUS - when fail, it usually means the buffer allocated is not big enough
+   -------------------------------------------------------------------------------*/
+CDF_STATUS csr_roam_get_wpa_rsn_rsp_ie(tpAniSirGlobal pMac, uint32_t sessionId,
+				       uint32_t *pLen, uint8_t *pBuf);
+
+/* ---------------------------------------------------------------------------
+    \fn csr_roam_get_num_pmkid_cache
+    \brief return number of PMKID cache entries
+    \return uint32_t - the number of PMKID cache entries
+   -------------------------------------------------------------------------------*/
+uint32_t csr_roam_get_num_pmkid_cache(tpAniSirGlobal pMac, uint32_t sessionId);
+
+/* ---------------------------------------------------------------------------
+    \fn csr_roam_get_pmkid_cache
+    \brief return PMKID cache from CSR
+    \param pNum - caller allocated memory that has the space of the number of pBuf tPmkidCacheInfo as input. Upon returned, *pNum has the
+    needed or actually number in tPmkidCacheInfo.
+    \param pPmkidCache - Caller allocated memory that contains PMKID cache, if any, upon return
+    \return CDF_STATUS - when fail, it usually means the buffer allocated is not big enough
+   -------------------------------------------------------------------------------*/
+CDF_STATUS csr_roam_get_pmkid_cache(tpAniSirGlobal pMac, uint32_t sessionId,
+				    uint32_t *pNum, tPmkidCacheInfo *pPmkidCache);
+
+/**
+ * csr_roam_get_connect_profile() - To return the current connect profile,
+ * caller must call csr_roam_free_connect_profile after it is done and before
+ * reuse for another csr_roam_get_connect_profile call.
+ *
+ * @pMac:          pointer to global adapter context
+ * @sessionId:     session ID
+ * @pProfile:      pointer to a caller allocated structure
+ *                 tCsrRoamConnectedProfile
+ *
+ * Return: CDF_STATUS. Failure if not connected, success otherwise
+ */
+CDF_STATUS csr_roam_get_connect_profile(tpAniSirGlobal pMac, uint32_t sessionId,
+					tCsrRoamConnectedProfile *pProfile);
+
+/* ---------------------------------------------------------------------------
+    \fn csr_roam_get_connect_state
+    \brief To return the current connect state of Roaming
+    \return CDF_STATUS
+   -------------------------------------------------------------------------------*/
+CDF_STATUS csr_roam_get_connect_state(tpAniSirGlobal pMac, uint32_t sessionId,
+				      eCsrConnectState *pState);
+
+/* ---------------------------------------------------------------------------
+    \fn csr_roam_free_connect_profile
+    \brief To free and reinitialize the profile return previous by csr_roam_get_connect_profile.
+    \param pProfile - pointer to a caller allocated structure tCsrRoamConnectedProfile
+    \return CDF_STATUS.
+   -------------------------------------------------------------------------------*/
+CDF_STATUS csr_roam_free_connect_profile(tpAniSirGlobal pMac,
+					 tCsrRoamConnectedProfile *pProfile);
+
+/* ---------------------------------------------------------------------------
+    \fn csr_apply_channel_and_power_list
+    \brief HDD calls this function to set the WNI_CFG_VALID_CHANNEL_LIST base on the band/mode settings.
+    This function must be called after CFG is downloaded and all the band/mode setting already passed into
+    CSR.
+    \return CDF_STATUS
+   -------------------------------------------------------------------------------*/
+CDF_STATUS csr_apply_channel_and_power_list(tpAniSirGlobal pMac);
+
+/**
+ * csr_change_config_params() - The CSR API exposed for HDD to provide config
+ * params to CSR during SMEs stop -> start sequence.
+ *
+ * @pMac:                 pointer to global adapter context
+ * @pUpdateConfigParam:   a pointer to a structure (tCsrUpdateConfigParam) that
+ * currently provides 11d related information like country code, Regulatory
+ * domain, valid channel list, Tx power per channel, a list with active/passive
+ * scan allowed per valid channel.
+ *
+ * If HDD changed the domain that will cause a reset. This function will
+ * provide the new set of 11d information for the new domain. Currrently this
+ * API provides info regarding 11d only at reset but we can extend this for
+ * other params (PMC, QoS) which needs to be initialized again at reset.
+ *
+ * Return: CDF_STATUS. status of operation
+ */
+CDF_STATUS csr_change_config_params(tpAniSirGlobal pMac,
+				    tCsrUpdateConfigParam *pUpdateConfigParam);
+
+/* ---------------------------------------------------------------------------
+    \fn csr_roam_connect_to_last_profile
+    \brief To disconnect and reconnect with the same profile
+    \return CDF_STATUS. It returns fail if currently connected
+   -------------------------------------------------------------------------------*/
+CDF_STATUS csr_roam_connect_to_last_profile(tpAniSirGlobal pMac, uint32_t sessionId);
+
+/* ---------------------------------------------------------------------------
+    \fn csr_roam_disconnect
+    \brief To disconnect from a network
+    \param reason -- To indicate the reason for disconnecting. Currently, only eCSR_DISCONNECT_REASON_MIC_ERROR is meanful.
+    \return CDF_STATUS
+   -------------------------------------------------------------------------------*/
+CDF_STATUS csr_roam_disconnect(tpAniSirGlobal pMac, uint32_t sessionId,
+			       eCsrRoamDisconnectReason reason);
+
+/* ---------------------------------------------------------------------------
+    \fn csr_scan_get_pmkid_candidate_list
+    \brief return the PMKID candidate list
+    \param pPmkidList - caller allocated buffer point to an array of tPmkidCandidateInfo
+    \param pNumItems - pointer to a variable that has the number of tPmkidCandidateInfo allocated
+    when retruning, this is either the number needed or number of items put into pPmkidList
+    \return CDF_STATUS - when fail, it usually means the buffer allocated is not big enough and pNumItems
+    has the number of tPmkidCandidateInfo.
+    \Note: pNumItems is a number of tPmkidCandidateInfo, not sizeof(tPmkidCandidateInfo) * something
+   -------------------------------------------------------------------------------*/
+CDF_STATUS csr_scan_get_pmkid_candidate_list(tpAniSirGlobal pMac, uint32_t sessionId,
+					     tPmkidCandidateInfo *pPmkidList,
+					     uint32_t *pNumItems);
+
+/* This function is used to stop a BSS. It is similar of csr_roamIssueDisconnect but this function */
+/* doesn't have any logic other than blindly trying to stop BSS */
+CDF_STATUS csr_roam_issue_stop_bss_cmd(tpAniSirGlobal pMac, uint32_t sessionId,
+				       bool fHighPriority);
+
+void csr_call_roaming_completion_callback(tpAniSirGlobal pMac,
+					  tCsrRoamSession *pSession,
+					  tCsrRoamInfo *pRoamInfo, uint32_t roamId,
+					  eCsrRoamResult roamResult);
+
+/* ---------------------------------------------------------------------------
+    \fn csr_roam_issue_disassociate_sta_cmd
+    \brief csr function that HDD calls to disassociate a associated station
+    \param sessionId    - session Id for Soft AP
+    \param pPeerMacAddr - MAC of associated station to delete
+    \param reason - reason code, be one of the tSirMacReasonCodes
+    \return CDF_STATUS
+   ---------------------------------------------------------------------------*/
+CDF_STATUS csr_roam_issue_disassociate_sta_cmd(tpAniSirGlobal pMac,
+					       uint32_t sessionId,
+					       const uint8_t *pPeerMacAddr,
+					       uint32_t reason);
+
+/**
+ * csr_roam_issue_deauth_sta_cmd() - issue deauthenticate station command
+ * @pMac:          Pointer to global structure for MAC
+ * @sessionId:     Session Id for Soft AP
+ * @pDelStaParams: Pointer to parameters of the station to deauthenticate
+ *
+ * CSR function that HDD calls to issue a deauthenticate station command
+ *
+ * Return: CDF_STATUS_SUCCESS on success or another CDF_STATUS_* on error
+ */
+CDF_STATUS csr_roam_issue_deauth_sta_cmd(tpAniSirGlobal pMac,
+		uint32_t sessionId,
+		struct tagCsrDelStaParams *pDelStaParams);
+
+/* ---------------------------------------------------------------------------
+    \fn csr_roam_issue_tkip_counter_measures
+    \brief csr function that HDD calls to start and stop tkip countermeasures
+    \param sessionId - session Id for Soft AP
+    \param bEnable   - Flag to start/stop countermeasures
+    \return CDF_STATUS
+   ---------------------------------------------------------------------------*/
+CDF_STATUS csr_roam_issue_tkip_counter_measures(tpAniSirGlobal pMac,
+						uint32_t sessionId, bool bEnable);
+
+CDF_STATUS csr_send_mb_tkip_counter_measures_req_msg(tpAniSirGlobal pMac,
+						     uint32_t sessinId, bool bEnable,
+						     tSirMacAddr bssId);
+
+/* ---------------------------------------------------------------------------
+    \fn csr_roam_get_associated_stas
+    \brief csr function that HDD calls to get list of associated stations based on module ID
+    \param sessionId - session Id for Soft AP
+    \param modId - module ID - PE/HAL/TL
+    \param pUsrContext - Opaque HDD context
+    \param pfnSapEventCallback - Sap event callback in HDD
+    \param pAssocStasBuf - Caller allocated memory to be filled with associatd stations info
+    \return CDF_STATUS
+   ---------------------------------------------------------------------------*/
+CDF_STATUS csr_roam_get_associated_stas(tpAniSirGlobal pMac, uint32_t sessionId,
+					CDF_MODULE_ID modId, void *pUsrContext,
+					void *pfnSapEventCallback,
+					uint8_t *pAssocStasBuf);
+
+CDF_STATUS csr_send_mb_get_associated_stas_req_msg(tpAniSirGlobal pMac,
+						   uint32_t sessionId,
+						   CDF_MODULE_ID modId,
+						   tSirMacAddr bssId,
+						   void *pUsrContext,
+						   void *pfnSapEventCallback,
+						   uint8_t *pAssocStasBuf);
+
+/* ---------------------------------------------------------------------------
+    \fn csr_roam_get_wps_session_overlap
+    \brief csr function that HDD calls to get WPS PBC session overlap information
+    \param sessionId - session Id for Soft AP
+    \param pUsrContext - Opaque HDD context
+    \param pfnSapEventCallback - Sap event callback in HDD
+    \param pRemoveMac - pointer to MAC address of session to be removed
+    \return CDF_STATUS
+   ---------------------------------------------------------------------------*/
+CDF_STATUS csr_roam_get_wps_session_overlap(tpAniSirGlobal pMac, uint32_t sessionId,
+					    void *pUsrContext,
+					    void *pfnSapEventCallback,
+					    struct cdf_mac_addr pRemoveMac);
+
+CDF_STATUS csr_send_mb_get_wpspbc_sessions(tpAniSirGlobal pMac, uint32_t sessionId,
+					   tSirMacAddr bssId, void *pUsrContext,
+					   void *pfnSapEventCallback,
+					   struct cdf_mac_addr pRemoveMac);
+
+/* ---------------------------------------------------------------------------
+    \fn csr_send_chng_mcc_beacon_interval
+    \brief csr function that HDD calls to send Update beacon interval
+    \param sessionId - session Id for Soft AP
+    \return CDF_STATUS
+   ---------------------------------------------------------------------------*/
+CDF_STATUS
+csr_send_chng_mcc_beacon_interval(tpAniSirGlobal pMac, uint32_t sessionId);
+
+#ifdef WLAN_FEATURE_VOWIFI_11R
+/* ---------------------------------------------------------------------------
+    \fn csr_roam_ft_pre_auth_rsp_processor
+    \brief csr function that handles pre auth response from LIM
+   ---------------------------------------------------------------------------*/
+void csr_roam_ft_pre_auth_rsp_processor(tHalHandle hHal,
+					tpSirFTPreAuthRsp pFTPreAuthRsp);
+#endif
+
+
+#if defined(FEATURE_WLAN_ESE)
+void update_cckmtsf(uint32_t *timeStamp0, uint32_t *timeStamp1,
+		    uint32_t *incr);
+#endif
+
+CDF_STATUS csr_roam_enqueue_preauth(tpAniSirGlobal pMac, uint32_t sessionId,
+				    tpSirBssDescription pBssDescription,
+				    eCsrRoamReason reason, bool fImmediate);
+CDF_STATUS csr_dequeue_roam_command(tpAniSirGlobal pMac, eCsrRoamReason reason);
+#ifdef FEATURE_WLAN_LFR
+void csr_init_occupied_channels_list(tpAniSirGlobal pMac, uint8_t sessionId);
+bool csr_neighbor_roam_is_new_connected_profile(tpAniSirGlobal pMac,
+						uint8_t sessionId);
+bool csr_neighbor_roam_connected_profile_match(tpAniSirGlobal pMac,
+					       uint8_t sessionId,
+					       tCsrScanResult *pResult,
+					       tDot11fBeaconIEs *pIes);
+#endif
+
+CDF_STATUS csr_scan_create_entry_in_scan_cache(tpAniSirGlobal pMac,
+						uint32_t sessionId,
+						struct cdf_mac_addr bssid,
+						uint8_t channel);
+
+CDF_STATUS csr_update_channel_list(tpAniSirGlobal pMac);
+CDF_STATUS csr_roam_del_pmkid_from_cache(tpAniSirGlobal pMac,
+					 uint32_t sessionId,
+					 const uint8_t *pBSSId,
+					 bool flush_cache);
+
+bool csr_elected_country_info(tpAniSirGlobal pMac);
+void csr_add_vote_for_country_info(tpAniSirGlobal pMac, uint8_t *pCountryCode);
+void csr_clear_votes_for_country_info(tpAniSirGlobal pMac);
+
+#endif
+
+#ifdef QCA_HT_2040_COEX
+CDF_STATUS csr_set_ht2040_mode(tpAniSirGlobal pMac, uint32_t sessionId,
+			       ePhyChanBondState cbMode, bool obssEnabled);
+#endif
+tSirBssDescription*
+csr_get_bssdescr_from_scan_handle(tScanResultHandle result_handle,
+				  tSirBssDescription *bss_descr);
+void csr_release_scan_command(tpAniSirGlobal pMac, tSmeCmd *pCommand,
+			      eCsrScanStatus scanStatus);
+void csr_scan_active_list_timeout_handle(void *userData);
+CDF_STATUS csr_prepare_disconnect_command(tpAniSirGlobal mac,
+			uint32_t session_id, tSmeCmd **sme_cmd);
diff --git a/core/sme/src/csr/csr_link_list.c b/core/sme/src/csr/csr_link_list.c
new file mode 100644
index 0000000..1fa0b8b
--- /dev/null
+++ b/core/sme/src/csr/csr_link_list.c
@@ -0,0 +1,571 @@
+/*
+ * Copyright (c) 2011-2012, 2014-2015 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 csr_link_list.c
+
+    Implementation for the Common link list interfaces.
+   ========================================================================== */
+
+#include "csr_link_list.h"
+#include "cdf_lock.h"
+#include "cdf_memory.h"
+#include "cdf_trace.h"
+#include "cdf_mc_timer.h"
+
+CDF_INLINE_FN void csr_list_init(tListElem *pList)
+{
+	pList->last = pList->next = pList;
+}
+
+CDF_INLINE_FN void csr_list_remove_entry(tListElem *pEntry)
+{
+	tListElem *pLast;
+	tListElem *pNext;
+
+	pLast = pEntry->last;
+	pNext = pEntry->next;
+	pLast->next = pNext;
+	pNext->last = pLast;
+}
+
+CDF_INLINE_FN tListElem *csr_list_remove_head(tListElem *pHead)
+{
+	tListElem *pEntry;
+	tListElem *pNext;
+
+	pEntry = pHead->next;
+	pNext = pEntry->next;
+	pHead->next = pNext;
+	pNext->last = pHead;
+
+	return pEntry;
+}
+
+CDF_INLINE_FN tListElem *csr_list_remove_tail(tListElem *pHead)
+{
+	tListElem *pEntry;
+	tListElem *pLast;
+
+	pEntry = pHead->last;
+	pLast = pEntry->last;
+	pHead->last = pLast;
+	pLast->next = pHead;
+
+	return pEntry;
+}
+
+CDF_INLINE_FN void csr_list_insert_tail(tListElem *pHead, tListElem *pEntry)
+{
+	tListElem *pLast;
+
+	pLast = pHead->last;
+	pEntry->last = pLast;
+	pEntry->next = pHead;
+	pLast->next = pEntry;
+	pHead->last = pEntry;
+}
+
+CDF_INLINE_FN void csr_list_insert_head(tListElem *pHead, tListElem *pEntry)
+{
+	tListElem *pNext;
+
+	pNext = pHead->next;
+	pEntry->next = pNext;
+	pEntry->last = pHead;
+	pNext->last = pEntry;
+	pHead->next = pEntry;
+}
+
+/* Insert pNewEntry before pEntry */
+void csr_list_insert_entry(tListElem *pEntry, tListElem *pNewEntry)
+{
+	tListElem *pLast;
+	if (!pEntry) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_FATAL,
+			  "%s: Error!! pEntry is Null", __func__);
+		return;
+	}
+
+	pLast = pEntry->last;
+	pLast->next = pNewEntry;
+	pEntry->last = pNewEntry;
+	pNewEntry->next = pEntry;
+	pNewEntry->last = pLast;
+}
+
+uint32_t csr_ll_count(tDblLinkList *pList)
+{
+	uint32_t c = 0;
+
+	if (!pList) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_FATAL,
+			  "%s: Error!! pList is Null", __func__);
+		return c;
+	}
+
+	if (pList && (LIST_FLAG_OPEN == pList->Flag)) {
+		c = pList->Count;
+	}
+
+	return c;
+}
+
+void csr_ll_lock(tDblLinkList *pList)
+{
+
+	if (!pList) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_FATAL,
+			  "%s: Error!! pList is Null", __func__);
+		return;
+	}
+
+	if (LIST_FLAG_OPEN == pList->Flag) {
+		cdf_mutex_acquire(&pList->Lock);
+	}
+}
+
+void csr_ll_unlock(tDblLinkList *pList)
+{
+
+	if (!pList) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_FATAL,
+			  "%s: Error!! pList is Null", __func__);
+		return;
+	}
+
+	if (LIST_FLAG_OPEN == pList->Flag) {
+		cdf_mutex_release(&pList->Lock);
+	}
+}
+
+bool csr_ll_is_list_empty(tDblLinkList *pList, bool fInterlocked)
+{
+	bool fEmpty = true;
+
+	if (!pList) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_FATAL,
+			  "%s: Error!! pList is Null", __func__);
+		return fEmpty;
+	}
+
+	if (LIST_FLAG_OPEN == pList->Flag) {
+		if (fInterlocked) {
+			csr_ll_lock(pList);
+		}
+
+		fEmpty = csrIsListEmpty(&pList->ListHead);
+
+		if (fInterlocked) {
+			csr_ll_unlock(pList);
+		}
+	}
+	return fEmpty;
+}
+
+bool csr_ll_find_entry(tDblLinkList *pList, tListElem *pEntryToFind)
+{
+	bool fFound = false;
+	tListElem *pEntry;
+
+	if (!pList) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_FATAL,
+			  "%s: Error!! pList is Null", __func__);
+		return fFound;
+	}
+
+	if (LIST_FLAG_OPEN == pList->Flag) {
+		pEntry = csr_ll_peek_head(pList, LL_ACCESS_NOLOCK);
+
+		/* Have to make sure we don't loop back to the head of the list, which will */
+		/* happen if the entry is NOT on the list... */
+
+		while (pEntry && (pEntry != &pList->ListHead)) {
+			if (pEntry == pEntryToFind) {
+				fFound = true;
+				break;
+			}
+			pEntry = pEntry->next;
+		}
+
+	}
+	return fFound;
+}
+
+CDF_STATUS csr_ll_open(tHddHandle hHdd, tDblLinkList *pList)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	CDF_STATUS cdf_status;
+
+	if (!pList) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_FATAL,
+			  "%s: Error!! pList is Null", __func__);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	if (LIST_FLAG_OPEN != pList->Flag) {
+		pList->Count = 0;
+		pList->cmdTimeoutTimer = NULL;
+		cdf_status = cdf_mutex_init(&pList->Lock);
+
+		if (CDF_IS_STATUS_SUCCESS(cdf_status)) {
+			csr_list_init(&pList->ListHead);
+			pList->Flag = LIST_FLAG_OPEN;
+			pList->hHdd = hHdd;
+		} else {
+			status = CDF_STATUS_E_FAILURE;
+		}
+	}
+	return status;
+}
+
+void csr_ll_close(tDblLinkList *pList)
+{
+	if (!pList) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_FATAL,
+			  "%s: Error!! pList is Null", __func__);
+		return;
+	}
+
+	if (LIST_FLAG_OPEN == pList->Flag) {
+		/* Make sure the list is empty... */
+		csr_ll_purge(pList, LL_ACCESS_LOCK);
+		cdf_mutex_destroy(&pList->Lock);
+		pList->Flag = LIST_FLAG_CLOSE;
+	}
+}
+
+void csr_ll_insert_tail(tDblLinkList *pList, tListElem *pEntry,
+			bool fInterlocked)
+{
+	if (!pList) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_FATAL,
+			  "%s: Error!! pList is Null", __func__);
+		return;
+	}
+
+	if (LIST_FLAG_OPEN == pList->Flag) {
+		if (fInterlocked) {
+			csr_ll_lock(pList);
+		}
+		csr_list_insert_tail(&pList->ListHead, pEntry);
+		pList->Count++;
+		if (fInterlocked) {
+			csr_ll_unlock(pList);
+		}
+	}
+}
+
+void csr_ll_insert_head(tDblLinkList *pList, tListElem *pEntry,
+			bool fInterlocked)
+{
+
+	if (!pList) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_FATAL,
+			  "%s: Error!! pList is Null", __func__);
+		return;
+	}
+
+	if (LIST_FLAG_OPEN == pList->Flag) {
+		if (fInterlocked) {
+			csr_ll_lock(pList);
+		}
+		csr_list_insert_head(&pList->ListHead, pEntry);
+		pList->Count++;
+		if (fInterlocked) {
+			csr_ll_unlock(pList);
+		}
+		if (pList->cmdTimeoutTimer && pList->cmdTimeoutDuration) {
+			/* timer to detect pending command in activelist */
+			cdf_mc_timer_start(pList->cmdTimeoutTimer,
+					   pList->cmdTimeoutDuration);
+		}
+	}
+}
+
+void csr_ll_insert_entry(tDblLinkList *pList, tListElem *pEntry,
+			 tListElem *pNewEntry, bool fInterlocked)
+{
+	if (!pList) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_FATAL,
+			  "%s: Error!! pList is Null", __func__);
+		return;
+	}
+
+	if (LIST_FLAG_OPEN == pList->Flag) {
+		if (fInterlocked) {
+			csr_ll_lock(pList);
+		}
+		csr_list_insert_entry(pEntry, pNewEntry);
+		pList->Count++;
+		if (fInterlocked) {
+			csr_ll_unlock(pList);
+		}
+	}
+}
+
+tListElem *csr_ll_remove_tail(tDblLinkList *pList, bool fInterlocked)
+{
+	tListElem *pEntry = NULL;
+
+	if (!pList) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_FATAL,
+			  "%s: Error!! pList is Null", __func__);
+		return pEntry;
+	}
+
+	if (LIST_FLAG_OPEN == pList->Flag) {
+		if (fInterlocked) {
+			csr_ll_lock(pList);
+		}
+
+		if (!csrIsListEmpty(&pList->ListHead)) {
+
+			pEntry = csr_list_remove_tail(&pList->ListHead);
+			pList->Count--;
+		}
+		if (fInterlocked) {
+			csr_ll_unlock(pList);
+		}
+	}
+
+	return pEntry;
+}
+
+tListElem *csr_ll_peek_tail(tDblLinkList *pList, bool fInterlocked)
+{
+	tListElem *pEntry = NULL;
+
+	if (!pList) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_FATAL,
+			  "%s: Error!! pList is Null", __func__);
+		return pEntry;
+	}
+
+	if (LIST_FLAG_OPEN == pList->Flag) {
+		if (fInterlocked) {
+			csr_ll_lock(pList);
+		}
+
+		if (!csrIsListEmpty(&pList->ListHead)) {
+			pEntry = pList->ListHead.last;
+		}
+		if (fInterlocked) {
+			csr_ll_unlock(pList);
+		}
+	}
+
+	return pEntry;
+}
+
+tListElem *csr_ll_remove_head(tDblLinkList *pList, bool fInterlocked)
+{
+	tListElem *pEntry = NULL;
+
+	if (!pList) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_FATAL,
+			  "%s: Error!! pList is Null", __func__);
+		return pEntry;
+	}
+
+	if (LIST_FLAG_OPEN == pList->Flag) {
+		if (fInterlocked) {
+			csr_ll_lock(pList);
+		}
+
+		if (!csrIsListEmpty(&pList->ListHead)) {
+			pEntry = csr_list_remove_head(&pList->ListHead);
+			pList->Count--;
+		}
+
+		if (fInterlocked) {
+			csr_ll_unlock(pList);
+		}
+	}
+
+	return pEntry;
+}
+
+tListElem *csr_ll_peek_head(tDblLinkList *pList, bool fInterlocked)
+{
+	tListElem *pEntry = NULL;
+
+	if (!pList) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_FATAL,
+			  "%s: Error!! pList is Null", __func__);
+		return pEntry;
+	}
+
+	if (LIST_FLAG_OPEN == pList->Flag) {
+		if (fInterlocked) {
+			csr_ll_lock(pList);
+		}
+
+		if (!csrIsListEmpty(&pList->ListHead)) {
+			pEntry = pList->ListHead.next;
+		}
+		if (fInterlocked) {
+			csr_ll_unlock(pList);
+		}
+	}
+
+	return pEntry;
+}
+
+void csr_ll_purge(tDblLinkList *pList, bool fInterlocked)
+{
+	tListElem *pEntry;
+
+	if (!pList) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_FATAL,
+			  "%s: Error!! pList is Null", __func__);
+		return;
+	}
+
+	if (LIST_FLAG_OPEN == pList->Flag) {
+		if (fInterlocked) {
+			csr_ll_lock(pList);
+		}
+		while ((pEntry = csr_ll_remove_head(pList, LL_ACCESS_NOLOCK))) {
+			/* just remove everything from the list until */
+			/* nothing left on the list. */
+		}
+		if (fInterlocked) {
+			csr_ll_unlock(pList);
+		}
+	}
+}
+
+bool csr_ll_remove_entry(tDblLinkList *pList, tListElem *pEntryToRemove,
+			 bool fInterlocked)
+{
+	bool fFound = false;
+	tListElem *pEntry;
+
+	if (!pList) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_FATAL,
+			  "%s: Error!! pList is Null", __func__);
+		return fFound;
+	}
+
+	if (LIST_FLAG_OPEN == pList->Flag) {
+		if (fInterlocked) {
+			csr_ll_lock(pList);
+		}
+
+		pEntry = csr_ll_peek_head(pList, LL_ACCESS_NOLOCK);
+
+		/* Have to make sure we don't loop back to the head of the list, which will */
+		/* happen if the entry is NOT on the list... */
+		while (pEntry && (pEntry != &pList->ListHead)) {
+			if (pEntry == pEntryToRemove) {
+				csr_list_remove_entry(pEntry);
+				pList->Count--;
+
+				fFound = true;
+				break;
+			}
+
+			pEntry = pEntry->next;
+		}
+		if (fInterlocked) {
+			csr_ll_unlock(pList);
+		}
+		if (pList->cmdTimeoutTimer) {
+			cdf_mc_timer_stop(pList->cmdTimeoutTimer);
+		}
+	}
+
+	return fFound;
+}
+
+tListElem *csr_ll_next(tDblLinkList *pList, tListElem *pEntry,
+		       bool fInterlocked)
+{
+	tListElem *pNextEntry = NULL;
+
+	if (!pList) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_FATAL,
+			  "%s: Error!! pList is Null", __func__);
+		return pNextEntry;
+	}
+
+	if (LIST_FLAG_OPEN == pList->Flag) {
+		if (fInterlocked) {
+			csr_ll_lock(pList);
+		}
+
+		if (!csrIsListEmpty(&pList->ListHead)
+		    && csr_ll_find_entry(pList, pEntry)) {
+			pNextEntry = pEntry->next;
+			/* Make sure we don't walk past the head */
+			if (pNextEntry == &pList->ListHead) {
+				pNextEntry = NULL;
+			}
+		}
+
+		if (fInterlocked) {
+			csr_ll_unlock(pList);
+		}
+	}
+
+	return pNextEntry;
+}
+
+tListElem *csr_ll_previous(tDblLinkList *pList, tListElem *pEntry,
+			   bool fInterlocked)
+{
+	tListElem *pNextEntry = NULL;
+
+	if (!pList) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_FATAL,
+			  "%s: Error!! pList is Null", __func__);
+		return pNextEntry;
+	}
+
+	if (LIST_FLAG_OPEN == pList->Flag) {
+		if (fInterlocked) {
+			csr_ll_lock(pList);
+		}
+
+		if (!csrIsListEmpty(&pList->ListHead)
+		    && csr_ll_find_entry(pList, pEntry)) {
+			pNextEntry = pEntry->last;
+			/* Make sure we don't walk past the head */
+			if (pNextEntry == &pList->ListHead) {
+				pNextEntry = NULL;
+			}
+		}
+
+		if (fInterlocked) {
+			csr_ll_unlock(pList);
+		}
+	}
+
+	return pNextEntry;
+}
diff --git a/core/sme/src/csr/csr_neighbor_roam.c b/core/sme/src/csr/csr_neighbor_roam.c
new file mode 100644
index 0000000..5aef6cf
--- /dev/null
+++ b/core/sme/src/csr/csr_neighbor_roam.c
@@ -0,0 +1,3541 @@
+/*
+ * Copyright (c) 2011-2015 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 csr_neighbor_roam.c
+
+	Implementation for the simple roaming algorithm for 802.11r Fast
+	transitions and Legacy roaming for Android platform.
+   ========================================================================== */
+
+#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
+#include "wma_types.h"
+#include "cds_mq.h"
+#include "csr_inside_api.h"
+#include "sms_debug.h"
+#include "sme_qos_internal.h"
+#include "sme_inside.h"
+#include "host_diag_core_event.h"
+#include "host_diag_core_log.h"
+#include "csr_api.h"
+#include "sme_api.h"
+#include "csr_neighbor_roam.h"
+#include "mac_trace.h"
+
+#define WLAN_FEATURE_NEIGHBOR_ROAMING_DEBUG 1
+#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING_DEBUG
+#define NEIGHBOR_ROAM_DEBUG sms_log
+#else
+#define NEIGHBOR_ROAM_DEBUG(x ...)
+#endif
+
+static void csr_neighbor_roam_reset_channel_info(tpCsrNeighborRoamChannelInfo
+						 rChInfo);
+static void csr_neighbor_roam_reset_preauth_control_info(tpAniSirGlobal pMac,
+							 uint8_t sessionId);
+
+CDF_STATUS csr_roam_copy_connected_profile(tpAniSirGlobal pMac, uint32_t sessionId,
+					   tCsrRoamProfile *pDstProfile);
+
+#ifdef WLAN_FEATURE_VOWIFI_11R
+static CDF_STATUS csr_neighbor_roam_issue_preauth_req(tpAniSirGlobal pMac,
+						      uint8_t sessionId);
+#endif
+
+#define CSR_NEIGHBOR_ROAM_STATE_TRANSITION(mac_ctx, newstate, session) \
+{ \
+	mac_ctx->roam.neighborRoamInfo[session].prevNeighborRoamState = \
+		mac_ctx->roam.neighborRoamInfo[session].neighborRoamState; \
+	mac_ctx->roam.neighborRoamInfo[session].neighborRoamState = newstate; \
+	CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG, \
+		FL("Sessionid (%d) NeighborRoam transition from %s to %s"), \
+		session, csr_neighbor_roam_state_to_string( \
+		mac_ctx->roam.neighborRoamInfo[session].prevNeighborRoamState),\
+		csr_neighbor_roam_state_to_string(newstate)); \
+}
+
+uint8_t *csr_neighbor_roam_state_to_string(uint8_t state)
+{
+	switch (state) {
+		CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_CLOSED);
+		CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_INIT);
+		CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_CONNECTED);
+		CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING);
+		CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING);
+		CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE);
+	default:
+		return "eCSR_NEIGHBOR_ROAM_STATE_UNKNOWN";
+	}
+
+}
+
+#ifdef FEATURE_WLAN_LFR_METRICS
+/**
+ * csr_neighbor_roam_send_lfr_metric_event() - Send event of LFR metric
+ * @mac_ctx: Handle returned by mac_open.
+ * @session_id: Session information
+ * @bssid: BSSID of attempted AP
+ * @status: Result of LFR operation
+ *
+ * LFR metrics - pre-auth completion metric
+ * Send the event to supplicant indicating pre-auth result
+ *
+ * Return: void
+ */
+
+static void csr_neighbor_roam_send_lfr_metric_event(
+				tpAniSirGlobal mac_ctx,
+				uint8_t session_id,
+				tSirMacAddr bssid,
+				eRoamCmdStatus status)
+{
+	tCsrRoamInfo *roam_info;
+
+	roam_info = cdf_mem_malloc(sizeof(tCsrRoamInfo));
+	if (NULL == roam_info) {
+		sms_log(mac_ctx, LOG1, FL("Memory allocation failed!"));
+	} else {
+		cdf_mem_copy((void *)roam_info->bssid,
+			     (void *)bssid, sizeof(*roam_info));
+		csr_roam_call_callback(mac_ctx, session_id, roam_info, 0,
+			status, 0);
+		cdf_mem_free(roam_info);
+	}
+}
+#else
+/* Empty inline function will be a no-op */
+static inline void csr_neighbor_roam_send_lfr_metric_event(
+				tpAniSirGlobal mac_ctx,
+				uint8_t session_id,
+				tSirMacAddr bssid,
+				eRoamCmdStatus status)
+{
+	;
+}
+#endif
+
+/**
+ * csr_neighbor_roam_free_neighbor_roam_bss_node()
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @neighborRoamBSSNode: Neighbor Roam BSS Node to be freed
+ *
+ * This function frees all the internal pointers CSR NeighborRoam BSS Info
+ * and also frees the node itself
+ *
+ * Return: None
+ */
+void csr_neighbor_roam_free_neighbor_roam_bss_node(tpAniSirGlobal pMac,
+						   tpCsrNeighborRoamBSSInfo
+						   neighborRoamBSSNode)
+{
+	if (neighborRoamBSSNode) {
+		if (neighborRoamBSSNode->pBssDescription) {
+			cdf_mem_free(neighborRoamBSSNode->pBssDescription);
+			neighborRoamBSSNode->pBssDescription = NULL;
+		}
+		cdf_mem_free(neighborRoamBSSNode);
+		neighborRoamBSSNode = NULL;
+	}
+
+	return;
+}
+
+/**
+ * csr_neighbor_roam_remove_roamable_ap_list_entry()
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @pList: The list from which the entry should be removed
+ * @pNeighborEntry: Neighbor Roam BSS Node to be removed
+ *
+ * This function removes a given entry from the given list
+ *
+ * Return: true if successfully removed, else false
+ */
+bool csr_neighbor_roam_remove_roamable_ap_list_entry(tpAniSirGlobal pMac,
+						     tDblLinkList *pList,
+						     tpCsrNeighborRoamBSSInfo
+						     pNeighborEntry)
+{
+	if (pList) {
+		return csr_ll_remove_entry(pList, &pNeighborEntry->List,
+					   LL_ACCESS_LOCK);
+	}
+
+	sms_log(pMac, LOGE,
+		FL
+			("Removing neighbor BSS node from list failed. Current count = %d"),
+		csr_ll_count(pList));
+
+	return false;
+}
+
+/**
+ * csr_neighbor_roam_next_roamable_ap() - Get next AP from roamable AP list
+ * @mac_ctx - The handle returned by mac_open.
+ * @plist - The list from which the entry should be returned
+ * @neighbor_entry - Neighbor Roam BSS Node whose next entry should be returned
+ *
+ * Gets the entry next to passed entry. If NULL is passed, return the entry
+ * in the head of the list
+ *
+ * Return: Neighbor Roam BSS Node to be returned
+ */
+tpCsrNeighborRoamBSSInfo csr_neighbor_roam_next_roamable_ap(
+				tpAniSirGlobal mac_ctx, tDblLinkList *llist,
+				tpCsrNeighborRoamBSSInfo neighbor_entry)
+{
+	tListElem *entry = NULL;
+	tpCsrNeighborRoamBSSInfo result = NULL;
+
+	if (llist) {
+		if (NULL == neighbor_entry)
+			entry = csr_ll_peek_head(llist, LL_ACCESS_LOCK);
+		else
+			entry = csr_ll_next(llist, &neighbor_entry->List,
+					LL_ACCESS_LOCK);
+		if (entry)
+			result = GET_BASE_ADDR(entry, tCsrNeighborRoamBSSInfo,
+					List);
+	}
+
+	return result;
+}
+
+/**
+ * csr_neighbor_roam_free_roamable_bss_list() - Frees roamable APs list
+ * @mac_ctx: The handle returned by mac_open.
+ * @llist: Neighbor Roam BSS List to be emptied
+ *
+ * Empties and frees all the nodes in the roamable AP list
+ *
+ * Return: none
+ */
+void csr_neighbor_roam_free_roamable_bss_list(tpAniSirGlobal mac_ctx,
+					      tDblLinkList *llist)
+{
+	tpCsrNeighborRoamBSSInfo result = NULL;
+
+	NEIGHBOR_ROAM_DEBUG(mac_ctx, LOG2,
+			    FL("Emptying the BSS list. Current count = %d"),
+			    csr_ll_count(llist));
+
+	/*
+	 * Pick up the head, remove and free the node till
+	 * the list becomes empty
+	 */
+	while ((result = csr_neighbor_roam_next_roamable_ap(mac_ctx, llist,
+							NULL)) != NULL) {
+		csr_neighbor_roam_remove_roamable_ap_list_entry(mac_ctx,
+			llist, result);
+		csr_neighbor_roam_free_neighbor_roam_bss_node(mac_ctx, result);
+	}
+	return;
+}
+
+static void csr_neighbor_roam_trigger_handoff(tpAniSirGlobal pMac,
+					      uint8_t sessionId)
+{
+	if (csr_roam_is_fast_roam_enabled(pMac, sessionId)) {
+		csr_neighbor_roam_issue_preauth_req(pMac, sessionId);
+	} else 	{
+		sms_log(pMac, LOGE, FL("Roaming is diisabled"));
+	}
+}
+
+CDF_STATUS
+csr_neighbor_roam_update_fast_roaming_enabled(tpAniSirGlobal pMac,
+					      uint8_t sessionId,
+					      const bool fastRoamEnabled)
+{
+	CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+		&pMac->roam.neighborRoamInfo[sessionId];
+	/* set fast roam enable/disable flag */
+	pMac->roam.configParam.isFastRoamIniFeatureEnabled = fastRoamEnabled;
+
+	switch (pNeighborRoamInfo->neighborRoamState) {
+	case eCSR_NEIGHBOR_ROAM_STATE_CONNECTED:
+		if (true == fastRoamEnabled) {
+			csr_roam_offload_scan(pMac, sessionId,
+					      ROAM_SCAN_OFFLOAD_START,
+					      REASON_CONNECT);
+		} else {
+			csr_roam_offload_scan(pMac, sessionId,
+					      ROAM_SCAN_OFFLOAD_STOP,
+					      REASON_DISCONNECTED);
+		}
+	break;
+	case eCSR_NEIGHBOR_ROAM_STATE_INIT:
+		NEIGHBOR_ROAM_DEBUG(pMac, LOG2,
+				FL
+				("Currently in INIT state, Nothing to do"));
+		break;
+	default:
+		NEIGHBOR_ROAM_DEBUG(pMac, LOGE,
+				FL
+				("Unexpected state %s, returning failure"),
+				mac_trace_get_neighbour_roam_state
+				(pNeighborRoamInfo->neighborRoamState));
+		cdf_status = CDF_STATUS_E_FAILURE;
+		break;
+	}
+	return cdf_status;
+}
+
+#ifdef FEATURE_WLAN_ESE
+CDF_STATUS csr_neighbor_roam_update_ese_mode_enabled(tpAniSirGlobal pMac,
+						     uint8_t sessionId,
+						     const bool eseMode)
+{
+	CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+	    &pMac->roam.neighborRoamInfo[sessionId];
+
+	switch (pNeighborRoamInfo->neighborRoamState) {
+	case eCSR_NEIGHBOR_ROAM_STATE_CONNECTED:
+		if (true == eseMode) {
+			csr_roam_offload_scan(pMac, sessionId,
+					   ROAM_SCAN_OFFLOAD_START,
+					   REASON_CONNECT);
+		} else if (false == eseMode) {
+			csr_roam_offload_scan(pMac, sessionId,
+					   ROAM_SCAN_OFFLOAD_STOP,
+					   REASON_DISCONNECTED);
+		}
+		break;
+
+	case eCSR_NEIGHBOR_ROAM_STATE_INIT:
+		NEIGHBOR_ROAM_DEBUG(pMac,
+				    LOG2,
+				    FL
+				    ("Currently in INIT state, Nothing to do"));
+		break;
+
+	default:
+		NEIGHBOR_ROAM_DEBUG(pMac, LOGE,
+				    FL
+				    ("Unexpected state %d, returning failure"),
+				    pNeighborRoamInfo->neighborRoamState);
+		break;
+	}
+	return cdf_status;
+}
+#endif
+
+CDF_STATUS csr_neighbor_roam_set_lookup_rssi_threshold(tpAniSirGlobal pMac,
+						uint8_t sessionId,
+						uint8_t
+						  neighborLookupRssiThreshold)
+{
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+	    &pMac->roam.neighborRoamInfo[sessionId];
+	CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
+
+	switch (pNeighborRoamInfo->neighborRoamState) {
+	case eCSR_NEIGHBOR_ROAM_STATE_CONNECTED:
+		NEIGHBOR_ROAM_DEBUG(pMac, LOG2,
+				FL("Currently in CONNECTED state, "
+				"sending ROAM_SCAN_OFFLOAD_UPDATE_CFG."));
+		pNeighborRoamInfo->cfgParams.neighborLookupThreshold =
+		    neighborLookupRssiThreshold;
+		pNeighborRoamInfo->currentNeighborLookupThreshold =
+		    pNeighborRoamInfo->cfgParams.neighborLookupThreshold;
+		csr_roam_offload_scan(pMac, sessionId,
+				   ROAM_SCAN_OFFLOAD_UPDATE_CFG,
+				   REASON_LOOKUP_THRESH_CHANGED);
+		break;
+
+	case eCSR_NEIGHBOR_ROAM_STATE_INIT:
+		NEIGHBOR_ROAM_DEBUG(pMac, LOG2,
+				    FL("Currently in INIT state, "
+				       "just set lookupRssi threshold."));
+		pNeighborRoamInfo->cfgParams.neighborLookupThreshold =
+		    neighborLookupRssiThreshold;
+		pNeighborRoamInfo->currentNeighborLookupThreshold =
+		    pNeighborRoamInfo->cfgParams.neighborLookupThreshold;
+		break;
+
+	default:
+		NEIGHBOR_ROAM_DEBUG(pMac, LOGE,
+				    FL
+				    ("Unexpected state %s, returning failure"),
+				    mac_trace_get_neighbour_roam_state
+				    (pNeighborRoamInfo->neighborRoamState));
+		cdf_status = CDF_STATUS_E_FAILURE;
+		break;
+	}
+	return cdf_status;
+}
+
+CDF_STATUS
+csr_neighbor_roam_set_opportunistic_scan_threshold_diff(tpAniSirGlobal pMac,
+						uint8_t sessionId,
+						uint8_t
+						    nOpportunisticThresholdDiff)
+{
+	CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+	    &pMac->roam.neighborRoamInfo[sessionId];
+
+	switch (pNeighborRoamInfo->neighborRoamState) {
+	case eCSR_NEIGHBOR_ROAM_STATE_CONNECTED:
+		NEIGHBOR_ROAM_DEBUG(pMac, LOG2,
+				    FL("Currently in CONNECTED state, "
+				       "sending ROAM_SCAN_OFFLOAD_UPDATE_CFG"));
+		pNeighborRoamInfo->cfgParams.nOpportunisticThresholdDiff =
+		    nOpportunisticThresholdDiff;
+		pNeighborRoamInfo->currentOpportunisticThresholdDiff =
+		    nOpportunisticThresholdDiff;
+
+		csr_roam_offload_scan(pMac,
+				   sessionId,
+				   ROAM_SCAN_OFFLOAD_UPDATE_CFG,
+				   REASON_OPPORTUNISTIC_THRESH_DIFF_CHANGED);
+		break;
+
+	case eCSR_NEIGHBOR_ROAM_STATE_INIT:
+		NEIGHBOR_ROAM_DEBUG(pMac, LOG2,
+				FL("Currently in INIT state, "
+				   "just set opportunistic threshold diff"));
+		pNeighborRoamInfo->cfgParams.nOpportunisticThresholdDiff =
+		    nOpportunisticThresholdDiff;
+		pNeighborRoamInfo->currentOpportunisticThresholdDiff =
+		    nOpportunisticThresholdDiff;
+		break;
+
+	default:
+		NEIGHBOR_ROAM_DEBUG(pMac, LOGE,
+				    FL("Unexpected state %d returning failure"),
+				    pNeighborRoamInfo->neighborRoamState);
+		cdf_status = CDF_STATUS_E_FAILURE;
+		break;
+	}
+	return cdf_status;
+}
+
+CDF_STATUS
+csr_neighbor_roam_set_roam_rescan_rssi_diff(tpAniSirGlobal pMac,
+					    uint8_t sessionId,
+					    uint8_t nRoamRescanRssiDiff)
+{
+	CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+	    &pMac->roam.neighborRoamInfo[sessionId];
+
+	switch (pNeighborRoamInfo->neighborRoamState) {
+	case eCSR_NEIGHBOR_ROAM_STATE_CONNECTED:
+		NEIGHBOR_ROAM_DEBUG(pMac, LOG2,
+				FL("Currently in CONNECTED state, "
+				   "sending ROAM_SCAN_OFFLOAD_UPDATE_CFG."));
+		pNeighborRoamInfo->cfgParams.nRoamRescanRssiDiff =
+		    nRoamRescanRssiDiff;
+		pNeighborRoamInfo->currentRoamRescanRssiDiff =
+		    nRoamRescanRssiDiff;
+		csr_roam_offload_scan(pMac, sessionId,
+				   ROAM_SCAN_OFFLOAD_UPDATE_CFG,
+				   REASON_ROAM_RESCAN_RSSI_DIFF_CHANGED);
+		break;
+
+	case eCSR_NEIGHBOR_ROAM_STATE_INIT:
+		NEIGHBOR_ROAM_DEBUG(pMac, LOG2,
+				    FL("Currently in INIT state, "
+				       "just set rescan rssi diff"));
+		pNeighborRoamInfo->cfgParams.nRoamRescanRssiDiff =
+		    nRoamRescanRssiDiff;
+		pNeighborRoamInfo->currentRoamRescanRssiDiff =
+		    nRoamRescanRssiDiff;
+		break;
+
+	default:
+		NEIGHBOR_ROAM_DEBUG(pMac, LOGE,
+				    FL("Unexpected state %d returning failure"),
+				    pNeighborRoamInfo->neighborRoamState);
+		cdf_status = CDF_STATUS_E_FAILURE;
+		break;
+	}
+	return cdf_status;
+}
+
+CDF_STATUS
+csr_neighbor_roam_set_roam_bmiss_first_bcnt(tpAniSirGlobal pMac,
+					    uint8_t sessionId,
+					    uint8_t nRoamBmissFirstBcnt)
+{
+	CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+	    &pMac->roam.neighborRoamInfo[sessionId];
+
+	switch (pNeighborRoamInfo->neighborRoamState) {
+	case eCSR_NEIGHBOR_ROAM_STATE_CONNECTED:
+		NEIGHBOR_ROAM_DEBUG(pMac, LOG2,
+				FL("Currently in CONNECTED state, "
+				   "sending ROAM_SCAN_OFFLOAD_UPDATE_CFG."));
+		pNeighborRoamInfo->cfgParams.nRoamBmissFirstBcnt =
+		    nRoamBmissFirstBcnt;
+		pNeighborRoamInfo->currentRoamBmissFirstBcnt =
+		    nRoamBmissFirstBcnt;
+
+		csr_roam_offload_scan(pMac,
+				   sessionId,
+				   ROAM_SCAN_OFFLOAD_UPDATE_CFG,
+				   REASON_ROAM_BMISS_FIRST_BCNT_CHANGED);
+		break;
+
+	case eCSR_NEIGHBOR_ROAM_STATE_INIT:
+		NEIGHBOR_ROAM_DEBUG(pMac,
+		  LOG2, FL
+		  ("Currently in INIT state, safe to set roam rescan rssi diff"));
+		pNeighborRoamInfo->cfgParams.nRoamBmissFirstBcnt =
+		    nRoamBmissFirstBcnt;
+		pNeighborRoamInfo->currentRoamBmissFirstBcnt =
+		    nRoamBmissFirstBcnt;
+		break;
+
+	default:
+		NEIGHBOR_ROAM_DEBUG(pMac,
+				    LOGE,
+				    FL("Unexpected state %d returning failure"),
+				    pNeighborRoamInfo->neighborRoamState);
+		cdf_status = CDF_STATUS_E_FAILURE;
+		break;
+	}
+	return cdf_status;
+}
+
+CDF_STATUS
+csr_neighbor_roam_set_roam_bmiss_final_bcnt(tpAniSirGlobal pMac,
+					    uint8_t sessionId,
+					    uint8_t nRoamBmissFinalBcnt)
+{
+	CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+	    &pMac->roam.neighborRoamInfo[sessionId];
+
+	switch (pNeighborRoamInfo->neighborRoamState) {
+	case eCSR_NEIGHBOR_ROAM_STATE_CONNECTED:
+		NEIGHBOR_ROAM_DEBUG(pMac, LOG2,
+				    FL("Currently in CONNECTED state, "
+				       "sending ROAM_SCAN_OFFLOAD_UPDATE_CFG."));
+		pNeighborRoamInfo->cfgParams.nRoamBmissFinalBcnt =
+		    nRoamBmissFinalBcnt;
+		pNeighborRoamInfo->currentRoamBmissFinalBcnt =
+		    nRoamBmissFinalBcnt;
+
+		csr_roam_offload_scan(pMac, sessionId,
+				   ROAM_SCAN_OFFLOAD_UPDATE_CFG,
+				   REASON_ROAM_BMISS_FINAL_BCNT_CHANGED);
+		break;
+
+	case eCSR_NEIGHBOR_ROAM_STATE_INIT:
+		NEIGHBOR_ROAM_DEBUG(pMac, LOG2,
+				    FL("Currently in INIT state, "
+				       "just set roam fianl bmiss count"));
+		pNeighborRoamInfo->cfgParams.nRoamBmissFinalBcnt =
+		    nRoamBmissFinalBcnt;
+		pNeighborRoamInfo->currentRoamBmissFinalBcnt =
+		    nRoamBmissFinalBcnt;
+		break;
+
+	default:
+		NEIGHBOR_ROAM_DEBUG(pMac,
+				    LOGE,
+				    FL("Unexpected state %d returning failure"),
+				    pNeighborRoamInfo->neighborRoamState);
+		cdf_status = CDF_STATUS_E_FAILURE;
+		break;
+	}
+	return cdf_status;
+}
+
+CDF_STATUS
+csr_neighbor_roam_set_roam_beacon_rssi_weight(tpAniSirGlobal pMac,
+					      uint8_t sessionId,
+					      uint8_t nRoamBeaconRssiWeight)
+{
+	CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+	    &pMac->roam.neighborRoamInfo[sessionId];
+
+	switch (pNeighborRoamInfo->neighborRoamState) {
+	case eCSR_NEIGHBOR_ROAM_STATE_CONNECTED:
+		NEIGHBOR_ROAM_DEBUG(pMac, LOG2,
+				FL("Currently in CONNECTED state, "
+				   "sending ROAM_SCAN_OFFLOAD_UPDATE_CFG."));
+		pNeighborRoamInfo->cfgParams.nRoamBeaconRssiWeight =
+		    nRoamBeaconRssiWeight;
+		pNeighborRoamInfo->currentRoamBeaconRssiWeight =
+		    nRoamBeaconRssiWeight;
+
+		csr_roam_offload_scan(pMac, sessionId,
+				   ROAM_SCAN_OFFLOAD_UPDATE_CFG,
+				   REASON_ROAM_BEACON_RSSI_WEIGHT_CHANGED);
+		break;
+
+	case eCSR_NEIGHBOR_ROAM_STATE_INIT:
+		NEIGHBOR_ROAM_DEBUG(pMac, LOG2,
+				    FL("Currently in INIT state, "
+				       "just set roam beacon rssi weight"));
+		pNeighborRoamInfo->cfgParams.nRoamBeaconRssiWeight =
+		    nRoamBeaconRssiWeight;
+		pNeighborRoamInfo->currentRoamBeaconRssiWeight =
+		    nRoamBeaconRssiWeight;
+		break;
+
+	default:
+		NEIGHBOR_ROAM_DEBUG(pMac,
+				    LOGE,
+				    FL("Unexpected state %d returning failure"),
+				    pNeighborRoamInfo->neighborRoamState);
+		cdf_status = CDF_STATUS_E_FAILURE;
+		break;
+	}
+	return cdf_status;
+}
+
+/*CleanUP Routines*/
+static void csr_neighbor_roam_reset_channel_info(tpCsrNeighborRoamChannelInfo
+						 rChInfo)
+{
+	if ((rChInfo->IAPPNeighborListReceived == false) &&
+	    (rChInfo->currentChannelListInfo.numOfChannels)) {
+		rChInfo->currentChanIndex =
+			CSR_NEIGHBOR_ROAM_INVALID_CHANNEL_INDEX;
+		rChInfo->currentChannelListInfo.numOfChannels = 0;
+
+		if (rChInfo->currentChannelListInfo.ChannelList)
+			cdf_mem_free(rChInfo->currentChannelListInfo.
+				     ChannelList);
+
+		rChInfo->currentChannelListInfo.ChannelList = NULL;
+	} else {
+		rChInfo->currentChanIndex = 0;
+	}
+}
+
+static void csr_neighbor_roam_reset_preauth_control_info(tpAniSirGlobal pMac,
+							 uint8_t sessionId)
+{
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+		&pMac->roam.neighborRoamInfo[sessionId];
+
+#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
+	pNeighborRoamInfo->is11rAssoc = false;
+	/* Purge pre-auth fail list */
+	csr_neighbor_roam_purge_preauth_failed_list(pMac);
+#endif
+
+	pNeighborRoamInfo->FTRoamInfo.preauthRspPending = false;
+	pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries = 0;
+#ifdef WLAN_FEATURE_VOWIFI_11R
+	/* Do not free up the preauth done list here */
+	pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum = 0;
+	pNeighborRoamInfo->FTRoamInfo.neighborRptPending = false;
+	pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport = 0;
+	cdf_mem_zero(pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo,
+		     sizeof(tCsrNeighborReportBssInfo) *
+		     MAX_BSS_IN_NEIGHBOR_RPT);
+#endif
+	pNeighborRoamInfo->uOsRequestedHandoff = 0;
+	cdf_mem_zero(&pNeighborRoamInfo->handoffReqInfo,
+		     sizeof(tCsrHandoffRequest));
+}
+
+/**
+ * csr_neighbor_roam_reset_connected_state_control_info()
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @sessionId : session id
+ *
+ * This function will reset the neighbor roam control info data structures.
+ * This function should be invoked whenever we move to CONNECTED state from
+ * any state other than INIT state
+ *
+ * Return: None
+ */
+void csr_neighbor_roam_reset_connected_state_control_info(tpAniSirGlobal pMac,
+							  uint8_t sessionId)
+{
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+		&pMac->roam.neighborRoamInfo[sessionId];
+
+	csr_neighbor_roam_reset_channel_info(&pNeighborRoamInfo->roamChannelInfo);
+	csr_neighbor_roam_free_roamable_bss_list(pMac,
+						 &pNeighborRoamInfo->roamableAPList);
+
+#ifdef WLAN_FEATURE_VOWIFI_11R
+	/* Do not free up the preauth done list here */
+	pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum = 0;
+	pNeighborRoamInfo->FTRoamInfo.neighborRptPending = false;
+	pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries = 0;
+	pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport = 0;
+	pNeighborRoamInfo->FTRoamInfo.preauthRspPending = 0;
+	cdf_mem_zero(pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo,
+		     sizeof(tCsrNeighborReportBssInfo) *
+		     MAX_BSS_IN_NEIGHBOR_RPT);
+#endif
+	pNeighborRoamInfo->uOsRequestedHandoff = 0;
+	cdf_mem_zero(&pNeighborRoamInfo->handoffReqInfo,
+		     sizeof(tCsrHandoffRequest));
+}
+
+void csr_neighbor_roam_reset_report_scan_state_control_info(tpAniSirGlobal pMac,
+							    uint8_t sessionId)
+{
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+		&pMac->roam.neighborRoamInfo[sessionId];
+
+	cdf_zero_macaddr(&pNeighborRoamInfo->currAPbssid);
+#ifdef FEATURE_WLAN_ESE
+	pNeighborRoamInfo->isESEAssoc = false;
+	pNeighborRoamInfo->isVOAdmitted = false;
+	pNeighborRoamInfo->MinQBssLoadRequired = 0;
+#endif
+
+	/* Purge roamable AP list */
+	csr_neighbor_roam_free_roamable_bss_list(pMac,
+						 &pNeighborRoamInfo->roamableAPList);
+	return;
+}
+
+/**
+ * csr_neighbor_roam_reset_init_state_control_info()
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @sessionId : session id
+ *
+ * This function will reset the neighbor roam control info data structures.
+ * This function should be invoked whenever we move to CONNECTED state from
+ * INIT state
+ *
+ * Return: None
+ */
+void csr_neighbor_roam_reset_init_state_control_info(tpAniSirGlobal pMac,
+						     uint8_t sessionId)
+{
+	csr_neighbor_roam_reset_connected_state_control_info(pMac, sessionId);
+
+	/* In addition to the above resets,
+	   we should clear off the curAPBssId/Session ID in the timers */
+	csr_neighbor_roam_reset_report_scan_state_control_info(pMac, sessionId);
+}
+
+#ifdef WLAN_FEATURE_VOWIFI_11R
+/* ---------------------------------------------------------------------------
+
+    \fn csr_neighbor_roam_purge_preauth_fail_list
+
+    \brief  This function empties the preauth fail list
+
+    \param  pMac - The handle returned by mac_open.
+
+    \return VOID
+
+   ---------------------------------------------------------------------------*/
+void csr_neighbor_roam_purge_preauth_fail_list(tpAniSirGlobal pMac)
+{
+	uint8_t i;
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL;
+
+	NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Purging the preauth fail list"));
+	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
+		pNeighborRoamInfo = &pMac->roam.neighborRoamInfo[i];
+		while (pNeighborRoamInfo->FTRoamInfo.preAuthFailList.
+		       numMACAddress) {
+			cdf_mem_zero(pNeighborRoamInfo->FTRoamInfo.
+				     preAuthFailList.
+				     macAddress[pNeighborRoamInfo->FTRoamInfo.
+						preAuthFailList.numMACAddress -
+						1], sizeof(tSirMacAddr));
+			pNeighborRoamInfo->FTRoamInfo.preAuthFailList.
+			numMACAddress--;
+		}
+	}
+	return;
+}
+
+/**
+ * csr_neighbor_roam_add_preauth_fail() - add bssid to preauth failed list
+ * @mac_ctx: The handle returned by mac_open.
+ * @bssid: BSSID to be added to the preauth fail list
+ *
+ * This function adds the given BSSID to the Preauth fail list
+ *
+ * Return: CDF_STATUS_SUCCESS on success, CDF_STATUS_E_FAILURE otherwise
+ */
+CDF_STATUS csr_neighbor_roam_add_preauth_fail(tpAniSirGlobal mac_ctx,
+					uint8_t session_id,
+					tSirMacAddr bssid)
+{
+	uint8_t i = 0;
+	tpCsrNeighborRoamControlInfo neighbor_roam_info =
+		&mac_ctx->roam.neighborRoamInfo[session_id];
+	uint8_t num_mac_addr = neighbor_roam_info->FTRoamInfo.preAuthFailList.
+				numMACAddress;
+
+	NEIGHBOR_ROAM_DEBUG(mac_ctx, LOGE,
+		FL(" Added BSSID " MAC_ADDRESS_STR " to Preauth failed list"),
+		MAC_ADDR_ARRAY(bssid));
+
+	for (i = 0;
+	     i < neighbor_roam_info->FTRoamInfo.preAuthFailList.numMACAddress;
+	     i++) {
+		if (true == cdf_mem_compare(
+		   neighbor_roam_info->FTRoamInfo.preAuthFailList.macAddress[i],
+		   bssid, sizeof(tSirMacAddr))) {
+			sms_log(mac_ctx, LOGW, FL("BSSID "MAC_ADDRESS_STR" already present in preauth fail list"),
+			MAC_ADDR_ARRAY(bssid));
+			return CDF_STATUS_SUCCESS;
+		}
+	}
+
+	if ((num_mac_addr + 1) > MAX_NUM_PREAUTH_FAIL_LIST_ADDRESS) {
+		sms_log(mac_ctx, LOGE,
+			FL("Cannot add, preauth fail list is full."));
+		return CDF_STATUS_E_FAILURE;
+	}
+	cdf_mem_copy(neighbor_roam_info->FTRoamInfo.preAuthFailList.
+		     macAddress[num_mac_addr], bssid, sizeof(tSirMacAddr));
+	neighbor_roam_info->FTRoamInfo.preAuthFailList.numMACAddress++;
+
+	return CDF_STATUS_SUCCESS;
+}
+
+/**
+ * csr_neighbor_roam_is_preauth_candidate()
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @bssId : BSSID of the candidate
+ *
+ * This function checks whether the given MAC address is already present
+ * in the preauth fail list and returns true/false accordingly
+ *
+ * Return: true if preauth candidate, false otherwise
+ */
+bool csr_neighbor_roam_is_preauth_candidate(tpAniSirGlobal pMac,
+					    uint8_t sessionId, tSirMacAddr bssId)
+{
+	uint8_t i = 0;
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+		&pMac->roam.neighborRoamInfo[sessionId];
+
+	if (csr_roam_is_roam_offload_scan_enabled(pMac)) {
+		return true;
+	}
+	if (0 == pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress)
+		return true;
+
+	for (i = 0;
+	     i < pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress;
+	     i++) {
+		if (true ==
+		    cdf_mem_compare(pNeighborRoamInfo->FTRoamInfo.
+				    preAuthFailList.macAddress[i], bssId,
+				    sizeof(tSirMacAddr))) {
+			NEIGHBOR_ROAM_DEBUG(pMac, LOGE,
+					    FL("BSSID " MAC_ADDRESS_STR
+					       " already present in preauth fail list"),
+					    MAC_ADDR_ARRAY(bssId));
+			return false;
+		}
+	}
+
+	return true;
+}
+
+/**
+ * csr_neighbor_roam_issue_preauth_req() - Send preauth request to first AP
+ * @mac_ctx: The handle returned by mac_open.
+ * @session_id: Session information
+ *
+ * This function issues preauth request to PE with the 1st AP entry in the
+ * roamable AP list
+ *
+ * Return: CDF_STATUS_SUCCESS on success, CDF_STATUS_E_FAILURE otherwise
+ */
+static CDF_STATUS csr_neighbor_roam_issue_preauth_req(tpAniSirGlobal mac_ctx,
+						      uint8_t session_id)
+{
+	tpCsrNeighborRoamControlInfo neighbor_roam_info =
+		&mac_ctx->roam.neighborRoamInfo[session_id];
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	tpCsrNeighborRoamBSSInfo neighbor_bss_node;
+
+
+	if (false != neighbor_roam_info->FTRoamInfo.preauthRspPending) {
+		/* This must not be true here */
+		CDF_ASSERT(neighbor_roam_info->FTRoamInfo.preauthRspPending ==
+			   false);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	/*
+	 * Issue Preauth request to PE here.
+	 * Need to issue the preauth request with the BSSID that is in the
+	 * head of the roamable AP list. Parameters that should be passed are
+	 * BSSID, Channel number and the neighborScanPeriod(probably). If
+	 * roamableAPList gets empty, should transition to REPORT_SCAN state
+	 */
+	neighbor_bss_node = csr_neighbor_roam_next_roamable_ap(mac_ctx,
+				&neighbor_roam_info->roamableAPList, NULL);
+
+	if (NULL == neighbor_bss_node) {
+		sms_log(mac_ctx, LOGW, FL("Roamable AP list is empty.. "));
+		return CDF_STATUS_E_FAILURE;
+	} else {
+		csr_neighbor_roam_send_lfr_metric_event(mac_ctx, session_id,
+			neighbor_bss_node->pBssDescription->bssId,
+			eCSR_ROAM_PREAUTH_INIT_NOTIFY);
+		status = csr_roam_enqueue_preauth(mac_ctx, session_id,
+				neighbor_bss_node->pBssDescription,
+				eCsrPerformPreauth, true);
+
+		sms_log(mac_ctx, LOG1,
+			FL("Before Pre-Auth: BSSID " MAC_ADDRESS_STR ", Ch:%d"),
+			MAC_ADDR_ARRAY(
+				neighbor_bss_node->pBssDescription->bssId),
+			(int)neighbor_bss_node->pBssDescription->channelId);
+
+		if (CDF_STATUS_SUCCESS != status) {
+			sms_log(mac_ctx, LOGE,
+				FL("Return failed preauth request status %d"),
+				status);
+			return status;
+		}
+	}
+
+	neighbor_roam_info->FTRoamInfo.preauthRspPending = true;
+
+	/* Increment the preauth retry count */
+	neighbor_roam_info->FTRoamInfo.numPreAuthRetries++;
+
+	/* Transition the state to preauthenticating */
+	CSR_NEIGHBOR_ROAM_STATE_TRANSITION
+		(mac_ctx, eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING,
+		session_id)
+
+	return status;
+}
+
+/**
+ * csr_neighbor_roam_preauth_rsp_handler() - handle preauth response
+ * @mac_ctx: The handle returned by mac_open.
+ * @session_id: SME session
+ * @lim_status: eSIR_SUCCESS/eSIR_FAILURE/eSIR_LIM_MAX_STA_REACHED_ERROR/
+ *              eSIT_LIM_AUTH_RSP_TIMEOUT status from PE
+ *
+ * This function handle the Preauth response from PE
+ * Every preauth is allowed max 3 tries if it fails. If a bssid failed
+ * for more than MAX_TRIES, we will remove it from the list and try
+ * with the next node in the roamable AP list and add the BSSID to
+ * pre-auth failed list. If no more entries present in roamable AP list,
+ * transition to REPORT_SCAN state.
+ *
+ * Return: CDF_STATUS_SUCCESS on success (i.e. pre-auth processed),
+ *         CDF_STATUS_E_FAILURE otherwise
+ */
+CDF_STATUS csr_neighbor_roam_preauth_rsp_handler(tpAniSirGlobal mac_ctx,
+						 uint8_t session_id,
+						 tSirRetStatus lim_status)
+{
+	tpCsrNeighborRoamControlInfo neighbor_roam_info =
+		&mac_ctx->roam.neighborRoamInfo[session_id];
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	CDF_STATUS preauth_processed = CDF_STATUS_SUCCESS;
+	tpCsrNeighborRoamBSSInfo preauth_rsp_node = NULL;
+
+	if (false == neighbor_roam_info->FTRoamInfo.preauthRspPending) {
+		/*
+		 * This can happen when we disconnect immediately
+		 * after sending a pre-auth request. During processing
+		 * of the disconnect command, we would have reset
+		 * preauthRspPending and transitioned to INIT state.
+		 */
+		NEIGHBOR_ROAM_DEBUG(mac_ctx, LOGW,
+			FL("Unexpected pre-auth response in state %d"),
+			neighbor_roam_info->neighborRoamState);
+		preauth_processed = CDF_STATUS_E_FAILURE;
+		goto DEQ_PREAUTH;
+	}
+	/* We can receive it in these 2 states. */
+	if ((neighbor_roam_info->neighborRoamState !=
+	     eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING)) {
+		NEIGHBOR_ROAM_DEBUG(mac_ctx, LOGW,
+			FL("Preauth response received in state %s"),
+			mac_trace_get_neighbour_roam_state
+				(neighbor_roam_info->neighborRoamState));
+		preauth_processed = CDF_STATUS_E_FAILURE;
+		goto DEQ_PREAUTH;
+	}
+
+	neighbor_roam_info->FTRoamInfo.preauthRspPending = false;
+
+	if (eSIR_SUCCESS == lim_status)
+		preauth_rsp_node =
+			csr_neighbor_roam_next_roamable_ap(
+				mac_ctx,
+				&neighbor_roam_info->roamableAPList,
+				NULL);
+	if ((eSIR_SUCCESS == lim_status) && (NULL != preauth_rsp_node)) {
+		NEIGHBOR_ROAM_DEBUG(mac_ctx, LOG1,
+			FL("Preauth completed successfully after %d tries"),
+			neighbor_roam_info->FTRoamInfo.numPreAuthRetries);
+		sms_log(mac_ctx, LOG1,
+			FL("After Pre-Auth: BSSID " MAC_ADDRESS_STR ", Ch:%d"),
+			MAC_ADDR_ARRAY(
+				preauth_rsp_node->pBssDescription->bssId),
+			(int)preauth_rsp_node->pBssDescription->channelId);
+
+		csr_neighbor_roam_send_lfr_metric_event(mac_ctx, session_id,
+			preauth_rsp_node->pBssDescription->bssId,
+			eCSR_ROAM_PREAUTH_STATUS_SUCCESS);
+		/*
+		 * Preauth completed successfully. Insert the preauthenticated
+		 * node to tail of preAuthDoneList.
+		 */
+		csr_neighbor_roam_remove_roamable_ap_list_entry(mac_ctx,
+			&neighbor_roam_info->roamableAPList,
+			preauth_rsp_node);
+		csr_ll_insert_tail(
+			&neighbor_roam_info->FTRoamInfo.preAuthDoneList,
+			&preauth_rsp_node->List, LL_ACCESS_LOCK);
+
+		/* Pre-auth successful. Transition to PREAUTH Done state */
+		CSR_NEIGHBOR_ROAM_STATE_TRANSITION
+			(mac_ctx, eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE,
+			session_id)
+		neighbor_roam_info->FTRoamInfo.numPreAuthRetries = 0;
+
+		/*
+		 * The caller of this function would start a timer and by
+		 * the time it expires, supplicant should have provided
+		 * the updated FTIEs to SME. So, when it expires, handoff
+		 * will be triggered then.
+		 */
+	} else {
+		tpCsrNeighborRoamBSSInfo neighbor_bss_node = NULL;
+		tListElem *entry;
+
+		sms_log(mac_ctx, LOGE,
+			FL("Preauth failed retry number %d, status = 0x%x"),
+			neighbor_roam_info->FTRoamInfo.numPreAuthRetries,
+			lim_status);
+
+		/*
+		 * Preauth failed. Add the bssId to the preAuth failed list
+		 * of MAC Address. Also remove the AP from roamable AP list.
+		 */
+		if ((neighbor_roam_info->FTRoamInfo.numPreAuthRetries >=
+		     CSR_NEIGHBOR_ROAM_MAX_NUM_PREAUTH_RETRIES) ||
+		    (eSIR_LIM_MAX_STA_REACHED_ERROR == lim_status)) {
+			/*
+			 * We are going to remove the node as it fails for
+			 * more than MAX tries. Reset this count to 0
+			 */
+			neighbor_roam_info->FTRoamInfo.numPreAuthRetries = 0;
+
+			/*
+			 * The one in the head of the list should be one with
+			 * which we issued pre-auth and failed
+			 */
+			entry = csr_ll_remove_head(
+					&neighbor_roam_info->roamableAPList,
+					LL_ACCESS_LOCK);
+			if (!entry) {
+				sms_log(mac_ctx, LOGE,
+					FL("Preauth list is empty"));
+				goto NEXT_PREAUTH;
+			}
+			neighbor_bss_node = GET_BASE_ADDR(entry,
+					tCsrNeighborRoamBSSInfo,
+					List);
+			/*
+			 * Add the BSSID to pre-auth fail list if
+			 * it is not requested by HDD
+			 */
+			if (!neighbor_roam_info->uOsRequestedHandoff)
+				status =
+					csr_neighbor_roam_add_preauth_fail(
+						mac_ctx, session_id,
+						neighbor_bss_node->
+							pBssDescription->bssId);
+			csr_neighbor_roam_send_lfr_metric_event(mac_ctx,
+				session_id,
+				neighbor_bss_node->pBssDescription->bssId,
+				eCSR_ROAM_PREAUTH_STATUS_FAILURE);
+			/* Now we can free this node */
+			csr_neighbor_roam_free_neighbor_roam_bss_node(
+				mac_ctx, neighbor_bss_node);
+		}
+NEXT_PREAUTH:
+		/* Issue preauth request for the same/next entry */
+		if (CDF_STATUS_SUCCESS == csr_neighbor_roam_issue_preauth_req(
+						mac_ctx, session_id))
+			goto DEQ_PREAUTH;
+
+		if (csr_roam_is_roam_offload_scan_enabled(mac_ctx)) {
+			if (neighbor_roam_info->uOsRequestedHandoff) {
+				neighbor_roam_info->uOsRequestedHandoff = 0;
+				csr_roam_offload_scan(mac_ctx, 0,
+						      ROAM_SCAN_OFFLOAD_START,
+						      REASON_PREAUTH_FAILED_FOR_ALL);
+			} else {
+				csr_roam_offload_scan(mac_ctx, 0,
+						      ROAM_SCAN_OFFLOAD_RESTART,
+						      REASON_PREAUTH_FAILED_FOR_ALL);
+			}
+			CSR_NEIGHBOR_ROAM_STATE_TRANSITION
+				(mac_ctx, eCSR_NEIGHBOR_ROAM_STATE_CONNECTED,
+				session_id);
+		}
+	}
+
+DEQ_PREAUTH:
+	csr_dequeue_roam_command(mac_ctx, eCsrPerformPreauth);
+	return preauth_processed;
+}
+#endif /* WLAN_FEATURE_NEIGHBOR_ROAMING */
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+/**
+ * csr_neighbor_roam_offload_update_preauth_list()
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @session_id: Session ID
+ * @roam_sync_ind_ptr: Roam offload sync Ind Info
+ *
+ * This function handles the RoamOffloadSynch and adds the
+ * roamed AP to the preauth done list
+ *
+ * Return: CDF_STATUS_SUCCESS on success, CDF_STATUS_E_FAILURE otherwise
+ */
+CDF_STATUS
+csr_neighbor_roam_offload_update_preauth_list(tpAniSirGlobal pMac,
+	roam_offload_synch_ind *roam_sync_ind_ptr, uint8_t session_id)
+{
+	tpCsrNeighborRoamControlInfo neighbor_roam_info_ptr =
+		&pMac->roam.neighborRoamInfo[session_id];
+	tpCsrNeighborRoamBSSInfo bss_info_ptr;
+	uint16_t bss_desc_len;
+
+	if (neighbor_roam_info_ptr->neighborRoamState !=
+	    eCSR_NEIGHBOR_ROAM_STATE_CONNECTED) {
+		NEIGHBOR_ROAM_DEBUG(pMac, LOGW,
+			FL("LFR3:Roam Offload Synch Ind received in state %d"),
+			neighbor_roam_info_ptr->neighborRoamState);
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	bss_info_ptr = cdf_mem_malloc(sizeof(tCsrNeighborRoamBSSInfo));
+	if (NULL == bss_info_ptr) {
+		sms_log(pMac, LOGE,
+		FL("LFR3:Memory allocation for Neighbor Roam BSS Info failed"));
+		return CDF_STATUS_E_NOMEM;
+	}
+	bss_desc_len = roam_sync_ind_ptr->bss_desc_ptr->length +
+		     sizeof(roam_sync_ind_ptr->bss_desc_ptr->length);
+	bss_info_ptr->pBssDescription = cdf_mem_malloc(bss_desc_len);
+	if (bss_info_ptr->pBssDescription != NULL) {
+		cdf_mem_copy(bss_info_ptr->pBssDescription,
+			     roam_sync_ind_ptr->bss_desc_ptr,
+			     bss_desc_len);
+	} else {
+		sms_log(pMac, LOGE,
+		FL("LFR3:Mem alloc for Neighbor Roam BSS Descriptor failed"));
+		cdf_mem_free(bss_info_ptr);
+		return CDF_STATUS_E_NOMEM;
+
+	}
+	csr_ll_insert_tail(&neighbor_roam_info_ptr->FTRoamInfo.preAuthDoneList,
+			   &bss_info_ptr->List, LL_ACCESS_LOCK);
+
+	CSR_NEIGHBOR_ROAM_STATE_TRANSITION
+		(pMac, eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE, session_id)
+	neighbor_roam_info_ptr->FTRoamInfo.numPreAuthRetries = 0;
+	CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
+		  "LFR3:Entry added to Auth Done List");
+
+	return CDF_STATUS_SUCCESS;
+}
+#endif
+/**
+ * csr_neighbor_roam_prepare_scan_profile_filter()
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @session_id: Session ID
+ * @scan_filter: Populated scan filter based on the connected profile
+ *
+ * This function creates a scan filter based on the currently
+ * connected profile. Based on this filter, scan results are obtained
+ *
+ * Return: CDF_STATUS_SUCCESS on success, CDF_STATUS_E_FAILURE otherwise
+ */
+CDF_STATUS
+csr_neighbor_roam_prepare_scan_profile_filter(tpAniSirGlobal pMac,
+					      tCsrScanResultFilter *pScanFilter,
+					      uint8_t sessionId)
+{
+	tpCsrNeighborRoamControlInfo nbr_roam_info =
+		&pMac->roam.neighborRoamInfo[sessionId];
+	tCsrRoamConnectedProfile *pCurProfile =
+		&pMac->roam.roamSession[sessionId].connectedProfile;
+	uint8_t i = 0;
+	struct roam_ext_params *roam_params;
+	uint8_t num_ch = 0;
+
+	CDF_ASSERT(pScanFilter != NULL);
+	if (pScanFilter == NULL)
+		return CDF_STATUS_E_FAILURE;
+
+	cdf_mem_zero(pScanFilter, sizeof(tCsrScanResultFilter));
+	roam_params = &pMac->roam.configParam.roam_params;
+	/* We dont want to set BSSID based Filter */
+	pScanFilter->BSSIDs.numOfBSSIDs = 0;
+	pScanFilter->scan_filter_for_roam = 1;
+	/* only for HDD requested handoff fill in the BSSID in the filter */
+	if (nbr_roam_info->uOsRequestedHandoff) {
+		pScanFilter->BSSIDs.numOfBSSIDs = 1;
+		pScanFilter->BSSIDs.bssid =
+			cdf_mem_malloc(sizeof(tSirMacAddr) *
+				       pScanFilter->BSSIDs.numOfBSSIDs);
+		if (NULL == pScanFilter->BSSIDs.bssid) {
+			sms_log(pMac, LOGE,
+				FL("Scan Filter BSSID mem alloc failed"));
+			return CDF_STATUS_E_NOMEM;
+		}
+
+		cdf_mem_zero(pScanFilter->BSSIDs.bssid,
+			     sizeof(tSirMacAddr) *
+			     pScanFilter->BSSIDs.numOfBSSIDs);
+
+		/* Populate the BSSID from handoff info received from HDD */
+		for (i = 0; i < pScanFilter->BSSIDs.numOfBSSIDs; i++) {
+			cdf_copy_macaddr(&pScanFilter->BSSIDs.bssid[i],
+				 &nbr_roam_info->handoffReqInfo.bssid);
+		}
+	}
+	CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
+		FL("No of Allowed SSID List:%d"),
+		roam_params->num_ssid_allowed_list);
+	if (roam_params->num_ssid_allowed_list) {
+		pScanFilter->SSIDs.numOfSSIDs =
+			roam_params->num_ssid_allowed_list;
+		pScanFilter->SSIDs.SSIDList =
+			cdf_mem_malloc(sizeof(tCsrSSIDInfo) *
+				pScanFilter->SSIDs.numOfSSIDs);
+		if (NULL == pScanFilter->SSIDs.SSIDList) {
+			sms_log(pMac, LOGE,
+				FL("Scan Filter SSID mem alloc failed"));
+			return CDF_STATUS_E_NOMEM;
+		}
+		for (i = 0; i < roam_params->num_ssid_allowed_list; i++) {
+			pScanFilter->SSIDs.SSIDList[i].handoffPermitted = 1;
+			pScanFilter->SSIDs.SSIDList[i].ssidHidden = 0;
+			cdf_mem_copy((void *)
+				pScanFilter->SSIDs.SSIDList[i].SSID.ssId,
+				roam_params->ssid_allowed_list[i].ssId,
+				roam_params->ssid_allowed_list[i].length);
+			pScanFilter->SSIDs.SSIDList[i].SSID.length =
+				roam_params->ssid_allowed_list[i].length;
+		}
+	} else {
+		/* Populate all the information from the connected profile */
+		pScanFilter->SSIDs.numOfSSIDs = 1;
+		pScanFilter->SSIDs.SSIDList =
+			cdf_mem_malloc(sizeof(tCsrSSIDInfo));
+		if (NULL == pScanFilter->SSIDs.SSIDList) {
+			sms_log(pMac, LOGE,
+				FL("Scan Filter SSID mem alloc failed"));
+			return CDF_STATUS_E_NOMEM;
+		}
+		pScanFilter->SSIDs.SSIDList->handoffPermitted = 1;
+		pScanFilter->SSIDs.SSIDList->ssidHidden = 0;
+		pScanFilter->SSIDs.SSIDList->SSID.length =
+			pCurProfile->SSID.length;
+		cdf_mem_copy((void *)pScanFilter->SSIDs.SSIDList->SSID.ssId,
+			(void *)pCurProfile->SSID.ssId,
+			pCurProfile->SSID.length);
+
+		NEIGHBOR_ROAM_DEBUG(pMac, LOG1,
+			FL("Filtering for SSID %.*s,length of SSID = %u"),
+			pScanFilter->SSIDs.SSIDList->SSID.length,
+			pScanFilter->SSIDs.SSIDList->SSID.ssId,
+			pScanFilter->SSIDs.SSIDList->SSID.length);
+	}
+	pScanFilter->authType.numEntries = 1;
+	pScanFilter->authType.authType[0] = pCurProfile->AuthType;
+
+	pScanFilter->EncryptionType.numEntries = 1;     /* This must be 1 */
+	pScanFilter->EncryptionType.encryptionType[0] =
+		pCurProfile->EncryptionType;
+
+	pScanFilter->mcEncryptionType.numEntries = 1;
+	pScanFilter->mcEncryptionType.encryptionType[0] =
+		pCurProfile->mcEncryptionType;
+
+	pScanFilter->BSSType = pCurProfile->BSSType;
+
+	num_ch =
+	    nbr_roam_info->roamChannelInfo.currentChannelListInfo.numOfChannels;
+	if (num_ch) {
+		/*
+		 * We are intrested only in the scan results on channels we
+		 * scanned
+		 */
+		pScanFilter->ChannelInfo.numOfChannels = num_ch;
+		pScanFilter->ChannelInfo.ChannelList =
+			cdf_mem_malloc(num_ch * sizeof(uint8_t));
+		if (NULL == pScanFilter->ChannelInfo.ChannelList) {
+			sms_log(pMac, LOGE,
+				FL("Scan Filter Ch list mem alloc failed"));
+			cdf_mem_free(pScanFilter->SSIDs.SSIDList);
+			pScanFilter->SSIDs.SSIDList = NULL;
+			return CDF_STATUS_E_NOMEM;
+		}
+		for (i = 0; i < pScanFilter->ChannelInfo.numOfChannels; i++) {
+			pScanFilter->ChannelInfo.ChannelList[i] =
+			  nbr_roam_info->roamChannelInfo.currentChannelListInfo.
+			  ChannelList[i];
+		}
+	} else {
+		pScanFilter->ChannelInfo.numOfChannels = 0;
+		pScanFilter->ChannelInfo.ChannelList = NULL;
+	}
+
+#ifdef WLAN_FEATURE_VOWIFI_11R
+	if (nbr_roam_info->is11rAssoc) {
+		/*
+		 * MDIE should be added as a part of profile. This should be
+		 * added as a part of filter as well
+		 */
+		pScanFilter->MDID.mdiePresent = pCurProfile->MDID.mdiePresent;
+		pScanFilter->MDID.mobilityDomain =
+			pCurProfile->MDID.mobilityDomain;
+	}
+#endif
+
+#ifdef WLAN_FEATURE_11W
+	pScanFilter->MFPEnabled = pCurProfile->MFPEnabled;
+	pScanFilter->MFPRequired = pCurProfile->MFPRequired;
+	pScanFilter->MFPCapable = pCurProfile->MFPCapable;
+#endif
+	return CDF_STATUS_SUCCESS;
+}
+
+uint32_t csr_get_current_ap_rssi(tpAniSirGlobal pMac,
+				 tScanResultHandle *pScanResultList,
+				 uint8_t sessionId)
+{
+	tCsrScanResultInfo *pScanResult;
+	tpCsrNeighborRoamControlInfo nbr_roam_info =
+		&pMac->roam.neighborRoamInfo[sessionId];
+	/* We are setting this as default value to make sure we return this value,
+	   when we do not see this AP in the scan result for some reason.However,it is
+	   less likely that we are associated to an AP and do not see it in the scan list */
+	uint32_t CurrAPRssi = -125;
+
+	while (NULL !=
+	       (pScanResult = csr_scan_result_get_next(pMac, *pScanResultList))) {
+		if (true ==
+		    cdf_mem_compare(pScanResult->BssDescriptor.bssId,
+				    nbr_roam_info->currAPbssid.bytes,
+				    sizeof(tSirMacAddr))) {
+			/* We got a match with the currently associated AP.
+			 * Capture the RSSI value and complete the while loop.
+			 * The while loop is completed in order to make the current entry go back to NULL,
+			 * and in the next while loop, it properly starts searching from the head of the list.
+			 * TODO: Can also try setting the current entry directly to NULL as soon as we find the new AP*/
+
+			CurrAPRssi =
+				(int)pScanResult->BssDescriptor.rssi * (-1);
+
+		} else {
+			continue;
+		}
+	}
+
+	return CurrAPRssi;
+
+}
+
+/**
+ * csr_neighbor_roam_process_scan_results() - build roaming candidate list
+ *
+ * @mac_ctx: The handle returned by mac_open.
+ * @sessionid: Session information
+ * @scan_results_list: List obtained from csr_scan_get_result()
+ *
+ * This function applies various candidate checks like LFR, 11r, preauth, ESE
+ * and builds a roamable AP list. It applies age limit only if no suitable
+ * recent candidates are found.
+ *
+ * Output list is built in mac_ctx->roam.neighborRoamInfo[sessionid].
+ *
+ * Return: void
+ */
+
+static void
+csr_neighbor_roam_process_scan_results(tpAniSirGlobal mac_ctx,
+		uint8_t sessionid,
+		tScanResultHandle *scan_results_list)
+{
+	tCsrScanResultInfo *scan_result;
+	tpCsrNeighborRoamControlInfo n_roam_info =
+		&mac_ctx->roam.neighborRoamInfo[sessionid];
+	tpCsrNeighborRoamBSSInfo bss_info;
+	uint32_t cur_ap_rssi;
+	uint32_t age_ticks = 0;
+	uint32_t limit_ticks =
+		cdf_system_msecs_to_ticks(ROAM_AP_AGE_LIMIT_MS);
+	uint8_t num_candidates = 0;
+	uint8_t num_dropped = 0;
+	/*
+	 * first iteration of scan list should consider
+	 * age constraint for candidates
+	 */
+	bool age_constraint = true;
+#ifdef FEATURE_WLAN_ESE
+	uint16_t qpresent;
+	uint16_t qavail;
+	bool voadmitted;
+#endif
+	/*
+	 * Find out the Current AP RSSI and keep it handy to check if
+	 * it is better than the RSSI of the AP which we are
+	 * going to roam.If so, we are going to continue with the
+	 * current AP.
+	 */
+	cur_ap_rssi = csr_get_current_ap_rssi(mac_ctx, scan_results_list,
+				sessionid);
+
+	/*
+	 * Expecting the scan result already to be in the sorted order based on
+	 * RSSI. Based on the previous state we need to check whether the list
+	 * should be sorted again taking neighbor score into consideration. If
+	 * previous state is CFG_CHAN_LIST_SCAN, there should not be a neighbor
+	 * score associated with any of the BSS. If the previous state is
+	 * REPORT_QUERY, then there will be neighbor score for each of the APs.
+	 * For now, let us take top of the list provided as it is by CSR Scan
+	 * result API. Hence it is assumed that neighbor score and rssi score
+	 * are in the same order. This will be taken care later.
+	 */
+
+	do {
+		while (true) {
+			tSirBssDescription *descr;
+
+			scan_result = csr_scan_result_get_next(
+						mac_ctx, *scan_results_list);
+			if (NULL == scan_result)
+				break;
+			descr = &scan_result->BssDescriptor;
+			CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
+				  FL("Scan result: BSSID " MAC_ADDRESS_STR
+				     " (Rssi %ld, Ch:%d)"),
+				  MAC_ADDR_ARRAY(descr->bssId),
+				  abs(descr->rssi), descr->channelId);
+
+			if (true == cdf_mem_compare(descr->bssId,
+					n_roam_info->currAPbssid.bytes,
+					sizeof(tSirMacAddr))) {
+				/*
+				 * currently associated AP. Do not have this
+				 * in the roamable AP list
+				 */
+				CDF_TRACE(CDF_MODULE_ID_SME,
+					  CDF_TRACE_LEVEL_INFO,
+					  "SKIP-currently associated AP");
+				continue;
+			}
+#ifdef FEATURE_WLAN_LFR
+			/*
+			 * In case of reassoc requested by upper layer, look
+			 * for exact match of bssid & channel. csr cache might
+			 * have duplicates
+			 */
+			if ((n_roam_info->uOsRequestedHandoff) &&
+			    ((false == cdf_mem_compare(descr->bssId,
+					n_roam_info->handoffReqInfo.bssid.bytes,
+					sizeof(tSirMacAddr)))
+			     || (descr->channelId !=
+				 n_roam_info->handoffReqInfo.channel))) {
+				CDF_TRACE(CDF_MODULE_ID_SME,
+					  CDF_TRACE_LEVEL_INFO,
+					  "SKIP-not a candidate AP for OS requested roam");
+				continue;
+			}
+#endif
+
+#ifdef WLAN_FEATURE_VOWIFI_11R
+			if ((n_roam_info->is11rAssoc) &&
+			    (!csr_neighbor_roam_is_preauth_candidate(mac_ctx,
+					sessionid, descr->bssId))) {
+				sms_log(mac_ctx, LOGE,
+					FL("BSSID present in pre-auth fail list.. Ignoring"));
+				continue;
+			}
+#endif /* WLAN_FEATURE_VOWIFI_11R */
+
+#ifdef FEATURE_WLAN_ESE
+			if (!csr_roam_is_roam_offload_scan_enabled(mac_ctx) &&
+			    (n_roam_info->isESEAssoc) &&
+			    !csr_neighbor_roam_is_preauth_candidate(mac_ctx,
+				sessionid, descr->bssId)) {
+				sms_log(mac_ctx, LOGE,
+					FL("BSSID present in pre-auth fail list.. Ignoring"));
+				continue;
+			}
+
+			qpresent = descr->QBSSLoad_present;
+			qavail = descr->QBSSLoad_avail;
+			voadmitted = n_roam_info->isVOAdmitted;
+			if (voadmitted)
+				sms_log(mac_ctx, LOG1,
+					FL("New AP QBSS present = %s, BW available = 0x%x, required = 0x%x"),
+					((qpresent) ? "yes" : "no"), qavail,
+					n_roam_info->MinQBssLoadRequired);
+			if (voadmitted && qpresent &&
+			    (qavail < n_roam_info->MinQBssLoadRequired)) {
+				CDF_TRACE(CDF_MODULE_ID_SME,
+					CDF_TRACE_LEVEL_INFO,
+					"BSSID : " MAC_ADDRESS_STR " has no bandwidth, ignoring",
+					MAC_ADDR_ARRAY(descr->bssId));
+				continue;
+			}
+			if (voadmitted && !qpresent) {
+				CDF_TRACE(CDF_MODULE_ID_SME,
+					CDF_TRACE_LEVEL_INFO,
+					"BSSID : " MAC_ADDRESS_STR " has no QBSS LOAD IE, ignoring",
+					MAC_ADDR_ARRAY(descr->bssId));
+				continue;
+			}
+#endif /* FEATURE_WLAN_ESE */
+
+#ifdef FEATURE_WLAN_LFR
+			/*
+			 * If we are supporting legacy roaming, and
+			 * if the candidate is on the "pre-auth failed" list,
+			 * ignore it.
+			 */
+			if (csr_roam_is_fast_roam_enabled(mac_ctx, sessionid) &&
+			    !csr_neighbor_roam_is_preauth_candidate(mac_ctx,
+				sessionid, descr->bssId)) {
+				sms_log(mac_ctx, LOGE,
+					FL("BSSID present in pre-auth fail list.. Ignoring"));
+				continue;
+			}
+#endif /* FEATURE_WLAN_LFR */
+
+			/* check the age of the AP */
+			age_ticks = (uint32_t) cdf_mc_timer_get_system_ticks() -
+					descr->nReceivedTime;
+			if (age_constraint == true && age_ticks > limit_ticks) {
+				num_dropped++;
+				CDF_TRACE(CDF_MODULE_ID_SME,
+					CDF_TRACE_LEVEL_WARN,
+					FL("Old AP (probe rsp/beacon) skipped.")
+					);
+				continue;
+			}
+
+			/* Finished all checks, now add it to candidate list */
+			bss_info =
+				cdf_mem_malloc(sizeof(tCsrNeighborRoamBSSInfo));
+			if (NULL == bss_info) {
+				sms_log(mac_ctx, LOGE,
+					FL("Memory allocation failed. Ignored candidate."));
+				continue;
+			}
+			bss_info->pBssDescription =
+				cdf_mem_malloc(descr->length +
+					sizeof(descr->length));
+			if (bss_info->pBssDescription != NULL) {
+				cdf_mem_copy(bss_info->pBssDescription, descr,
+					descr->length + sizeof(descr->length));
+			} else {
+				sms_log(mac_ctx, LOGE,
+					FL("Memory allocation failed. Ignored candidate."));
+				cdf_mem_free(bss_info);
+				continue;
+			}
+			/*
+			 * Assign some preference value for now. Need to
+			 * calculate theactual score based on RSSI and neighbor
+			 * AP score
+			 */
+			bss_info->apPreferenceVal = 10;
+			num_candidates++;
+			csr_ll_insert_tail(&n_roam_info->roamableAPList,
+				&bss_info->List, LL_ACCESS_LOCK);
+		} /* end of while (csr_scan_result_get_next) */
+
+		/* if some candidates were found, then no need to repeat */
+		if (num_candidates)
+			break;
+		/*
+		 * if age_constraint is already false, we have done two
+		 * iterations and no candidate were found
+		 */
+		if (age_constraint == false) {
+			CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+				  "%s: No roam able candidates found",
+				  __func__);
+			break;
+		}
+		/*
+		 * if all candidates were dropped rescan the scan
+		 * list but this time without age constraint.
+		 */
+		age_constraint = false;
+		/* if no candidates were dropped no need to repeat */
+	} while (num_dropped);
+
+	/*
+	 * Now we have all the scan results in our local list. Good time to free
+	 * up the the list we got as a part of csrGetScanResult
+	 */
+	csr_scan_result_purge(mac_ctx, *scan_results_list);
+}
+
+static CDF_STATUS csr_neighbor_roam_process_scan_complete(tpAniSirGlobal pMac,
+							  uint8_t sessionId)
+{
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+		&pMac->roam.neighborRoamInfo[sessionId];
+	tCsrScanResultFilter scanFilter;
+	tScanResultHandle scanResult;
+	uint32_t tempVal = 0;
+	CDF_STATUS hstatus;
+
+	hstatus = csr_neighbor_roam_prepare_scan_profile_filter(pMac,
+								&scanFilter,
+								sessionId);
+	NEIGHBOR_ROAM_DEBUG(pMac, LOGW,
+			    FL
+			    ("11R/ESE/Other Association: Prepare scan to find neighbor AP filter status  = %d"),
+			    hstatus);
+	if (CDF_STATUS_SUCCESS != hstatus) {
+		sms_log(pMac, LOGE,
+			FL
+			("Scan Filter preparation failed for Assoc type %d.. Bailing out.."),
+			tempVal);
+		return CDF_STATUS_E_FAILURE;
+	}
+	hstatus = csr_scan_get_result(pMac, &scanFilter, &scanResult);
+	if (hstatus != CDF_STATUS_SUCCESS) {
+		NEIGHBOR_ROAM_DEBUG(pMac, LOGE,
+				    FL("Get Scan Result status code %d"),
+				    hstatus);
+	}
+	/* Process the scan results and update roamable AP list */
+	csr_neighbor_roam_process_scan_results(pMac, sessionId, &scanResult);
+
+	/* Free the scan filter */
+	csr_free_scan_filter(pMac, &scanFilter);
+
+	tempVal = csr_ll_count(&pNeighborRoamInfo->roamableAPList);
+
+	if (tempVal) {
+		csr_neighbor_roam_trigger_handoff(pMac, sessionId);
+		return CDF_STATUS_SUCCESS;
+	}
+
+	if (csr_roam_is_roam_offload_scan_enabled(pMac)) {
+		if (pNeighborRoamInfo->uOsRequestedHandoff) {
+			csr_roam_offload_scan(pMac, sessionId,
+					      ROAM_SCAN_OFFLOAD_START,
+					      REASON_NO_CAND_FOUND_OR_NOT_ROAMING_NOW);
+			pNeighborRoamInfo->uOsRequestedHandoff = 0;
+		} else {
+			/* There is no candidate or We are not roaming Now.
+			 * Inform the FW to restart Roam Offload Scan  */
+			csr_roam_offload_scan(pMac, sessionId,
+					      ROAM_SCAN_OFFLOAD_RESTART,
+					      REASON_NO_CAND_FOUND_OR_NOT_ROAMING_NOW);
+		}
+		CSR_NEIGHBOR_ROAM_STATE_TRANSITION
+			(pMac, eCSR_NEIGHBOR_ROAM_STATE_CONNECTED, sessionId);
+	}
+	return CDF_STATUS_SUCCESS;
+
+}
+
+
+#if defined WLAN_FEATURE_VOWIFI_11R && defined WLAN_FEATURE_VOWIFI
+/**
+ * csr_neighbor_roam_channels_filter_by_current_band()
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @session_id: Session ID
+ * @input_ch_list: The input channel list
+ * @input_num_of_ch: The number of channels in input channel list
+ * @output_ch_list: The output channel list
+ * @output_num_of_ch: The number of channels in output channel list
+ * @merged_output_num_of_ch: The final number of channels in the
+ * 				output channel list.
+ *
+ * This function is used to filter out the channels based on the
+ * currently associated AP channel
+ *
+ * Return: CDF_STATUS_SUCCESS on success, CDF_STATUS_E_FAILURE otherwise
+ */
+CDF_STATUS csr_neighbor_roam_channels_filter_by_current_band(tpAniSirGlobal pMac,
+							     uint8_t sessionId,
+							     uint8_t *
+							     pInputChannelList,
+							     uint8_t
+							     inputNumOfChannels,
+							     uint8_t *
+							     pOutputChannelList,
+							     uint8_t *
+							     pMergedOutputNumOfChannels)
+{
+	uint8_t i = 0;
+	uint8_t numChannels = 0;
+	uint8_t currAPoperationChannel =
+		pMac->roam.neighborRoamInfo[sessionId].currAPoperationChannel;
+	/* Check for NULL pointer */
+	if (!pInputChannelList)
+		return CDF_STATUS_E_INVAL;
+
+	/* Check for NULL pointer */
+	if (!pOutputChannelList)
+		return CDF_STATUS_E_INVAL;
+
+	if (inputNumOfChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+			  "%s: Wrong Number of Input Channels %d",
+			  __func__, inputNumOfChannels);
+		return CDF_STATUS_E_INVAL;
+	}
+	for (i = 0; i < inputNumOfChannels; i++) {
+		if (get_rf_band(currAPoperationChannel) ==
+		    get_rf_band(pInputChannelList[i])) {
+			pOutputChannelList[numChannels] = pInputChannelList[i];
+			numChannels++;
+		}
+	}
+
+	/* Return final number of channels */
+	*pMergedOutputNumOfChannels = numChannels;
+
+	return CDF_STATUS_SUCCESS;
+}
+
+/**
+ * csr_neighbor_roam_channels_filter_by_current_band()
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @session_id: Session ID
+ * @input_ch_list: The additional channels to merge in to the
+ * 			"merged" channels list.
+ * @input_num_of_ch: The number of additional channels.
+ * @output_ch_list: The place to put the "merged" channel list.
+ * @output_num_of_ch: The original number of channels in the
+ * 			"merged" channels list.
+ * @merged_output_num_of_ch: The final number of channels in the
+ * 				"merged" channel list.
+ *
+ * This function is used to merge two channel list.
+ * NB: If called with outputNumOfChannels == 0, this routines simply
+ * copies the input channel list to the output channel list. if number
+ * of merged channels are more than 100, num of channels set to 100
+ *
+ * Return: CDF_STATUS_SUCCESS on success, CDF_STATUS_E_FAILURE otherwise
+ */
+CDF_STATUS csr_neighbor_roam_merge_channel_lists(tpAniSirGlobal pMac,
+						 uint8_t *pInputChannelList,
+						 uint8_t inputNumOfChannels,
+						 uint8_t *pOutputChannelList,
+						 uint8_t outputNumOfChannels,
+						 uint8_t *
+						 pMergedOutputNumOfChannels)
+{
+	uint8_t i = 0;
+	uint8_t j = 0;
+	uint8_t numChannels = outputNumOfChannels;
+
+	/* Check for NULL pointer */
+	if (!pInputChannelList)
+		return CDF_STATUS_E_INVAL;
+
+	/* Check for NULL pointer */
+	if (!pOutputChannelList)
+		return CDF_STATUS_E_INVAL;
+
+	if (inputNumOfChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+			  "%s: Wrong Number of Input Channels %d",
+			  __func__, inputNumOfChannels);
+		return CDF_STATUS_E_INVAL;
+	}
+	if (outputNumOfChannels >= WNI_CFG_VALID_CHANNEL_LIST_LEN) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+			  "%s: Wrong Number of Output Channels %d",
+			  __func__, outputNumOfChannels);
+		return CDF_STATUS_E_INVAL;
+	}
+	/* Add the "new" channels in the input list to the end of the output list. */
+	for (i = 0; i < inputNumOfChannels; i++) {
+		for (j = 0; j < outputNumOfChannels; j++) {
+			if (pInputChannelList[i] == pOutputChannelList[j])
+				break;
+		}
+		if (j == outputNumOfChannels) {
+			if (pInputChannelList[i]) {
+				CDF_TRACE(CDF_MODULE_ID_SME,
+					  CDF_TRACE_LEVEL_INFO,
+					  "%s: [INFOLOG] Adding extra %d to Neighbor channel list",
+					  __func__, pInputChannelList[i]);
+				pOutputChannelList[numChannels] =
+					pInputChannelList[i];
+				numChannels++;
+			}
+		}
+		if (numChannels >= WNI_CFG_VALID_CHANNEL_LIST_LEN) {
+			CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
+				  "%s: Merge Neighbor channel list reached Max "
+				  "limit %d", __func__, numChannels);
+			break;
+		}
+	}
+
+	/* Return final number of channels */
+	*pMergedOutputNumOfChannels = numChannels;
+
+	return CDF_STATUS_SUCCESS;
+}
+
+/**
+ * csr_neighbor_roam_create_chan_list_from_neighbor_report()
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @session_id: Session ID
+ *
+ * This function is invoked when neighbor report is received for the
+ * neighbor request. Based on the channels present in the neighbor report,
+ * it generates channel list which will be used in REPORT_SCAN state to
+ * scan for these neighbor APs
+ *
+ * Return: CDF_STATUS_SUCCESS on success, CDF_STATUS_E_FAILURE otherwise
+ */
+CDF_STATUS csr_neighbor_roam_create_chan_list_from_neighbor_report(tpAniSirGlobal pMac,
+								   uint8_t sessionId)
+{
+	tpRrmNeighborReportDesc pNeighborBssDesc;
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+		&pMac->roam.neighborRoamInfo[sessionId];
+	uint8_t numChannels = 0;
+	uint8_t i = 0;
+	uint8_t channelList[MAX_BSS_IN_NEIGHBOR_RPT];
+	uint8_t mergedOutputNumOfChannels = 0;
+
+	/* This should always start from 0 whenever we create a channel list out of neighbor AP list */
+	pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport = 0;
+
+	pNeighborBssDesc = sme_rrm_get_first_bss_entry_from_neighbor_cache(pMac);
+
+	while (pNeighborBssDesc) {
+		if (pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport >=
+		    MAX_BSS_IN_NEIGHBOR_RPT)
+			break;
+
+		/* Update the neighbor BSS Info in the 11r FT Roam Info */
+		pNeighborRoamInfo->FTRoamInfo.
+		neighboReportBssInfo[pNeighborRoamInfo->FTRoamInfo.
+				     numBssFromNeighborReport].channelNum =
+			pNeighborBssDesc->pNeighborBssDescription->channel;
+		pNeighborRoamInfo->FTRoamInfo.
+		neighboReportBssInfo[pNeighborRoamInfo->FTRoamInfo.
+				     numBssFromNeighborReport].
+		neighborScore = (uint8_t) pNeighborBssDesc->roamScore;
+		cdf_mem_copy(pNeighborRoamInfo->FTRoamInfo.
+			     neighboReportBssInfo[pNeighborRoamInfo->FTRoamInfo.
+						  numBssFromNeighborReport].
+			     neighborBssId,
+			     pNeighborBssDesc->pNeighborBssDescription->bssId,
+			     sizeof(tSirMacAddr));
+		pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport++;
+
+		/* Saving the channel list non-redundantly */
+		for (i = 0; (i < numChannels && i < MAX_BSS_IN_NEIGHBOR_RPT);
+		     i++) {
+			if (pNeighborBssDesc->pNeighborBssDescription->
+			    channel == channelList[i])
+				break;
+		}
+
+		if (i == numChannels) {
+			if (pNeighborBssDesc->pNeighborBssDescription->channel) {
+				if (CSR_IS_ROAM_INTRA_BAND_ENABLED(pMac)) {
+					/* Make sure to add only if its the same band */
+					if (get_rf_band
+						    (pNeighborRoamInfo->
+						    currAPoperationChannel) ==
+					    get_rf_band(pNeighborBssDesc->
+							pNeighborBssDescription->
+							channel)) {
+						CDF_TRACE(CDF_MODULE_ID_SME,
+							  CDF_TRACE_LEVEL_INFO,
+							  "%s: [INFOLOG] Adding %d to Neighbor channel list (Same band)\n",
+							  __func__,
+							  pNeighborBssDesc->
+							  pNeighborBssDescription->
+							  channel);
+						channelList[numChannels] =
+							pNeighborBssDesc->
+							pNeighborBssDescription->
+							channel;
+						numChannels++;
+					}
+				} else {
+					CDF_TRACE(CDF_MODULE_ID_SME,
+						  CDF_TRACE_LEVEL_INFO,
+						  "%s: [INFOLOG] Adding %d to Neighbor channel list\n",
+						  __func__,
+						  pNeighborBssDesc->
+						  pNeighborBssDescription->
+						  channel);
+					channelList[numChannels] =
+						pNeighborBssDesc->
+						pNeighborBssDescription->channel;
+					numChannels++;
+				}
+			}
+		}
+
+		pNeighborBssDesc =
+			sme_rrm_get_next_bss_entry_from_neighbor_cache(pMac,
+								       pNeighborBssDesc);
+	}
+
+	if (pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.
+	    ChannelList) {
+		cdf_mem_free(pNeighborRoamInfo->roamChannelInfo.
+			     currentChannelListInfo.ChannelList);
+	}
+
+	pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList =
+		NULL;
+	pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.
+	numOfChannels = 0;
+	/* Store the obtained channel list to the Neighbor Control data structure */
+	if (numChannels)
+		pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.
+		ChannelList =
+			cdf_mem_malloc((numChannels) * sizeof(uint8_t));
+	if (NULL ==
+	    pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.
+	    ChannelList) {
+		sms_log(pMac, LOGE,
+			FL
+				("Memory allocation for Channel list failed.. TL event ignored"));
+		return CDF_STATUS_E_NOMEM;
+	}
+
+	cdf_mem_copy(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.
+		     ChannelList, channelList, (numChannels) * sizeof(uint8_t));
+	pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.
+	numOfChannels = numChannels;
+	/*
+	 * Create a Union of occupied channel list learnt by the DUT along with the Neighbor
+	 * report Channels. This increases the chances of the DUT to get a candidate AP while
+	 * roaming even if the Neighbor Report is not able to provide sufficient information.
+	 * */
+	if (pMac->scan.occupiedChannels[sessionId].numChannels) {
+		csr_neighbor_roam_merge_channel_lists(pMac,
+						      &pMac->scan.
+						      occupiedChannels[sessionId].
+						      channelList[0],
+						      pMac->scan.
+						      occupiedChannels[sessionId].
+						      numChannels,
+						      &pNeighborRoamInfo->
+						      roamChannelInfo.
+						      currentChannelListInfo.
+						      ChannelList[0],
+						      pNeighborRoamInfo->
+						      roamChannelInfo.
+						      currentChannelListInfo.
+						      numOfChannels,
+						      &mergedOutputNumOfChannels);
+		pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.
+		numOfChannels = mergedOutputNumOfChannels;
+
+	}
+	/*Indicate the firmware about the update only if any new channels are added.
+	 * Otherwise, the firmware would already be knowing the non-IAPPneighborlist
+	 * channels. There is no need to update.*/
+	if (numChannels) {
+		sms_log(pMac, LOG1,
+			FL("IAPP Neighbor list callback received as expected"
+			   "in state %s."),
+			mac_trace_get_neighbour_roam_state(pNeighborRoamInfo->
+							   neighborRoamState));
+		pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived =
+			true;
+		if (csr_roam_is_roam_offload_scan_enabled(pMac)) {
+			csr_roam_offload_scan(pMac, sessionId,
+					      ROAM_SCAN_OFFLOAD_UPDATE_CFG,
+					      REASON_CHANNEL_LIST_CHANGED);
+		}
+	}
+	pNeighborRoamInfo->roamChannelInfo.currentChanIndex = 0;
+
+	return CDF_STATUS_SUCCESS;
+}
+#endif /* WLAN_FEATURE_VOWIFI_11R */
+
+#ifdef FEATURE_WLAN_LFR
+/**
+ * csr_neighbor_roam_is_ssid_and_security_match() - to match ssid/security
+ * @pMac: Pointer to mac context
+ * @pCurProfile: pointer to current roam profile
+ * @pBssDesc: pointer to bss description
+ * @pIes: pointer to local ies
+ *
+ * This routine will be called to see if SSID and security parameters
+ * are matching.
+ *
+ * Return: bool
+ */
+bool csr_neighbor_roam_is_ssid_and_security_match(tpAniSirGlobal pMac,
+		tCsrRoamConnectedProfile *pCurProfile,
+		tSirBssDescription *pBssDesc, tDot11fBeaconIEs *pIes)
+{
+	tCsrAuthList authType;
+	tCsrEncryptionList uCEncryptionType;
+	tCsrEncryptionList mCEncryptionType;
+	bool fMatch = false;
+
+	authType.numEntries = 1;
+	authType.authType[0] = pCurProfile->AuthType;
+	uCEncryptionType.numEntries = 1;
+	uCEncryptionType.encryptionType[0] = pCurProfile->EncryptionType;
+	mCEncryptionType.numEntries = 1;
+	mCEncryptionType.encryptionType[0] = pCurProfile->mcEncryptionType;
+
+	/* Again, treat missing pIes as a non-match. */
+	if (!pIes)
+		return false;
+
+	/* Treat a missing SSID as a non-match. */
+	if (!pIes->SSID.present)
+		return false;
+
+	fMatch = csr_is_ssid_match(pMac,
+			(void *)pCurProfile->SSID.ssId,
+			pCurProfile->SSID.length,
+			pIes->SSID.ssid,
+			pIes->SSID.num_ssid, true);
+	if (true == fMatch) {
+		/*
+		 * for now we are sending NULL for all PMF related filter
+		 * parameters during roam to the neighbor AP because
+		 * so far 80211W spec doesn't specify anything about
+		 * roaming scenario.
+		 *
+		 * Once roaming scenario is defined, we should re-visit
+		 * this section and remove this comment.
+		 */
+		fMatch = csr_is_security_match(pMac, &authType,
+				&uCEncryptionType,
+				&mCEncryptionType, NULL,
+				NULL, NULL, pBssDesc,
+				pIes, NULL, NULL, NULL);
+		return fMatch;
+	} else {
+		return fMatch;
+	}
+
+}
+
+bool csr_neighbor_roam_is_new_connected_profile(tpAniSirGlobal pMac,
+						uint8_t sessionId)
+{
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+		&pMac->roam.neighborRoamInfo[sessionId];
+	tCsrRoamConnectedProfile *pCurrProfile = NULL;
+	tCsrRoamConnectedProfile *pPrevProfile = NULL;
+	tDot11fBeaconIEs *pIes = NULL;
+	tSirBssDescription *pBssDesc = NULL;
+	bool fNew = true;
+
+	if (!(pMac->roam.roamSession && CSR_IS_SESSION_VALID(pMac, sessionId))) {
+		return fNew;
+	}
+
+	pCurrProfile = &pMac->roam.roamSession[sessionId].connectedProfile;
+	if (!pCurrProfile) {
+		return fNew;
+	}
+
+	pPrevProfile = &pNeighborRoamInfo->prevConnProfile;
+	if (!pPrevProfile) {
+		return fNew;
+	}
+
+	pBssDesc = pPrevProfile->pBssDesc;
+	if (pBssDesc) {
+		if (CDF_IS_STATUS_SUCCESS(
+		    csr_get_parsed_bss_description_ies(pMac, pBssDesc, &pIes))
+		    && csr_neighbor_roam_is_ssid_and_security_match(pMac,
+					pCurrProfile, pBssDesc, pIes)) {
+			fNew = false;
+		}
+		if (pIes) {
+			cdf_mem_free(pIes);
+		}
+	}
+
+	if (fNew) {
+		sms_log(pMac, LOG1,
+			FL("Prev roam profile did not match current"));
+	} else {
+		sms_log(pMac, LOG1, FL("Prev roam profile matches current"));
+	}
+
+	return fNew;
+}
+
+bool csr_neighbor_roam_connected_profile_match(tpAniSirGlobal pMac,
+					       uint8_t sessionId,
+					       tCsrScanResult *pResult,
+					       tDot11fBeaconIEs *pIes)
+{
+	tCsrRoamConnectedProfile *pCurProfile = NULL;
+	tSirBssDescription *pBssDesc = &pResult->Result.BssDescriptor;
+
+	if (!(pMac->roam.roamSession && CSR_IS_SESSION_VALID(pMac, sessionId))) {
+		return false;
+	}
+
+	pCurProfile = &pMac->roam.roamSession[sessionId].connectedProfile;
+
+	if (!pCurProfile) {
+		return false;
+	}
+
+	return csr_neighbor_roam_is_ssid_and_security_match(pMac, pCurProfile,
+							    pBssDesc, pIes);
+}
+
+/**
+ * csr_neighbor_roam_prepare_non_occupied_channel_list() - prepare non-occup CL
+ * @pMac: The handle returned by mac_open
+ * @pInputChannelList: The default channels list
+ * @numOfChannels: The number of channels in the default channels list
+ * @pOutputChannelList: The place to put the non-occupied channel list
+ * @pOutputNumOfChannels: Number of channels in the non-occupied channel list
+ *
+ * This function is used to prepare a channel list that is derived from
+ * the list of valid channels and does not include those in the occupied list
+ *
+ * Return CDF_STATUS
+ */
+CDF_STATUS
+csr_neighbor_roam_prepare_non_occupied_channel_list(tpAniSirGlobal pMac,
+		uint8_t sessionId, uint8_t *pInputChannelList,
+		uint8_t numOfChannels, uint8_t *pOutputChannelList,
+		uint8_t *pOutputNumOfChannels)
+{
+	uint8_t i = 0;
+	uint8_t outputNumOfChannels = 0;
+	uint8_t numOccupiedChannels =
+			pMac->scan.occupiedChannels[sessionId].numChannels;
+	uint8_t *pOccupiedChannelList =
+			pMac->scan.occupiedChannels[sessionId].channelList;
+
+	for (i = 0; i < numOfChannels; i++) {
+		if (csr_is_channel_present_in_list
+				(pOccupiedChannelList, numOccupiedChannels,
+				 pInputChannelList[i]))
+			continue;
+		/*
+		 * DFS channel will be added in the list only when the
+		 * DFS Roaming scan flag is enabled
+		 */
+		if (CDS_IS_DFS_CH(pInputChannelList[i])) {
+			if (CSR_ROAMING_DFS_CHANNEL_DISABLED !=
+				pMac->roam.configParam.allowDFSChannelRoam) {
+				pOutputChannelList[outputNumOfChannels++] =
+						pInputChannelList[i];
+			}
+		} else {
+			pOutputChannelList[outputNumOfChannels++] =
+						pInputChannelList[i];
+		}
+	}
+
+	sms_log(pMac, LOG2,
+		FL("Number of channels in the valid channel list=%d; "
+		   "Number of channels in the non-occupied list list=%d"),
+		numOfChannels, outputNumOfChannels);
+
+	/* Return the number of channels */
+	*pOutputNumOfChannels = outputNumOfChannels;
+	return CDF_STATUS_SUCCESS;
+}
+#endif /* FEATURE_WLAN_LFR */
+
+/**
+ * csr_roam_reset_roam_params - API to reset the roaming parameters
+ * @mac_ctx:          Pointer to the global MAC structure
+ *
+ * The BSSID blacklist should not be cleared since it has to
+ * be used across connections. These parameters will be cleared
+ * and sent to firmware with with the roaming STOP command.
+ *
+ * Return: VOID
+ */
+void csr_roam_reset_roam_params(tpAniSirGlobal mac_ctx)
+{
+	struct roam_ext_params *roam_params = NULL;
+
+	/*
+	 * clear all the whitelist parameters and remaining
+	 * needs to be retained across connections.
+	 */
+	CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
+		FL("Roaming parameters are reset"));
+	roam_params = &mac_ctx->roam.configParam.roam_params;
+	roam_params->num_ssid_allowed_list = 0;
+	cdf_mem_set(&roam_params->ssid_allowed_list, 0,
+			sizeof(tSirMacSSid) * MAX_SSID_ALLOWED_LIST);
+}
+
+/**
+ * csr_neighbor_roam_indicate_disconnect() - To indicate disconnect
+ * @pMac: The handle returned by mac_open
+ * @sessionId: CSR session id that got disconnected
+ *
+ * This function is called by CSR as soon as the station disconnects
+ * from the AP. This function does the necessary cleanup of neighbor roam
+ * data structures. Neighbor roam state transitions to INIT state whenever
+ * this function is called except if the current state is REASSOCIATING
+ *
+ * Return: CDF_STATUS
+ */
+CDF_STATUS csr_neighbor_roam_indicate_disconnect(tpAniSirGlobal pMac,
+						 uint8_t sessionId)
+{
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+			&pMac->roam.neighborRoamInfo[sessionId];
+#ifdef FEATURE_WLAN_LFR
+	tCsrRoamConnectedProfile *pPrevProfile =
+			&pNeighborRoamInfo->prevConnProfile;
+#endif
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+	tCsrRoamSession *roam_session = NULL;
+
+	if (NULL == pSession) {
+		sms_log(pMac, LOGE, FL("pSession is NULL"));
+		return CDF_STATUS_E_FAILURE;
+	}
+	CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
+			FL("Disconn ind on session %d in state %d from bss :"
+			MAC_ADDRESS_STR), sessionId,
+			pNeighborRoamInfo->neighborRoamState,
+			MAC_ADDR_ARRAY(pSession->connectedProfile.bssid.bytes));
+#ifdef FEATURE_WLAN_LFR
+	/*
+	 * Free the current previous profile and move
+	 * the current profile to prev profile.
+	 */
+	csr_roam_free_connect_profile(pMac, pPrevProfile);
+	csr_roam_copy_connect_profile(pMac, sessionId, pPrevProfile);
+#endif
+	/*
+	 * clear the roaming parameters that are per connection.
+	 * For a new connection, they have to be programmed again.
+	 */
+	if (!csr_neighbor_middle_of_roaming((tHalHandle)pMac, sessionId))
+		csr_roam_reset_roam_params(pMac);
+	if (NULL != pSession) {
+		roam_session = &pMac->roam.roamSession[sessionId];
+		if (NULL != pSession->pCurRoamProfile && (CDF_STA_MODE !=
+			roam_session->pCurRoamProfile->csrPersona)) {
+			sms_log(pMac, LOGE,
+				FL("Ignore disconn ind rcvd from nonSTA persona"
+					"sessionId: %d, csrPersonna %d"),
+				sessionId,
+				(int)roam_session->pCurRoamProfile->csrPersona);
+			return CDF_STATUS_SUCCESS;
+		}
+#ifdef FEATURE_WLAN_ESE
+		if (pSession->connectedProfile.isESEAssoc) {
+			cdf_mem_copy(&pSession->prevApSSID,
+				&pSession->connectedProfile.SSID,
+				sizeof(tSirMacSSid));
+			cdf_copy_macaddr(&pSession->prevApBssid,
+					&pSession->connectedProfile.bssid);
+			pSession->prevOpChannel =
+				pSession->connectedProfile.operationChannel;
+			pSession->isPrevApInfoValid = true;
+			pSession->roamTS1 = cdf_mc_timer_get_system_time();
+		}
+#endif
+	}
+
+	switch (pNeighborRoamInfo->neighborRoamState) {
+	case eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING:
+		/*
+		 * Stop scan and neighbor refresh timers.
+		 * These are indeed not required when we'r in reassoc state.
+		 */
+		if (!CSR_IS_ROAM_SUBSTATE_DISASSOC_HO(pMac, sessionId)) {
+			/*
+			 * Disconnect indication during Disassoc Handoff
+			 * sub-state is received when we are trying to
+			 * disconnect with the old AP during roam.
+			 * BUT, if receive a disconnect indication outside of
+			 * Disassoc Handoff sub-state, then it means that
+			 * this is a genuine disconnect and we need to clean up.
+			 * Otherwise, we will be stuck in reassoc state which'll
+			 * in-turn block scans.
+			 */
+			CSR_NEIGHBOR_ROAM_STATE_TRANSITION
+				(pMac, eCSR_NEIGHBOR_ROAM_STATE_INIT,
+				sessionId);
+			pNeighborRoamInfo->roamChannelInfo.
+				IAPPNeighborListReceived = false;
+		}
+		break;
+
+	case eCSR_NEIGHBOR_ROAM_STATE_INIT:
+		csr_neighbor_roam_reset_init_state_control_info(pMac,
+				sessionId);
+		break;
+
+	case eCSR_NEIGHBOR_ROAM_STATE_CONNECTED:
+		CSR_NEIGHBOR_ROAM_STATE_TRANSITION(
+				pMac, eCSR_NEIGHBOR_ROAM_STATE_INIT, sessionId)
+		pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived =
+				false;
+		csr_neighbor_roam_reset_connected_state_control_info(pMac,
+				sessionId);
+		break;
+
+	case eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE:
+		/* Stop pre-auth to reassoc interval timer */
+		cdf_mc_timer_stop(&pSession->ftSmeContext.
+				preAuthReassocIntvlTimer);
+	case eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING:
+		CSR_NEIGHBOR_ROAM_STATE_TRANSITION(
+				pMac, eCSR_NEIGHBOR_ROAM_STATE_INIT, sessionId)
+		pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived =
+				false;
+		csr_neighbor_roam_reset_preauth_control_info(pMac, sessionId);
+		csr_neighbor_roam_reset_report_scan_state_control_info(pMac,
+				sessionId);
+		break;
+	default:
+		NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("Received disconnect event"
+				"in state %s "),
+				mac_trace_get_neighbour_roam_state(
+					pNeighborRoamInfo->neighborRoamState));
+		NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("Transit to INIT state"));
+		CSR_NEIGHBOR_ROAM_STATE_TRANSITION
+			(pMac, eCSR_NEIGHBOR_ROAM_STATE_INIT, sessionId)
+			pNeighborRoamInfo->roamChannelInfo.
+			IAPPNeighborListReceived = false;
+		break;
+	}
+	/*Inform the Firmware to STOP Scanning as the host has a disconnect. */
+	if (csr_roam_is_sta_mode(pMac, sessionId)) {
+		csr_roam_offload_scan(pMac, sessionId, ROAM_SCAN_OFFLOAD_STOP,
+				REASON_DISCONNECTED);
+	}
+
+	return CDF_STATUS_SUCCESS;
+}
+
+/**
+ * csr_neighbor_roam_info_ctx_init() - Initialize neighbor roam struct
+ * @pMac: mac context
+ * @session_id: Session Id
+ *
+ * This initializes all the necessary data structures related to the
+ * associated AP.
+ *
+ * Return: CDF status
+ */
+static void csr_neighbor_roam_info_ctx_init(
+		tpAniSirGlobal pMac,
+		uint8_t session_id)
+{
+	tpCsrNeighborRoamControlInfo ngbr_roam_info =
+		&pMac->roam.neighborRoamInfo[session_id];
+	tCsrRoamSession *session = &pMac->roam.roamSession[session_id];
+
+#if  defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
+	int init_ft_flag = false;
+#endif
+
+#ifdef FEATURE_WLAN_LFR
+	/*
+	 * Initialize the occupied list ONLY if we are
+	 * transitioning from INIT state to CONNECTED state.
+	 */
+	if (eCSR_NEIGHBOR_ROAM_STATE_INIT ==
+		ngbr_roam_info->neighborRoamState)
+		csr_init_occupied_channels_list(pMac, session_id);
+#endif
+	CSR_NEIGHBOR_ROAM_STATE_TRANSITION
+		(pMac, eCSR_NEIGHBOR_ROAM_STATE_CONNECTED, session_id);
+
+	cdf_copy_macaddr(&ngbr_roam_info->currAPbssid,
+			&session->connectedProfile.bssid);
+	ngbr_roam_info->currAPoperationChannel =
+		session->connectedProfile.operationChannel;
+	ngbr_roam_info->currentNeighborLookupThreshold =
+		ngbr_roam_info->cfgParams.neighborLookupThreshold;
+	ngbr_roam_info->currentOpportunisticThresholdDiff =
+		ngbr_roam_info->cfgParams.nOpportunisticThresholdDiff;
+	ngbr_roam_info->currentRoamRescanRssiDiff =
+		ngbr_roam_info->cfgParams.nRoamRescanRssiDiff;
+	ngbr_roam_info->currentRoamBmissFirstBcnt =
+		ngbr_roam_info->cfgParams.nRoamBmissFirstBcnt;
+	ngbr_roam_info->currentRoamBmissFinalBcnt =
+		ngbr_roam_info->cfgParams.nRoamBmissFinalBcnt;
+	ngbr_roam_info->currentRoamBeaconRssiWeight =
+		ngbr_roam_info->cfgParams.nRoamBeaconRssiWeight;
+
+#if  defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
+	/**
+	 * Now we can clear the preauthDone that
+	 * was saved as we are connected afresh */
+	csr_neighbor_roam_free_roamable_bss_list(pMac,
+		&ngbr_roam_info->FTRoamInfo.preAuthDoneList);
+#endif
+
+#ifdef WLAN_FEATURE_VOWIFI_11R
+	/* Based on the auth scheme tell if we are 11r */
+	if (csr_is_auth_type11r
+		(session->connectedProfile.AuthType,
+		session->connectedProfile.MDID.mdiePresent)) {
+		if (pMac->roam.configParam.isFastTransitionEnabled)
+			init_ft_flag = true;
+		ngbr_roam_info->is11rAssoc = true;
+	} else
+		ngbr_roam_info->is11rAssoc = false;
+	NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("11rAssoc is = %d"),
+		ngbr_roam_info->is11rAssoc);
+#endif
+
+#ifdef FEATURE_WLAN_ESE
+	/* Based on the auth scheme tell if we are 11r */
+	if (session->connectedProfile.isESEAssoc) {
+		if (pMac->roam.configParam.isFastTransitionEnabled)
+			init_ft_flag = true;
+		ngbr_roam_info->isESEAssoc = true;
+	} else
+		ngbr_roam_info->isESEAssoc = false;
+	NEIGHBOR_ROAM_DEBUG(pMac, LOG2,
+		FL("isESEAssoc is = %d ft = %d"),
+		ngbr_roam_info->isESEAssoc, init_ft_flag);
+#endif
+#ifdef FEATURE_WLAN_LFR
+	/* If "Legacy Fast Roaming" is enabled */
+	if (csr_roam_is_fast_roam_enabled(pMac, session_id))
+		init_ft_flag = true;
+#endif
+#if  defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
+	if (init_ft_flag == false)
+		return;
+	/* Initialize all the data structures needed for the 11r FT Preauth */
+	ngbr_roam_info->FTRoamInfo.currentNeighborRptRetryNum = 0;
+	csr_neighbor_roam_purge_preauth_failed_list(pMac);
+	if (!cds_is_multiple_active_sta_sessions() &&
+		csr_roam_is_roam_offload_scan_enabled(pMac)) {
+		/*
+		 * If this is not a INFRA type BSS, then do not send the command
+		 * down to firmware.Do not send the START command for
+		 * other session connections.*/
+		if (!csr_roam_is_sta_mode(pMac, session_id)) {
+			CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
+				"Wrong Mode %d",
+				session->connectedProfile.BSSType);
+			return;
+		}
+		ngbr_roam_info->uOsRequestedHandoff = 0;
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+		if (session->roamOffloadSynchParams.bRoamSynchInProgress) {
+			if (pMac->roam.pReassocResp != NULL) {
+				CDF_TRACE(CDF_MODULE_ID_SME,
+					CDF_TRACE_LEVEL_DEBUG,
+					"Free Reassoc Rsp");
+				cdf_mem_free(pMac->roam.pReassocResp);
+				pMac->roam.pReassocResp = NULL;
+			}
+			CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
+				"LFR3:Send SynchCnf auth, authenticated");
+			csr_roam_offload_send_synch_cnf(pMac, session_id);
+		} else
+#endif
+			csr_roam_offload_scan(pMac, session_id,
+				ROAM_SCAN_OFFLOAD_START,
+				REASON_CONNECT);
+	}
+#endif
+}
+
+/**
+ * csr_neighbor_roam_indicate_connect()
+ * @pMac: mac context
+ * @session_id: Session Id
+ * @cdf_status: CDF status
+ *
+ * This function is called by CSR as soon as the station connects to an AP.
+ * This initializes all the necessary data structures related to the
+ * associated AP and transitions the state to CONNECTED state
+ *
+ * Return: CDF status
+ */
+CDF_STATUS csr_neighbor_roam_indicate_connect(
+		tpAniSirGlobal pMac, uint8_t session_id,
+		CDF_STATUS cdf_status)
+{
+	tpCsrNeighborRoamControlInfo ngbr_roam_info =
+		&pMac->roam.neighborRoamInfo[session_id];
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	tCsrRoamInfo roamInfo;
+	tCsrRoamSession *session = &pMac->roam.roamSession[session_id];
+	tpSirSetActiveModeSetBncFilterReq msg;
+#endif
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+
+	/* if session id invalid then we need return failure */
+	if (NULL == ngbr_roam_info || !CSR_IS_SESSION_VALID(pMac, session_id)
+	|| (NULL == pMac->roam.roamSession[session_id].pCurRoamProfile)) {
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	sms_log(pMac, LOG2,
+		FL("Connect ind. received with session id %d in state %s"),
+		session_id, mac_trace_get_neighbour_roam_state(
+			ngbr_roam_info->neighborRoamState));
+
+	/* Bail out if this is NOT a STA persona */
+	if (pMac->roam.roamSession[session_id].pCurRoamProfile->csrPersona !=
+	CDF_STA_MODE) {
+		sms_log(pMac, LOGE,
+			FL("Ignoring Connect ind received from a non STA."
+			"session_id: %d, csrPersonna %d"), session_id,
+			(int)session->pCurRoamProfile->csrPersona);
+		return CDF_STATUS_SUCCESS;
+	}
+	/* if a concurrent session is running */
+	if ((false ==
+		CSR_IS_FASTROAM_IN_CONCURRENCY_INI_FEATURE_ENABLED(pMac)) &&
+		(csr_is_concurrent_session_running(pMac))) {
+		sms_log(pMac, LOGE,
+			FL("Ignoring Connect ind. received in multisession %d"),
+			csr_is_concurrent_session_running(pMac));
+		return CDF_STATUS_SUCCESS;
+	}
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	if (session->roamOffloadSynchParams.bRoamSynchInProgress &&
+		(eSIR_ROAM_AUTH_STATUS_AUTHENTICATED ==
+		session->roamOffloadSynchParams.authStatus)) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
+			"LFR3:csr_neighbor_roam_indicate_connect");
+		msg = cdf_mem_malloc(sizeof(tSirSetActiveModeSetBncFilterReq));
+		if (msg == NULL) {
+			CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+				"LFR3:Mem Alloc failed for beacon Filter Req");
+			return CDF_STATUS_E_NOMEM;
+		}
+		msg->messageType = eWNI_SME_SET_BCN_FILTER_REQ;
+		msg->length = sizeof(uint8_t);
+		msg->seesionId = session_id;
+		status = cds_send_mb_message_to_mac(msg);
+		cdf_copy_macaddr(&roamInfo.peerMac,
+			&session->connectedProfile.bssid);
+		roamInfo.roamSynchInProgress =
+			session->roamOffloadSynchParams.bRoamSynchInProgress;
+		csr_roam_call_callback(pMac, session_id, &roamInfo, 0,
+			eCSR_ROAM_SET_KEY_COMPLETE,
+			eCSR_ROAM_RESULT_AUTHENTICATED);
+	}
+#endif
+
+	switch (ngbr_roam_info->neighborRoamState) {
+	case eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING:
+		if (CDF_STATUS_SUCCESS != cdf_status) {
+			/**
+			 * Just transition the state to INIT state.Rest of the
+			 * clean up happens when we get next connect indication
+			 */
+			CSR_NEIGHBOR_ROAM_STATE_TRANSITION(
+				pMac, eCSR_NEIGHBOR_ROAM_STATE_INIT,
+				session_id)
+			ngbr_roam_info->roamChannelInfo.IAPPNeighborListReceived =
+				false;
+			break;
+		}
+	/* Fall through if the status is SUCCESS */
+	case eCSR_NEIGHBOR_ROAM_STATE_INIT:
+		/* Reset all the data structures here */
+		csr_neighbor_roam_reset_init_state_control_info(pMac,
+			session_id);
+		csr_neighbor_roam_info_ctx_init(pMac, session_id);
+		break;
+	default:
+		sms_log(pMac, LOGE,
+			FL("Connect evt received in invalid state %s Ignoring"),
+			mac_trace_get_neighbour_roam_state(
+			ngbr_roam_info->neighborRoamState));
+		break;
+	}
+	return status;
+}
+
+#ifdef WLAN_FEATURE_VOWIFI_11R
+/* ---------------------------------------------------------------------------
+
+    \fn csr_neighbor_roam_purge_preauth_failed_list
+
+    \brief  This function purges all the MAC addresses in the pre-auth fail list
+
+    \param  pMac - The handle returned by mac_open.
+
+    \return VOID
+
+   ---------------------------------------------------------------------------*/
+void csr_neighbor_roam_purge_preauth_failed_list(tpAniSirGlobal pMac)
+{
+	uint8_t i, j;
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL;
+
+	for (j = 0; j < CSR_ROAM_SESSION_MAX; j++) {
+		pNeighborRoamInfo = &pMac->roam.neighborRoamInfo[j];
+		for (i = 0;
+		     i <
+		     pNeighborRoamInfo->FTRoamInfo.preAuthFailList.
+		     numMACAddress; i++) {
+			cdf_mem_zero(pNeighborRoamInfo->FTRoamInfo.
+				     preAuthFailList.macAddress[i],
+				     sizeof(tSirMacAddr));
+		}
+		pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress = 0;
+	}
+}
+
+/* ---------------------------------------------------------------------------
+
+    \fn csr_neighbor_roam_init11r_assoc_info
+
+    \brief  This function initializes 11r related neighbor roam data structures
+
+    \param  pMac - The handle returned by mac_open.
+
+    \return CDF_STATUS_SUCCESS on success, corresponding error code otherwise
+
+   ---------------------------------------------------------------------------*/
+CDF_STATUS csr_neighbor_roam_init11r_assoc_info(tpAniSirGlobal pMac)
+{
+	CDF_STATUS status;
+	uint8_t i;
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL;
+	tpCsr11rAssocNeighborInfo pFTRoamInfo = NULL;
+
+	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
+		pNeighborRoamInfo = &pMac->roam.neighborRoamInfo[i];
+		pFTRoamInfo = &pNeighborRoamInfo->FTRoamInfo;
+
+		pNeighborRoamInfo->is11rAssoc = false;
+		pNeighborRoamInfo->cfgParams.maxNeighborRetries =
+			pMac->roam.configParam.neighborRoamConfig.
+			nMaxNeighborRetries;
+
+		pFTRoamInfo->neighborReportTimeout =
+			CSR_NEIGHBOR_ROAM_REPORT_QUERY_TIMEOUT;
+		pFTRoamInfo->PEPreauthRespTimeout =
+			CSR_NEIGHBOR_ROAM_PREAUTH_RSP_WAIT_MULTIPLIER *
+			pNeighborRoamInfo->cfgParams.neighborScanPeriod;
+		pFTRoamInfo->neighborRptPending = false;
+		pFTRoamInfo->preauthRspPending = false;
+
+		pFTRoamInfo->currentNeighborRptRetryNum = 0;
+		pFTRoamInfo->numBssFromNeighborReport = 0;
+
+		cdf_mem_zero(pFTRoamInfo->neighboReportBssInfo,
+			     sizeof(tCsrNeighborReportBssInfo) *
+			     MAX_BSS_IN_NEIGHBOR_RPT);
+
+		status = csr_ll_open(pMac->hHdd, &pFTRoamInfo->preAuthDoneList);
+		if (CDF_STATUS_SUCCESS != status) {
+			sms_log(pMac, LOGE,
+				FL("LL Open of preauth done AP List failed"));
+			return CDF_STATUS_E_RESOURCES;
+		}
+	}
+	return status;
+}
+#endif /* WLAN_FEATURE_VOWIFI_11R */
+
+/* ---------------------------------------------------------------------------
+
+    \fn csr_neighbor_roam_init
+
+    \brief  This function initializes neighbor roam data structures
+
+    \param  pMac - The handle returned by mac_open.
+
+    \return CDF_STATUS_SUCCESS on success, corresponding error code otherwise
+
+   ---------------------------------------------------------------------------*/
+CDF_STATUS csr_neighbor_roam_init(tpAniSirGlobal pMac, uint8_t sessionId)
+{
+	CDF_STATUS status;
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+		&pMac->roam.neighborRoamInfo[sessionId];
+
+	pNeighborRoamInfo->neighborRoamState = eCSR_NEIGHBOR_ROAM_STATE_CLOSED;
+	pNeighborRoamInfo->prevNeighborRoamState =
+		eCSR_NEIGHBOR_ROAM_STATE_CLOSED;
+	pNeighborRoamInfo->cfgParams.maxChannelScanTime =
+		pMac->roam.configParam.neighborRoamConfig.nNeighborScanMaxChanTime;
+	pNeighborRoamInfo->cfgParams.minChannelScanTime =
+		pMac->roam.configParam.neighborRoamConfig.nNeighborScanMinChanTime;
+	pNeighborRoamInfo->cfgParams.maxNeighborRetries = 0;
+	pNeighborRoamInfo->cfgParams.neighborLookupThreshold =
+		pMac->roam.configParam.neighborRoamConfig.
+		nNeighborLookupRssiThreshold;
+	pNeighborRoamInfo->cfgParams.delay_before_vdev_stop =
+		pMac->roam.configParam.neighborRoamConfig.
+		delay_before_vdev_stop;
+	pNeighborRoamInfo->cfgParams.nOpportunisticThresholdDiff =
+		pMac->roam.configParam.neighborRoamConfig.
+		nOpportunisticThresholdDiff;
+	pNeighborRoamInfo->cfgParams.nRoamRescanRssiDiff =
+		pMac->roam.configParam.neighborRoamConfig.nRoamRescanRssiDiff;
+	pNeighborRoamInfo->cfgParams.nRoamBmissFirstBcnt =
+		pMac->roam.configParam.neighborRoamConfig.nRoamBmissFirstBcnt;
+	pNeighborRoamInfo->cfgParams.nRoamBmissFinalBcnt =
+		pMac->roam.configParam.neighborRoamConfig.nRoamBmissFinalBcnt;
+	pNeighborRoamInfo->cfgParams.nRoamBeaconRssiWeight =
+		pMac->roam.configParam.neighborRoamConfig.nRoamBeaconRssiWeight;
+	pNeighborRoamInfo->cfgParams.neighborScanPeriod =
+		pMac->roam.configParam.neighborRoamConfig.nNeighborScanTimerPeriod;
+	pNeighborRoamInfo->cfgParams.neighborResultsRefreshPeriod =
+		pMac->roam.configParam.neighborRoamConfig.
+		nNeighborResultsRefreshPeriod;
+	pNeighborRoamInfo->cfgParams.emptyScanRefreshPeriod =
+		pMac->roam.configParam.neighborRoamConfig.nEmptyScanRefreshPeriod;
+
+	pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels =
+		pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.
+		numChannels;
+
+	pNeighborRoamInfo->cfgParams.channelInfo.ChannelList =
+		cdf_mem_malloc(pMac->roam.configParam.neighborRoamConfig.
+			       neighborScanChanList.numChannels);
+
+	if (NULL == pNeighborRoamInfo->cfgParams.channelInfo.ChannelList) {
+		sms_log(pMac, LOGE,
+			FL("Memory Allocation for CFG Channel List failed"));
+		return CDF_STATUS_E_NOMEM;
+	}
+
+	/* Update the roam global structure from CFG */
+	cdf_mem_copy(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList,
+		     pMac->roam.configParam.neighborRoamConfig.
+		     neighborScanChanList.channelList,
+		     pMac->roam.configParam.neighborRoamConfig.
+		     neighborScanChanList.numChannels);
+	pNeighborRoamInfo->cfgParams.hi_rssi_scan_max_count =
+		pMac->roam.configParam.neighborRoamConfig.
+			nhi_rssi_scan_max_count;
+	pNeighborRoamInfo->cfgParams.hi_rssi_scan_rssi_delta =
+		pMac->roam.configParam.neighborRoamConfig.
+			nhi_rssi_scan_rssi_delta;
+	pNeighborRoamInfo->cfgParams.hi_rssi_scan_delay =
+		pMac->roam.configParam.neighborRoamConfig.
+			nhi_rssi_scan_delay;
+	pNeighborRoamInfo->cfgParams.hi_rssi_scan_rssi_ub =
+		pMac->roam.configParam.neighborRoamConfig.
+			nhi_rssi_scan_rssi_ub;
+
+	cdf_zero_macaddr(&pNeighborRoamInfo->currAPbssid);
+	pNeighborRoamInfo->currentNeighborLookupThreshold =
+		pNeighborRoamInfo->cfgParams.neighborLookupThreshold;
+	pNeighborRoamInfo->currentOpportunisticThresholdDiff =
+		pNeighborRoamInfo->cfgParams.nOpportunisticThresholdDiff;
+	pNeighborRoamInfo->currentRoamRescanRssiDiff =
+		pNeighborRoamInfo->cfgParams.nRoamRescanRssiDiff;
+	pNeighborRoamInfo->currentRoamBmissFirstBcnt =
+		pNeighborRoamInfo->cfgParams.nRoamBmissFirstBcnt;
+	pNeighborRoamInfo->currentRoamBmissFinalBcnt =
+		pNeighborRoamInfo->cfgParams.nRoamBmissFinalBcnt;
+	pNeighborRoamInfo->currentRoamBeaconRssiWeight =
+		pNeighborRoamInfo->cfgParams.nRoamBeaconRssiWeight;
+#ifdef FEATURE_WLAN_LFR
+	cdf_mem_set(&pNeighborRoamInfo->prevConnProfile,
+		    sizeof(tCsrRoamConnectedProfile), 0);
+#endif
+
+	status = csr_ll_open(pMac->hHdd, &pNeighborRoamInfo->roamableAPList);
+	if (CDF_STATUS_SUCCESS != status) {
+		sms_log(pMac, LOGE, FL("LL Open of roam able AP List failed"));
+		cdf_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.
+			     ChannelList);
+		pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL;
+		return CDF_STATUS_E_RESOURCES;
+	}
+
+	pNeighborRoamInfo->roamChannelInfo.currentChanIndex =
+		CSR_NEIGHBOR_ROAM_INVALID_CHANNEL_INDEX;
+	pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.
+	numOfChannels = 0;
+	pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList =
+		NULL;
+	pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = false;
+
+#ifdef WLAN_FEATURE_VOWIFI_11R
+	status = csr_neighbor_roam_init11r_assoc_info(pMac);
+	if (CDF_STATUS_SUCCESS != status) {
+		sms_log(pMac, LOGE, FL("LL Open of roam able AP List failed"));
+		cdf_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.
+			     ChannelList);
+		pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL;
+		csr_ll_close(&pNeighborRoamInfo->roamableAPList);
+		return CDF_STATUS_E_RESOURCES;
+	}
+#endif
+
+	CSR_NEIGHBOR_ROAM_STATE_TRANSITION(pMac, eCSR_NEIGHBOR_ROAM_STATE_INIT,
+					   sessionId)
+	pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = false;
+	/* Set the Last Sent Cmd as RSO_STOP */
+	pNeighborRoamInfo->last_sent_cmd = ROAM_SCAN_OFFLOAD_STOP;
+	return CDF_STATUS_SUCCESS;
+}
+
+/* ---------------------------------------------------------------------------
+
+    \fn csr_neighbor_roam_close
+
+    \brief  This function closes/frees all the neighbor roam data structures
+
+    \param  pMac - The handle returned by mac_open.
+    \param  sessionId - Session identifier
+    \return VOID
+
+   ---------------------------------------------------------------------------*/
+void csr_neighbor_roam_close(tpAniSirGlobal pMac, uint8_t sessionId)
+{
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+		&pMac->roam.neighborRoamInfo[sessionId];
+
+	if (eCSR_NEIGHBOR_ROAM_STATE_CLOSED ==
+	    pNeighborRoamInfo->neighborRoamState) {
+		sms_log(pMac, LOGW,
+			FL("Neighbor Roam Algorithm Already Closed"));
+		return;
+	}
+
+	if (pNeighborRoamInfo->cfgParams.channelInfo.ChannelList)
+		cdf_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.
+			     ChannelList);
+
+	pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL;
+
+	/* Should free up the nodes in the list before closing the double Linked list */
+	csr_neighbor_roam_free_roamable_bss_list(pMac,
+						 &pNeighborRoamInfo->roamableAPList);
+	csr_ll_close(&pNeighborRoamInfo->roamableAPList);
+
+	if (pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.
+	    ChannelList) {
+		cdf_mem_free(pNeighborRoamInfo->roamChannelInfo.
+			     currentChannelListInfo.ChannelList);
+	}
+
+	pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList =
+		NULL;
+	pNeighborRoamInfo->roamChannelInfo.currentChanIndex =
+		CSR_NEIGHBOR_ROAM_INVALID_CHANNEL_INDEX;
+	pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.
+	numOfChannels = 0;
+	pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList =
+		NULL;
+	pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = false;
+
+	/* Free the profile.. */
+	csr_release_profile(pMac, &pNeighborRoamInfo->csrNeighborRoamProfile);
+#ifdef FEATURE_WLAN_LFR
+	csr_roam_free_connect_profile(pMac, &pNeighborRoamInfo->prevConnProfile);
+#endif
+#ifdef WLAN_FEATURE_VOWIFI_11R
+	pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum = 0;
+	pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport = 0;
+	cdf_mem_zero(pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo,
+		     sizeof(tCsrNeighborReportBssInfo) *
+		     MAX_BSS_IN_NEIGHBOR_RPT);
+	csr_neighbor_roam_free_roamable_bss_list(pMac,
+						 &pNeighborRoamInfo->FTRoamInfo.
+						 preAuthDoneList);
+	csr_ll_close(&pNeighborRoamInfo->FTRoamInfo.preAuthDoneList);
+#endif /* WLAN_FEATURE_VOWIFI_11R */
+
+	CSR_NEIGHBOR_ROAM_STATE_TRANSITION(pMac,
+		eCSR_NEIGHBOR_ROAM_STATE_CLOSED, sessionId)
+
+	return;
+}
+
+/**
+ * csr_neighbor_roam_request_handoff() - Handoff to a different AP
+ * @mac_ctx: Pointer to Global MAC structure
+ * @session_id: Session ID
+ *
+ * This function triggers actual switching from one AP to the new AP.
+ * It issues disassociate with reason code as Handoff and CSR as a part of
+ * handling disassoc rsp, issues reassociate to the new AP
+ *
+ * Return: none
+ */
+void csr_neighbor_roam_request_handoff(tpAniSirGlobal mac_ctx,
+		uint8_t session_id)
+{
+	tCsrRoamInfo roam_info;
+	tpCsrNeighborRoamControlInfo neighbor_roam_info =
+		&mac_ctx->roam.neighborRoamInfo[session_id];
+	tCsrNeighborRoamBSSInfo handoff_node;
+	uint32_t roamid = 0;
+	CDF_STATUS status;
+
+	CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG, "%s session_id=%d",
+		  __func__, session_id);
+
+	if (neighbor_roam_info->neighborRoamState !=
+		eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE) {
+		sms_log(mac_ctx, LOGE,
+			FL("Roam requested when Neighbor roam is in %s state"),
+			mac_trace_get_neighbour_roam_state(
+			neighbor_roam_info->neighborRoamState));
+		return;
+	}
+
+	if (false == csr_neighbor_roam_get_handoff_ap_info(mac_ctx,
+			&handoff_node, session_id)) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+		FL("failed to obtain handoff AP"));
+		return;
+	}
+	CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
+		  FL("HANDOFF CANDIDATE BSSID "MAC_ADDRESS_STR),
+		  MAC_ADDR_ARRAY(handoff_node.pBssDescription->bssId));
+
+	cdf_mem_zero(&roam_info, sizeof(tCsrRoamInfo));
+	csr_roam_call_callback(mac_ctx, session_id, &roam_info, roamid,
+			       eCSR_ROAM_FT_START, eSIR_SME_SUCCESS);
+
+	cdf_mem_zero(&roam_info, sizeof(tCsrRoamInfo));
+	CSR_NEIGHBOR_ROAM_STATE_TRANSITION
+		(mac_ctx, eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING, session_id)
+
+	csr_neighbor_roam_send_lfr_metric_event(mac_ctx, session_id,
+		handoff_node.pBssDescription->bssId,
+		eCSR_ROAM_HANDOVER_SUCCESS);
+	/* Free the profile.. Just to make sure we dont leak memory here */
+	csr_release_profile(mac_ctx,
+		&neighbor_roam_info->csrNeighborRoamProfile);
+	/*
+	 * Create the Handoff AP profile. Copy the currently connected profile
+	 * and update only the BSSID and channel number. This should happen
+	 * before issuing disconnect
+	 */
+	status = csr_roam_copy_connected_profile(mac_ctx, session_id,
+			&neighbor_roam_info->csrNeighborRoamProfile);
+	if (CDF_STATUS_SUCCESS != status) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+			FL("csr_roam_copy_connected_profile failed %d"),
+			status);
+		return;
+	}
+	cdf_mem_copy(neighbor_roam_info->csrNeighborRoamProfile.BSSIDs.bssid,
+		     handoff_node.pBssDescription->bssId, sizeof(tSirMacAddr));
+	neighbor_roam_info->csrNeighborRoamProfile.ChannelInfo.ChannelList[0] =
+		handoff_node.pBssDescription->channelId;
+
+	NEIGHBOR_ROAM_DEBUG(mac_ctx, LOGW,
+		" csr_roamHandoffRequested: disassociating with current AP");
+
+	if (!CDF_IS_STATUS_SUCCESS
+		    (csr_roam_issue_disassociate_cmd
+			    (mac_ctx, session_id,
+			    eCSR_DISCONNECT_REASON_HANDOFF))) {
+		sms_log(mac_ctx, LOGW,
+			"csr_roamHandoffRequested:  fail to issue disassociate");
+		return;
+	}
+	/* notify HDD for handoff, providing the BSSID too */
+	roam_info.reasonCode = eCsrRoamReasonBetterAP;
+
+	cdf_mem_copy(roam_info.bssid.bytes,
+		     handoff_node.pBssDescription->bssId,
+		     sizeof(struct cdf_mac_addr));
+
+	csr_roam_call_callback(mac_ctx, session_id, &roam_info, 0,
+			       eCSR_ROAM_ROAMING_START, eCSR_ROAM_RESULT_NONE);
+
+	return;
+}
+
+/**
+ * csr_neighbor_roam_is_handoff_in_progress()
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @session_id: Session ID
+ *
+ * This function returns whether handoff is in progress or not based on
+ * the current neighbor roam state
+ *
+ * Return: true if reassoc in progress, false otherwise
+ */
+bool csr_neighbor_roam_is_handoff_in_progress(tpAniSirGlobal pMac, uint8_t sessionId)
+{
+	if (eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING ==
+	    pMac->roam.neighborRoamInfo[sessionId].neighborRoamState)
+		return true;
+
+	return false;
+}
+
+#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(WLAN_FEATURE_NEIGHBOR_ROAMING)
+/* ---------------------------------------------------------------------------
+
+    \fn csr_neighbor_roam_is11r_assoc
+
+    \brief  This function returns whether the current association is a 11r assoc or not
+
+    \param  pMac - The handle returned by mac_open.
+
+    \return true if current assoc is 11r, false otherwise
+
+   ---------------------------------------------------------------------------*/
+bool csr_neighbor_roam_is11r_assoc(tpAniSirGlobal pMac, uint8_t sessionId)
+{
+	return pMac->roam.neighborRoamInfo[sessionId].is11rAssoc;
+}
+#endif /* WLAN_FEATURE_VOWIFI_11R */
+
+/**
+ * csr_neighbor_roam_get_handoff_ap_info - Identifies the best AP for roaming
+ *
+ * @pMac:        mac context
+ * @session_id:     Session Id
+ * @hand_off_node:    AP node that is the handoff candidate returned
+ *
+ * This function returns the best possible AP for handoff. For 11R case, it
+ * returns the 1st entry from pre-auth done list. For non-11r case, it returns
+ * the 1st entry from roamable AP list
+ *
+ * Return: true if able find handoff AP, false otherwise
+ */
+
+bool csr_neighbor_roam_get_handoff_ap_info(tpAniSirGlobal pMac,
+			tpCsrNeighborRoamBSSInfo hand_off_node,
+			uint8_t session_id)
+{
+	tpCsrNeighborRoamControlInfo ngbr_roam_info =
+		&pMac->roam.neighborRoamInfo[session_id];
+	tpCsrNeighborRoamBSSInfo bss_node = NULL;
+
+	if (NULL == hand_off_node) {
+		CDF_ASSERT(NULL != hand_off_node);
+		return false;
+	}
+#ifdef WLAN_FEATURE_VOWIFI_11R
+	if (ngbr_roam_info->is11rAssoc) {
+		/* Always the BSS info in the head is the handoff candidate */
+		bss_node = csr_neighbor_roam_next_roamable_ap(
+			pMac,
+			&ngbr_roam_info->FTRoamInfo.preAuthDoneList,
+			NULL);
+		NEIGHBOR_ROAM_DEBUG(pMac, LOG1,
+			FL("Number of Handoff candidates = %d"),
+			csr_ll_count(&
+				ngbr_roam_info->FTRoamInfo.preAuthDoneList));
+	} else
+#endif
+#ifdef FEATURE_WLAN_ESE
+	if (ngbr_roam_info->isESEAssoc) {
+		/* Always the BSS info in the head is the handoff candidate */
+		bss_node =
+			csr_neighbor_roam_next_roamable_ap(pMac,
+				&ngbr_roam_info->FTRoamInfo.preAuthDoneList,
+				NULL);
+		NEIGHBOR_ROAM_DEBUG(pMac, LOG1,
+			FL("Number of Handoff candidates = %d"),
+			csr_ll_count(&ngbr_roam_info->FTRoamInfo.
+			preAuthDoneList));
+	} else
+#endif
+#ifdef FEATURE_WLAN_LFR
+	if (csr_roam_is_fast_roam_enabled(pMac, session_id)) {
+		/* Always the BSS info in the head is the handoff candidate */
+		bss_node =
+			csr_neighbor_roam_next_roamable_ap(pMac,
+			&ngbr_roam_info->FTRoamInfo.preAuthDoneList,
+			NULL);
+		NEIGHBOR_ROAM_DEBUG(pMac, LOG1,
+			FL("Number of Handoff candidates = %d"),
+			csr_ll_count(
+				&ngbr_roam_info->FTRoamInfo.preAuthDoneList));
+	} else
+#endif
+	{
+		bss_node =
+			csr_neighbor_roam_next_roamable_ap(pMac,
+				&ngbr_roam_info->roamableAPList,
+				NULL);
+		NEIGHBOR_ROAM_DEBUG(pMac, LOG1,
+			FL("Number of Handoff candidates = %d"),
+			csr_ll_count(&ngbr_roam_info->roamableAPList));
+	}
+	if (NULL == bss_node)
+		return false;
+	cdf_mem_copy(hand_off_node, bss_node, sizeof(tCsrNeighborRoamBSSInfo));
+	return true;
+}
+
+/* ---------------------------------------------------------------------------
+    \brief  This function returns true if preauth is completed
+
+    \param  pMac - The handle returned by mac_open.
+
+    \return bool
+
+   ---------------------------------------------------------------------------*/
+bool csr_neighbor_roam_state_preauth_done(tpAniSirGlobal pMac, uint8_t sessionId)
+{
+	return pMac->roam.neighborRoamInfo[sessionId].neighborRoamState ==
+		eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE;
+}
+
+/* ---------------------------------------------------------------------------
+    \brief  In the event that we are associated with AP1 and we have
+    completed pre auth with AP2. Then we receive a deauth/disassoc from
+    AP1.
+    At this point neighbor roam is in pre auth done state, pre auth timer
+    is running. We now handle this case by stopping timer and clearing
+    the pre-auth state. We basically clear up and just go to disconnected
+    state.
+
+    \param  pMac - The handle returned by mac_open.
+
+    \return bool
+   ---------------------------------------------------------------------------*/
+void csr_neighbor_roam_tranistion_preauth_done_to_disconnected(tpAniSirGlobal pMac,
+							       uint8_t sessionId)
+{
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+		&pMac->roam.neighborRoamInfo[sessionId];
+	tCsrRoamSession *session = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!session) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
+			  FL("session is NULL"));
+		return;
+	}
+
+	if (pNeighborRoamInfo->neighborRoamState !=
+	    eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE)
+		return;
+
+	/* Stop timer */
+	cdf_mc_timer_stop(&session->ftSmeContext.preAuthReassocIntvlTimer);
+
+	/* Transition to init state */
+	CSR_NEIGHBOR_ROAM_STATE_TRANSITION(pMac, eCSR_NEIGHBOR_ROAM_STATE_INIT,
+					   sessionId)
+	pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = false;
+}
+
+/* ---------------------------------------------------------------------------
+    \brief  This function returns true if STA is in the middle of roaming states
+
+    \param  halHandle - The handle from HDD context.
+    \param  sessionId - Session identifier
+
+    \return bool
+
+   ---------------------------------------------------------------------------*/
+bool csr_neighbor_middle_of_roaming(tpAniSirGlobal pMac, uint8_t sessionId)
+{
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+		&pMac->roam.neighborRoamInfo[sessionId];
+	bool val = (eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING ==
+		    pNeighborRoamInfo->neighborRoamState) ||
+		   (eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING ==
+		    pNeighborRoamInfo->neighborRoamState) ||
+		   (eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE ==
+		    pNeighborRoamInfo->neighborRoamState);
+	return val;
+}
+
+/**
+ * csr_neighbor_roam_candidate_found_ind_hdlr()
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg_buf: pointer to msg buff
+ *
+ * This function is called by CSR as soon as TL posts the candidate
+ * found indication to SME via MC thread
+ *
+ * Return: CDF_STATUS_SUCCESS on success, corresponding error code otherwise
+ */
+CDF_STATUS csr_neighbor_roam_candidate_found_ind_hdlr(tpAniSirGlobal pMac, void *pMsg)
+{
+	tSirSmeCandidateFoundInd *pSirSmeCandidateFoundInd =
+		(tSirSmeCandidateFoundInd *) pMsg;
+	uint32_t sessionId = pSirSmeCandidateFoundInd->sessionId;
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+		&pMac->roam.neighborRoamInfo[sessionId];
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+
+	sms_log(pMac, LOG1, FL("Received indication from firmware"));
+
+	/* we must be in connected state, if not ignore it */
+	if ((eCSR_NEIGHBOR_ROAM_STATE_CONNECTED !=
+	     pNeighborRoamInfo->neighborRoamState)
+	    || (pNeighborRoamInfo->uOsRequestedHandoff)) {
+		sms_log(pMac, LOGE,
+			FL
+				("Received in not CONNECTED state OR uOsRequestedHandoff is set. Ignore it"));
+		status = CDF_STATUS_E_FAILURE;
+	} else {
+		/* Firmware indicated that roaming candidate is found. Beacons
+		 * are already in the SME scan results table.
+		 * Process the results for choosing best roaming candidate.
+		 */
+		csr_save_scan_results(pMac, eCsrScanCandidateFound,
+				      sessionId);
+		/* Future enhancements:
+		 * If firmware tags candidate beacons, give them preference
+		 * for roaming.
+		 * Age out older entries so that new candidate beacons
+		 * will get preference.
+		 */
+		status = csr_neighbor_roam_process_scan_complete(pMac,
+								 sessionId);
+		if (CDF_STATUS_SUCCESS != status) {
+			sms_log(pMac, LOGE,
+				FL("Neighbor scan process complete failed with status %d"),
+				status);
+			return CDF_STATUS_E_FAILURE;
+		}
+	}
+
+	return status;
+}
+
+/**
+ * csr_neighbor_roam_process_handoff_req - Processes handoff request
+ *
+ * @mac_ctx  Pointer to mac context
+ * @session_id  SME session id
+ *
+ * This function is called start with the handoff process. First do a
+ * SSID scan for the BSSID provided.
+ *
+ * Return: status
+ */
+CDF_STATUS csr_neighbor_roam_process_handoff_req(
+			tpAniSirGlobal mac_ctx,
+			uint8_t session_id)
+{
+	tpCsrNeighborRoamControlInfo roam_ctrl_info =
+		&mac_ctx->roam.neighborRoamInfo[session_id];
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	uint32_t roam_id;
+	tCsrRoamProfile *profile = NULL;
+	tCsrRoamSession *session = CSR_GET_SESSION(mac_ctx, session_id);
+	uint8_t i = 0;
+
+	if (NULL == session) {
+		sms_log(mac_ctx, LOGE, FL("session is NULL "));
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	roam_id = GET_NEXT_ROAM_ID(&mac_ctx->roam);
+	profile = cdf_mem_malloc(sizeof(tCsrRoamProfile));
+	if (NULL == profile) {
+		sms_log(mac_ctx, LOGE, FL("Memory alloc failed"));
+		return CDF_STATUS_E_NOMEM;
+	}
+	cdf_mem_set(profile, sizeof(tCsrRoamProfile), 0);
+	status =
+		csr_roam_copy_profile(mac_ctx, profile,
+				      session->pCurRoamProfile);
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		sms_log(mac_ctx, LOGE, FL("Profile copy failed"));
+		goto end;
+	}
+	/* Add the BSSID & Channel */
+	profile->BSSIDs.numOfBSSIDs = 1;
+	if (NULL == profile->BSSIDs.bssid) {
+		profile->BSSIDs.bssid =
+			cdf_mem_malloc(sizeof(tSirMacAddr) *
+				profile->BSSIDs.numOfBSSIDs);
+		if (NULL == profile->BSSIDs.bssid) {
+			sms_log(mac_ctx, LOGE, FL("mem alloc failed for BSSID"));
+			status = CDF_STATUS_E_NOMEM;
+			goto end;
+		}
+	}
+
+	cdf_mem_zero(profile->BSSIDs.bssid,
+		sizeof(tSirMacAddr) *
+		profile->BSSIDs.numOfBSSIDs);
+
+	/* Populate the BSSID from handoff info received from HDD */
+	for (i = 0; i < profile->BSSIDs.numOfBSSIDs; i++) {
+		cdf_copy_macaddr(&profile->BSSIDs.bssid[i],
+				&roam_ctrl_info->handoffReqInfo.bssid);
+	}
+
+	profile->ChannelInfo.numOfChannels = 1;
+	if (NULL == profile->ChannelInfo.ChannelList) {
+		profile->ChannelInfo.ChannelList =
+			cdf_mem_malloc(sizeof(*profile->
+				ChannelInfo.ChannelList) *
+				profile->ChannelInfo.numOfChannels);
+		if (NULL == profile->ChannelInfo.ChannelList) {
+			sms_log(mac_ctx, LOGE,
+				FL("mem alloc failed for ChannelList"));
+			status = CDF_STATUS_E_NOMEM;
+			goto end;
+		}
+	}
+	profile->ChannelInfo.ChannelList[0] =
+		roam_ctrl_info->handoffReqInfo.channel;
+
+	/* do a SSID scan */
+	status =
+		csr_scan_for_ssid(mac_ctx, session_id, profile, roam_id, false);
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		sms_log(mac_ctx, LOGE, FL("SSID scan failed"));
+	}
+
+end:
+	if (NULL != profile) {
+		csr_release_profile(mac_ctx, profile);
+		cdf_mem_free(profile);
+	}
+
+	return status;
+}
+
+/* ---------------------------------------------------------------------------
+
+    \fn csr_neighbor_roam_sssid_scan_done
+
+    \brief  This function is called once SSID scan is done. If SSID scan failed
+    to find our candidate add an entry to csr scan cache ourself before starting
+    the handoff process
+
+    \param  pMac - The handle returned by mac_open.
+
+    \return CDF_STATUS_SUCCESS on success, corresponding error code otherwise
+
+   ---------------------------------------------------------------------------*/
+CDF_STATUS csr_neighbor_roam_sssid_scan_done(tpAniSirGlobal pMac,
+					     uint8_t sessionId, CDF_STATUS status)
+{
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+		&pMac->roam.neighborRoamInfo[sessionId];
+	CDF_STATUS hstatus;
+
+	sms_log(pMac, LOGE, FL("called "));
+
+	/* we must be in connected state, if not ignore it */
+	if (eCSR_NEIGHBOR_ROAM_STATE_CONNECTED !=
+	    pNeighborRoamInfo->neighborRoamState) {
+		sms_log(pMac, LOGE,
+			FL("Received in not CONNECTED state. Ignore it"));
+		return CDF_STATUS_E_FAILURE;
+	}
+	/* if SSID scan failed to find our candidate add an entry to csr scan cache ourself */
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		sms_log(pMac, LOGE, FL("Add an entry to csr scan cache"));
+		hstatus = csr_scan_create_entry_in_scan_cache(pMac, sessionId,
+							      pNeighborRoamInfo->
+							      handoffReqInfo.bssid,
+							      pNeighborRoamInfo->
+							      handoffReqInfo.channel);
+		if (CDF_STATUS_SUCCESS != hstatus) {
+			sms_log(pMac, LOGE,
+				FL
+					("csr_scan_create_entry_in_scan_cache failed with status %d"),
+				hstatus);
+			return CDF_STATUS_E_FAILURE;
+		}
+	}
+
+	/* Now we have completed scanning for the candidate provided by HDD. Let move on to HO */
+	hstatus = csr_neighbor_roam_process_scan_complete(pMac, sessionId);
+
+	if (CDF_STATUS_SUCCESS != hstatus) {
+		sms_log(pMac, LOGE,
+			FL
+				("Neighbor scan process complete failed with status %d"),
+			hstatus);
+		return CDF_STATUS_E_FAILURE;
+	}
+	return CDF_STATUS_SUCCESS;
+}
+
+
+/**
+ * csr_neighbor_roam_handoff_req_hdlr - Processes handoff request
+ * @mac_ctx  Pointer to mac context
+ * @msg  message sent to HDD
+ *
+ * This function is called by CSR as soon as it gets a handoff request
+ * to SME via MC thread
+ *
+ * Return: status
+ */
+CDF_STATUS csr_neighbor_roam_handoff_req_hdlr(
+			tpAniSirGlobal mac_ctx, void *msg)
+{
+	tAniHandoffReq *handoff_req = (tAniHandoffReq *) msg;
+	uint32_t session_id = handoff_req->sessionId;
+	tpCsrNeighborRoamControlInfo roam_ctrl_info =
+		&mac_ctx->roam.neighborRoamInfo[session_id];
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+
+	/* we must be in connected state, if not ignore it */
+	if (eCSR_NEIGHBOR_ROAM_STATE_CONNECTED !=
+		roam_ctrl_info->neighborRoamState) {
+		sms_log(mac_ctx, LOGE,
+			FL("Received in not CONNECTED state. Ignore it"));
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	/* save the handoff info came from HDD as part of the reassoc req */
+	handoff_req = (tAniHandoffReq *) msg;
+	if (NULL == handoff_req) {
+		sms_log(mac_ctx, LOGE, FL("Received msg is NULL"));
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	/* sanity check */
+	if (true == cdf_mem_compare(handoff_req->bssid,
+		roam_ctrl_info->currAPbssid.bytes,
+		sizeof(tSirMacAddr))) {
+		sms_log(mac_ctx, LOGE,
+			FL
+			("Received req has same BSSID as current AP!!"));
+		return CDF_STATUS_E_FAILURE;
+	}
+	roam_ctrl_info->handoffReqInfo.channel =
+		handoff_req->channel;
+	roam_ctrl_info->handoffReqInfo.src =
+		handoff_req->handoff_src;
+	cdf_mem_copy(&roam_ctrl_info->handoffReqInfo.bssid.bytes,
+			&handoff_req->bssid, CDF_MAC_ADDR_SIZE);
+	roam_ctrl_info->uOsRequestedHandoff = 1;
+	status = csr_roam_offload_scan(mac_ctx, session_id,
+		ROAM_SCAN_OFFLOAD_STOP,
+		REASON_OS_REQUESTED_ROAMING_NOW);
+	if (CDF_STATUS_SUCCESS != status) {
+		sms_log(mac_ctx, LOGE,
+			FL("csr_roam_offload_scan failed"));
+		roam_ctrl_info->uOsRequestedHandoff = 0;
+	}
+	return status;
+}
+
+/**
+ * csr_neighbor_roam_proceed_with_handoff_req()
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @session_id: Session ID
+ *
+ * This function is called by CSR as soon as it gets rsp back for
+ * ROAM_SCAN_OFFLOAD_STOP with reason REASON_OS_REQUESTED_ROAMING_NOW
+ *
+ * Return: CDF_STATUS_SUCCESS on success, corresponding error code otherwise
+ */
+CDF_STATUS csr_neighbor_roam_proceed_with_handoff_req(tpAniSirGlobal pMac,
+						      uint8_t sessionId)
+{
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+		&pMac->roam.neighborRoamInfo[sessionId];
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	/* we must be in connected state, if not ignore it */
+	if ((eCSR_NEIGHBOR_ROAM_STATE_CONNECTED !=
+	     pNeighborRoamInfo->neighborRoamState)
+	    || (!pNeighborRoamInfo->uOsRequestedHandoff)) {
+		sms_log(pMac, LOGE,
+			FL
+				("Received in not CONNECTED state or uOsRequestedHandoff is not set. Ignore it"));
+		status = CDF_STATUS_E_FAILURE;
+	} else {
+		/* Let's go ahead with handoff */
+		status = csr_neighbor_roam_process_handoff_req(pMac, sessionId);
+	}
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		pNeighborRoamInfo->uOsRequestedHandoff = 0;
+	}
+	return status;
+}
+
+/* ---------------------------------------------------------------------------
+
+    \fn csr_neighbor_roam_start_lfr_scan
+
+    \brief  This function is called if HDD requested handoff failed for some
+    reason. start the LFR logic at that point.By the time, this function is
+    called, a STOP command has already been issued.
+
+    \param  pMac - The handle returned by mac_open.
+
+    \return CDF_STATUS_SUCCESS on success, corresponding error code otherwise
+
+   ---------------------------------------------------------------------------*/
+CDF_STATUS csr_neighbor_roam_start_lfr_scan(tpAniSirGlobal pMac, uint8_t sessionId)
+{
+	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+		&pMac->roam.neighborRoamInfo[sessionId];
+	pNeighborRoamInfo->uOsRequestedHandoff = 0;
+	/* There is no candidate or We are not roaming Now.
+	 * Inform the FW to restart Roam Offload Scan  */
+	csr_roam_offload_scan(pMac, sessionId, ROAM_SCAN_OFFLOAD_START,
+			      REASON_NO_CAND_FOUND_OR_NOT_ROAMING_NOW);
+
+	return CDF_STATUS_SUCCESS;
+}
+#endif /* WLAN_FEATURE_NEIGHBOR_ROAMING */
diff --git a/core/sme/src/csr/csr_tdls_process.c b/core/sme/src/csr/csr_tdls_process.c
new file mode 100644
index 0000000..30fadcd
--- /dev/null
+++ b/core/sme/src/csr/csr_tdls_process.c
@@ -0,0 +1,820 @@
+/*
+ * Copyright (c) 2012-2015 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 csr_tdls_process.c
+
+    Implementation for the TDLS interface to PE.
+   ========================================================================== */
+
+#ifdef FEATURE_WLAN_TDLS
+
+#include "ani_global.h"          /* for tpAniSirGlobal */
+#include "cds_mq.h"
+#include "csr_inside_api.h"
+#include "sme_inside.h"
+#include "sms_debug.h"
+
+#include "csr_support.h"
+
+#include "host_diag_core_log.h"
+#include "host_diag_core_event.h"
+#include "csr_internal.h"
+
+/*
+ * common routine to remove TDLS cmd from SME command list..
+ * commands are removed after getting reponse from PE.
+ */
+CDF_STATUS csr_tdls_remove_sme_cmd(tpAniSirGlobal pMac, eSmeCommandType cmdType)
+{
+	CDF_STATUS status = CDF_STATUS_E_FAILURE;
+	tListElem *pEntry;
+	tSmeCmd *pCommand;
+
+	pEntry = csr_ll_peek_head(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK);
+	if (pEntry) {
+		pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
+		if (cmdType == pCommand->command) {
+			if (csr_ll_remove_entry(&pMac->sme.smeCmdActiveList,
+						pEntry, LL_ACCESS_LOCK)) {
+				cdf_mem_zero(&pCommand->u.tdlsCmd,
+					     sizeof(tTdlsCmd));
+				csr_release_command(pMac, pCommand);
+				sme_process_pending_queue(pMac);
+				status = CDF_STATUS_SUCCESS;
+			}
+		}
+	}
+	return status;
+}
+
+/**
+ * csr_tdls_send_mgmt_req() - to send a TDLS frame to PE through SME
+ * @hHal: HAL context
+ * @sessionId: SME session id
+ * @tdlsSendMgmt: tdls mgmt pointer
+ *
+ * TDLS request API, called from HDD to send a TDLS frame in SME/CSR and
+ * send message to PE to trigger TDLS discovery procedure.
+ */
+CDF_STATUS csr_tdls_send_mgmt_req(tHalHandle hHal, uint8_t sessionId,
+				  tCsrTdlsSendMgmt *tdlsSendMgmt)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	tSmeCmd *tdlsSendMgmtCmd;
+	tTdlsSendMgmtCmdInfo *tdlsSendMgmtCmdInfo;
+	CDF_STATUS status = CDF_STATUS_E_FAILURE;
+
+	/* If connected and in Infra. Only then allow this */
+	if (!CSR_IS_SESSION_VALID(pMac, sessionId) ||
+			!csr_is_conn_state_connected_infra(pMac, sessionId) ||
+			(NULL == tdlsSendMgmt))
+		return status;
+	tdlsSendMgmtCmd = csr_get_command_buffer(pMac);
+	if (!tdlsSendMgmtCmd)
+		return status;
+	tdlsSendMgmtCmdInfo = &tdlsSendMgmtCmd->u.tdlsCmd.u.tdlsSendMgmtCmdInfo;
+	tdlsSendMgmtCmd->sessionId = sessionId;
+	tdlsSendMgmtCmdInfo->frameType = tdlsSendMgmt->frameType;
+	tdlsSendMgmtCmdInfo->dialog = tdlsSendMgmt->dialog;
+	tdlsSendMgmtCmdInfo->statusCode = tdlsSendMgmt->statusCode;
+	tdlsSendMgmtCmdInfo->responder = tdlsSendMgmt->responder;
+	tdlsSendMgmtCmdInfo->peerCapability = tdlsSendMgmt->peerCapability;
+	cdf_mem_copy(tdlsSendMgmtCmdInfo->peerMac, tdlsSendMgmt->peerMac,
+			sizeof(tSirMacAddr));
+
+	if ((0 != tdlsSendMgmt->len) && (NULL != tdlsSendMgmt->buf)) {
+		tdlsSendMgmtCmdInfo->buf = cdf_mem_malloc(tdlsSendMgmt->len);
+		if (NULL == tdlsSendMgmtCmdInfo->buf) {
+			status = CDF_STATUS_E_NOMEM;
+			sms_log(pMac, LOGE, FL("Alloc Failed"));
+			CDF_ASSERT(0);
+			return status;
+		}
+		cdf_mem_copy(tdlsSendMgmtCmdInfo->buf, tdlsSendMgmt->buf,
+				tdlsSendMgmt->len);
+		tdlsSendMgmtCmdInfo->len = tdlsSendMgmt->len;
+	} else {
+		tdlsSendMgmtCmdInfo->buf = NULL;
+		tdlsSendMgmtCmdInfo->len = 0;
+	}
+
+	tdlsSendMgmtCmd->command = eSmeCommandTdlsSendMgmt;
+	tdlsSendMgmtCmd->u.tdlsCmd.size = sizeof(tTdlsSendMgmtCmdInfo);
+	sme_push_command(pMac, tdlsSendMgmtCmd, false);
+	status = CDF_STATUS_SUCCESS;
+	return status;
+}
+
+/*
+ * TDLS request API, called from HDD to add a TDLS peer
+ */
+CDF_STATUS csr_tdls_change_peer_sta(tHalHandle hHal, uint8_t sessionId,
+				    const tSirMacAddr peerMac,
+				    tCsrStaParams *pstaParams)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	tSmeCmd *tdlsAddStaCmd;
+	CDF_STATUS status = CDF_STATUS_E_FAILURE;
+
+	/* If connected and in Infra. Only then allow this */
+	if (CSR_IS_SESSION_VALID(pMac, sessionId) &&
+	    csr_is_conn_state_connected_infra(pMac, sessionId) &&
+	    (NULL != peerMac) && (NULL != pstaParams)) {
+
+		tdlsAddStaCmd = csr_get_command_buffer(pMac);
+
+		if (tdlsAddStaCmd) {
+			tTdlsAddStaCmdInfo *tdlsAddStaCmdInfo =
+				&tdlsAddStaCmd->u.tdlsCmd.u.tdlsAddStaCmdInfo;
+
+			tdlsAddStaCmdInfo->tdlsAddOper = TDLS_OPER_UPDATE;
+
+			tdlsAddStaCmd->sessionId = sessionId;
+
+			cdf_mem_copy(tdlsAddStaCmdInfo->peerMac,
+				     peerMac, sizeof(tSirMacAddr));
+			tdlsAddStaCmdInfo->capability = pstaParams->capability;
+			tdlsAddStaCmdInfo->uapsdQueues =
+				pstaParams->uapsd_queues;
+			tdlsAddStaCmdInfo->maxSp = pstaParams->max_sp;
+			cdf_mem_copy(tdlsAddStaCmdInfo->extnCapability,
+				     pstaParams->extn_capability,
+				     sizeof(pstaParams->extn_capability));
+
+			tdlsAddStaCmdInfo->htcap_present =
+				pstaParams->htcap_present;
+			if (pstaParams->htcap_present)
+				cdf_mem_copy(&tdlsAddStaCmdInfo->HTCap,
+					     &pstaParams->HTCap,
+					     sizeof(pstaParams->HTCap));
+			else
+				cdf_mem_set(&tdlsAddStaCmdInfo->HTCap,
+					    sizeof(pstaParams->HTCap), 0);
+
+			tdlsAddStaCmdInfo->vhtcap_present =
+				pstaParams->vhtcap_present;
+			if (pstaParams->vhtcap_present)
+				cdf_mem_copy(&tdlsAddStaCmdInfo->VHTCap,
+					     &pstaParams->VHTCap,
+					     sizeof(pstaParams->VHTCap));
+			else
+				cdf_mem_set(&tdlsAddStaCmdInfo->VHTCap,
+					    sizeof(pstaParams->VHTCap), 0);
+
+			tdlsAddStaCmdInfo->supportedRatesLen =
+				pstaParams->supported_rates_len;
+
+			if (0 != pstaParams->supported_rates_len)
+				cdf_mem_copy(&tdlsAddStaCmdInfo->supportedRates,
+					     pstaParams->supported_rates,
+					     pstaParams->supported_rates_len);
+
+			tdlsAddStaCmd->command = eSmeCommandTdlsAddPeer;
+			tdlsAddStaCmd->u.tdlsCmd.size =
+				sizeof(tTdlsAddStaCmdInfo);
+			sme_push_command(pMac, tdlsAddStaCmd, false);
+			status = CDF_STATUS_SUCCESS;
+		}
+	}
+
+	return status;
+}
+
+/*
+ * TDLS request API, called from HDD to Send Link Establishment Parameters
+ */
+CDF_STATUS csr_tdls_send_link_establish_params(tHalHandle hHal,
+					       uint8_t sessionId,
+					       const tSirMacAddr peerMac,
+					       tCsrTdlsLinkEstablishParams *
+					       tdlsLinkEstablishParams)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	tSmeCmd *tdlsLinkEstablishCmd;
+	CDF_STATUS status = CDF_STATUS_E_FAILURE;
+	/* If connected and in Infra. Only then allow this */
+	if (CSR_IS_SESSION_VALID(pMac, sessionId) &&
+	    csr_is_conn_state_connected_infra(pMac, sessionId) &&
+	    (NULL != peerMac)) {
+		tdlsLinkEstablishCmd = csr_get_command_buffer(pMac);
+
+		if (tdlsLinkEstablishCmd) {
+			tTdlsLinkEstablishCmdInfo *tdlsLinkEstablishCmdInfo =
+				&tdlsLinkEstablishCmd->u.tdlsCmd.u.
+				tdlsLinkEstablishCmdInfo;
+
+			tdlsLinkEstablishCmd->sessionId = sessionId;
+
+			cdf_mem_copy(tdlsLinkEstablishCmdInfo->peerMac,
+				     peerMac, sizeof(tSirMacAddr));
+			tdlsLinkEstablishCmdInfo->isBufSta =
+				tdlsLinkEstablishParams->isBufSta;
+			tdlsLinkEstablishCmdInfo->isResponder =
+				tdlsLinkEstablishParams->isResponder;
+			tdlsLinkEstablishCmdInfo->maxSp =
+				tdlsLinkEstablishParams->maxSp;
+			tdlsLinkEstablishCmdInfo->uapsdQueues =
+				tdlsLinkEstablishParams->uapsdQueues;
+			tdlsLinkEstablishCmdInfo->isOffChannelSupported =
+				tdlsLinkEstablishParams->isOffChannelSupported;
+			cdf_mem_copy(tdlsLinkEstablishCmdInfo->
+				     supportedChannels,
+				     tdlsLinkEstablishParams->supportedChannels,
+				     tdlsLinkEstablishParams->
+				     supportedChannelsLen);
+			tdlsLinkEstablishCmdInfo->supportedChannelsLen =
+				tdlsLinkEstablishParams->supportedChannelsLen;
+			cdf_mem_copy(tdlsLinkEstablishCmdInfo->
+				     supportedOperClasses,
+				     tdlsLinkEstablishParams->
+				     supportedOperClasses,
+				     tdlsLinkEstablishParams->
+				     supportedOperClassesLen);
+			tdlsLinkEstablishCmdInfo->supportedOperClassesLen =
+				tdlsLinkEstablishParams->supportedOperClassesLen;
+			tdlsLinkEstablishCmdInfo->isResponder =
+				tdlsLinkEstablishParams->isResponder;
+			tdlsLinkEstablishCmdInfo->maxSp =
+				tdlsLinkEstablishParams->maxSp;
+			tdlsLinkEstablishCmdInfo->uapsdQueues =
+				tdlsLinkEstablishParams->uapsdQueues;
+			tdlsLinkEstablishCmd->command =
+				eSmeCommandTdlsLinkEstablish;
+			tdlsLinkEstablishCmd->u.tdlsCmd.size =
+				sizeof(tTdlsLinkEstablishCmdInfo);
+			sme_push_command(pMac, tdlsLinkEstablishCmd, false);
+			status = CDF_STATUS_SUCCESS;
+		}
+	}
+
+	return status;
+}
+
+/*
+ * TDLS request API, called from HDD to add a TDLS peer
+ */
+CDF_STATUS csr_tdls_add_peer_sta(tHalHandle hHal, uint8_t sessionId,
+				 const tSirMacAddr peerMac)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	tSmeCmd *tdlsAddStaCmd;
+	CDF_STATUS status = CDF_STATUS_E_FAILURE;
+
+	/* If connected and in Infra. Only then allow this */
+	if (CSR_IS_SESSION_VALID(pMac, sessionId) &&
+	    csr_is_conn_state_connected_infra(pMac, sessionId) &&
+	    (NULL != peerMac)) {
+		tdlsAddStaCmd = csr_get_command_buffer(pMac);
+
+		if (tdlsAddStaCmd) {
+			tTdlsAddStaCmdInfo *tdlsAddStaCmdInfo =
+				&tdlsAddStaCmd->u.tdlsCmd.u.tdlsAddStaCmdInfo;
+
+			tdlsAddStaCmd->sessionId = sessionId;
+			tdlsAddStaCmdInfo->tdlsAddOper = TDLS_OPER_ADD;
+
+			cdf_mem_copy(tdlsAddStaCmdInfo->peerMac,
+				     peerMac, sizeof(tSirMacAddr));
+
+			tdlsAddStaCmd->command = eSmeCommandTdlsAddPeer;
+			tdlsAddStaCmd->u.tdlsCmd.size =
+				sizeof(tTdlsAddStaCmdInfo);
+			sme_push_command(pMac, tdlsAddStaCmd, false);
+			status = CDF_STATUS_SUCCESS;
+		}
+	}
+
+	return status;
+}
+
+/*
+ * TDLS request API, called from HDD to delete a TDLS peer
+ */
+CDF_STATUS csr_tdls_del_peer_sta(tHalHandle hHal, uint8_t sessionId,
+				 const tSirMacAddr peerMac)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	tSmeCmd *tdlsDelStaCmd;
+	CDF_STATUS status = CDF_STATUS_E_FAILURE;
+
+	/* If connected and in Infra. Only then allow this */
+	if (CSR_IS_SESSION_VALID(pMac, sessionId) &&
+	    csr_is_conn_state_connected_infra(pMac, sessionId) &&
+	    (NULL != peerMac)) {
+		tdlsDelStaCmd = csr_get_command_buffer(pMac);
+
+		if (tdlsDelStaCmd) {
+			tTdlsDelStaCmdInfo *tdlsDelStaCmdInfo =
+				&tdlsDelStaCmd->u.tdlsCmd.u.tdlsDelStaCmdInfo;
+
+			tdlsDelStaCmd->sessionId = sessionId;
+
+			cdf_mem_copy(tdlsDelStaCmdInfo->peerMac,
+				     peerMac, sizeof(tSirMacAddr));
+
+			tdlsDelStaCmd->command = eSmeCommandTdlsDelPeer;
+			tdlsDelStaCmd->u.tdlsCmd.size =
+				sizeof(tTdlsDelStaCmdInfo);
+			sme_push_command(pMac, tdlsDelStaCmd, false);
+			status = CDF_STATUS_SUCCESS;
+		}
+	}
+
+	return status;
+}
+
+/*
+ * TDLS messages sent to PE .
+ */
+CDF_STATUS tdls_send_message(tpAniSirGlobal pMac, uint16_t msg_type,
+			     void *msg_data, uint32_t msg_size)
+{
+
+	tSirMbMsg *pMsg = (tSirMbMsg *) msg_data;
+	pMsg->type = msg_type;
+	pMsg->msgLen = (uint16_t) (msg_size);
+
+	CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
+		  ("sending msg = %d"), pMsg->type);
+	/* Send message. */
+	if (cds_send_mb_message_to_mac(pMsg) != CDF_STATUS_SUCCESS) {
+		sms_log(pMac, LOGE, FL("Cannot send message"));
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	return CDF_STATUS_SUCCESS;
+}
+
+CDF_STATUS csr_tdls_process_send_mgmt(tpAniSirGlobal pMac, tSmeCmd *cmd)
+{
+	tTdlsSendMgmtCmdInfo *tdlsSendMgmtCmdInfo =
+		&cmd->u.tdlsCmd.u.tdlsSendMgmtCmdInfo;
+	tSirTdlsSendMgmtReq *tdlsSendMgmtReq = NULL;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, cmd->sessionId);
+	CDF_STATUS status = CDF_STATUS_E_FAILURE;
+
+	if (NULL == pSession) {
+		sms_log(pMac, LOGE, FL("pSession is NULL"));
+		return CDF_STATUS_E_FAILURE;
+	}
+	if (NULL == pSession->pConnectBssDesc) {
+		sms_log(pMac, LOGE, FL("BSS Description is not present"));
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	tdlsSendMgmtReq =
+		cdf_mem_malloc(sizeof(tSirTdlsSendMgmtReq) +
+			       tdlsSendMgmtCmdInfo->len);
+	if (NULL == tdlsSendMgmtReq)
+		status = CDF_STATUS_E_NOMEM;
+	else
+		status = CDF_STATUS_SUCCESS;
+
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		sms_log(pMac, LOGE, FL("alloc failed"));
+		CDF_ASSERT(0);
+		return status;
+	}
+	tdlsSendMgmtReq->sessionId = cmd->sessionId;
+	/* Using dialog as transactionId. This can be used to match response with request */
+	tdlsSendMgmtReq->transactionId = tdlsSendMgmtCmdInfo->dialog;
+	tdlsSendMgmtReq->reqType = tdlsSendMgmtCmdInfo->frameType;
+	tdlsSendMgmtReq->dialog = tdlsSendMgmtCmdInfo->dialog;
+	tdlsSendMgmtReq->statusCode = tdlsSendMgmtCmdInfo->statusCode;
+	tdlsSendMgmtReq->responder = tdlsSendMgmtCmdInfo->responder;
+	tdlsSendMgmtReq->peerCapability = tdlsSendMgmtCmdInfo->peerCapability;
+
+	cdf_mem_copy(tdlsSendMgmtReq->bssid,
+		     pSession->pConnectBssDesc->bssId, sizeof(tSirMacAddr));
+
+	cdf_mem_copy(tdlsSendMgmtReq->peerMac,
+		     tdlsSendMgmtCmdInfo->peerMac, sizeof(tSirMacAddr));
+
+	if (tdlsSendMgmtCmdInfo->len && tdlsSendMgmtCmdInfo->buf) {
+		cdf_mem_copy(tdlsSendMgmtReq->addIe, tdlsSendMgmtCmdInfo->buf,
+			     tdlsSendMgmtCmdInfo->len);
+
+	}
+	/* Send the request to PE. */
+	sms_log(pMac, LOG1, "sending TDLS Mgmt Frame req to PE ");
+	status = tdls_send_message(pMac, eWNI_SME_TDLS_SEND_MGMT_REQ,
+				   (void *)tdlsSendMgmtReq,
+				   sizeof(tSirTdlsSendMgmtReq) +
+				   tdlsSendMgmtCmdInfo->len);
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		sms_log(pMac, LOGE, FL("Failed to send request to MAC"));
+	}
+	if (tdlsSendMgmtCmdInfo->len && tdlsSendMgmtCmdInfo->buf) {
+		/* Done with the buf. Free it. */
+		cdf_mem_free(tdlsSendMgmtCmdInfo->buf);
+		tdlsSendMgmtCmdInfo->buf = NULL;
+		tdlsSendMgmtCmdInfo->len = 0;
+	}
+
+	return status;
+}
+
+CDF_STATUS csr_tdls_process_add_sta(tpAniSirGlobal pMac, tSmeCmd *cmd)
+{
+	tTdlsAddStaCmdInfo *tdlsAddStaCmdInfo =
+		&cmd->u.tdlsCmd.u.tdlsAddStaCmdInfo;
+	tSirTdlsAddStaReq *tdlsAddStaReq = NULL;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, cmd->sessionId);
+	CDF_STATUS status = CDF_STATUS_E_FAILURE;
+
+	if (NULL == pSession) {
+		sms_log(pMac, LOGE, FL("pSession is NULL"));
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	if (NULL == pSession->pConnectBssDesc) {
+		sms_log(pMac, LOGE, FL("BSS description is not present"));
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	tdlsAddStaReq = cdf_mem_malloc(sizeof(tSirTdlsAddStaReq));
+	if (NULL == tdlsAddStaReq)
+		status = CDF_STATUS_E_NOMEM;
+	else
+		status = CDF_STATUS_SUCCESS;
+
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		sms_log(pMac, LOGE, FL("alloc failed"));
+		CDF_ASSERT(0);
+		return status;
+	}
+	tdlsAddStaReq->sessionId = cmd->sessionId;
+	tdlsAddStaReq->tdlsAddOper = tdlsAddStaCmdInfo->tdlsAddOper;
+	/* Using dialog as transactionId. This can be used to match response with request */
+	tdlsAddStaReq->transactionId = 0;
+
+	cdf_mem_copy(tdlsAddStaReq->bssid,
+		     pSession->pConnectBssDesc->bssId, sizeof(tSirMacAddr));
+
+	cdf_mem_copy(tdlsAddStaReq->peerMac,
+		     tdlsAddStaCmdInfo->peerMac, sizeof(tSirMacAddr));
+
+	tdlsAddStaReq->capability = tdlsAddStaCmdInfo->capability;
+	tdlsAddStaReq->uapsd_queues = tdlsAddStaCmdInfo->uapsdQueues;
+	tdlsAddStaReq->max_sp = tdlsAddStaCmdInfo->maxSp;
+
+	cdf_mem_copy(tdlsAddStaReq->extn_capability,
+		     tdlsAddStaCmdInfo->extnCapability, SIR_MAC_MAX_EXTN_CAP);
+	tdlsAddStaReq->htcap_present = tdlsAddStaCmdInfo->htcap_present;
+	cdf_mem_copy(&tdlsAddStaReq->htCap,
+		     &tdlsAddStaCmdInfo->HTCap,
+		     sizeof(tdlsAddStaCmdInfo->HTCap));
+	tdlsAddStaReq->vhtcap_present = tdlsAddStaCmdInfo->vhtcap_present;
+	cdf_mem_copy(&tdlsAddStaReq->vhtCap,
+		     &tdlsAddStaCmdInfo->VHTCap,
+		     sizeof(tdlsAddStaCmdInfo->VHTCap));
+	tdlsAddStaReq->supported_rates_length =
+		tdlsAddStaCmdInfo->supportedRatesLen;
+	cdf_mem_copy(&tdlsAddStaReq->supported_rates,
+		     tdlsAddStaCmdInfo->supportedRates,
+		     tdlsAddStaCmdInfo->supportedRatesLen);
+
+	/* Send the request to PE. */
+	sms_log(pMac, LOGE, "sending TDLS Add Sta req to PE ");
+	status = tdls_send_message(pMac, eWNI_SME_TDLS_ADD_STA_REQ,
+				   (void *)tdlsAddStaReq,
+				   sizeof(tSirTdlsAddStaReq));
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		sms_log(pMac, LOGE, FL("Failed to send request to MAC"));
+	}
+	return status;
+}
+
+CDF_STATUS csr_tdls_process_del_sta(tpAniSirGlobal pMac, tSmeCmd *cmd)
+{
+	tTdlsDelStaCmdInfo *tdlsDelStaCmdInfo =
+		&cmd->u.tdlsCmd.u.tdlsDelStaCmdInfo;
+	tSirTdlsDelStaReq *tdlsDelStaReq = NULL;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, cmd->sessionId);
+	CDF_STATUS status = CDF_STATUS_E_FAILURE;
+
+	if (NULL == pSession) {
+		sms_log(pMac, LOGE, FL("pSession is NULL"));
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	if (NULL == pSession->pConnectBssDesc) {
+		sms_log(pMac, LOGE, FL("BSS description is not present"));
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	tdlsDelStaReq = cdf_mem_malloc(sizeof(tSirTdlsDelStaReq));
+	if (NULL == tdlsDelStaReq)
+		status = CDF_STATUS_E_NOMEM;
+	else
+		status = CDF_STATUS_SUCCESS;
+
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		sms_log(pMac, LOGE, FL("alloc failed"));
+		CDF_ASSERT(0);
+		return status;
+	}
+	tdlsDelStaReq->sessionId = cmd->sessionId;
+	/* Using dialog as transactionId. This can be used to match response with request */
+	tdlsDelStaReq->transactionId = 0;
+
+	cdf_mem_copy(tdlsDelStaReq->bssid,
+		     pSession->pConnectBssDesc->bssId, sizeof(tSirMacAddr));
+
+	cdf_mem_copy(tdlsDelStaReq->peerMac,
+		     tdlsDelStaCmdInfo->peerMac, sizeof(tSirMacAddr));
+
+	/* Send the request to PE. */
+	sms_log(pMac, LOG1,
+		"sending TDLS Del Sta " MAC_ADDRESS_STR " req to PE",
+		MAC_ADDR_ARRAY(tdlsDelStaCmdInfo->peerMac));
+	status = tdls_send_message(pMac, eWNI_SME_TDLS_DEL_STA_REQ,
+				   (void *)tdlsDelStaReq,
+				   sizeof(tSirTdlsDelStaReq));
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		sms_log(pMac, LOGE, FL("Failed to send request to MAC"));
+	}
+	return status;
+}
+
+/*
+ * commands received from CSR
+ */
+CDF_STATUS csr_tdls_process_cmd(tpAniSirGlobal pMac, tSmeCmd *cmd)
+{
+	eSmeCommandType cmdType = cmd->command;
+	bool status = true;
+	switch (cmdType) {
+	case eSmeCommandTdlsSendMgmt:
+	{
+		status = csr_tdls_process_send_mgmt(pMac, cmd);
+		if (CDF_IS_STATUS_SUCCESS(status)) {
+			status = false;
+		}
+	}
+	break;
+	case eSmeCommandTdlsAddPeer:
+	{
+		status = csr_tdls_process_add_sta(pMac, cmd);
+		if (CDF_IS_STATUS_SUCCESS(status)) {
+			status = false;
+		}
+	}
+	break;
+	case eSmeCommandTdlsDelPeer:
+	{
+		status = csr_tdls_process_del_sta(pMac, cmd);
+		if (CDF_IS_STATUS_SUCCESS(status)) {
+			status = false;
+		}
+	}
+	break;
+	case eSmeCommandTdlsLinkEstablish:
+	{
+		status = csr_tdls_process_link_establish(pMac, cmd);
+		if (CDF_IS_STATUS_SUCCESS(status)) {
+			status = false;
+		}
+	}
+	break;
+	default:
+	{
+		/* TODO: Add defualt handling */
+		break;
+	}
+
+	}
+	return status;
+}
+
+CDF_STATUS csr_tdls_process_link_establish(tpAniSirGlobal pMac, tSmeCmd *cmd)
+{
+	tTdlsLinkEstablishCmdInfo *tdlsLinkEstablishCmdInfo =
+		&cmd->u.tdlsCmd.u.tdlsLinkEstablishCmdInfo;
+	tSirTdlsLinkEstablishReq *tdlsLinkEstablishReq = NULL;
+	CDF_STATUS status = CDF_STATUS_E_FAILURE;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, cmd->sessionId);
+
+	if (NULL == pSession) {
+		sms_log(pMac, LOGE, FL("pSession is NULL"));
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	tdlsLinkEstablishReq = cdf_mem_malloc(sizeof(tSirTdlsLinkEstablishReq));
+
+	if (tdlsLinkEstablishReq == NULL) {
+		sms_log(pMac, LOGE, FL("alloc failed"));
+		CDF_ASSERT(0);
+		return CDF_STATUS_E_NOMEM;
+	}
+	tdlsLinkEstablishReq->sessionId = cmd->sessionId;
+	/* Using dialog as transactionId. This can be used to match response with request */
+	tdlsLinkEstablishReq->transactionId = 0;
+	cdf_mem_copy(tdlsLinkEstablishReq->peerMac,
+		     tdlsLinkEstablishCmdInfo->peerMac, sizeof(tSirMacAddr));
+	cdf_mem_copy(tdlsLinkEstablishReq->bssid,
+		     pSession->pConnectBssDesc->bssId, sizeof(tSirMacAddr));
+	cdf_mem_copy(tdlsLinkEstablishReq->supportedChannels,
+		     tdlsLinkEstablishCmdInfo->supportedChannels,
+		     tdlsLinkEstablishCmdInfo->supportedChannelsLen);
+	tdlsLinkEstablishReq->supportedChannelsLen =
+		tdlsLinkEstablishCmdInfo->supportedChannelsLen;
+	cdf_mem_copy(tdlsLinkEstablishReq->supportedOperClasses,
+		     tdlsLinkEstablishCmdInfo->supportedOperClasses,
+		     tdlsLinkEstablishCmdInfo->supportedOperClassesLen);
+	tdlsLinkEstablishReq->supportedOperClassesLen =
+		tdlsLinkEstablishCmdInfo->supportedOperClassesLen;
+	tdlsLinkEstablishReq->isBufSta = tdlsLinkEstablishCmdInfo->isBufSta;
+	tdlsLinkEstablishReq->isResponder =
+		tdlsLinkEstablishCmdInfo->isResponder;
+	tdlsLinkEstablishReq->uapsdQueues =
+		tdlsLinkEstablishCmdInfo->uapsdQueues;
+	tdlsLinkEstablishReq->maxSp = tdlsLinkEstablishCmdInfo->maxSp;
+
+	/* Send the request to PE. */
+	sms_log(pMac, LOGE, "sending TDLS Link Establish Request to PE \n");
+	status = tdls_send_message(pMac, eWNI_SME_TDLS_LINK_ESTABLISH_REQ,
+				   (void *)tdlsLinkEstablishReq,
+				   sizeof(tSirTdlsLinkEstablishReq));
+				   if (!CDF_IS_STATUS_SUCCESS(status)) {
+					   sms_log(pMac, LOGE, FL("Failed to send request to MAC\n"));
+				   }
+				   return status;
+}
+
+/*
+ * TDLS Message processor, will be called after TDLS message recieved from
+ * PE
+ */
+CDF_STATUS tdls_msg_processor(tpAniSirGlobal pMac, uint16_t msgType,
+			      void *pMsgBuf)
+{
+	tCsrRoamInfo roamInfo = { 0 };
+	eCsrRoamResult roamResult;
+	tSirTdlsAddStaRsp *addStaRsp = (tSirTdlsAddStaRsp *) pMsgBuf;
+	tSirTdlsDelStaRsp *delStaRsp = (tSirTdlsDelStaRsp *) pMsgBuf;
+	tpSirTdlsDelStaInd pSirTdlsDelStaInd = (tpSirTdlsDelStaInd) pMsgBuf;
+	tpSirTdlsDelAllPeerInd pSirTdlsDelAllPeerInd =
+		(tpSirTdlsDelAllPeerInd) pMsgBuf;
+	tpSirMgmtTxCompletionInd tdls_tx_comp_ind =
+		(tpSirMgmtTxCompletionInd) pMsgBuf;
+	tSirTdlsLinkEstablishReqRsp *linkEstablishReqRsp =
+		(tSirTdlsLinkEstablishReqRsp *) pMsgBuf;
+	tSirTdlsEventnotify *tevent = (tSirTdlsEventnotify *) pMsgBuf;
+
+	switch (msgType) {
+	case eWNI_SME_TDLS_SEND_MGMT_RSP:
+		/* remove pending eSmeCommandTdlsDiscovery command */
+		csr_tdls_remove_sme_cmd(pMac, eSmeCommandTdlsSendMgmt);
+		break;
+	case eWNI_SME_TDLS_ADD_STA_RSP:
+		cdf_mem_copy(&roamInfo.peerMac, addStaRsp->peerMac,
+				sizeof(tSirMacAddr));
+		roamInfo.staId = addStaRsp->staId;
+		roamInfo.ucastSig = addStaRsp->ucastSig;
+		roamInfo.bcastSig = addStaRsp->bcastSig;
+		roamInfo.statusCode = addStaRsp->statusCode;
+		/*
+		 * register peer with TL, we have to go through HDD as
+		 * this is the only way to register any STA with TL.
+		 */
+		if (addStaRsp->tdlsAddOper == TDLS_OPER_ADD)
+			roamResult = eCSR_ROAM_RESULT_ADD_TDLS_PEER;
+		else    /* addStaRsp->tdlsAddOper must be TDLS_OPER_UPDATE */
+			roamResult = eCSR_ROAM_RESULT_UPDATE_TDLS_PEER;
+		csr_roam_call_callback(pMac, addStaRsp->sessionId,
+				&roamInfo, 0, eCSR_ROAM_TDLS_STATUS_UPDATE,
+				roamResult);
+
+		/* remove pending eSmeCommandTdlsDiscovery command */
+		csr_tdls_remove_sme_cmd(pMac, eSmeCommandTdlsAddPeer);
+		break;
+	case eWNI_SME_TDLS_DEL_STA_RSP:
+		cdf_mem_copy(&roamInfo.peerMac, delStaRsp->peerMac,
+				sizeof(tSirMacAddr));
+		roamInfo.staId = delStaRsp->staId;
+		roamInfo.statusCode = delStaRsp->statusCode;
+		/*
+		 * register peer with TL, we have to go through HDD as
+		 * this is the only way to register any STA with TL.
+		 */
+		csr_roam_call_callback(pMac, delStaRsp->sessionId,
+				&roamInfo, 0,
+				eCSR_ROAM_TDLS_STATUS_UPDATE,
+				eCSR_ROAM_RESULT_DELETE_TDLS_PEER);
+
+		csr_tdls_remove_sme_cmd(pMac, eSmeCommandTdlsDelPeer);
+		break;
+	case eWNI_SME_TDLS_DEL_STA_IND:
+		cdf_mem_copy(&roamInfo.peerMac,
+				pSirTdlsDelStaInd->peerMac,
+				sizeof(tSirMacAddr));
+		roamInfo.staId = pSirTdlsDelStaInd->staId;
+		roamInfo.reasonCode = pSirTdlsDelStaInd->reasonCode;
+
+		/* Sending the TEARDOWN indication to HDD. */
+		csr_roam_call_callback(pMac,
+				pSirTdlsDelStaInd->sessionId, &roamInfo,
+				0, eCSR_ROAM_TDLS_STATUS_UPDATE,
+				eCSR_ROAM_RESULT_TEARDOWN_TDLS_PEER_IND);
+		break;
+	case eWNI_SME_TDLS_DEL_ALL_PEER_IND:
+		/* Sending the TEARDOWN indication to HDD. */
+		csr_roam_call_callback(pMac,
+				pSirTdlsDelAllPeerInd->sessionId,
+				&roamInfo, 0,
+				eCSR_ROAM_TDLS_STATUS_UPDATE,
+				eCSR_ROAM_RESULT_DELETE_ALL_TDLS_PEER_IND);
+		break;
+	case eWNI_SME_MGMT_FRM_TX_COMPLETION_IND:
+		roamInfo.reasonCode =
+			tdls_tx_comp_ind->txCompleteStatus;
+
+		csr_roam_call_callback(pMac,
+				tdls_tx_comp_ind->sessionId,
+				&roamInfo, 0,
+				eCSR_ROAM_RESULT_MGMT_TX_COMPLETE_IND,
+				0);
+		break;
+	case eWNI_SME_TDLS_LINK_ESTABLISH_RSP:
+		csr_roam_call_callback(pMac,
+				linkEstablishReqRsp->sessionId,
+				&roamInfo, 0,
+				eCSR_ROAM_TDLS_STATUS_UPDATE,
+				eCSR_ROAM_RESULT_LINK_ESTABLISH_REQ_RSP);
+		/* remove pending eSmeCommandTdlsLinkEstablish command */
+		csr_tdls_remove_sme_cmd(pMac, eSmeCommandTdlsLinkEstablish);
+		break;
+	case eWNI_SME_TDLS_SHOULD_DISCOVER:
+		cdf_mem_copy(&roamInfo.peerMac, tevent->peerMac,
+				sizeof(tSirMacAddr));
+		roamInfo.reasonCode = tevent->peer_reason;
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
+				"%s: eWNI_SME_TDLS_SHOULD_DISCOVER for peer mac: "
+				MAC_ADDRESS_STR " peer_reason: %d",
+				__func__, MAC_ADDR_ARRAY(tevent->peerMac),
+				tevent->peer_reason);
+		csr_roam_call_callback(pMac, tevent->sessionId, &roamInfo,
+				0, eCSR_ROAM_TDLS_STATUS_UPDATE,
+				eCSR_ROAM_RESULT_TDLS_SHOULD_DISCOVER);
+		break;
+	case eWNI_SME_TDLS_SHOULD_TEARDOWN:
+		cdf_mem_copy(&roamInfo.peerMac, tevent->peerMac,
+				sizeof(tSirMacAddr));
+		roamInfo.reasonCode = tevent->peer_reason;
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
+				"%s: eWNI_SME_TDLS_SHOULD_TEARDOWN for peer mac: "
+				MAC_ADDRESS_STR " peer_reason: %d",
+				__func__, MAC_ADDR_ARRAY(tevent->peerMac),
+				tevent->peer_reason);
+		csr_roam_call_callback(pMac, tevent->sessionId, &roamInfo,
+				0, eCSR_ROAM_TDLS_STATUS_UPDATE,
+				eCSR_ROAM_RESULT_TDLS_SHOULD_TEARDOWN);
+		break;
+	case eWNI_SME_TDLS_PEER_DISCONNECTED:
+		cdf_mem_copy(&roamInfo.peerMac, tevent->peerMac,
+				sizeof(tSirMacAddr));
+		roamInfo.reasonCode = tevent->peer_reason;
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
+				"%s: eWNI_SME_TDLS_PEER_DISCONNECTED for peer mac: "
+				MAC_ADDRESS_STR " peer_reason: %d",
+				__func__, MAC_ADDR_ARRAY(tevent->peerMac),
+				tevent->peer_reason);
+		csr_roam_call_callback(pMac, tevent->sessionId, &roamInfo,
+				0, eCSR_ROAM_TDLS_STATUS_UPDATE,
+				eCSR_ROAM_RESULT_TDLS_SHOULD_PEER_DISCONNECTED);
+		break;
+	default:
+		break;
+	}
+
+	return CDF_STATUS_SUCCESS;
+}
+#endif
diff --git a/core/sme/src/csr/csr_util.c b/core/sme/src/csr/csr_util.c
new file mode 100644
index 0000000..eea8cbd
--- /dev/null
+++ b/core/sme/src/csr/csr_util.c
@@ -0,0 +1,5626 @@
+/*
+ * Copyright (c) 2011-2015 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 csr_util.c
+
+    Implementation supporting routines for CSR.
+   ========================================================================== */
+
+#include "ani_global.h"
+
+#include "csr_support.h"
+#include "csr_inside_api.h"
+#include "sms_debug.h"
+#include "sme_qos_internal.h"
+#include "wma_types.h"
+#include "cds_utils.h"
+
+
+uint8_t csr_wpa_oui[][CSR_WPA_OUI_SIZE] = {
+	{0x00, 0x50, 0xf2, 0x00}
+	,
+	{0x00, 0x50, 0xf2, 0x01}
+	,
+	{0x00, 0x50, 0xf2, 0x02}
+	,
+	{0x00, 0x50, 0xf2, 0x03}
+	,
+	{0x00, 0x50, 0xf2, 0x04}
+	,
+	{0x00, 0x50, 0xf2, 0x05}
+	,
+#ifdef FEATURE_WLAN_ESE
+	{0x00, 0x40, 0x96, 0x00}
+	,                       /* CCKM */
+#endif /* FEATURE_WLAN_ESE */
+};
+
+uint8_t csr_rsn_oui[][CSR_RSN_OUI_SIZE] = {
+	{0x00, 0x0F, 0xAC, 0x00}
+	,                       /* group cipher */
+	{0x00, 0x0F, 0xAC, 0x01}
+	,                       /* WEP-40 or RSN */
+	{0x00, 0x0F, 0xAC, 0x02}
+	,                       /* TKIP or RSN-PSK */
+	{0x00, 0x0F, 0xAC, 0x03}
+	,                       /* Reserved */
+	{0x00, 0x0F, 0xAC, 0x04}
+	,                       /* AES-CCMP */
+	{0x00, 0x0F, 0xAC, 0x05}
+	,                       /* WEP-104 */
+	{0x00, 0x40, 0x96, 0x00}
+	,                       /* CCKM */
+	{0x00, 0x0F, 0xAC, 0x06}
+	,                       /* BIP (encryption type) or
+				RSN-PSK-SHA256 (authentication type) */
+	/* RSN-8021X-SHA256 (authentication type) */
+	{0x00, 0x0F, 0xAC, 0x05}
+};
+
+#ifdef FEATURE_WLAN_WAPI
+uint8_t csr_wapi_oui[][CSR_WAPI_OUI_SIZE] = {
+	{0x00, 0x14, 0x72, 0x00}
+	,                       /* Reserved */
+	{0x00, 0x14, 0x72, 0x01}
+	,                       /* WAI certificate or SMS4 */
+	{0x00, 0x14, 0x72, 0x02} /* WAI PSK */
+};
+#endif /* FEATURE_WLAN_WAPI */
+uint8_t csr_wme_info_oui[CSR_WME_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x02 };
+uint8_t csr_wme_parm_oui[CSR_WME_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x02 };
+
+
+/* ////////////////////////////////////////////////////////////////////// */
+
+/**
+ * \var g_phy_rates_suppt
+ *
+ * \brief Rate support lookup table
+ *
+ *
+ * This is a  lookup table indexing rates &  configuration parameters to
+ * support.  Given a rate (in  unites of 0.5Mpbs) & three bools (MIMO
+ * Enabled, Channel  Bonding Enabled, & Concatenation  Enabled), one can
+ * determine  whether  the given  rate  is  supported  by computing  two
+ * indices.  The  first maps  the rate to  table row as  indicated below
+ * (i.e. eHddSuppRate_6Mbps maps to  row zero, eHddSuppRate_9Mbps to row
+ * 1, and so on).  Index two can be computed like so:
+ *
+ * \code
+ *  idx2 = ( fEsf  ? 0x4 : 0x0 ) |
+ *         ( fCb   ? 0x2 : 0x0 ) |
+ *         ( fMimo ? 0x1 : 0x0 );
+ * \endcode
+ *
+ *
+ * Given that:
+ *
+ *  \code
+ *  fSupported = g_phy_rates_suppt[idx1][idx2];
+ *  \endcode
+ *
+ *
+ * This table is based on  the document "PHY Supported Rates.doc".  This
+ * table is  permissive in that a  rate is reflected  as being supported
+ * even  when turning  off an  enabled feature  would be  required.  For
+ * instance, "PHY Supported Rates"  lists 42Mpbs as unsupported when CB,
+ * ESF, &  MIMO are all  on.  However,  if we turn  off either of  CB or
+ * MIMO, it then becomes supported.   Therefore, we mark it as supported
+ * even in index 7 of this table.
+ *
+ *
+ */
+
+static const bool g_phy_rates_suppt[24][8] = {
+
+	/* SSF   SSF    SSF    SSF    ESF    ESF    ESF    ESF */
+	/* SIMO  MIMO   SIMO   MIMO   SIMO   MIMO   SIMO   MIMO */
+	/* No CB No CB  CB     CB     No CB  No CB  CB     CB */
+	{true, true, true, true, true, true, true, true},       /* 6Mbps */
+	{true, true, true, true, true, true, true, true},       /* 9Mbps */
+	{true, true, true, true, true, true, true, true},       /* 12Mbps */
+	{true, true, true, true, true, true, true, true},       /* 18Mbps */
+	{false, false, true, true, false, false, true, true},   /* 20Mbps */
+	{true, true, true, true, true, true, true, true},       /* 24Mbps */
+	{true, true, true, true, true, true, true, true},       /* 36Mbps */
+	{false, false, true, true, false, true, true, true},    /* 40Mbps */
+	{false, false, true, true, false, true, true, true},    /* 42Mbps */
+	{true, true, true, true, true, true, true, true},       /* 48Mbps */
+	{true, true, true, true, true, true, true, true},       /* 54Mbps */
+	{false, true, true, true, false, true, true, true},     /* 72Mbps */
+	{false, false, true, true, false, true, true, true},    /* 80Mbps */
+	{false, false, true, true, false, true, true, true},    /* 84Mbps */
+	{false, true, true, true, false, true, true, true},     /* 96Mbps */
+	{false, true, true, true, false, true, true, true},     /* 108Mbps */
+	{false, false, true, true, false, true, true, true},    /* 120Mbps */
+	{false, false, true, true, false, true, true, true},    /* 126Mbps */
+	{false, false, false, true, false, false, false, true}, /* 144Mbps */
+	{false, false, false, true, false, false, false, true}, /* 160Mbps */
+	{false, false, false, true, false, false, false, true}, /* 168Mbps */
+	{false, false, false, true, false, false, false, true}, /* 192Mbps */
+	{false, false, false, true, false, false, false, true}, /* 216Mbps */
+	{false, false, false, true, false, false, false, true}, /* 240Mbps */
+
+};
+
+#define CASE_RETURN_STR(n) {\
+	case (n): return (# n);\
+}
+
+const char *get_e_roam_cmd_status_str(eRoamCmdStatus val)
+{
+	switch (val) {
+		CASE_RETURN_STR(eCSR_ROAM_CANCELLED);
+		CASE_RETURN_STR(eCSR_ROAM_ROAMING_START);
+		CASE_RETURN_STR(eCSR_ROAM_ROAMING_COMPLETION);
+		CASE_RETURN_STR(eCSR_ROAM_ASSOCIATION_START);
+		CASE_RETURN_STR(eCSR_ROAM_ASSOCIATION_COMPLETION);
+		CASE_RETURN_STR(eCSR_ROAM_DISASSOCIATED);
+		CASE_RETURN_STR(eCSR_ROAM_SHOULD_ROAM);
+		CASE_RETURN_STR(eCSR_ROAM_SCAN_FOUND_NEW_BSS);
+		CASE_RETURN_STR(eCSR_ROAM_LOSTLINK);
+	default:
+		return "unknown";
+	}
+}
+
+const char *get_e_csr_roam_result_str(eCsrRoamResult val)
+{
+	switch (val) {
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_NONE);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_FAILURE);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_ASSOCIATED);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_NOT_ASSOCIATED);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_MIC_FAILURE);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_FORCED);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_DISASSOC_IND);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_DEAUTH_IND);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_CAP_CHANGED);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_IBSS_CONNECT);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_IBSS_INACTIVE);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_IBSS_NEW_PEER);
+		CASE_RETURN_STR(eCSR_ROAM_RESULT_IBSS_COALESCED);
+	default:
+		return "unknown";
+	}
+}
+
+bool csr_get_bss_id_bss_desc(tHalHandle hHal, tSirBssDescription *pSirBssDesc,
+			     struct cdf_mac_addr *pBssId)
+{
+	cdf_mem_copy(pBssId, &pSirBssDesc->bssId[0],
+			sizeof(struct cdf_mac_addr));
+	return true;
+}
+
+bool csr_is_bss_id_equal(tHalHandle hHal, tSirBssDescription *pSirBssDesc1,
+			 tSirBssDescription *pSirBssDesc2)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	bool fEqual = false;
+	struct cdf_mac_addr bssId1;
+	struct cdf_mac_addr bssId2;
+
+	do {
+		if (!pSirBssDesc1)
+			break;
+		if (!pSirBssDesc2)
+			break;
+
+		if (!csr_get_bss_id_bss_desc(pMac, pSirBssDesc1, &bssId1))
+			break;
+		if (!csr_get_bss_id_bss_desc(pMac, pSirBssDesc2, &bssId2))
+			break;
+
+		fEqual = cdf_is_macaddr_equal(&bssId1, &bssId2);
+	} while (0);
+
+	return fEqual;
+}
+
+bool csr_is_conn_state_connected_ibss(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	return eCSR_ASSOC_STATE_TYPE_IBSS_CONNECTED ==
+		pMac->roam.roamSession[sessionId].connectState;
+}
+
+bool csr_is_conn_state_disconnected_ibss(tpAniSirGlobal pMac,
+					 uint32_t sessionId)
+{
+	return eCSR_ASSOC_STATE_TYPE_IBSS_DISCONNECTED ==
+		pMac->roam.roamSession[sessionId].connectState;
+}
+
+bool csr_is_conn_state_connected_infra(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	return eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED ==
+		pMac->roam.roamSession[sessionId].connectState;
+}
+
+bool csr_is_conn_state_connected(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	if (csr_is_conn_state_connected_ibss(pMac, sessionId)
+	    || csr_is_conn_state_connected_infra(pMac, sessionId)
+	    || csr_is_conn_state_connected_wds(pMac, sessionId))
+		return true;
+	else
+		return false;
+}
+
+bool csr_is_conn_state_infra(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	return csr_is_conn_state_connected_infra(pMac, sessionId);
+}
+
+bool csr_is_conn_state_ibss(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	return csr_is_conn_state_connected_ibss(pMac, sessionId) ||
+	       csr_is_conn_state_disconnected_ibss(pMac, sessionId);
+}
+
+bool csr_is_conn_state_connected_wds(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	return eCSR_ASSOC_STATE_TYPE_WDS_CONNECTED ==
+		pMac->roam.roamSession[sessionId].connectState;
+}
+
+bool csr_is_conn_state_connected_infra_ap(tpAniSirGlobal pMac,
+					  uint32_t sessionId)
+{
+	return (eCSR_ASSOC_STATE_TYPE_INFRA_CONNECTED ==
+		 pMac->roam.roamSession[sessionId].connectState) ||
+	       (eCSR_ASSOC_STATE_TYPE_INFRA_DISCONNECTED ==
+		 pMac->roam.roamSession[sessionId].connectState);
+}
+
+bool csr_is_conn_state_disconnected_wds(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	return eCSR_ASSOC_STATE_TYPE_WDS_DISCONNECTED ==
+		pMac->roam.roamSession[sessionId].connectState;
+}
+
+bool csr_is_conn_state_wds(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	return csr_is_conn_state_connected_wds(pMac, sessionId) ||
+	       csr_is_conn_state_disconnected_wds(pMac, sessionId);
+}
+
+bool csr_is_conn_state_ap(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	tCsrRoamSession *pSession;
+	pSession = CSR_GET_SESSION(pMac, sessionId);
+	if (!pSession)
+		return false;
+	if (CSR_IS_INFRA_AP(&pSession->connectedProfile))
+		return true;
+	return false;
+}
+
+bool csr_is_any_session_in_connect_state(tpAniSirGlobal pMac)
+{
+	uint32_t i;
+	bool fRc = false;
+
+	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
+		if (CSR_IS_SESSION_VALID(pMac, i) &&
+		    (csr_is_conn_state_infra(pMac, i)
+		     || csr_is_conn_state_ibss(pMac, i)
+		     || csr_is_conn_state_ap(pMac, i))) {
+			fRc = true;
+			break;
+		}
+	}
+
+	return fRc;
+}
+
+int8_t csr_get_infra_session_id(tpAniSirGlobal pMac)
+{
+	uint8_t i;
+	int8_t sessionid = -1;
+
+	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
+		if (CSR_IS_SESSION_VALID(pMac, i)
+		    && csr_is_conn_state_infra(pMac, i)) {
+			sessionid = i;
+			break;
+		}
+	}
+
+	return sessionid;
+}
+
+uint8_t csr_get_infra_operation_channel(tpAniSirGlobal pMac, uint8_t sessionId)
+{
+	uint8_t channel;
+
+	if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
+		channel =
+			pMac->roam.roamSession[sessionId].connectedProfile.
+			operationChannel;
+	} else {
+		channel = 0;
+	}
+	return channel;
+}
+
+bool csr_is_session_client_and_connected(tpAniSirGlobal pMac, uint8_t sessionId)
+{
+	tCsrRoamSession *pSession = NULL;
+	if (CSR_IS_SESSION_VALID(pMac, sessionId)
+	    && csr_is_conn_state_infra(pMac, sessionId)) {
+		pSession = CSR_GET_SESSION(pMac, sessionId);
+		if (NULL != pSession->pCurRoamProfile) {
+			if ((pSession->pCurRoamProfile->csrPersona ==
+			     CDF_STA_MODE)
+			    || (pSession->pCurRoamProfile->csrPersona ==
+				CDF_P2P_CLIENT_MODE))
+				return true;
+		}
+	}
+	return false;
+}
+
+/**
+ * csr_get_concurrent_operation_channel() - To get concurrent operating channel
+ * @mac_ctx: Pointer to mac context
+ *
+ * This routine will return operating channel on FIRST BSS that is
+ * active/operating to be used for concurrency mode.
+ * If other BSS is not up or not connected it will return 0
+ *
+ * Return: uint8_t
+ */
+uint8_t csr_get_concurrent_operation_channel(tpAniSirGlobal mac_ctx)
+{
+	tCsrRoamSession *session = NULL;
+	uint8_t i = 0;
+	tCDF_CON_MODE persona;
+
+	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
+		if (!CSR_IS_SESSION_VALID(mac_ctx, i))
+			continue;
+		session = CSR_GET_SESSION(mac_ctx, i);
+		if (NULL == session->pCurRoamProfile)
+			continue;
+		persona = session->pCurRoamProfile->csrPersona;
+		if ((((persona == CDF_STA_MODE) ||
+			(persona == CDF_P2P_CLIENT_MODE)) &&
+			(session->connectState ==
+				eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED)) ||
+			(((persona == CDF_P2P_GO_MODE) ||
+				(persona == CDF_SAP_MODE))
+				 && (session->connectState !=
+					 eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED)))
+			return session->connectedProfile.operationChannel;
+
+	}
+	return 0;
+}
+
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+
+#define HALF_BW_OF(eCSR_bw_val) ((eCSR_bw_val)/2)
+
+/* calculation of center channel based on V/HT BW and WIFI channel bw=5MHz) */
+
+#define CSR_GET_HT40_PLUS_CCH(och) ((och)+2)
+#define CSR_GET_HT40_MINUS_CCH(och) ((och)-2)
+
+#define CSR_GET_HT80_PLUS_LL_CCH(och) ((och)+6)
+#define CSR_GET_HT80_PLUS_HL_CCH(och) ((och)+2)
+#define CSR_GET_HT80_MINUS_LH_CCH(och) ((och)-2)
+#define CSR_GET_HT80_MINUS_HH_CCH(och) ((och)-6)
+
+/**
+ * csr_get_ch_from_ht_profile() - to get channel from HT profile
+ * @pMac: pointer to Mac context
+ * @htp: pointer to HT profile
+ * @och: operating channel
+ * @cfreq: channel frequency
+ * @hbw: half bandwidth
+ *
+ * This function will fill half bandwidth and channel frequency based
+ * on the HT profile
+ *
+ * Return: none
+ */
+void csr_get_ch_from_ht_profile(tpAniSirGlobal pMac, tCsrRoamHTProfile *htp,
+				uint16_t och, uint16_t *cfreq, uint16_t *hbw)
+{
+	uint16_t cch, ch_bond;
+
+	if (och > 14)
+		ch_bond = pMac->roam.configParam.channelBondingMode5GHz;
+	else
+		ch_bond = pMac->roam.configParam.channelBondingMode24GHz;
+
+	cch = och;
+	*hbw = HALF_BW_OF(eCSR_BW_20MHz_VAL);
+
+	if (!ch_bond)
+		goto ret;
+
+	sms_log(pMac, LOG1, FL("##HTC: %d scbw: %d rcbw: %d sco: %d"
+#ifdef WLAN_FEATURE_11AC
+				"VHTC: %d apc: %d apbw: %d"
+#endif
+			      ),
+			htp->htCapability, htp->htSupportedChannelWidthSet,
+			htp->htRecommendedTxWidthSet,
+			htp->htSecondaryChannelOffset,
+#ifdef WLAN_FEATURE_11AC
+			htp->vhtCapability, htp->apCenterChan, htp->apChanWidth
+#endif
+	       );
+
+#ifdef WLAN_FEATURE_11AC
+	if (htp->vhtCapability) {
+		cch = htp->apCenterChan;
+		if (htp->apChanWidth == WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ)
+			*hbw = HALF_BW_OF(eCSR_BW_80MHz_VAL);
+		else if (htp->apChanWidth == WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)
+			*hbw = HALF_BW_OF(eCSR_BW_160MHz_VAL);
+
+		if (!*hbw && htp->htCapability) {
+			if (htp->htSupportedChannelWidthSet ==
+				eHT_CHANNEL_WIDTH_40MHZ)
+				*hbw = HALF_BW_OF(eCSR_BW_40MHz_VAL);
+			else
+				*hbw = HALF_BW_OF(eCSR_BW_20MHz_VAL);
+		}
+	} else
+#endif
+		if (htp->htCapability) {
+			if (htp->htSupportedChannelWidthSet ==
+					eHT_CHANNEL_WIDTH_40MHZ) {
+				*hbw = HALF_BW_OF(eCSR_BW_40MHz_VAL);
+				if (htp->htSecondaryChannelOffset ==
+					PHY_DOUBLE_CHANNEL_LOW_PRIMARY)
+					cch = CSR_GET_HT40_PLUS_CCH(och);
+				else if (htp->htSecondaryChannelOffset ==
+					PHY_DOUBLE_CHANNEL_HIGH_PRIMARY)
+					cch = CSR_GET_HT40_MINUS_CCH(och);
+			} else {
+				cch = och;
+				*hbw = HALF_BW_OF(eCSR_BW_20MHz_VAL);
+			}
+		}
+
+ret:
+	*cfreq = cds_chan_to_freq(cch);
+	return;
+}
+
+/**
+ * csr_calc_chb_for_sap_phymode() - to calc channel bandwidth for sap phymode
+ * @mac_ctx: pointer to mac context
+ * @sap_ch: SAP operating channel
+ * @sap_phymode: SAP physical mode
+ * @sap_cch: concurrency channel
+ * @sap_hbw: SAP half bw
+ * @chb: channel bandwidth
+ *
+ * This routine is called to calculate channel bandwidth
+ *
+ * Return: none
+ */
+static void csr_calc_chb_for_sap_phymode(tpAniSirGlobal mac_ctx,
+		uint16_t *sap_ch, eCsrPhyMode *sap_phymode,
+		uint16_t *sap_cch, uint16_t *sap_hbw, uint8_t *chb)
+{
+	if (*sap_phymode == eCSR_DOT11_MODE_11n ||
+			*sap_phymode == eCSR_DOT11_MODE_11n_ONLY) {
+
+		*sap_hbw = HALF_BW_OF(eCSR_BW_40MHz_VAL);
+		if (*chb == PHY_DOUBLE_CHANNEL_LOW_PRIMARY)
+			*sap_cch = CSR_GET_HT40_PLUS_CCH(*sap_ch);
+		else if (*chb == PHY_DOUBLE_CHANNEL_HIGH_PRIMARY)
+			*sap_cch = CSR_GET_HT40_MINUS_CCH(*sap_ch);
+
+	}
+#ifdef WLAN_FEATURE_11AC
+	else if (*sap_phymode == eCSR_DOT11_MODE_11ac ||
+			*sap_phymode == eCSR_DOT11_MODE_11ac_ONLY) {
+		/*11AC only 80/40/20 Mhz supported in Rome */
+		if (mac_ctx->roam.configParam.nVhtChannelWidth ==
+				(WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ + 1)) {
+			*sap_hbw = HALF_BW_OF(eCSR_BW_80MHz_VAL);
+			if (*chb ==
+				(PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW - 1))
+				*sap_cch = CSR_GET_HT80_PLUS_LL_CCH(*sap_ch);
+			else if (*chb ==
+				(PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW
+				     - 1))
+				*sap_cch = CSR_GET_HT80_PLUS_HL_CCH(*sap_ch);
+			else if (*chb ==
+				 (PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH
+				     - 1))
+				*sap_cch = CSR_GET_HT80_MINUS_LH_CCH(*sap_ch);
+			else if (*chb ==
+				(PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH
+				     - 1))
+				*sap_cch = CSR_GET_HT80_MINUS_HH_CCH(*sap_ch);
+		} else {
+			*sap_hbw = HALF_BW_OF(eCSR_BW_40MHz_VAL);
+			if (*chb == (PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW
+					- 1))
+				*sap_cch = CSR_GET_HT40_PLUS_CCH(*sap_ch);
+			else if (*chb ==
+				(PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW
+				     - 1))
+				*sap_cch = CSR_GET_HT40_MINUS_CCH(*sap_ch);
+			else if (*chb ==
+				(PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH
+				     - 1))
+				*sap_cch = CSR_GET_HT40_PLUS_CCH(*sap_ch);
+			else if (*chb ==
+				(PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH
+				     - 1))
+				*sap_cch = CSR_GET_HT40_MINUS_CCH(*sap_ch);
+		}
+	}
+#endif
+}
+
+/**
+ * csr_handle_conc_chnl_overlap_for_sap_go - To handle overlap for AP+AP
+ * @mac_ctx: pointer to mac context
+ * @session: Current session
+ * @sap_ch: SAP/GO operating channel
+ * @sap_hbw: SAP/GO half bw
+ * @sap_cfreq: SAP/GO channel frequency
+ * @intf_ch: concurrent SAP/GO operating channel
+ * @intf_hbw: concurrent SAP/GO half bw
+ * @intf_cfreq: concurrent SAP/GO channel frequency
+ *
+ * This routine is called to check if one SAP/GO channel is overlapping with
+ * other SAP/GO channel
+ *
+ * Return: none
+ */
+static void csr_handle_conc_chnl_overlap_for_sap_go(tpAniSirGlobal mac_ctx,
+		tCsrRoamSession *session,
+		uint16_t *sap_ch, uint16_t *sap_hbw, uint16_t *sap_cfreq,
+		uint16_t *intf_ch, uint16_t *intf_hbw, uint16_t *intf_cfreq)
+{
+	/*
+	 * if conc_custom_rule1 is defined then we don't
+	 * want p2pgo to follow SAP's channel or SAP to
+	 * follow P2PGO's channel.
+	 */
+	if (0 == mac_ctx->roam.configParam.conc_custom_rule1 &&
+		0 == mac_ctx->roam.configParam.conc_custom_rule2) {
+		if (*sap_ch == 0) {
+			*sap_ch = session->connectedProfile.operationChannel;
+			csr_get_ch_from_ht_profile(mac_ctx,
+				&session->connectedProfile.HTProfile,
+				*sap_ch, sap_cfreq, sap_hbw);
+		} else if (*sap_ch !=
+				session->connectedProfile.operationChannel) {
+			*intf_ch = session->connectedProfile.operationChannel;
+			csr_get_ch_from_ht_profile(mac_ctx,
+					&session->connectedProfile.HTProfile,
+					*intf_ch, intf_cfreq, intf_hbw);
+		}
+	} else if (*sap_ch == 0 &&
+			(session->pCurRoamProfile->csrPersona ==
+					CDF_SAP_MODE)) {
+		*sap_ch = session->connectedProfile.operationChannel;
+		csr_get_ch_from_ht_profile(mac_ctx,
+				&session->connectedProfile.HTProfile,
+				*sap_ch, sap_cfreq, sap_hbw);
+	}
+}
+
+
+/**
+ * csr_check_concurrent_channel_overlap() - To check concurrent overlap chnls
+ * @mac_ctx: Pointer to mac context
+ * @sap_ch: SAP channel
+ * @sap_phymode: SAP phy mode
+ * @cc_switch_mode: concurrent switch mode
+ *
+ * This routine will be called to check concurrent overlap channels
+ *
+ * Return: uint16_t
+ */
+uint16_t csr_check_concurrent_channel_overlap(tpAniSirGlobal mac_ctx,
+			uint16_t sap_ch, eCsrPhyMode sap_phymode,
+			uint8_t cc_switch_mode)
+{
+	tCsrRoamSession *session = NULL;
+	uint8_t i = 0, chb = PHY_SINGLE_CHANNEL_CENTERED;
+	uint16_t intf_ch = 0, sap_hbw = 0, intf_hbw = 0, intf_cfreq = 0;
+	uint16_t sap_cfreq = 0;
+	uint16_t sap_lfreq, sap_hfreq, intf_lfreq, intf_hfreq, sap_cch;
+
+	if (mac_ctx->roam.configParam.cc_switch_mode ==
+			CDF_MCC_TO_SCC_SWITCH_DISABLE)
+		return 0;
+
+	if (sap_ch != 0) {
+		sap_cch = sap_ch;
+		sap_hbw = HALF_BW_OF(eCSR_BW_20MHz_VAL);
+
+		if (sap_ch > 14)
+			chb = mac_ctx->roam.configParam.channelBondingMode5GHz;
+		else
+			chb = mac_ctx->roam.configParam.channelBondingMode24GHz;
+
+		if (chb)
+			csr_calc_chb_for_sap_phymode(mac_ctx, &sap_ch,
+					&sap_phymode, &sap_cch, &sap_hbw, &chb);
+		sap_cfreq = cds_chan_to_freq(sap_cch);
+	}
+
+	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
+		if (!CSR_IS_SESSION_VALID(mac_ctx, i))
+			continue;
+
+		session = CSR_GET_SESSION(mac_ctx, i);
+		if (NULL == session->pCurRoamProfile)
+			continue;
+		if (((session->pCurRoamProfile->csrPersona == CDF_STA_MODE) ||
+			(session->pCurRoamProfile->csrPersona ==
+				CDF_P2P_CLIENT_MODE)) &&
+			(session->connectState ==
+				eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED)) {
+			intf_ch = session->connectedProfile.operationChannel;
+			csr_get_ch_from_ht_profile(mac_ctx,
+				&session->connectedProfile.HTProfile,
+				intf_ch, &intf_cfreq, &intf_hbw);
+		} else if (((session->pCurRoamProfile->csrPersona ==
+					CDF_P2P_GO_MODE) ||
+				(session->pCurRoamProfile->csrPersona ==
+					CDF_SAP_MODE)) &&
+				(session->connectState !=
+					eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED)) {
+				csr_handle_conc_chnl_overlap_for_sap_go(mac_ctx,
+					session, &sap_ch, &sap_hbw, &sap_cfreq,
+					&intf_ch, &intf_hbw, &intf_cfreq);
+		}
+	}
+
+	if (intf_ch && sap_ch != intf_ch &&
+			cc_switch_mode != CDF_MCC_TO_SCC_SWITCH_FORCE) {
+		sap_lfreq = sap_cfreq - sap_hbw;
+		sap_hfreq = sap_cfreq + sap_hbw;
+		intf_lfreq = intf_cfreq - intf_hbw;
+		intf_hfreq = intf_cfreq + intf_hbw;
+
+		sms_log(mac_ctx, LOGE,
+			FL("\nSAP:  OCH: %03d OCF: %d CCH: %03d CF: %d BW: %d LF: %d HF: %d\n"
+			"INTF: OCH: %03d OCF: %d CCH: %03d CF: %d BW: %d LF: %d HF: %d"),
+			sap_ch, cds_chan_to_freq(sap_ch),
+			cds_freq_to_chan(sap_cfreq), sap_cfreq, sap_hbw * 2,
+			sap_lfreq, sap_hfreq, intf_ch,
+			cds_chan_to_freq(intf_ch), cds_freq_to_chan(intf_cfreq),
+			intf_cfreq, intf_hbw * 2, intf_lfreq, intf_hfreq);
+
+		if (!(((sap_lfreq > intf_lfreq && sap_lfreq < intf_hfreq) ||
+			(sap_hfreq > intf_lfreq && sap_hfreq < intf_hfreq)) ||
+			((intf_lfreq > sap_lfreq && intf_lfreq < sap_hfreq) ||
+			(intf_hfreq > sap_lfreq && intf_hfreq < sap_hfreq))))
+			intf_ch = 0;
+	} else if (intf_ch && sap_ch != intf_ch &&
+				cc_switch_mode == CDF_MCC_TO_SCC_SWITCH_FORCE) {
+		if (!((intf_ch < 14 && sap_ch < 14) ||
+			(intf_ch > 14 && sap_ch > 14)))
+			intf_ch = 0;
+	} else if (intf_ch == sap_ch) {
+		intf_ch = 0;
+	}
+
+	sms_log(mac_ctx, LOGE, FL("##Concurrent Channels %s Interfering"),
+		intf_ch == 0 ? "Not" : "Are");
+	return intf_ch;
+}
+#endif
+
+bool csr_is_all_session_disconnected(tpAniSirGlobal pMac)
+{
+	uint32_t i;
+	bool fRc = true;
+
+	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
+		if (CSR_IS_SESSION_VALID(pMac, i)
+		    && !csr_is_conn_state_disconnected(pMac, i)) {
+			fRc = false;
+			break;
+		}
+	}
+
+	return fRc;
+}
+
+/**
+ * csr_is_sta_session_connected() - to find if concurrent sta is active
+ * @mac_ctx: pointer to mac context
+ *
+ * This function will iterate through each session and check if sta
+ * session exist and active
+ *
+ * Return: true or false
+ */
+bool csr_is_sta_session_connected(tpAniSirGlobal mac_ctx)
+{
+	uint32_t i;
+	tCsrRoamSession *pSession = NULL;
+
+	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
+		if (CSR_IS_SESSION_VALID(mac_ctx, i) &&
+			!csr_is_conn_state_disconnected(mac_ctx, i)) {
+			pSession = CSR_GET_SESSION(mac_ctx, i);
+
+			if ((NULL != pSession->pCurRoamProfile) &&
+				(CDF_STA_MODE ==
+					pSession->pCurRoamProfile->csrPersona))
+				return true;
+		}
+	}
+
+	return false;
+}
+
+/**
+ * csr_is_p2p_session_connected() - to find if any p2p session is active
+ * @mac_ctx: pointer to mac context
+ *
+ * This function will iterate through each session and check if any p2p
+ * session exist and active
+ *
+ * Return: true or false
+ */
+bool csr_is_p2p_session_connected(tpAniSirGlobal pMac)
+{
+	uint32_t i;
+	tCsrRoamSession *pSession = NULL;
+	tCDF_CON_MODE persona;
+
+	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
+		if (CSR_IS_SESSION_VALID(pMac, i)
+		    && !csr_is_conn_state_disconnected(pMac, i)) {
+			pSession = CSR_GET_SESSION(pMac, i);
+			persona = pSession->pCurRoamProfile->csrPersona;
+			if ((NULL != pSession->pCurRoamProfile) &&
+				((CDF_P2P_CLIENT_MODE == persona) ||
+				(CDF_P2P_GO_MODE == persona))) {
+				return true;
+			}
+		}
+	}
+
+	return false;
+}
+
+bool csr_is_any_session_connected(tpAniSirGlobal pMac)
+{
+	uint32_t i, count;
+	bool fRc = false;
+
+	count = 0;
+	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
+		if (CSR_IS_SESSION_VALID(pMac, i)
+		    && !csr_is_conn_state_disconnected(pMac, i))
+			count++;
+	}
+
+	if (count > 0)
+		fRc = true;
+	return fRc;
+}
+
+bool csr_is_infra_connected(tpAniSirGlobal pMac)
+{
+	uint32_t i;
+	bool fRc = false;
+
+	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
+		if (CSR_IS_SESSION_VALID(pMac, i)
+		    && csr_is_conn_state_connected_infra(pMac, i)) {
+			fRc = true;
+			break;
+		}
+	}
+
+	return fRc;
+}
+
+bool csr_is_concurrent_infra_connected(tpAniSirGlobal pMac)
+{
+	uint32_t i, noOfConnectedInfra = 0;
+
+	bool fRc = false;
+
+	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
+		if (CSR_IS_SESSION_VALID(pMac, i)
+		    && csr_is_conn_state_connected_infra(pMac, i)) {
+			++noOfConnectedInfra;
+		}
+	}
+
+	/* More than one Infra Sta Connected */
+	if (noOfConnectedInfra > 1)
+		fRc = true;
+	return fRc;
+}
+
+bool csr_is_ibss_started(tpAniSirGlobal pMac)
+{
+	uint32_t i;
+	bool fRc = false;
+
+	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
+		if (CSR_IS_SESSION_VALID(pMac, i)
+		    && csr_is_conn_state_ibss(pMac, i)) {
+			fRc = true;
+			break;
+		}
+	}
+
+	return fRc;
+}
+
+bool csr_is_btamp_started(tpAniSirGlobal pMac)
+{
+	uint32_t i;
+	bool fRc = false;
+
+	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
+		if (CSR_IS_SESSION_VALID(pMac, i)
+		    && csr_is_conn_state_connected_wds(pMac, i)) {
+			fRc = true;
+			break;
+		}
+	}
+
+	return fRc;
+}
+
+bool csr_is_concurrent_session_running(tpAniSirGlobal pMac)
+{
+	uint32_t sessionId, noOfCocurrentSession = 0;
+	eCsrConnectState connectState;
+
+	bool fRc = false;
+
+	for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++) {
+		if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
+			connectState =
+				pMac->roam.roamSession[sessionId].connectState;
+			if ((eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED ==
+			     connectState)
+			    || (eCSR_ASSOC_STATE_TYPE_INFRA_CONNECTED ==
+				connectState)
+			    || (eCSR_ASSOC_STATE_TYPE_INFRA_DISCONNECTED ==
+				connectState)) {
+				++noOfCocurrentSession;
+			}
+		}
+	}
+
+	/* More than one session is Up and Running */
+	if (noOfCocurrentSession > 1)
+		fRc = true;
+	return fRc;
+}
+
+bool csr_is_infra_ap_started(tpAniSirGlobal pMac)
+{
+	uint32_t sessionId;
+	bool fRc = false;
+
+	for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++) {
+		if (CSR_IS_SESSION_VALID(pMac, sessionId)
+		    && (csr_is_conn_state_connected_infra_ap(pMac, sessionId))) {
+			fRc = true;
+			break;
+		}
+	}
+
+	return fRc;
+
+}
+
+bool csr_is_btamp(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	return csr_is_conn_state_connected_wds(pMac, sessionId);
+}
+
+bool csr_is_conn_state_disconnected(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	return eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED ==
+	       pMac->roam.roamSession[sessionId].connectState;
+}
+
+/**
+ * csr_is_valid_mc_concurrent_session() - To check concurren session is valid
+ * @mac_ctx: pointer to mac context
+ * @session_id: session id
+ * @bss_descr: bss description
+ *
+ * This function validates the concurrent session
+ *
+ * Return: true or false
+ */
+bool csr_is_valid_mc_concurrent_session(tpAniSirGlobal mac_ctx,
+		uint32_t session_id,
+		tSirBssDescription *bss_descr)
+{
+	tCsrRoamSession *pSession = NULL;
+
+	/* Check for MCC support */
+	if (!mac_ctx->roam.configParam.fenableMCCMode)
+		return false;
+	if (!CSR_IS_SESSION_VALID(mac_ctx, session_id))
+		return false;
+	/* Validate BeaconInterval */
+	pSession = CSR_GET_SESSION(mac_ctx, session_id);
+	if (NULL == pSession->pCurRoamProfile)
+		return false;
+	if (CDF_STATUS_SUCCESS ==
+		csr_isconcurrentsession_valid(mac_ctx, session_id,
+			pSession->pCurRoamProfile->csrPersona)) {
+		if (CDF_STATUS_SUCCESS ==
+			csr_validate_mcc_beacon_interval(mac_ctx,
+				bss_descr->channelId,
+				&bss_descr->beaconInterval, session_id,
+				pSession->pCurRoamProfile->csrPersona))
+			return true;
+	}
+	return false;
+}
+
+static tSirMacCapabilityInfo csr_get_bss_capabilities(tSirBssDescription *
+						      pSirBssDesc)
+{
+	tSirMacCapabilityInfo dot11Caps;
+
+	/* tSirMacCapabilityInfo is 16-bit */
+	cdf_get_u16((uint8_t *) &pSirBssDesc->capabilityInfo,
+		    (uint16_t *) &dot11Caps);
+
+	return dot11Caps;
+}
+
+bool csr_is_infra_bss_desc(tSirBssDescription *pSirBssDesc)
+{
+	tSirMacCapabilityInfo dot11Caps = csr_get_bss_capabilities(pSirBssDesc);
+
+	return (bool) dot11Caps.ess;
+}
+
+bool csr_is_ibss_bss_desc(tSirBssDescription *pSirBssDesc)
+{
+	tSirMacCapabilityInfo dot11Caps = csr_get_bss_capabilities(pSirBssDesc);
+
+	return (bool) dot11Caps.ibss;
+}
+
+bool csr_is_qo_s_bss_desc(tSirBssDescription *pSirBssDesc)
+{
+	tSirMacCapabilityInfo dot11Caps = csr_get_bss_capabilities(pSirBssDesc);
+
+	return (bool) dot11Caps.qos;
+}
+
+bool csr_is_privacy(tSirBssDescription *pSirBssDesc)
+{
+	tSirMacCapabilityInfo dot11Caps = csr_get_bss_capabilities(pSirBssDesc);
+
+	return (bool) dot11Caps.privacy;
+}
+
+bool csr_is11d_supported(tpAniSirGlobal pMac)
+{
+	return pMac->roam.configParam.Is11dSupportEnabled;
+}
+
+bool csr_is11h_supported(tpAniSirGlobal pMac)
+{
+	return pMac->roam.configParam.Is11hSupportEnabled;
+}
+
+bool csr_is11e_supported(tpAniSirGlobal pMac)
+{
+	return pMac->roam.configParam.Is11eSupportEnabled;
+}
+
+bool csr_is_mcc_supported(tpAniSirGlobal pMac)
+{
+	return pMac->roam.configParam.fenableMCCMode;
+
+}
+
+bool csr_is_wmm_supported(tpAniSirGlobal pMac)
+{
+	if (eCsrRoamWmmNoQos == pMac->roam.configParam.WMMSupportMode)
+		return false;
+	else
+		return true;
+}
+
+/* pIes is the IEs for pSirBssDesc2 */
+bool csr_is_ssid_equal(tHalHandle hHal, tSirBssDescription *pSirBssDesc1,
+		       tSirBssDescription *pSirBssDesc2, tDot11fBeaconIEs *pIes2)
+{
+	bool fEqual = false;
+	tSirMacSSid Ssid1, Ssid2;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	tDot11fBeaconIEs *pIes1 = NULL;
+	tDot11fBeaconIEs *pIesLocal = pIes2;
+
+	do {
+		if ((NULL == pSirBssDesc1) || (NULL == pSirBssDesc2))
+			break;
+		if (!pIesLocal
+		    &&
+		    !CDF_IS_STATUS_SUCCESS(csr_get_parsed_bss_description_ies
+						   (pMac, pSirBssDesc2,
+						    &pIesLocal))) {
+			sms_log(pMac, LOGE, FL("  fail to parse IEs"));
+			break;
+		}
+		if (!CDF_IS_STATUS_SUCCESS
+			(csr_get_parsed_bss_description_ies(pMac,
+				pSirBssDesc1, &pIes1))) {
+			break;
+		}
+		if ((!pIes1->SSID.present) || (!pIesLocal->SSID.present))
+			break;
+		if (pIes1->SSID.num_ssid != pIesLocal->SSID.num_ssid)
+			break;
+		cdf_mem_copy(Ssid1.ssId, pIes1->SSID.ssid,
+			     pIes1->SSID.num_ssid);
+		cdf_mem_copy(Ssid2.ssId, pIesLocal->SSID.ssid,
+			     pIesLocal->SSID.num_ssid);
+
+		fEqual =
+			cdf_mem_compare(Ssid1.ssId, Ssid2.ssId,
+					pIesLocal->SSID.num_ssid);
+
+	} while (0);
+	if (pIes1)
+		cdf_mem_free(pIes1);
+	if (pIesLocal && !pIes2)
+		cdf_mem_free(pIesLocal);
+
+	return fEqual;
+}
+
+/* pIes can be passed in as NULL if the caller doesn't have one prepared */
+bool csr_is_bss_description_wme(tHalHandle hHal, tSirBssDescription *pSirBssDesc,
+				tDot11fBeaconIEs *pIes)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	/* Assume that WME is found... */
+	bool fWme = true;
+	tDot11fBeaconIEs *pIesTemp = pIes;
+
+	do {
+		if (pIesTemp == NULL) {
+			if (!CDF_IS_STATUS_SUCCESS
+				    (csr_get_parsed_bss_description_ies
+					    (pMac, pSirBssDesc, &pIesTemp))) {
+				fWme = false;
+				break;
+			}
+		}
+		/* if the Wme Info IE is found, then WME is supported... */
+		if (CSR_IS_QOS_BSS(pIesTemp))
+			break;
+		/* if none of these are found, then WME is NOT supported... */
+		fWme = false;
+	} while (0);
+	if (!csr_is_wmm_supported(pMac) && fWme) {
+		if (!pIesTemp->HTCaps.present) {
+			fWme = false;
+		}
+	}
+	if ((pIes == NULL) && (NULL != pIesTemp)) {
+		/* we allocate memory here so free it before returning */
+		cdf_mem_free(pIesTemp);
+	}
+
+	return fWme;
+}
+
+eCsrMediaAccessType csr_get_qo_s_from_bss_desc(tHalHandle hHal,
+					       tSirBssDescription *pSirBssDesc,
+					       tDot11fBeaconIEs *pIes)
+{
+	eCsrMediaAccessType qosType = eCSR_MEDIUM_ACCESS_DCF;
+
+	if (NULL == pIes) {
+		CDF_ASSERT(pIes != NULL);
+		return qosType;
+	}
+
+	do {
+		/* if we find WMM in the Bss Description, then we let this */
+		/* override and use WMM. */
+		if (csr_is_bss_description_wme(hHal, pSirBssDesc, pIes)) {
+			qosType = eCSR_MEDIUM_ACCESS_WMM_eDCF_DSCP;
+		} else {
+			/* if the QoS bit is on, then the AP is advertising 11E QoS... */
+			if (csr_is_qo_s_bss_desc(pSirBssDesc)) {
+				qosType = eCSR_MEDIUM_ACCESS_11e_eDCF;
+			} else {
+				qosType = eCSR_MEDIUM_ACCESS_DCF;
+			}
+			/* scale back based on the types turned on for the adapter... */
+			if (eCSR_MEDIUM_ACCESS_11e_eDCF == qosType
+			    && !csr_is11e_supported(hHal)) {
+				qosType = eCSR_MEDIUM_ACCESS_DCF;
+			}
+		}
+
+	} while (0);
+
+	return qosType;
+}
+
+/* Caller allocates memory for pIEStruct */
+CDF_STATUS csr_parse_bss_description_ies(tHalHandle hHal,
+					  tSirBssDescription *pBssDesc,
+					  tDot11fBeaconIEs *pIEStruct)
+{
+	CDF_STATUS status = CDF_STATUS_E_FAILURE;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	int ieLen =
+		(int)(pBssDesc->length + sizeof(pBssDesc->length) -
+		      GET_FIELD_OFFSET(tSirBssDescription, ieFields));
+
+	if (ieLen > 0 && pIEStruct) {
+		if (!DOT11F_FAILED
+			    (dot11f_unpack_beacon_i_es
+				    (pMac, (uint8_t *) pBssDesc->ieFields, ieLen,
+				    pIEStruct))) {
+			status = CDF_STATUS_SUCCESS;
+		}
+	}
+
+	return status;
+}
+
+/* This function will allocate memory for the parsed IEs to the caller. Caller must free the memory */
+/* after it is done with the data only if this function succeeds */
+CDF_STATUS csr_get_parsed_bss_description_ies(tHalHandle hHal,
+					       tSirBssDescription *pBssDesc,
+					       tDot11fBeaconIEs **ppIEStruct)
+{
+	CDF_STATUS status = CDF_STATUS_E_INVAL;
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	if (pBssDesc && ppIEStruct) {
+		*ppIEStruct = cdf_mem_malloc(sizeof(tDot11fBeaconIEs));
+		if ((*ppIEStruct) != NULL) {
+			cdf_mem_set((void *)*ppIEStruct,
+				    sizeof(tDot11fBeaconIEs), 0);
+			status =
+				csr_parse_bss_description_ies(hHal, pBssDesc,
+							       *ppIEStruct);
+			if (!CDF_IS_STATUS_SUCCESS(status)) {
+				cdf_mem_free(*ppIEStruct);
+				*ppIEStruct = NULL;
+			}
+		} else {
+			sms_log(pMac, LOGE, FL(" failed to allocate memory"));
+			CDF_ASSERT(0);
+			return CDF_STATUS_E_NOMEM;
+		}
+	}
+
+	return status;
+}
+
+bool csr_is_nullssid(uint8_t *pBssSsid, uint8_t len)
+{
+	bool fNullSsid = false;
+
+	uint32_t SsidLength;
+	uint8_t *pSsidStr;
+
+	do {
+		if (0 == len) {
+			fNullSsid = true;
+			break;
+		}
+		/* Consider 0 or space for hidden SSID */
+		if (0 == pBssSsid[0]) {
+			fNullSsid = true;
+			break;
+		}
+
+		SsidLength = len;
+		pSsidStr = pBssSsid;
+
+		while (SsidLength) {
+			if (*pSsidStr)
+				break;
+
+			pSsidStr++;
+			SsidLength--;
+		}
+
+		if (0 == SsidLength) {
+			fNullSsid = true;
+			break;
+		}
+	} while (0);
+
+	return fNullSsid;
+}
+
+uint32_t csr_get_frag_thresh(tHalHandle hHal)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	return pMac->roam.configParam.FragmentationThreshold;
+}
+
+uint32_t csr_get_rts_thresh(tHalHandle hHal)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+	return pMac->roam.configParam.RTSThreshold;
+}
+
+eCsrPhyMode csr_translate_to_phy_mode_from_bss_desc(tSirBssDescription *pSirBssDesc)
+{
+	eCsrPhyMode phyMode;
+
+	switch (pSirBssDesc->nwType) {
+	case eSIR_11A_NW_TYPE:
+		phyMode = eCSR_DOT11_MODE_11a;
+		break;
+
+	case eSIR_11B_NW_TYPE:
+		phyMode = eCSR_DOT11_MODE_11b;
+		break;
+
+	case eSIR_11G_NW_TYPE:
+		phyMode = eCSR_DOT11_MODE_11g;
+		break;
+
+	case eSIR_11N_NW_TYPE:
+		phyMode = eCSR_DOT11_MODE_11n;
+		break;
+#ifdef WLAN_FEATURE_11AC
+	case eSIR_11AC_NW_TYPE:
+	default:
+		phyMode = eCSR_DOT11_MODE_11ac;
+#else
+	default:
+		phyMode = eCSR_DOT11_MODE_11n;
+#endif
+		break;
+	}
+	return phyMode;
+}
+
+uint32_t csr_translate_to_wni_cfg_dot11_mode(tpAniSirGlobal pMac,
+					     eCsrCfgDot11Mode csrDot11Mode)
+{
+	uint32_t ret;
+
+	switch (csrDot11Mode) {
+	case eCSR_CFG_DOT11_MODE_AUTO:
+		sms_log(pMac, LOGW,
+			FL("  Warning: sees eCSR_CFG_DOT11_MODE_AUTO "));
+		if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC))
+			ret = WNI_CFG_DOT11_MODE_11AC;
+		else
+			ret = WNI_CFG_DOT11_MODE_11N;
+		break;
+	case eCSR_CFG_DOT11_MODE_11A:
+		ret = WNI_CFG_DOT11_MODE_11A;
+		break;
+	case eCSR_CFG_DOT11_MODE_11B:
+		ret = WNI_CFG_DOT11_MODE_11B;
+		break;
+	case eCSR_CFG_DOT11_MODE_11G:
+		ret = WNI_CFG_DOT11_MODE_11G;
+		break;
+	case eCSR_CFG_DOT11_MODE_11N:
+		ret = WNI_CFG_DOT11_MODE_11N;
+		break;
+	case eCSR_CFG_DOT11_MODE_11G_ONLY:
+		ret = WNI_CFG_DOT11_MODE_11G_ONLY;
+		break;
+	case eCSR_CFG_DOT11_MODE_11N_ONLY:
+		ret = WNI_CFG_DOT11_MODE_11N_ONLY;
+		break;
+	case eCSR_CFG_DOT11_MODE_11AC_ONLY:
+		if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC))
+			ret = WNI_CFG_DOT11_MODE_11AC_ONLY;
+		else
+			ret = WNI_CFG_DOT11_MODE_11N;
+		break;
+	case eCSR_CFG_DOT11_MODE_11AC:
+		if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC))
+			ret = WNI_CFG_DOT11_MODE_11AC;
+		else
+			ret = WNI_CFG_DOT11_MODE_11N;
+		break;
+	default:
+		sms_log(pMac, LOGW, FL("doesn't expect %d as csrDo11Mode"),
+			csrDot11Mode);
+		if (eCSR_BAND_24 == pMac->roam.configParam.eBand) {
+			ret = WNI_CFG_DOT11_MODE_11G;
+		} else {
+			ret = WNI_CFG_DOT11_MODE_11A;
+		}
+		break;
+	}
+
+	return ret;
+}
+
+/**
+ * csr_get_phy_mode_from_bss() - Get Phy Mode
+ * @pMac:           Global MAC context
+ * @pBSSDescription: BSS Descriptor
+ * @pPhyMode:        Physical Mode
+ * @pIes:            Pointer to the IE fields
+ *
+ * This function should only return the super set of supported modes
+ * 11n implies 11b/g/a/n.
+ *
+ * Return: success
+ **/
+CDF_STATUS csr_get_phy_mode_from_bss(tpAniSirGlobal pMac,
+		tSirBssDescription *pBSSDescription,
+		eCsrPhyMode *pPhyMode, tDot11fBeaconIEs *pIes)
+{
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	eCsrPhyMode phyMode =
+		csr_translate_to_phy_mode_from_bss_desc(pBSSDescription);
+
+	if (pIes) {
+		if (pIes->HTCaps.present) {
+			phyMode = eCSR_DOT11_MODE_11n;
+#ifdef WLAN_FEATURE_11AC
+			if (IS_BSS_VHT_CAPABLE(pIes->VHTCaps) ||
+				IS_BSS_VHT_CAPABLE(pIes->vendor2_ie.VHTCaps))
+				phyMode = eCSR_DOT11_MODE_11ac;
+#endif
+		}
+		*pPhyMode = phyMode;
+	}
+
+	return status;
+}
+
+/**
+ * csr_get_phy_mode_in_use() - to get phymode
+ * @phyModeIn: physical mode
+ * @bssPhyMode: physical mode in bss
+ * @f5GhzBand: 5Ghz band
+ * @pCfgDot11ModeToUse: dot11 mode in use
+ *
+ * This function returns the correct eCSR_CFG_DOT11_MODE is the two phyModes
+ * matches. bssPhyMode is the mode derived from the BSS description
+ * f5GhzBand is derived from the channel id of BSS description
+ *
+ * Return: true or false
+ */
+bool csr_get_phy_mode_in_use(eCsrPhyMode phyModeIn, eCsrPhyMode bssPhyMode,
+			     bool f5GhzBand, eCsrCfgDot11Mode *pCfgDot11ModeToUse)
+{
+	bool fMatch = false;
+	eCsrCfgDot11Mode cfgDot11Mode;
+	cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N;
+
+	switch (phyModeIn) {
+	/* 11a or 11b or 11g */
+	case eCSR_DOT11_MODE_abg:
+		fMatch = true;
+		if (f5GhzBand)
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A;
+		else if (eCSR_DOT11_MODE_11b == bssPhyMode)
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B;
+		else
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G;
+		break;
+
+	case eCSR_DOT11_MODE_11a:
+		if (f5GhzBand) {
+			fMatch = true;
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A;
+		}
+		break;
+
+	case eCSR_DOT11_MODE_11g:
+		if (!f5GhzBand) {
+			fMatch = true;
+			if (eCSR_DOT11_MODE_11b == bssPhyMode)
+				cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B;
+			else
+				cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G;
+		}
+		break;
+
+	case eCSR_DOT11_MODE_11g_ONLY:
+		if (eCSR_DOT11_MODE_11g == bssPhyMode) {
+			fMatch = true;
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G;
+		}
+		break;
+
+	case eCSR_DOT11_MODE_11b:
+		if (!f5GhzBand) {
+			fMatch = true;
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B;
+		}
+		break;
+
+	case eCSR_DOT11_MODE_11b_ONLY:
+		if (eCSR_DOT11_MODE_11b == bssPhyMode) {
+			fMatch = true;
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B;
+		}
+		break;
+
+	case eCSR_DOT11_MODE_11n:
+		fMatch = true;
+		switch (bssPhyMode) {
+		case eCSR_DOT11_MODE_11g:
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G;
+			break;
+		case eCSR_DOT11_MODE_11b:
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B;
+			break;
+		case eCSR_DOT11_MODE_11a:
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A;
+			break;
+		case eCSR_DOT11_MODE_11n:
+#ifdef WLAN_FEATURE_11AC
+		case eCSR_DOT11_MODE_11ac:
+#endif
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N;
+			break;
+
+		default:
+#ifdef WLAN_FEATURE_11AC
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC;
+#else
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N;
+#endif
+			break;
+		}
+		break;
+
+	case eCSR_DOT11_MODE_11n_ONLY:
+		if ((eCSR_DOT11_MODE_11n == bssPhyMode)) {
+			fMatch = true;
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N;
+
+		}
+
+		break;
+#ifdef WLAN_FEATURE_11AC
+	case eCSR_DOT11_MODE_11ac:
+		fMatch = true;
+		switch (bssPhyMode) {
+		case eCSR_DOT11_MODE_11g:
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G;
+			break;
+		case eCSR_DOT11_MODE_11b:
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B;
+			break;
+		case eCSR_DOT11_MODE_11a:
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A;
+			break;
+		case eCSR_DOT11_MODE_11n:
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N;
+			break;
+		case eCSR_DOT11_MODE_11ac:
+		default:
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC;
+			break;
+		}
+		break;
+
+	case eCSR_DOT11_MODE_11ac_ONLY:
+		if ((eCSR_DOT11_MODE_11ac == bssPhyMode)) {
+			fMatch = true;
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC;
+		}
+		break;
+#endif
+
+	default:
+		fMatch = true;
+		switch (bssPhyMode) {
+		case eCSR_DOT11_MODE_11g:
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G;
+			break;
+		case eCSR_DOT11_MODE_11b:
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B;
+			break;
+		case eCSR_DOT11_MODE_11a:
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A;
+			break;
+		case eCSR_DOT11_MODE_11n:
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N;
+			break;
+#ifdef WLAN_FEATURE_11AC
+		case eCSR_DOT11_MODE_11ac:
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC;
+			break;
+#endif
+		default:
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_AUTO;
+			break;
+		}
+		break;
+	}
+
+	if (fMatch && pCfgDot11ModeToUse) {
+#ifdef WLAN_FEATURE_11AC
+		if (cfgDot11Mode == eCSR_CFG_DOT11_MODE_11AC
+		    && (!IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)))
+			*pCfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11N;
+		else
+#endif
+			*pCfgDot11ModeToUse = cfgDot11Mode;
+	}
+	return fMatch;
+}
+
+/**
+ * csr_is_phy_mode_match() - to find if phy mode matches
+ * @pMac: pointer to mac context
+ * @phyMode: physical mode
+ * @pSirBssDesc: bss description
+ * @pProfile: pointer to roam profile
+ * @pReturnCfgDot11Mode: dot1 mode to return
+ * @pIes: pointer to IEs
+ *
+ * This function decides whether the one of the bit of phyMode is matching the
+ * mode in the BSS and allowed by the user setting
+ *
+ * Return: true or false based on mode that fits the criteria
+ */
+bool csr_is_phy_mode_match(tpAniSirGlobal pMac, uint32_t phyMode,
+			   tSirBssDescription *pSirBssDesc,
+			   tCsrRoamProfile *pProfile,
+			   eCsrCfgDot11Mode *pReturnCfgDot11Mode,
+			   tDot11fBeaconIEs *pIes)
+{
+	bool fMatch = false;
+	eCsrPhyMode phyModeInBssDesc = eCSR_DOT11_MODE_AUTO, phyMode2;
+	eCsrCfgDot11Mode cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_AUTO;
+	uint32_t bitMask, loopCount;
+
+	if (!CDF_IS_STATUS_SUCCESS(csr_get_phy_mode_from_bss(pMac, pSirBssDesc,
+					&phyModeInBssDesc, pIes)))
+		return fMatch;
+
+	if ((0 == phyMode) || (eCSR_DOT11_MODE_AUTO & phyMode)) {
+		if (eCSR_CFG_DOT11_MODE_ABG ==
+				pMac->roam.configParam.uCfgDot11Mode)
+			phyMode = eCSR_DOT11_MODE_abg;
+		else if (eCSR_CFG_DOT11_MODE_AUTO ==
+				pMac->roam.configParam.uCfgDot11Mode)
+#ifdef WLAN_FEATURE_11AC
+			phyMode = eCSR_DOT11_MODE_11ac;
+#else
+			phyMode = eCSR_DOT11_MODE_11n;
+#endif
+
+		else
+			/* user's pick */
+			phyMode = pMac->roam.configParam.phyMode;
+	}
+
+	if ((0 == phyMode) || (eCSR_DOT11_MODE_AUTO & phyMode)) {
+		if (0 != phyMode) {
+			if (eCSR_DOT11_MODE_AUTO & phyMode) {
+				phyMode2 =
+					eCSR_DOT11_MODE_AUTO & phyMode;
+			}
+		} else {
+			phyMode2 = phyMode;
+		}
+		fMatch = csr_get_phy_mode_in_use(phyMode2, phyModeInBssDesc,
+				CDS_IS_CHANNEL_5GHZ(pSirBssDesc->channelId),
+				&cfgDot11ModeToUse);
+	} else {
+		bitMask = 1;
+		loopCount = 0;
+		while (loopCount < eCSR_NUM_PHY_MODE) {
+			phyMode2 = (phyMode & (bitMask << loopCount++));
+			if (0 != phyMode2 && csr_get_phy_mode_in_use(phyMode2,
+						phyModeInBssDesc,
+						CDS_IS_CHANNEL_5GHZ
+						(pSirBssDesc->channelId),
+						&cfgDot11ModeToUse)) {
+				fMatch = true;
+				break;
+			}
+		}
+	}
+	if (fMatch && pReturnCfgDot11Mode) {
+		if (pProfile) {
+			/*
+			 * IEEE 11n spec (8.4.3): HT STA shall
+			 * eliminate TKIP as a choice for the pairwise
+			 * cipher suite if CCMP is advertised by the AP
+			 * or if the AP included an HT capabilities
+			 * element in its Beacons and Probe Response.
+			 */
+			if ((!CSR_IS_11n_ALLOWED(
+					pProfile->negotiatedUCEncryptionType))
+					&& ((eCSR_CFG_DOT11_MODE_11N ==
+						cfgDot11ModeToUse) ||
+#ifdef WLAN_FEATURE_11AC
+					(eCSR_CFG_DOT11_MODE_11AC ==
+						cfgDot11ModeToUse)
+#endif
+				)) {
+				/* We cannot do 11n here */
+				if (!CDS_IS_CHANNEL_5GHZ
+						(pSirBssDesc->channelId)) {
+					cfgDot11ModeToUse =
+						eCSR_CFG_DOT11_MODE_11G;
+				} else {
+					cfgDot11ModeToUse =
+						eCSR_CFG_DOT11_MODE_11A;
+				}
+			}
+		}
+		*pReturnCfgDot11Mode = cfgDot11ModeToUse;
+	}
+
+	return fMatch;
+}
+
+eCsrCfgDot11Mode csr_find_best_phy_mode(tpAniSirGlobal pMac, uint32_t phyMode)
+{
+	eCsrCfgDot11Mode cfgDot11ModeToUse;
+	eCsrBand eBand = pMac->roam.configParam.eBand;
+
+	if ((0 == phyMode) ||
+#ifdef WLAN_FEATURE_11AC
+	    (eCSR_DOT11_MODE_11ac & phyMode) ||
+#endif
+	    (eCSR_DOT11_MODE_AUTO & phyMode)) {
+#ifdef WLAN_FEATURE_11AC
+		if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) {
+			cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11AC;
+		} else
+#endif
+		{
+			/* Default to 11N mode if user has configured 11ac mode
+			 * and FW doesn't supports 11ac mode .
+			 */
+			cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11N;
+		}
+	} else {
+		if ((eCSR_DOT11_MODE_11n | eCSR_DOT11_MODE_11n_ONLY) & phyMode) {
+			cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11N;
+		} else if (eCSR_DOT11_MODE_abg & phyMode) {
+			if (eCSR_BAND_24 != eBand) {
+				cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11A;
+			} else {
+				cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11G;
+			}
+		} else if (eCSR_DOT11_MODE_11a & phyMode) {
+			cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11A;
+		} else if ((eCSR_DOT11_MODE_11g | eCSR_DOT11_MODE_11g_ONLY) &
+			   phyMode) {
+			cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11G;
+		} else {
+			cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11B;
+		}
+	}
+
+	return cfgDot11ModeToUse;
+}
+
+uint32_t csr_get11h_power_constraint(tHalHandle hHal,
+				     tDot11fIEPowerConstraints *pPowerConstraint)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	uint32_t localPowerConstraint = 0;
+
+	/* check if .11h support is enabled, if not, the power constraint is 0. */
+	if (pMac->roam.configParam.Is11hSupportEnabled
+	    && pPowerConstraint->present) {
+		localPowerConstraint = pPowerConstraint->localPowerConstraints;
+	}
+
+	return localPowerConstraint;
+}
+
+bool csr_is_profile_wpa(tCsrRoamProfile *pProfile)
+{
+	bool fWpaProfile = false;
+
+	switch (pProfile->negotiatedAuthType) {
+	case eCSR_AUTH_TYPE_WPA:
+	case eCSR_AUTH_TYPE_WPA_PSK:
+	case eCSR_AUTH_TYPE_WPA_NONE:
+#ifdef FEATURE_WLAN_ESE
+	case eCSR_AUTH_TYPE_CCKM_WPA:
+#endif
+		fWpaProfile = true;
+		break;
+
+	default:
+		fWpaProfile = false;
+		break;
+	}
+
+	if (fWpaProfile) {
+		switch (pProfile->negotiatedUCEncryptionType) {
+		case eCSR_ENCRYPT_TYPE_WEP40:
+		case eCSR_ENCRYPT_TYPE_WEP104:
+		case eCSR_ENCRYPT_TYPE_TKIP:
+		case eCSR_ENCRYPT_TYPE_AES:
+			fWpaProfile = true;
+			break;
+
+		default:
+			fWpaProfile = false;
+			break;
+		}
+	}
+	return fWpaProfile;
+}
+
+bool csr_is_profile_rsn(tCsrRoamProfile *pProfile)
+{
+	bool fRSNProfile = false;
+
+	switch (pProfile->negotiatedAuthType) {
+	case eCSR_AUTH_TYPE_RSN:
+	case eCSR_AUTH_TYPE_RSN_PSK:
+#ifdef WLAN_FEATURE_VOWIFI_11R
+	case eCSR_AUTH_TYPE_FT_RSN:
+	case eCSR_AUTH_TYPE_FT_RSN_PSK:
+#endif
+#ifdef FEATURE_WLAN_ESE
+	case eCSR_AUTH_TYPE_CCKM_RSN:
+#endif
+#ifdef WLAN_FEATURE_11W
+	case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
+	case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
+#endif
+		fRSNProfile = true;
+		break;
+
+	default:
+		fRSNProfile = false;
+		break;
+	}
+
+	if (fRSNProfile) {
+		switch (pProfile->negotiatedUCEncryptionType) {
+		/* !!REVIEW - For WPA2, use of RSN IE mandates */
+		/* use of AES as encryption. Here, we qualify */
+		/* even if encryption type is WEP or TKIP */
+		case eCSR_ENCRYPT_TYPE_WEP40:
+		case eCSR_ENCRYPT_TYPE_WEP104:
+		case eCSR_ENCRYPT_TYPE_TKIP:
+		case eCSR_ENCRYPT_TYPE_AES:
+			fRSNProfile = true;
+			break;
+
+		default:
+			fRSNProfile = false;
+			break;
+		}
+	}
+	return fRSNProfile;
+}
+
+/**
+ * csr_isconcurrentsession_valid() - check if concurrent session is valid
+ * @mac_ctx: pointer to mac context
+ * @cur_sessionid: current session id
+ * @cur_bss_persona: current BSS persona
+ *
+ * This function will check if concurrent session is valid
+ *
+ * Return: CDF_STATUS
+ */
+CDF_STATUS
+csr_isconcurrentsession_valid(tpAniSirGlobal mac_ctx, uint32_t cur_sessionid,
+			      tCDF_CON_MODE cur_bss_persona)
+{
+	uint32_t sessionid = 0;
+	tCDF_CON_MODE bss_persona;
+	eCsrConnectState connect_state, temp;
+	tCsrRoamSession *roam_session;
+
+	for (sessionid = 0; sessionid < CSR_ROAM_SESSION_MAX; sessionid++) {
+		if (cur_sessionid == sessionid)
+			continue;
+		if (!CSR_IS_SESSION_VALID(mac_ctx, sessionid))
+			continue;
+		roam_session = &mac_ctx->roam.roamSession[sessionid];
+		bss_persona = roam_session->bssParams.bssPersona;
+		connect_state = roam_session->connectState;
+
+		switch (cur_bss_persona) {
+		case CDF_STA_MODE:
+			CDF_TRACE(CDF_MODULE_ID_SME,
+					CDF_TRACE_LEVEL_INFO,
+					FL("** STA session **"));
+			return CDF_STATUS_SUCCESS;
+
+		case CDF_SAP_MODE:
+			temp = eCSR_ASSOC_STATE_TYPE_IBSS_DISCONNECTED;
+#ifndef WLAN_FEATURE_MBSSID
+			if ((bss_persona == CDF_SAP_MODE) &&
+					(connect_state !=
+					 eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED)) {
+				CDF_TRACE(CDF_MODULE_ID_SME,
+						CDF_TRACE_LEVEL_ERROR,
+						FL("sap mode already exist"));
+				return CDF_STATUS_E_FAILURE;
+			} else
+#endif
+				if ((bss_persona == CDF_IBSS_MODE)
+					&& (connect_state != temp)) {
+					CDF_TRACE(CDF_MODULE_ID_SME,
+							CDF_TRACE_LEVEL_ERROR,
+							FL("Can't start GO"));
+					return CDF_STATUS_E_FAILURE;
+				}
+			break;
+
+		case CDF_P2P_GO_MODE:
+			temp = eCSR_ASSOC_STATE_TYPE_IBSS_DISCONNECTED;
+			if ((bss_persona == CDF_P2P_GO_MODE) &&
+					(connect_state !=
+					 eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED)) {
+				CDF_TRACE(CDF_MODULE_ID_SME,
+						CDF_TRACE_LEVEL_ERROR,
+						FL("GO mode already exists"));
+				return CDF_STATUS_E_FAILURE;
+			} else if ((bss_persona == CDF_IBSS_MODE)
+					&& (connect_state != temp)) {
+				CDF_TRACE(CDF_MODULE_ID_SME,
+						CDF_TRACE_LEVEL_ERROR,
+						FL("Can't start SAP"));
+				return CDF_STATUS_E_FAILURE;
+			}
+			break;
+		case CDF_IBSS_MODE:
+			if ((bss_persona == CDF_IBSS_MODE) && (connect_state !=
+					eCSR_ASSOC_STATE_TYPE_IBSS_CONNECTED)) {
+				CDF_TRACE(CDF_MODULE_ID_SME,
+						CDF_TRACE_LEVEL_ERROR,
+						FL("IBSS mode already exist"));
+				return CDF_STATUS_E_FAILURE;
+			} else if (((bss_persona == CDF_P2P_GO_MODE) ||
+					(bss_persona == CDF_SAP_MODE)) &&
+					(connect_state !=
+					 eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED)) {
+				CDF_TRACE(CDF_MODULE_ID_SME,
+						CDF_TRACE_LEVEL_ERROR,
+						FL("Can't start GO"));
+				return CDF_STATUS_E_FAILURE;
+			}
+			break;
+		case CDF_P2P_CLIENT_MODE:
+			CDF_TRACE(CDF_MODULE_ID_SME,
+				CDF_TRACE_LEVEL_INFO,
+				FL("**P2P-Client session**"));
+			return CDF_STATUS_SUCCESS;
+		default:
+			CDF_TRACE(CDF_MODULE_ID_SME,
+				CDF_TRACE_LEVEL_ERROR,
+				FL("Persona not handled = %d"),
+				cur_bss_persona);
+			break;
+		}
+	}
+	return CDF_STATUS_SUCCESS;
+
+}
+
+/**
+ * csr_update_mcc_p2p_beacon_interval() - update p2p beacon interval
+ * @mac_ctx: pointer to mac context
+ *
+ * This function is to update the mcc p2p beacon interval
+ *
+ * Return: CDF_STATUS
+ */
+CDF_STATUS csr_update_mcc_p2p_beacon_interval(tpAniSirGlobal mac_ctx)
+{
+	uint32_t session_id = 0;
+	tCsrRoamSession *roam_session;
+
+	/* If MCC is not supported just break and return SUCCESS */
+	if (!mac_ctx->roam.configParam.fenableMCCMode)
+		return CDF_STATUS_E_FAILURE;
+
+	for (session_id = 0; session_id < CSR_ROAM_SESSION_MAX; session_id++) {
+		/*
+		 * If GO in MCC support different beacon interval,
+		 * change the BI of the P2P-GO
+		 */
+		roam_session = &mac_ctx->roam.roamSession[session_id];
+		if (roam_session->bssParams.bssPersona != CDF_P2P_GO_MODE)
+			continue;
+		/*
+		 * Handle different BI scneario based on the
+		 * configuration set.If Config is set to 0x02 then
+		 * Disconnect all the P2P clients associated. If config
+		 * is set to 0x04 then update the BI without
+		 * disconnecting all the clients
+		 */
+		if ((mac_ctx->roam.configParam.fAllowMCCGODiffBI == 0x04)
+				&& (roam_session->bssParams.
+					updatebeaconInterval)) {
+			return csr_send_chng_mcc_beacon_interval(mac_ctx,
+					session_id);
+		} else if (roam_session->bssParams.updatebeaconInterval) {
+			/*
+			 * If the configuration of fAllowMCCGODiffBI is set to
+			 * other than 0x04
+			 */
+			return csr_roam_call_callback(mac_ctx,
+					session_id,
+					NULL, 0,
+					eCSR_ROAM_DISCONNECT_ALL_P2P_CLIENTS,
+					eCSR_ROAM_RESULT_NONE);
+		}
+	}
+	return CDF_STATUS_E_FAILURE;
+}
+
+uint16_t csr_calculate_mcc_beacon_interval(tpAniSirGlobal pMac, uint16_t sta_bi,
+					   uint16_t go_gbi)
+{
+	uint8_t num_beacons = 0;
+	uint8_t is_multiple = 0;
+	uint16_t go_cbi = 0;
+	uint16_t go_fbi = 0;
+	uint16_t sta_cbi = 0;
+
+	/* If GO's given beacon Interval is less than 100 */
+	if (go_gbi < 100)
+		go_cbi = 100;
+	/* if GO's given beacon Interval is greater than or equal to 100 */
+	else
+		go_cbi = 100 + (go_gbi % 100);
+
+	if (sta_bi == 0) {
+		/* There is possibility to receive zero as value.
+		   Which will cause divide by zero. Hence initialise with 100
+		 */
+		sta_bi = 100;
+		sms_log(pMac, LOGW,
+			FL("sta_bi 2nd parameter is zero, initialize to %d"),
+			sta_bi);
+	}
+	/* check, if either one is multiple of another */
+	if (sta_bi > go_cbi) {
+		is_multiple = !(sta_bi % go_cbi);
+	} else {
+		is_multiple = !(go_cbi % sta_bi);
+	}
+	/* if it is multiple, then accept GO's beacon interval range [100,199] as it  is */
+	if (is_multiple) {
+		return go_cbi;
+	}
+	/* else , if it is not multiple, then then check for number of beacons to be */
+	/* inserted based on sta BI */
+	num_beacons = sta_bi / 100;
+	if (num_beacons) {
+		/* GO's final beacon interval will be aligned to sta beacon interval, but */
+		/* in the range of [100, 199]. */
+		sta_cbi = sta_bi / num_beacons;
+		go_fbi = sta_cbi;
+	} else {
+		/* if STA beacon interval is less than 100, use GO's change bacon interval */
+		/* instead of updating to STA's beacon interval. */
+		go_fbi = go_cbi;
+	}
+	return go_fbi;
+}
+
+CDF_STATUS csr_validate_mcc_beacon_interval(tpAniSirGlobal pMac, uint8_t channelId,
+					    uint16_t *beaconInterval,
+					    uint32_t cursessionId,
+					    tCDF_CON_MODE currBssPersona)
+{
+	uint32_t sessionId = 0;
+	uint16_t new_beaconInterval = 0;
+
+	/* If MCC is not supported just break */
+	if (!pMac->roam.configParam.fenableMCCMode) {
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++) {
+		if (cursessionId != sessionId) {
+			if (!CSR_IS_SESSION_VALID(pMac, sessionId)) {
+				continue;
+			}
+
+			switch (currBssPersona) {
+			case CDF_STA_MODE:
+				if (pMac->roam.roamSession[sessionId].
+					pCurRoamProfile &&
+				   (pMac->roam.roamSession[sessionId].
+					pCurRoamProfile->csrPersona ==
+				    CDF_P2P_CLIENT_MODE)) {
+					/* check for P2P client mode */
+					sms_log(pMac, LOG1,
+						FL
+							(" Beacon Interval Validation not required for STA/CLIENT"));
+				}
+				/*
+				 * IF SAP has started and STA wants to connect
+				 * on different channel MCC should
+				 *  MCC should not be enabled so making it
+				 * false to enforce on same channel
+				 */
+				else if (pMac->roam.roamSession[sessionId].
+					 bssParams.bssPersona ==
+					 CDF_SAP_MODE) {
+					if (pMac->roam.roamSession[sessionId].
+					    bssParams.operationChn !=
+					    channelId) {
+						sms_log(pMac, LOGE,
+							FL
+								("*** MCC with SAP+STA sessions ****"));
+						return CDF_STATUS_SUCCESS;
+					}
+				} else if (pMac->roam.roamSession[sessionId].
+						bssParams.bssPersona ==
+						CDF_P2P_GO_MODE) {
+					/*
+					 * Check for P2P go scenario
+					 * if GO in MCC support different
+					 * beacon interval,
+					 * change the BI of the P2P-GO
+					 */
+					if ((pMac->roam.roamSession[sessionId].
+					     bssParams.operationChn !=
+					     channelId)
+					    && (pMac->roam.
+						roamSession[sessionId].
+						bssParams.beaconInterval !=
+						*beaconInterval)) {
+						/* if GO in MCC support different beacon interval, return success */
+						if (pMac->roam.configParam.
+						    fAllowMCCGODiffBI == 0x01) {
+							return
+								CDF_STATUS_SUCCESS;
+						}
+						/* Send only Broadcast disassoc and update beaconInterval */
+						/* If configuration is set to 0x04 then dont */
+						/* disconnect all the station */
+						else if ((pMac->roam.
+							  configParam.
+							  fAllowMCCGODiffBI ==
+							  0x02)
+							 || (pMac->roam.
+							     configParam.
+							     fAllowMCCGODiffBI
+							     == 0x04)) {
+							/* Check to pass the right beacon Interval */
+							 if (pMac->roam.configParam.conc_custom_rule1 ||
+								pMac->roam.configParam.conc_custom_rule2) {
+								 new_beaconInterval = CSR_CUSTOM_CONC_GO_BI;
+							 } else {
+								 new_beaconInterval =
+									 csr_calculate_mcc_beacon_interval(pMac,
+										*beaconInterval,
+										pMac->roam.
+										roamSession
+										[sessionId].
+										bssParams.
+										beaconInterval);
+							 }
+							sms_log(pMac, LOG1,
+								FL
+									(" Peer AP BI : %d, new Beacon Interval: %d"),
+								*beaconInterval,
+								new_beaconInterval);
+							/* Update the becon Interval */
+							if (new_beaconInterval
+							    !=
+							    pMac->roam.
+							    roamSession
+							    [sessionId].
+							    bssParams.
+							    beaconInterval) {
+								/* Update the beaconInterval now */
+								sms_log(pMac,
+									LOGE,
+									FL
+										(" Beacon Interval got changed config used: %d\n"),
+									pMac->
+									roam.
+									configParam.
+									fAllowMCCGODiffBI);
+
+								pMac->roam.
+								roamSession
+								[sessionId].
+								bssParams.
+								beaconInterval
+									=
+										new_beaconInterval;
+								pMac->roam.
+								roamSession
+								[sessionId].
+								bssParams.
+								updatebeaconInterval
+									= true;
+								return
+									csr_update_mcc_p2p_beacon_interval
+										(pMac);
+							}
+							return
+								CDF_STATUS_SUCCESS;
+						}
+						/* Disconnect the P2P session */
+						else if (pMac->roam.configParam.
+							 fAllowMCCGODiffBI ==
+							 0x03) {
+							pMac->roam.roamSession[sessionId].bssParams.updatebeaconInterval = false;
+							return
+								csr_roam_call_callback
+									(pMac, sessionId,
+									NULL, 0,
+									eCSR_ROAM_SEND_P2P_STOP_BSS,
+									eCSR_ROAM_RESULT_NONE);
+						} else {
+							sms_log(pMac, LOGE,
+								FL
+									("BeaconInterval is different cannot connect to preferred AP..."));
+							return
+								CDF_STATUS_E_FAILURE;
+						}
+					}
+				}
+				break;
+
+			case CDF_P2P_CLIENT_MODE:
+				if (pMac->roam.roamSession[sessionId].
+					pCurRoamProfile &&
+				   (pMac->roam.roamSession[sessionId].
+					pCurRoamProfile->csrPersona ==
+					CDF_STA_MODE)) {
+					/* check for P2P client mode */
+					sms_log(pMac, LOG1,
+						FL
+							(" Ignore Beacon Interval Validation..."));
+				} else if (pMac->roam.roamSession[sessionId].
+						bssParams.bssPersona ==
+						CDF_P2P_GO_MODE) {
+					/* Check for P2P go scenario */
+					if ((pMac->roam.roamSession[sessionId].
+					     bssParams.operationChn !=
+					     channelId)
+					    && (pMac->roam.
+						roamSession[sessionId].
+						bssParams.beaconInterval !=
+						*beaconInterval)) {
+						sms_log(pMac, LOGE,
+							FL
+								("BeaconInterval is different cannot connect to P2P_GO network ..."));
+						return CDF_STATUS_E_FAILURE;
+					}
+				}
+				break;
+
+			case CDF_SAP_MODE:
+				break;
+
+			case CDF_P2P_GO_MODE:
+			{
+				if (pMac->roam.roamSession[sessionId].
+					pCurRoamProfile &&
+				   ((pMac->roam.roamSession[sessionId].
+					pCurRoamProfile->csrPersona ==
+					CDF_P2P_CLIENT_MODE) ||
+				    (pMac->roam.roamSession[sessionId].
+					pCurRoamProfile->csrPersona ==
+					CDF_STA_MODE))) {
+					/* check for P2P_client scenario */
+					if ((pMac->roam.
+					     roamSession[sessionId].
+					     connectedProfile.
+					     operationChannel == 0)
+					    && (pMac->roam.
+						roamSession[sessionId].
+						connectedProfile.
+						beaconInterval == 0)) {
+						continue;
+					}
+
+					if (csr_is_conn_state_connected_infra
+						    (pMac, sessionId)
+					    && (pMac->roam.
+						roamSession[sessionId].
+						connectedProfile.
+						operationChannel !=
+						channelId)
+					    && (pMac->roam.
+						roamSession[sessionId].
+						connectedProfile.
+						beaconInterval !=
+						*beaconInterval)) {
+						/*
+						 * Updated beaconInterval should be used only when we are starting a new BSS
+						 * not incase of client or STA case
+						 */
+						/* Calculate beacon Interval for P2P-GO incase of MCC */
+						if (pMac->roam.configParam.conc_custom_rule1 ||
+							pMac->roam.configParam.conc_custom_rule2) {
+							new_beaconInterval = CSR_CUSTOM_CONC_GO_BI;
+						} else {
+							new_beaconInterval =
+								csr_calculate_mcc_beacon_interval
+								(pMac,
+								 pMac->roam.
+								 roamSession
+								 [sessionId].
+								 connectedProfile.
+								 beaconInterval,
+								 *beaconInterval);
+						}
+						if (*beaconInterval !=
+						    new_beaconInterval)
+							*beaconInterval
+								=
+									new_beaconInterval;
+						return
+							CDF_STATUS_SUCCESS;
+					}
+				}
+			}
+			break;
+
+			default:
+				sms_log(pMac, LOGE,
+					FL(" Persona not supported : %d"),
+					currBssPersona);
+				return CDF_STATUS_E_FAILURE;
+			}
+		}
+	}
+
+	return CDF_STATUS_SUCCESS;
+}
+
+#ifdef WLAN_FEATURE_VOWIFI_11R
+/* Function to return true if the authtype is 11r */
+bool csr_is_auth_type11r(eCsrAuthType AuthType, uint8_t mdiePresent)
+{
+	switch (AuthType) {
+	case eCSR_AUTH_TYPE_OPEN_SYSTEM:
+		if (mdiePresent)
+			return true;
+		break;
+	case eCSR_AUTH_TYPE_FT_RSN_PSK:
+	case eCSR_AUTH_TYPE_FT_RSN:
+		return true;
+		break;
+	default:
+		break;
+	}
+	return false;
+}
+
+/* Function to return true if the profile is 11r */
+bool csr_is_profile11r(tCsrRoamProfile *pProfile)
+{
+	return csr_is_auth_type11r(pProfile->negotiatedAuthType,
+				   pProfile->MDID.mdiePresent);
+}
+
+#endif
+
+#ifdef FEATURE_WLAN_ESE
+
+/* Function to return true if the authtype is ESE */
+bool csr_is_auth_type_ese(eCsrAuthType AuthType)
+{
+	switch (AuthType) {
+	case eCSR_AUTH_TYPE_CCKM_WPA:
+	case eCSR_AUTH_TYPE_CCKM_RSN:
+		return true;
+		break;
+	default:
+		break;
+	}
+	return false;
+}
+
+/* Function to return true if the profile is ESE */
+bool csr_is_profile_ese(tCsrRoamProfile *pProfile)
+{
+	return csr_is_auth_type_ese(pProfile->negotiatedAuthType);
+}
+
+#endif
+
+#ifdef FEATURE_WLAN_WAPI
+bool csr_is_profile_wapi(tCsrRoamProfile *pProfile)
+{
+	bool fWapiProfile = false;
+
+	switch (pProfile->negotiatedAuthType) {
+	case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE:
+	case eCSR_AUTH_TYPE_WAPI_WAI_PSK:
+		fWapiProfile = true;
+		break;
+
+	default:
+		fWapiProfile = false;
+		break;
+	}
+
+	if (fWapiProfile) {
+		switch (pProfile->negotiatedUCEncryptionType) {
+		case eCSR_ENCRYPT_TYPE_WPI:
+			fWapiProfile = true;
+			break;
+
+		default:
+			fWapiProfile = false;
+			break;
+		}
+	}
+	return fWapiProfile;
+}
+
+static bool csr_is_wapi_oui_equal(tpAniSirGlobal pMac, uint8_t *Oui1,
+				  uint8_t *Oui2)
+{
+	return cdf_mem_compare(Oui1, Oui2, CSR_WAPI_OUI_SIZE);
+}
+
+static bool csr_is_wapi_oui_match(tpAniSirGlobal pMac,
+				  uint8_t AllCyphers[][CSR_WAPI_OUI_SIZE],
+				  uint8_t cAllCyphers, uint8_t Cypher[],
+				  uint8_t Oui[])
+{
+	bool fYes = false;
+	uint8_t idx;
+
+	for (idx = 0; idx < cAllCyphers; idx++) {
+		if (csr_is_wapi_oui_equal(pMac, AllCyphers[idx], Cypher)) {
+			fYes = true;
+			break;
+		}
+	}
+
+	if (fYes && Oui) {
+		cdf_mem_copy(Oui, AllCyphers[idx], CSR_WAPI_OUI_SIZE);
+	}
+
+	return fYes;
+}
+#endif /* FEATURE_WLAN_WAPI */
+
+static bool csr_is_wpa_oui_equal(tpAniSirGlobal pMac, uint8_t *Oui1,
+				 uint8_t *Oui2)
+{
+	return cdf_mem_compare(Oui1, Oui2, CSR_WPA_OUI_SIZE);
+}
+
+static bool csr_is_oui_match(tpAniSirGlobal pMac,
+			     uint8_t AllCyphers[][CSR_WPA_OUI_SIZE],
+			     uint8_t cAllCyphers, uint8_t Cypher[], uint8_t Oui[])
+{
+	bool fYes = false;
+	uint8_t idx;
+
+	for (idx = 0; idx < cAllCyphers; idx++) {
+		if (csr_is_wpa_oui_equal(pMac, AllCyphers[idx], Cypher)) {
+			fYes = true;
+			break;
+		}
+	}
+
+	if (fYes && Oui) {
+		cdf_mem_copy(Oui, AllCyphers[idx], CSR_WPA_OUI_SIZE);
+	}
+
+	return fYes;
+}
+
+static bool csr_match_rsnoui_index(tpAniSirGlobal pMac,
+				   uint8_t AllCyphers[][CSR_RSN_OUI_SIZE],
+				   uint8_t cAllCyphers, uint8_t ouiIndex,
+				   uint8_t Oui[])
+{
+	return csr_is_oui_match
+		(pMac, AllCyphers, cAllCyphers, csr_rsn_oui[ouiIndex], Oui);
+
+}
+
+#ifdef FEATURE_WLAN_WAPI
+static bool csr_match_wapi_oui_index(tpAniSirGlobal pMac,
+				     uint8_t AllCyphers[][CSR_WAPI_OUI_SIZE],
+				     uint8_t cAllCyphers, uint8_t ouiIndex,
+				     uint8_t Oui[])
+{
+	return csr_is_wapi_oui_match
+		(pMac, AllCyphers, cAllCyphers, csr_wapi_oui[ouiIndex], Oui);
+
+}
+#endif /* FEATURE_WLAN_WAPI */
+
+static bool csr_match_wpaoui_index(tpAniSirGlobal pMac,
+				   uint8_t AllCyphers[][CSR_RSN_OUI_SIZE],
+				   uint8_t cAllCyphers, uint8_t ouiIndex,
+				   uint8_t Oui[])
+{
+	return csr_is_oui_match
+		(pMac, AllCyphers, cAllCyphers, csr_wpa_oui[ouiIndex], Oui);
+
+}
+
+#ifdef FEATURE_WLAN_WAPI
+static bool csr_is_auth_wapi_cert(tpAniSirGlobal pMac,
+				  uint8_t AllSuites[][CSR_WAPI_OUI_SIZE],
+				  uint8_t cAllSuites, uint8_t Oui[])
+{
+	return csr_is_wapi_oui_match
+		(pMac, AllSuites, cAllSuites, csr_wapi_oui[1], Oui);
+}
+
+static bool csr_is_auth_wapi_psk(tpAniSirGlobal pMac,
+				 uint8_t AllSuites[][CSR_WAPI_OUI_SIZE],
+				 uint8_t cAllSuites, uint8_t Oui[])
+{
+	return csr_is_wapi_oui_match
+		(pMac, AllSuites, cAllSuites, csr_wapi_oui[2], Oui);
+}
+#endif /* FEATURE_WLAN_WAPI */
+
+#ifdef WLAN_FEATURE_VOWIFI_11R
+
+/*
+ * Function for 11R FT Authentication. We match the FT Authentication Cipher
+ * suite here. This matches for FT Auth with the 802.1X exchange.
+ */
+static bool csr_is_ft_auth_rsn(tpAniSirGlobal pMac,
+			       uint8_t AllSuites[][CSR_RSN_OUI_SIZE],
+			       uint8_t cAllSuites, uint8_t Oui[])
+{
+	return csr_is_oui_match
+		(pMac, AllSuites, cAllSuites, csr_rsn_oui[03], Oui);
+}
+
+/*
+ * Function for 11R FT Authentication. We match the FT Authentication Cipher
+ * suite here. This matches for FT Auth with the PSK.
+ */
+static bool csr_is_ft_auth_rsn_psk(tpAniSirGlobal pMac,
+				   uint8_t AllSuites[][CSR_RSN_OUI_SIZE],
+				   uint8_t cAllSuites, uint8_t Oui[])
+{
+	return csr_is_oui_match
+		(pMac, AllSuites, cAllSuites, csr_rsn_oui[04], Oui);
+}
+
+#endif
+
+#ifdef FEATURE_WLAN_ESE
+
+/*
+ * Function for ESE CCKM AKM Authentication. We match the CCKM AKM
+ * Authentication Key Management suite here. This matches for CCKM AKM Auth
+ * with the 802.1X exchange.
+ */
+static bool csr_is_ese_cckm_auth_rsn(tpAniSirGlobal pMac,
+				     uint8_t AllSuites[][CSR_RSN_OUI_SIZE],
+				     uint8_t cAllSuites, uint8_t Oui[])
+{
+	return csr_is_oui_match
+		(pMac, AllSuites, cAllSuites, csr_rsn_oui[06], Oui);
+}
+
+static bool csr_is_ese_cckm_auth_wpa(tpAniSirGlobal pMac,
+				     uint8_t AllSuites[][CSR_WPA_OUI_SIZE],
+				     uint8_t cAllSuites, uint8_t Oui[])
+{
+	return csr_is_oui_match
+		(pMac, AllSuites, cAllSuites, csr_wpa_oui[06], Oui);
+}
+
+#endif
+
+static bool csr_is_auth_rsn(tpAniSirGlobal pMac,
+			    uint8_t AllSuites[][CSR_RSN_OUI_SIZE],
+			    uint8_t cAllSuites, uint8_t Oui[])
+{
+	return csr_is_oui_match
+		(pMac, AllSuites, cAllSuites, csr_rsn_oui[01], Oui);
+}
+
+static bool csr_is_auth_rsn_psk(tpAniSirGlobal pMac,
+				uint8_t AllSuites[][CSR_RSN_OUI_SIZE],
+				uint8_t cAllSuites, uint8_t Oui[])
+{
+	return csr_is_oui_match
+		(pMac, AllSuites, cAllSuites, csr_rsn_oui[02], Oui);
+}
+
+#ifdef WLAN_FEATURE_11W
+static bool csr_is_auth_rsn_psk_sha256(tpAniSirGlobal pMac,
+				       uint8_t AllSuites[][CSR_RSN_OUI_SIZE],
+				       uint8_t cAllSuites, uint8_t Oui[])
+{
+	return csr_is_oui_match
+		(pMac, AllSuites, cAllSuites, csr_rsn_oui[07], Oui);
+}
+static bool csr_is_auth_rsn8021x_sha256(tpAniSirGlobal pMac,
+					uint8_t AllSuites[][CSR_RSN_OUI_SIZE],
+					uint8_t cAllSuites, uint8_t Oui[])
+{
+	return csr_is_oui_match
+		(pMac, AllSuites, cAllSuites, csr_rsn_oui[8], Oui);
+}
+#endif
+
+static bool csr_is_auth_wpa(tpAniSirGlobal pMac,
+			    uint8_t AllSuites[][CSR_WPA_OUI_SIZE],
+			    uint8_t cAllSuites, uint8_t Oui[])
+{
+	return csr_is_oui_match
+		(pMac, AllSuites, cAllSuites, csr_wpa_oui[01], Oui);
+}
+
+static bool csr_is_auth_wpa_psk(tpAniSirGlobal pMac,
+				uint8_t AllSuites[][CSR_WPA_OUI_SIZE],
+				uint8_t cAllSuites, uint8_t Oui[])
+{
+	return csr_is_oui_match
+		(pMac, AllSuites, cAllSuites, csr_wpa_oui[02], Oui);
+}
+
+uint8_t csr_get_oui_index_from_cipher(eCsrEncryptionType enType)
+{
+	uint8_t OUIIndex;
+
+	switch (enType) {
+	case eCSR_ENCRYPT_TYPE_WEP40:
+	case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
+		OUIIndex = CSR_OUI_WEP40_OR_1X_INDEX;
+		break;
+	case eCSR_ENCRYPT_TYPE_WEP104:
+	case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
+		OUIIndex = CSR_OUI_WEP104_INDEX;
+		break;
+	case eCSR_ENCRYPT_TYPE_TKIP:
+		OUIIndex = CSR_OUI_TKIP_OR_PSK_INDEX;
+		break;
+	case eCSR_ENCRYPT_TYPE_AES:
+		OUIIndex = CSR_OUI_AES_INDEX;
+		break;
+	case eCSR_ENCRYPT_TYPE_NONE:
+		OUIIndex = CSR_OUI_USE_GROUP_CIPHER_INDEX;
+		break;
+#ifdef FEATURE_WLAN_WAPI
+	case eCSR_ENCRYPT_TYPE_WPI:
+		OUIIndex = CSR_OUI_WAPI_WAI_CERT_OR_SMS4_INDEX;
+		break;
+#endif /* FEATURE_WLAN_WAPI */
+	default:                /* HOWTO handle this? */
+		OUIIndex = CSR_OUI_RESERVED_INDEX;
+		break;
+	} /* switch */
+
+	return OUIIndex;
+}
+/**
+ * csr_get_rsn_information() - to get RSN infomation
+ * @hal: pointer to HAL
+ * @auth_type: auth type
+ * @encr_type: encryption type
+ * @mc_encryption: multicast encryption type
+ * @rsn_ie: pointer to RSN IE
+ * @ucast_cipher: Unicast cipher
+ * @mcast_cipher: Multicast cipher
+ * @auth_suite: Authentication suite
+ * @capabilities: RSN capabilities
+ * @negotiated_authtype: Negotiated auth type
+ * @negotiated_mccipher: negotiated multicast cipher
+ *
+ * This routine will get all RSN information
+ *
+ * Return: bool
+ */
+bool csr_get_rsn_information(tHalHandle hal, tCsrAuthList *auth_type,
+			     eCsrEncryptionType encr_type,
+			     tCsrEncryptionList *mc_encryption,
+			     tDot11fIERSN *rsn_ie, uint8_t *ucast_cipher,
+			     uint8_t *mcast_cipher, uint8_t *auth_suite,
+			     tCsrRSNCapabilities *capabilities,
+			     eCsrAuthType *negotiated_authtype,
+			     eCsrEncryptionType *negotiated_mccipher)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	bool acceptable_cipher = false;
+	uint8_t c_ucast_cipher = 0;
+	uint8_t c_mcast_cipher = 0;
+	uint8_t c_auth_suites = 0, i;
+	uint8_t unicast[CSR_RSN_OUI_SIZE];
+	uint8_t multicast[CSR_RSN_OUI_SIZE];
+	uint8_t authsuites[CSR_RSN_MAX_AUTH_SUITES][CSR_RSN_OUI_SIZE];
+	uint8_t authentication[CSR_RSN_OUI_SIZE];
+	uint8_t mccipher_arr[CSR_RSN_MAX_MULTICAST_CYPHERS][CSR_RSN_OUI_SIZE];
+	eCsrAuthType neg_authtype = eCSR_AUTH_TYPE_UNKNOWN;
+
+	if (!rsn_ie->present)
+		goto end;
+	c_mcast_cipher++;
+	cdf_mem_copy(mccipher_arr, rsn_ie->gp_cipher_suite,
+			CSR_RSN_OUI_SIZE);
+	c_ucast_cipher =
+		(uint8_t) (rsn_ie->pwise_cipher_suite_count);
+	c_auth_suites = (uint8_t) (rsn_ie->akm_suite_count);
+	for (i = 0; i < c_auth_suites && i < CSR_RSN_MAX_AUTH_SUITES; i++) {
+		cdf_mem_copy((void *)&authsuites[i],
+			(void *)&rsn_ie->akm_suites[i], CSR_RSN_OUI_SIZE);
+	}
+
+	/* Check - Is requested unicast Cipher supported by the BSS. */
+	acceptable_cipher = csr_match_rsnoui_index(mac_ctx,
+				rsn_ie->pwise_cipher_suites, c_ucast_cipher,
+				csr_get_oui_index_from_cipher(encr_type),
+				unicast);
+
+	if (!acceptable_cipher)
+		goto end;
+
+	/* unicast is supported. Pick the first matching Group cipher, if any */
+	for (i = 0; i < mc_encryption->numEntries; i++) {
+		acceptable_cipher = csr_match_rsnoui_index(mac_ctx,
+					mccipher_arr, c_mcast_cipher,
+					csr_get_oui_index_from_cipher(
+					    mc_encryption->encryptionType[i]),
+					multicast);
+		if (acceptable_cipher)
+			break;
+	}
+	if (!acceptable_cipher)
+		goto end;
+
+	if (negotiated_mccipher)
+		*negotiated_mccipher = mc_encryption->encryptionType[i];
+
+	/* Initializing with false as it has true value already */
+	acceptable_cipher = false;
+	for (i = 0; i < auth_type->numEntries; i++) {
+		/*
+		 * Ciphers are supported, Match authentication algorithm and
+		 * pick first matching authtype.
+		 */
+#ifdef WLAN_FEATURE_VOWIFI_11R
+		/* Changed the AKM suites according to order of preference */
+		if (csr_is_ft_auth_rsn(mac_ctx, authsuites,
+					c_auth_suites, authentication)) {
+			if (eCSR_AUTH_TYPE_FT_RSN == auth_type->authType[i])
+				neg_authtype = eCSR_AUTH_TYPE_FT_RSN;
+		}
+		if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN)
+				&& csr_is_ft_auth_rsn_psk(mac_ctx, authsuites,
+					c_auth_suites, authentication)) {
+			if (eCSR_AUTH_TYPE_FT_RSN_PSK ==
+					auth_type->authType[i])
+				neg_authtype = eCSR_AUTH_TYPE_FT_RSN_PSK;
+		}
+#endif
+#ifdef FEATURE_WLAN_ESE
+		/* ESE only supports 802.1X.  No PSK. */
+		if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) &&
+				csr_is_ese_cckm_auth_rsn(mac_ctx, authsuites,
+					c_auth_suites, authentication)) {
+			if (eCSR_AUTH_TYPE_CCKM_RSN == auth_type->authType[i])
+				neg_authtype = eCSR_AUTH_TYPE_CCKM_RSN;
+		}
+#endif
+		if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN)
+				&& csr_is_auth_rsn(mac_ctx, authsuites,
+					c_auth_suites, authentication)) {
+			if (eCSR_AUTH_TYPE_RSN == auth_type->authType[i])
+				neg_authtype = eCSR_AUTH_TYPE_RSN;
+		}
+		if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN)
+				&& csr_is_auth_rsn_psk(mac_ctx, authsuites,
+					c_auth_suites, authentication)) {
+			if (eCSR_AUTH_TYPE_RSN_PSK == auth_type->authType[i])
+				neg_authtype = eCSR_AUTH_TYPE_RSN_PSK;
+		}
+#ifdef WLAN_FEATURE_11W
+		if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN)
+			&& csr_is_auth_rsn_psk_sha256(mac_ctx, authsuites,
+					c_auth_suites, authentication)) {
+			if (eCSR_AUTH_TYPE_RSN_PSK_SHA256 ==
+					auth_type->authType[i])
+				neg_authtype = eCSR_AUTH_TYPE_RSN_PSK_SHA256;
+		}
+		if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) &&
+				csr_is_auth_rsn8021x_sha256(mac_ctx, authsuites,
+					c_auth_suites, authentication)) {
+			if (eCSR_AUTH_TYPE_RSN_8021X_SHA256 ==
+					auth_type->authType[i])
+				neg_authtype = eCSR_AUTH_TYPE_RSN_8021X_SHA256;
+		}
+#endif
+
+		/*
+		 * The 1st auth type in the APs RSN IE, to match stations
+		 * connecting profiles auth type will cause us to exit this
+		 * loop. This is added as some APs advertise multiple akms in
+		 * the RSN IE
+		 */
+		if (eCSR_AUTH_TYPE_UNKNOWN != neg_authtype) {
+			acceptable_cipher = true;
+			break;
+		}
+	} /* for */
+end:
+	if (acceptable_cipher) {
+		if (mcast_cipher)
+			cdf_mem_copy(mcast_cipher, multicast,
+					CSR_RSN_OUI_SIZE);
+
+		if (ucast_cipher)
+			cdf_mem_copy(ucast_cipher, unicast, CSR_RSN_OUI_SIZE);
+
+		if (auth_suite)
+			cdf_mem_copy(auth_suite, authentication,
+					CSR_RSN_OUI_SIZE);
+
+		if (negotiated_authtype)
+			*negotiated_authtype = neg_authtype;
+
+		if (capabilities) {
+			/* Bit 0 Preauthentication */
+			capabilities->PreAuthSupported =
+				(rsn_ie->RSN_Cap[0] >> 0) & 0x1;
+			/* Bit 1 No Pairwise */
+			capabilities->NoPairwise =
+				(rsn_ie->RSN_Cap[0] >> 1) & 0x1;
+			/* Bit 2, 3 PTKSA Replay Counter */
+			capabilities->PTKSAReplayCounter =
+				(rsn_ie->RSN_Cap[0] >> 2) & 0x3;
+			/* Bit 4, 5 GTKSA Replay Counter */
+			capabilities->GTKSAReplayCounter =
+				(rsn_ie->RSN_Cap[0] >> 4) & 0x3;
+#ifdef WLAN_FEATURE_11W
+			/* Bit 6 MFPR */
+			capabilities->MFPRequired =
+				(rsn_ie->RSN_Cap[0] >> 6) & 0x1;
+			/* Bit 7 MFPC */
+			capabilities->MFPCapable =
+				(rsn_ie->RSN_Cap[0] >> 7) & 0x1;
+#else
+			/* Bit 6 MFPR */
+			capabilities->MFPRequired = 0;
+			/* Bit 7 MFPC */
+			capabilities->MFPCapable = 0;
+#endif
+			/* remaining reserved */
+			capabilities->Reserved = rsn_ie->RSN_Cap[1] & 0xff;
+		}
+	}
+	return acceptable_cipher;
+}
+
+#ifdef WLAN_FEATURE_11W
+/**
+ * csr_is_pmf_capabilities_in_rsn_match() - check for PMF capability
+ * @hHal:                  Global HAL handle
+ * @pFilterMFPEnabled:     given by supplicant to us to specify what kind
+ *                         of connection supplicant is expecting to make
+ *                         if it is enabled then make PMF connection.
+ *                         if it is disabled then make normal connection.
+ * @pFilterMFPRequired:    given by supplicant based on our configuration
+ *                         if it is 1 then we will require mandatory
+ *                         PMF connection and if it is 0 then we PMF
+ *                         connection is optional.
+ * @pFilterMFPCapable:     given by supplicant based on our configuration
+ *                         if it 1 then we are PMF capable and if it 0
+ *                         then we are not PMF capable.
+ * @pRSNIe:                RSNIe from Beacon/probe response of
+ *                         neighbor AP against which we will compare
+ *                         our capabilities.
+ *
+ * This function is to match our current capabilities with the AP
+ * to which we are expecting make the connection.
+ *
+ * Return:   if our PMF capabilities matches with AP then we
+ *           will return true to indicate that we are good
+ *           to make connection with it. Else we will return false
+ **/
+static bool
+csr_is_pmf_capabilities_in_rsn_match(tHalHandle hHal,
+				     bool *pFilterMFPEnabled,
+				     uint8_t *pFilterMFPRequired,
+				     uint8_t *pFilterMFPCapable,
+				     tDot11fIERSN *pRSNIe)
+{
+	uint8_t apProfileMFPCapable = 0;
+	uint8_t apProfileMFPRequired = 0;
+	if (pRSNIe && pFilterMFPEnabled && pFilterMFPCapable
+	    && pFilterMFPRequired) {
+		/* Extracting MFPCapable bit from RSN Ie */
+		apProfileMFPCapable = (pRSNIe->RSN_Cap[0] >> 7) & 0x1;
+		apProfileMFPRequired = (pRSNIe->RSN_Cap[0] >> 6) & 0x1;
+		if (*pFilterMFPEnabled && *pFilterMFPCapable
+		    && *pFilterMFPRequired && (apProfileMFPCapable == 0)) {
+			CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
+				  "AP is not capable to make PMF connection");
+			return false;
+		} else if (*pFilterMFPEnabled && *pFilterMFPCapable &&
+			   !(*pFilterMFPRequired) &&
+				(apProfileMFPCapable == 0)) {
+			/*
+			 * This is tricky, because supplicant asked us to
+			 * make mandatory PMF connection eventhough PMF
+			 * connection is optional here.
+			 * so if AP is not capable of PMF then drop it.
+			 * Don't try to connect with it.
+			 */
+			CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
+				  "we need PMF connection & AP isn't capable to make PMF connection");
+			return false;
+		} else if (!(*pFilterMFPCapable) &&
+			   apProfileMFPCapable && apProfileMFPRequired) {
+
+			/*
+			 * In this case, AP with whom we trying to connect
+			 * requires mandatory PMF connections and we are not
+			 * capable so this AP is not good choice to connect
+			 */
+			CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
+				  "AP needs PMF connection and we are not capable of pmf connection");
+			return false;
+		} else if (!(*pFilterMFPEnabled) && *pFilterMFPCapable &&
+			   (apProfileMFPCapable == 1)) {
+			CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
+				  "we don't need PMF connection even though both parties are capable");
+			return false;
+		}
+	}
+	return true;
+}
+#endif
+
+bool csr_is_rsn_match(tHalHandle hHal, tCsrAuthList *pAuthType,
+		      eCsrEncryptionType enType,
+		      tCsrEncryptionList *pEnMcType,
+		      bool *pMFPEnabled, uint8_t *pMFPRequired,
+		      uint8_t *pMFPCapable,
+		      tDot11fBeaconIEs *pIes,
+		      eCsrAuthType *pNegotiatedAuthType,
+		      eCsrEncryptionType *pNegotiatedMCCipher)
+{
+	bool fRSNMatch = false;
+
+	/* See if the cyphers in the Bss description match with the settings in the profile. */
+	fRSNMatch =
+		csr_get_rsn_information(hHal, pAuthType, enType, pEnMcType, &pIes->RSN,
+					NULL, NULL, NULL, NULL, pNegotiatedAuthType,
+					pNegotiatedMCCipher);
+#ifdef WLAN_FEATURE_11W
+	/* If all the filter matches then finally checks for PMF capabilities */
+	if (fRSNMatch) {
+		fRSNMatch = csr_is_pmf_capabilities_in_rsn_match(hHal, pMFPEnabled,
+								 pMFPRequired,
+								 pMFPCapable,
+								 &pIes->RSN);
+	}
+#endif
+	return fRSNMatch;
+}
+
+bool csr_lookup_pmkid(tpAniSirGlobal pMac, uint32_t sessionId, uint8_t *pBSSId,
+		      uint8_t *pPMKId)
+{
+	bool fRC = false, fMatchFound = false;
+	uint32_t Index;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("  session %d not found "), sessionId);
+		return false;
+	}
+
+	do {
+		for (Index = 0; Index < CSR_MAX_PMKID_ALLOWED; Index++) {
+			sms_log(pMac, LOG1,
+				"match PMKID " MAC_ADDRESS_STR " to ",
+				MAC_ADDR_ARRAY(pBSSId));
+			if (cdf_mem_compare
+			    (pBSSId, pSession->PmkidCacheInfo[Index].BSSID.bytes,
+			    sizeof(struct cdf_mac_addr))) {
+				/* match found */
+				fMatchFound = true;
+				break;
+			}
+		}
+
+		if (!fMatchFound)
+			break;
+
+		cdf_mem_copy(pPMKId, pSession->PmkidCacheInfo[Index].PMKID,
+			     CSR_RSN_PMKID_SIZE);
+
+		fRC = true;
+	} while (0);
+	sms_log(pMac, LOGW,
+		"csr_lookup_pmkid called return match = %d pMac->roam.NumPmkidCache = %d",
+		fRC, pSession->NumPmkidCache);
+
+	return fRC;
+}
+
+uint8_t csr_construct_rsn_ie(tHalHandle hHal, uint32_t sessionId,
+			     tCsrRoamProfile *pProfile,
+			     tSirBssDescription *pSirBssDesc,
+			     tDot11fBeaconIEs *pIes, tCsrRSNIe *pRSNIe)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	bool fRSNMatch;
+	uint8_t cbRSNIe = 0;
+	uint8_t UnicastCypher[CSR_RSN_OUI_SIZE];
+	uint8_t MulticastCypher[CSR_RSN_OUI_SIZE];
+	uint8_t AuthSuite[CSR_RSN_OUI_SIZE];
+	tCsrRSNAuthIe *pAuthSuite;
+	tCsrRSNCapabilities RSNCapabilities;
+	tCsrRSNPMKIe *pPMK;
+	uint8_t PMKId[CSR_RSN_PMKID_SIZE];
+#ifdef WLAN_FEATURE_11W
+	uint8_t *pGroupMgmtCipherSuite;
+#endif
+	tDot11fBeaconIEs *pIesLocal = pIes;
+	eCsrAuthType negAuthType = eCSR_AUTH_TYPE_UNKNOWN;
+
+	sms_log(pMac, LOGW, "%s called...", __func__);
+
+	do {
+		if (!csr_is_profile_rsn(pProfile))
+			break;
+
+		if (!pIesLocal
+		    &&
+		    (!CDF_IS_STATUS_SUCCESS
+			     (csr_get_parsed_bss_description_ies
+				     (pMac, pSirBssDesc, &pIesLocal)))) {
+			break;
+		}
+		/* See if the cyphers in the Bss description match with the settings in the profile. */
+		fRSNMatch =
+			csr_get_rsn_information(hHal, &pProfile->AuthType,
+						pProfile->negotiatedUCEncryptionType,
+						&pProfile->mcEncryptionType,
+						&pIesLocal->RSN, UnicastCypher,
+						MulticastCypher, AuthSuite,
+						&RSNCapabilities, &negAuthType, NULL);
+		if (!fRSNMatch)
+			break;
+
+		pRSNIe->IeHeader.ElementID = SIR_MAC_RSN_EID;
+
+		pRSNIe->Version = CSR_RSN_VERSION_SUPPORTED;
+
+		cdf_mem_copy(pRSNIe->MulticastOui, MulticastCypher,
+			     sizeof(MulticastCypher));
+
+		pRSNIe->cUnicastCyphers = 1;
+
+		cdf_mem_copy(&pRSNIe->UnicastOui[0], UnicastCypher,
+			     sizeof(UnicastCypher));
+
+		pAuthSuite =
+			(tCsrRSNAuthIe *) (&pRSNIe->
+					   UnicastOui[pRSNIe->cUnicastCyphers]);
+
+		pAuthSuite->cAuthenticationSuites = 1;
+		cdf_mem_copy(&pAuthSuite->AuthOui[0], AuthSuite,
+			     sizeof(AuthSuite));
+
+		/* RSN capabilities follows the Auth Suite (two octects) */
+		/* !!REVIEW - What should STA put in RSN capabilities, currently */
+		/* just putting back APs capabilities */
+		/* For one, we shouldn't EVER be sending out "pre-auth supported".  It is an AP only capability */
+		/* For another, we should use the Management Frame Protection values given by the supplicant */
+		RSNCapabilities.PreAuthSupported = 0;
+#ifdef WLAN_FEATURE_11W
+		if (RSNCapabilities.MFPCapable && pProfile->MFPCapable) {
+			RSNCapabilities.MFPCapable = pProfile->MFPCapable;
+			RSNCapabilities.MFPRequired = pProfile->MFPRequired;
+		} else {
+			RSNCapabilities.MFPCapable = 0;
+			RSNCapabilities.MFPRequired = 0;
+		}
+#endif
+		*(uint16_t *) (&pAuthSuite->AuthOui[1]) =
+			*((uint16_t *) (&RSNCapabilities));
+
+		pPMK =
+			(tCsrRSNPMKIe *) (((uint8_t *) (&pAuthSuite->AuthOui[1])) +
+					  sizeof(uint16_t));
+
+		/* Don't include the PMK SA IDs for CCKM associations. */
+		if (
+#ifdef FEATURE_WLAN_ESE
+			(eCSR_AUTH_TYPE_CCKM_RSN != negAuthType) &&
+#endif
+			csr_lookup_pmkid(pMac, sessionId, pSirBssDesc->bssId,
+					 &(PMKId[0]))) {
+			pPMK->cPMKIDs = 1;
+
+			cdf_mem_copy(pPMK->PMKIDList[0].PMKID, PMKId,
+				     CSR_RSN_PMKID_SIZE);
+		} else {
+			pPMK->cPMKIDs = 0;
+		}
+
+#ifdef WLAN_FEATURE_11W
+		if (pProfile->MFPEnabled) {
+			pGroupMgmtCipherSuite =
+				(uint8_t *) pPMK + sizeof(uint16_t) +
+				(pPMK->cPMKIDs * CSR_RSN_PMKID_SIZE);
+			cdf_mem_copy(pGroupMgmtCipherSuite, csr_rsn_oui[07],
+				     CSR_WPA_OUI_SIZE);
+		}
+#endif
+
+		/* Add in the fixed fields plus 1 Unicast cypher, less the IE Header length */
+		/* Add in the size of the Auth suite (count plus a single OUI) */
+		/* Add in the RSN caps field. */
+		/* Add PMKID count and PMKID (if any) */
+		/* Add group management cipher suite */
+		pRSNIe->IeHeader.Length =
+			(uint8_t) (sizeof(*pRSNIe) - sizeof(pRSNIe->IeHeader) +
+				   sizeof(*pAuthSuite) +
+				   sizeof(tCsrRSNCapabilities));
+		if (pPMK->cPMKIDs) {
+			pRSNIe->IeHeader.Length += (uint8_t) (sizeof(uint16_t) +
+							      (pPMK->cPMKIDs *
+							       CSR_RSN_PMKID_SIZE));
+		}
+#ifdef WLAN_FEATURE_11W
+		if (pProfile->MFPEnabled) {
+			if (0 == pPMK->cPMKIDs)
+				pRSNIe->IeHeader.Length += sizeof(uint16_t);
+			pRSNIe->IeHeader.Length += CSR_WPA_OUI_SIZE;
+		}
+#endif
+
+		/* return the size of the IE header (total) constructed... */
+		cbRSNIe = pRSNIe->IeHeader.Length + sizeof(pRSNIe->IeHeader);
+
+	} while (0);
+
+	if (!pIes && pIesLocal) {
+		/* locally allocated */
+		cdf_mem_free(pIesLocal);
+	}
+
+	return cbRSNIe;
+}
+
+#ifdef FEATURE_WLAN_WAPI
+/**
+ * csr_get_wapi_information() - to get WAPI infomation
+ * @hal: pointer to HAL
+ * @auth_type: auth type
+ * @encr_type: encryption type
+ * @mc_encryption: multicast encryption type
+ * @wapi_ie: pointer to WAPI IE
+ * @ucast_cipher: Unicast cipher
+ * @mcast_cipher: Multicast cipher
+ * @auth_suite: Authentication suite
+ * @negotiated_authtype: Negotiated auth type
+ * @negotiated_mccipher: negotiated multicast cipher
+ *
+ * This routine will get all WAPI information
+ *
+ * Return: bool
+ */
+bool csr_get_wapi_information(tHalHandle hal, tCsrAuthList *auth_type,
+			      eCsrEncryptionType encr_type,
+			      tCsrEncryptionList *mc_encryption,
+			      tDot11fIEWAPI *wapi_ie, uint8_t *ucast_cipher,
+			      uint8_t *mcast_cipher, uint8_t *auth_suite,
+			      eCsrAuthType *negotiated_authtype,
+			      eCsrEncryptionType *negotiated_mccipher)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	bool acceptable_cipher = false;
+	uint8_t c_ucast_cipher = 0;
+	uint8_t c_mcast_cipher = 0;
+	uint8_t c_auth_suites = 0, i;
+	uint8_t unicast[CSR_WAPI_OUI_SIZE];
+	uint8_t multicast[CSR_WAPI_OUI_SIZE];
+	uint8_t authsuites[CSR_WAPI_MAX_AUTH_SUITES][CSR_WAPI_OUI_SIZE];
+	uint8_t authentication[CSR_WAPI_OUI_SIZE];
+	uint8_t mccipher_arr[CSR_WAPI_MAX_MULTICAST_CYPHERS][CSR_WAPI_OUI_SIZE];
+	eCsrAuthType neg_authtype = eCSR_AUTH_TYPE_UNKNOWN;
+	uint8_t wapioui_idx = 0;
+
+	if (!wapi_ie->present)
+		goto end;
+
+	c_mcast_cipher++;
+	cdf_mem_copy(mccipher_arr, wapi_ie->multicast_cipher_suite,
+			CSR_WAPI_OUI_SIZE);
+	c_ucast_cipher = (uint8_t) (wapi_ie->unicast_cipher_suite_count);
+	c_auth_suites = (uint8_t) (wapi_ie->akm_suite_count);
+	for (i = 0; i < c_auth_suites && i < CSR_WAPI_MAX_AUTH_SUITES; i++)
+		cdf_mem_copy((void *)&authsuites[i],
+			(void *)&wapi_ie->akm_suites[i], CSR_WAPI_OUI_SIZE);
+
+	wapioui_idx = csr_get_oui_index_from_cipher(encr_type);
+	if (wapioui_idx >= CSR_OUI_WAPI_WAI_MAX_INDEX) {
+		sms_log(mac_ctx, LOGE,
+			FL("Wapi OUI index = %d out of limit"),
+			wapioui_idx);
+		acceptable_cipher = false;
+		goto end;
+	}
+	/* Check - Is requested unicast Cipher supported by the BSS. */
+	acceptable_cipher = csr_match_wapi_oui_index(mac_ctx,
+				wapi_ie->unicast_cipher_suites,
+				c_ucast_cipher, wapioui_idx, unicast);
+	if (!acceptable_cipher)
+		goto end;
+
+	/* unicast is supported. Pick the first matching Group cipher, if any */
+	for (i = 0; i < mc_encryption->numEntries; i++) {
+		wapioui_idx = csr_get_oui_index_from_cipher(
+					mc_encryption->encryptionType[i]);
+		if (wapioui_idx >= CSR_OUI_WAPI_WAI_MAX_INDEX) {
+			sms_log(mac_ctx, LOGE,
+				FL("Wapi OUI index = %d out of limit"),
+				wapioui_idx);
+			acceptable_cipher = false;
+			break;
+		}
+		acceptable_cipher = csr_match_wapi_oui_index(mac_ctx,
+						mccipher_arr, c_mcast_cipher,
+						wapioui_idx, multicast);
+		if (acceptable_cipher)
+			break;
+	}
+	if (!acceptable_cipher)
+		goto end;
+
+	if (negotiated_mccipher)
+		*negotiated_mccipher =
+			mc_encryption->encryptionType[i];
+
+	/*
+	 * Ciphers are supported, Match authentication algorithm and
+	 * pick first matching authtype
+	 */
+	if (csr_is_auth_wapi_cert
+			(mac_ctx, authsuites, c_auth_suites, authentication)) {
+		neg_authtype =
+			eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
+	} else if (csr_is_auth_wapi_psk(mac_ctx, authsuites,
+				c_auth_suites, authentication)) {
+		neg_authtype = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
+	} else {
+		acceptable_cipher = false;
+		neg_authtype = eCSR_AUTH_TYPE_UNKNOWN;
+	}
+
+	/* Caller doesn't care about auth type, or BSS doesn't match */
+	if ((0 == auth_type->numEntries) || (false == acceptable_cipher))
+		goto end;
+
+	acceptable_cipher = false;
+	for (i = 0; i < auth_type->numEntries; i++) {
+		if (auth_type->authType[i] == neg_authtype) {
+			acceptable_cipher = true;
+			break;
+		}
+	}
+
+end:
+	if (acceptable_cipher) {
+		if (mcast_cipher)
+			cdf_mem_copy(mcast_cipher, multicast,
+					CSR_WAPI_OUI_SIZE);
+		if (ucast_cipher)
+			cdf_mem_copy(ucast_cipher, unicast, CSR_WAPI_OUI_SIZE);
+		if (auth_suite)
+			cdf_mem_copy(auth_suite, authentication,
+					CSR_WAPI_OUI_SIZE);
+		if (negotiated_authtype)
+			*negotiated_authtype = neg_authtype;
+	}
+	return acceptable_cipher;
+}
+
+bool csr_is_wapi_match(tHalHandle hHal, tCsrAuthList *pAuthType,
+		       eCsrEncryptionType enType, tCsrEncryptionList *pEnMcType,
+		       tDot11fBeaconIEs *pIes, eCsrAuthType *pNegotiatedAuthType,
+		       eCsrEncryptionType *pNegotiatedMCCipher)
+{
+	bool fWapiMatch = false;
+
+	/* See if the cyphers in the Bss description match with the settings in the profile. */
+	fWapiMatch =
+		csr_get_wapi_information(hHal, pAuthType, enType, pEnMcType,
+					 &pIes->WAPI, NULL, NULL, NULL,
+					 pNegotiatedAuthType, pNegotiatedMCCipher);
+
+	return fWapiMatch;
+}
+
+bool csr_lookup_bkid(tpAniSirGlobal pMac, uint32_t sessionId, uint8_t *pBSSId,
+		     uint8_t *pBKId)
+{
+	bool fRC = false, fMatchFound = false;
+	uint32_t Index;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	if (!pSession) {
+		sms_log(pMac, LOGE, FL("  session %d not found "), sessionId);
+		return false;
+	}
+
+	do {
+		for (Index = 0; Index < pSession->NumBkidCache; Index++) {
+			sms_log(pMac, LOGW, "match BKID " MAC_ADDRESS_STR " to ",
+				MAC_ADDR_ARRAY(pBSSId));
+			if (cdf_mem_compare
+			    (pBSSId, pSession->BkidCacheInfo[Index].BSSID.bytes,
+				    sizeof(struct cdf_mac_addr))) {
+				/* match found */
+				fMatchFound = true;
+				break;
+			}
+		}
+
+		if (!fMatchFound)
+			break;
+
+		cdf_mem_copy(pBKId, pSession->BkidCacheInfo[Index].BKID,
+			     CSR_WAPI_BKID_SIZE);
+
+		fRC = true;
+	} while (0);
+	sms_log(pMac, LOGW,
+		"csr_lookup_bkid called return match = %d pMac->roam.NumBkidCache = %d",
+		fRC, pSession->NumBkidCache);
+
+	return fRC;
+}
+
+uint8_t csr_construct_wapi_ie(tpAniSirGlobal pMac, uint32_t sessionId,
+			      tCsrRoamProfile *pProfile,
+			      tSirBssDescription *pSirBssDesc,
+			      tDot11fBeaconIEs *pIes, tCsrWapiIe *pWapiIe)
+{
+	bool fWapiMatch = false;
+	uint8_t cbWapiIe = 0;
+	uint8_t UnicastCypher[CSR_WAPI_OUI_SIZE];
+	uint8_t MulticastCypher[CSR_WAPI_OUI_SIZE];
+	uint8_t AuthSuite[CSR_WAPI_OUI_SIZE];
+	uint8_t BKId[CSR_WAPI_BKID_SIZE];
+	uint8_t *pWapi = NULL;
+	bool fBKIDFound = false;
+	tDot11fBeaconIEs *pIesLocal = pIes;
+
+	do {
+		if (!csr_is_profile_wapi(pProfile))
+			break;
+
+		if (!pIesLocal
+		    &&
+		    (!CDF_IS_STATUS_SUCCESS
+			     (csr_get_parsed_bss_description_ies
+				     (pMac, pSirBssDesc, &pIesLocal)))) {
+			break;
+		}
+		/* See if the cyphers in the Bss description match with the settings in the profile. */
+		fWapiMatch =
+			csr_get_wapi_information(pMac, &pProfile->AuthType,
+						 pProfile->negotiatedUCEncryptionType,
+						 &pProfile->mcEncryptionType,
+						 &pIesLocal->WAPI, UnicastCypher,
+						 MulticastCypher, AuthSuite, NULL,
+						 NULL);
+		if (!fWapiMatch)
+			break;
+
+		cdf_mem_set(pWapiIe, sizeof(tCsrWapiIe), 0);
+
+		pWapiIe->IeHeader.ElementID = DOT11F_EID_WAPI;
+
+		pWapiIe->Version = CSR_WAPI_VERSION_SUPPORTED;
+
+		pWapiIe->cAuthenticationSuites = 1;
+		cdf_mem_copy(&pWapiIe->AuthOui[0], AuthSuite,
+			     sizeof(AuthSuite));
+
+		pWapi = (uint8_t *) (&pWapiIe->AuthOui[1]);
+
+		*pWapi = (uint16_t) 1;  /* cUnicastCyphers */
+		pWapi += 2;
+		cdf_mem_copy(pWapi, UnicastCypher, sizeof(UnicastCypher));
+		pWapi += sizeof(UnicastCypher);
+
+		cdf_mem_copy(pWapi, MulticastCypher, sizeof(MulticastCypher));
+		pWapi += sizeof(MulticastCypher);
+
+		/* WAPI capabilities follows the Auth Suite (two octects) */
+		/* we shouldn't EVER be sending out "pre-auth supported".  It is an AP only capability */
+		/* & since we already did a memset pWapiIe to 0, skip these fields */
+		pWapi += 2;
+
+		fBKIDFound =
+			csr_lookup_bkid(pMac, sessionId, pSirBssDesc->bssId,
+					&(BKId[0]));
+
+		if (fBKIDFound) {
+			/* Do we need to change the endianness here */
+			*pWapi = (uint16_t) 1;  /* cBKIDs */
+			pWapi += 2;
+			cdf_mem_copy(pWapi, BKId, CSR_WAPI_BKID_SIZE);
+		} else {
+			*pWapi = 0;
+			pWapi += 1;
+			*pWapi = 0;
+			pWapi += 1;
+		}
+
+		/* Add in the IE fields except the IE header */
+		/* Add BKID count and BKID (if any) */
+		pWapiIe->IeHeader.Length =
+			(uint8_t) (sizeof(*pWapiIe) - sizeof(pWapiIe->IeHeader));
+
+		/*2 bytes for BKID Count field */
+		pWapiIe->IeHeader.Length += sizeof(uint16_t);
+
+		if (fBKIDFound) {
+			pWapiIe->IeHeader.Length += CSR_WAPI_BKID_SIZE;
+		}
+		/* return the size of the IE header (total) constructed... */
+		cbWapiIe = pWapiIe->IeHeader.Length + sizeof(pWapiIe->IeHeader);
+
+	} while (0);
+
+	if (!pIes && pIesLocal) {
+		/* locally allocated */
+		cdf_mem_free(pIesLocal);
+	}
+
+	return cbWapiIe;
+}
+#endif /* FEATURE_WLAN_WAPI */
+
+/**
+ * csr_get_wpa_cyphers() - to get WPA cipher info
+ * @mac_ctx: pointer to mac context
+ * @auth_type: auth type
+ * @encr_type: encryption type
+ * @mc_encryption: multicast encryption type
+ * @wpa_ie: pointer to WPA IE
+ * @ucast_cipher: Unicast cipher
+ * @mcast_cipher: Multicast cipher
+ * @auth_suite: Authentication suite
+ * @negotiated_authtype: Negotiated auth type
+ * @negotiated_mccipher: negotiated multicast cipher
+ *
+ * This routine will get all WPA information
+ *
+ * Return: bool
+ */
+bool csr_get_wpa_cyphers(tpAniSirGlobal mac_ctx, tCsrAuthList *auth_type,
+		eCsrEncryptionType encr_type, tCsrEncryptionList *mc_encryption,
+		tDot11fIEWPA *wpa_ie, uint8_t *ucast_cipher,
+		uint8_t *mcast_cipher, uint8_t *auth_suite,
+		eCsrAuthType *negotiated_authtype,
+		eCsrEncryptionType *negotiated_mccipher)
+{
+	bool acceptable_cipher = false;
+	uint8_t c_ucast_cipher = 0;
+	uint8_t c_mcast_cipher = 0;
+	uint8_t c_auth_suites = 0;
+	uint8_t unicast[CSR_WPA_OUI_SIZE];
+	uint8_t multicast[CSR_WPA_OUI_SIZE];
+	uint8_t authentication[CSR_WPA_OUI_SIZE];
+	uint8_t mccipher_arr[1][CSR_WPA_OUI_SIZE];
+	uint8_t i;
+	eCsrAuthType neg_authtype = eCSR_AUTH_TYPE_UNKNOWN;
+
+	if (!wpa_ie->present)
+		goto end;
+	c_mcast_cipher = 1;
+	cdf_mem_copy(mccipher_arr, wpa_ie->multicast_cipher, CSR_WPA_OUI_SIZE);
+	c_ucast_cipher = (uint8_t) (wpa_ie->unicast_cipher_count);
+	c_auth_suites = (uint8_t) (wpa_ie->auth_suite_count);
+
+	/* Check - Is requested unicast Cipher supported by the BSS. */
+	acceptable_cipher = csr_match_wpaoui_index(mac_ctx,
+				wpa_ie->unicast_ciphers, c_ucast_cipher,
+				csr_get_oui_index_from_cipher(encr_type),
+				unicast);
+	if (!acceptable_cipher)
+		goto end;
+	/* unicast is supported. Pick the first matching Group cipher, if any */
+	for (i = 0; i < mc_encryption->numEntries; i++) {
+		acceptable_cipher = csr_match_wpaoui_index(mac_ctx,
+					mccipher_arr, c_mcast_cipher,
+					csr_get_oui_index_from_cipher(
+					    mc_encryption->encryptionType[i]),
+					multicast);
+		if (acceptable_cipher)
+			break;
+	}
+	if (!acceptable_cipher)
+		goto end;
+
+	if (negotiated_mccipher)
+		*negotiated_mccipher = mc_encryption->encryptionType[i];
+
+	/* Initializing with false as it has true value already */
+	acceptable_cipher = false;
+	for (i = 0; i < auth_type->numEntries; i++) {
+		/*
+		 * Ciphers are supported, Match authentication algorithm and
+		 * pick first matching authtype
+		 */
+		if (csr_is_auth_wpa(mac_ctx, wpa_ie->auth_suites, c_auth_suites,
+			authentication)) {
+			if (eCSR_AUTH_TYPE_WPA == auth_type->authType[i])
+				neg_authtype = eCSR_AUTH_TYPE_WPA;
+		}
+		if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) &&
+			csr_is_auth_wpa_psk(mac_ctx,
+				wpa_ie->auth_suites, c_auth_suites,
+				authentication)) {
+			if (eCSR_AUTH_TYPE_WPA_PSK == auth_type->authType[i])
+				neg_authtype = eCSR_AUTH_TYPE_WPA_PSK;
+		}
+#ifdef FEATURE_WLAN_ESE
+		if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN)
+			&& csr_is_ese_cckm_auth_wpa(mac_ctx,
+				wpa_ie->auth_suites, c_auth_suites,
+				authentication)) {
+			if (eCSR_AUTH_TYPE_CCKM_WPA == auth_type->authType[i])
+				neg_authtype = eCSR_AUTH_TYPE_CCKM_WPA;
+		}
+#endif /* FEATURE_WLAN_ESE */
+
+		/*
+		 * The 1st auth type in the APs WPA IE, to match stations
+		 * connecting profiles auth type will cause us to exit this
+		 * loop. This is added as some APs advertise multiple akms in
+		 * the WPA IE
+		 */
+		if (eCSR_AUTH_TYPE_UNKNOWN != neg_authtype) {
+			acceptable_cipher = true;
+			break;
+		}
+	}
+
+end:
+	if (acceptable_cipher) {
+		if (mcast_cipher)
+			cdf_mem_copy((uint8_t **) mcast_cipher, multicast,
+					CSR_WPA_OUI_SIZE);
+
+		if (ucast_cipher)
+			cdf_mem_copy((uint8_t **) ucast_cipher, unicast,
+					CSR_WPA_OUI_SIZE);
+
+		if (auth_suite)
+			cdf_mem_copy((uint8_t **) auth_suite, authentication,
+					CSR_WPA_OUI_SIZE);
+
+		if (negotiated_authtype)
+			*negotiated_authtype = neg_authtype;
+	}
+
+	return acceptable_cipher;
+}
+
+bool csr_is_wpa_encryption_match(tpAniSirGlobal pMac, tCsrAuthList *pAuthType,
+				 eCsrEncryptionType enType,
+				 tCsrEncryptionList *pEnMcType,
+				 tDot11fBeaconIEs *pIes,
+				 eCsrAuthType *pNegotiatedAuthtype,
+				 eCsrEncryptionType *pNegotiatedMCCipher)
+{
+	bool fWpaMatch = false;
+
+	/* See if the cyphers in the Bss description match with the settings in the profile. */
+	fWpaMatch =
+		csr_get_wpa_cyphers(pMac, pAuthType, enType, pEnMcType, &pIes->WPA,
+				    NULL, NULL, NULL, pNegotiatedAuthtype,
+				    pNegotiatedMCCipher);
+
+	return fWpaMatch;
+}
+
+uint8_t csr_construct_wpa_ie(tHalHandle hHal, tCsrRoamProfile *pProfile,
+			     tSirBssDescription *pSirBssDesc,
+			     tDot11fBeaconIEs *pIes, tCsrWpaIe *pWpaIe)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	bool fWpaMatch;
+	uint8_t cbWpaIe = 0;
+	uint8_t UnicastCypher[CSR_WPA_OUI_SIZE];
+	uint8_t MulticastCypher[CSR_WPA_OUI_SIZE];
+	uint8_t AuthSuite[CSR_WPA_OUI_SIZE];
+	tCsrWpaAuthIe *pAuthSuite;
+	tDot11fBeaconIEs *pIesLocal = pIes;
+
+	do {
+		if (!csr_is_profile_wpa(pProfile))
+			break;
+
+		if (!pIesLocal
+		    &&
+		    (!CDF_IS_STATUS_SUCCESS
+			     (csr_get_parsed_bss_description_ies
+				     (pMac, pSirBssDesc, &pIesLocal)))) {
+			break;
+		}
+		/* See if the cyphers in the Bss description match with the settings in the profile. */
+		fWpaMatch =
+			csr_get_wpa_cyphers(hHal, &pProfile->AuthType,
+					    pProfile->negotiatedUCEncryptionType,
+					    &pProfile->mcEncryptionType,
+					    &pIesLocal->WPA, UnicastCypher,
+					    MulticastCypher, AuthSuite, NULL, NULL);
+		if (!fWpaMatch)
+			break;
+
+		pWpaIe->IeHeader.ElementID = SIR_MAC_WPA_EID;
+
+		cdf_mem_copy(pWpaIe->Oui, csr_wpa_oui[01], sizeof(pWpaIe->Oui));
+
+		pWpaIe->Version = CSR_WPA_VERSION_SUPPORTED;
+
+		cdf_mem_copy(pWpaIe->MulticastOui, MulticastCypher,
+			     sizeof(MulticastCypher));
+
+		pWpaIe->cUnicastCyphers = 1;
+
+		cdf_mem_copy(&pWpaIe->UnicastOui[0], UnicastCypher,
+			     sizeof(UnicastCypher));
+
+		pAuthSuite =
+			(tCsrWpaAuthIe *) (&pWpaIe->
+					   UnicastOui[pWpaIe->cUnicastCyphers]);
+
+		pAuthSuite->cAuthenticationSuites = 1;
+		cdf_mem_copy(&pAuthSuite->AuthOui[0], AuthSuite,
+			     sizeof(AuthSuite));
+
+		/* The WPA capabilities follows the Auth Suite (two octects)-- */
+		/* this field is optional, and we always "send" zero, so just */
+		/* remove it.  This is consistent with our assumptions in the */
+		/* frames compiler; c.f. bug 15234: */
+		/* http://gold.woodsidenet.com/bugzilla/show_bug.cgi?id=15234 */
+
+		/* Add in the fixed fields plus 1 Unicast cypher, less the IE Header length */
+		/* Add in the size of the Auth suite (count plus a single OUI) */
+		pWpaIe->IeHeader.Length =
+			sizeof(*pWpaIe) - sizeof(pWpaIe->IeHeader) +
+			sizeof(*pAuthSuite);
+
+		/* return the size of the IE header (total) constructed... */
+		cbWpaIe = pWpaIe->IeHeader.Length + sizeof(pWpaIe->IeHeader);
+
+	} while (0);
+
+	if (!pIes && pIesLocal) {
+		/* locally allocated */
+		cdf_mem_free(pIesLocal);
+	}
+
+	return cbWpaIe;
+}
+
+/* If a WPAIE exists in the profile, just use it. Or else construct one from the BSS */
+/* Caller allocated memory for pWpaIe and guarrantee it can contain a max length WPA IE */
+uint8_t csr_retrieve_wpa_ie(tHalHandle hHal, tCsrRoamProfile *pProfile,
+			    tSirBssDescription *pSirBssDesc,
+			    tDot11fBeaconIEs *pIes, tCsrWpaIe *pWpaIe)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	uint8_t cbWpaIe = 0;
+
+	do {
+		if (!csr_is_profile_wpa(pProfile))
+			break;
+		if (pProfile->nWPAReqIELength && pProfile->pWPAReqIE) {
+			if (SIR_MAC_WPA_IE_MAX_LENGTH >=
+			    pProfile->nWPAReqIELength) {
+				cbWpaIe = (uint8_t) pProfile->nWPAReqIELength;
+				cdf_mem_copy(pWpaIe, pProfile->pWPAReqIE,
+					     cbWpaIe);
+			} else {
+				sms_log(pMac, LOGW,
+					"  csr_retrieve_wpa_ie detect invalid WPA IE length (%d) ",
+					pProfile->nWPAReqIELength);
+			}
+		} else {
+			cbWpaIe =
+				csr_construct_wpa_ie(pMac, pProfile, pSirBssDesc, pIes,
+						     pWpaIe);
+		}
+	} while (0);
+
+	return cbWpaIe;
+}
+
+/* If a RSNIE exists in the profile, just use it. Or else construct one from the BSS */
+/* Caller allocated memory for pWpaIe and guarrantee it can contain a max length WPA IE */
+uint8_t csr_retrieve_rsn_ie(tHalHandle hHal, uint32_t sessionId,
+			    tCsrRoamProfile *pProfile,
+			    tSirBssDescription *pSirBssDesc,
+			    tDot11fBeaconIEs *pIes, tCsrRSNIe *pRsnIe)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	uint8_t cbRsnIe = 0;
+
+	do {
+		if (!csr_is_profile_rsn(pProfile))
+			break;
+#ifdef FEATURE_WLAN_LFR
+		if (csr_roam_is_fast_roam_enabled(pMac, sessionId)) {
+			/* If "Legacy Fast Roaming" is enabled ALWAYS rebuild the RSN IE from */
+			/* scratch. So it contains the current PMK-IDs */
+			cbRsnIe =
+				csr_construct_rsn_ie(pMac, sessionId, pProfile,
+						     pSirBssDesc, pIes, pRsnIe);
+		} else
+#endif
+		if (pProfile->nRSNReqIELength && pProfile->pRSNReqIE) {
+			/* If you have one started away, re-use it. */
+			if (SIR_MAC_WPA_IE_MAX_LENGTH >=
+			    pProfile->nRSNReqIELength) {
+				cbRsnIe = (uint8_t) pProfile->nRSNReqIELength;
+				cdf_mem_copy(pRsnIe, pProfile->pRSNReqIE,
+					     cbRsnIe);
+			} else {
+				sms_log(pMac, LOGW,
+					"  csr_retrieve_rsn_ie detect invalid RSN IE length (%d) ",
+					pProfile->nRSNReqIELength);
+			}
+		} else {
+			cbRsnIe =
+				csr_construct_rsn_ie(pMac, sessionId, pProfile,
+						     pSirBssDesc, pIes, pRsnIe);
+		}
+	} while (0);
+
+	return cbRsnIe;
+}
+
+#ifdef FEATURE_WLAN_WAPI
+/* If a WAPI IE exists in the profile, just use it. Or else construct one from the BSS */
+/* Caller allocated memory for pWapiIe and guarrantee it can contain a max length WAPI IE */
+uint8_t csr_retrieve_wapi_ie(tHalHandle hHal, uint32_t sessionId,
+			     tCsrRoamProfile *pProfile,
+			     tSirBssDescription *pSirBssDesc,
+			     tDot11fBeaconIEs *pIes, tCsrWapiIe *pWapiIe)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	uint8_t cbWapiIe = 0;
+
+	do {
+		if (!csr_is_profile_wapi(pProfile))
+			break;
+		if (pProfile->nWAPIReqIELength && pProfile->pWAPIReqIE) {
+			if (DOT11F_IE_WAPI_MAX_LEN >=
+			    pProfile->nWAPIReqIELength) {
+				cbWapiIe = (uint8_t) pProfile->nWAPIReqIELength;
+				cdf_mem_copy(pWapiIe, pProfile->pWAPIReqIE,
+					     cbWapiIe);
+			} else {
+				sms_log(pMac, LOGW,
+					"  csr_retrieve_wapi_ie detect invalid WAPI IE length (%d) ",
+					pProfile->nWAPIReqIELength);
+			}
+		} else {
+			cbWapiIe =
+				csr_construct_wapi_ie(pMac, sessionId, pProfile,
+						      pSirBssDesc, pIes, pWapiIe);
+		}
+	} while (0);
+
+	return cbWapiIe;
+}
+#endif /* FEATURE_WLAN_WAPI */
+
+bool csr_rates_is_dot11_rate11b_supported_rate(uint8_t dot11Rate)
+{
+	bool fSupported = false;
+	uint16_t nonBasicRate =
+		(uint16_t) (BITS_OFF(dot11Rate, CSR_DOT11_BASIC_RATE_MASK));
+
+	switch (nonBasicRate) {
+	case eCsrSuppRate_1Mbps:
+	case eCsrSuppRate_2Mbps:
+	case eCsrSuppRate_5_5Mbps:
+	case eCsrSuppRate_11Mbps:
+		fSupported = true;
+		break;
+
+	default:
+		break;
+	}
+
+	return fSupported;
+}
+
+bool csr_rates_is_dot11_rate11a_supported_rate(uint8_t dot11Rate)
+{
+	bool fSupported = false;
+	uint16_t nonBasicRate =
+		(uint16_t) (BITS_OFF(dot11Rate, CSR_DOT11_BASIC_RATE_MASK));
+
+	switch (nonBasicRate) {
+	case eCsrSuppRate_6Mbps:
+	case eCsrSuppRate_9Mbps:
+	case eCsrSuppRate_12Mbps:
+	case eCsrSuppRate_18Mbps:
+	case eCsrSuppRate_24Mbps:
+	case eCsrSuppRate_36Mbps:
+	case eCsrSuppRate_48Mbps:
+	case eCsrSuppRate_54Mbps:
+		fSupported = true;
+		break;
+
+	default:
+		break;
+	}
+
+	return fSupported;
+}
+
+tAniEdType csr_translate_encrypt_type_to_ed_type(eCsrEncryptionType EncryptType)
+{
+	tAniEdType edType;
+
+	switch (EncryptType) {
+	default:
+	case eCSR_ENCRYPT_TYPE_NONE:
+		edType = eSIR_ED_NONE;
+		break;
+
+	case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
+	case eCSR_ENCRYPT_TYPE_WEP40:
+		edType = eSIR_ED_WEP40;
+		break;
+
+	case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
+	case eCSR_ENCRYPT_TYPE_WEP104:
+		edType = eSIR_ED_WEP104;
+		break;
+
+	case eCSR_ENCRYPT_TYPE_TKIP:
+		edType = eSIR_ED_TKIP;
+		break;
+
+	case eCSR_ENCRYPT_TYPE_AES:
+		edType = eSIR_ED_CCMP;
+		break;
+#ifdef FEATURE_WLAN_WAPI
+	case eCSR_ENCRYPT_TYPE_WPI:
+		edType = eSIR_ED_WPI;
+		break;
+#endif
+#ifdef WLAN_FEATURE_11W
+	/* 11w BIP */
+	case eCSR_ENCRYPT_TYPE_AES_CMAC:
+		edType = eSIR_ED_AES_128_CMAC;
+		break;
+#endif
+	}
+
+	return edType;
+}
+
+/**
+ * csr_validate_wep() - to validate wep
+ * @uc_encry_type: unicast encryption type
+ * @auth_list: Auth list
+ * @mc_encryption_list: multicast encryption type
+ * @negotiated_authtype: negotiated auth type
+ * @negotiated_mc_encry: negotiated mc encry type
+ * @bss_descr: BSS description
+ * @ie_ptr: IE pointer
+ *
+ * This function just checks whether HDD is giving correct values for
+ * Multicast cipher and Auth
+ *
+ * Return: bool
+ */
+bool csr_validate_wep(tpAniSirGlobal mac_ctx, eCsrEncryptionType uc_encry_type,
+		      tCsrAuthList *auth_list,
+		      tCsrEncryptionList *mc_encryption_list,
+		      eCsrAuthType *negotiated_authtype,
+		      eCsrEncryptionType *negotiated_mc_encry,
+		      tSirBssDescription *bss_descr, tDot11fBeaconIEs *ie_ptr)
+{
+	uint32_t idx;
+	bool match = false;
+	eCsrAuthType negotiated_auth = eCSR_AUTH_TYPE_OPEN_SYSTEM;
+	eCsrEncryptionType negotiated_mccipher = eCSR_ENCRYPT_TYPE_UNKNOWN;
+
+	/* If privacy bit is not set, consider no match */
+	if (!csr_is_privacy(bss_descr))
+		goto end;
+
+	for (idx = 0; idx < mc_encryption_list->numEntries; idx++) {
+		switch (mc_encryption_list->encryptionType[idx]) {
+		case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
+		case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
+		case eCSR_ENCRYPT_TYPE_WEP40:
+		case eCSR_ENCRYPT_TYPE_WEP104:
+			/*
+			 * Multicast list may contain WEP40/WEP104.
+			 * Check whether it matches UC.
+			 */
+			if (uc_encry_type ==
+				mc_encryption_list->encryptionType[idx]) {
+				match = true;
+				negotiated_mccipher =
+					mc_encryption_list->encryptionType[idx];
+			}
+			break;
+		default:
+			match = false;
+			break;
+		}
+		if (match)
+			break;
+	}
+
+	if (!match)
+		goto end;
+
+	for (idx = 0; idx < auth_list->numEntries; idx++) {
+		switch (auth_list->authType[idx]) {
+		case eCSR_AUTH_TYPE_OPEN_SYSTEM:
+		case eCSR_AUTH_TYPE_SHARED_KEY:
+		case eCSR_AUTH_TYPE_AUTOSWITCH:
+			match = true;
+			negotiated_auth = auth_list->authType[idx];
+			break;
+		default:
+			match = false;
+		}
+		if (match)
+			break;
+	}
+
+	if (!match)
+		goto end;
+
+	if (!ie_ptr)
+		goto end;
+
+	/*
+	 * In case of WPA / WPA2, check whether it supports WEP as well.
+	 * Prepare the encryption type for WPA/WPA2 functions
+	 */
+	if (eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == uc_encry_type)
+		uc_encry_type = eCSR_ENCRYPT_TYPE_WEP40;
+	else if (eCSR_ENCRYPT_TYPE_WEP104 == uc_encry_type)
+		uc_encry_type = eCSR_ENCRYPT_TYPE_WEP104;
+
+	/* else we can use the encryption type directly */
+	if (ie_ptr->WPA.present) {
+		match = cdf_mem_compare(ie_ptr->WPA.multicast_cipher,
+				csr_wpa_oui[csr_get_oui_index_from_cipher(
+					uc_encry_type)],
+				CSR_WPA_OUI_SIZE);
+		if (match)
+			goto end;
+	}
+	if (ie_ptr->RSN.present) {
+		match = cdf_mem_compare(ie_ptr->RSN.gp_cipher_suite,
+				csr_rsn_oui[csr_get_oui_index_from_cipher(
+					uc_encry_type)],
+				CSR_RSN_OUI_SIZE);
+	}
+
+
+end:
+	if (match) {
+		if (negotiated_authtype)
+			*negotiated_authtype = negotiated_auth;
+		if (negotiated_mc_encry)
+			*negotiated_mc_encry = negotiated_mccipher;
+	}
+	return match;
+}
+
+/**
+ * csr_validate_open_none() - Check if the security is matching
+ * @bss_desc:          BSS Descriptor on which the check is done
+ * @mc_enc_type:       Multicast encryption type
+ * @mc_cipher:         Multicast Cipher
+ * @auth_type:         Authentication type
+ * @neg_auth_type:     Negotiated Auth type with the AP
+ *
+ * Return: Boolean value to tell if matched or not.
+ */
+static bool csr_validate_open_none(tSirBssDescription *bss_desc,
+	tCsrEncryptionList *mc_enc_type, eCsrEncryptionType *mc_cipher,
+	tCsrAuthList *auth_type, eCsrAuthType *neg_auth_type)
+{
+	bool match;
+	uint8_t idx;
+
+	/*
+	 * for NO encryption, if the Bss description has the
+	 * Privacy bit turned on, then encryption is required
+	 * so we have to reject this Bss.
+	 */
+	if (csr_is_privacy(bss_desc))
+		match = false;
+	else
+		match = true;
+	if (match) {
+		match = false;
+		/* Check MC cipher and Auth type requested. */
+		for (idx = 0; idx < mc_enc_type->numEntries; idx++) {
+			if (eCSR_ENCRYPT_TYPE_NONE ==
+				mc_enc_type->encryptionType[idx]) {
+				match = true;
+				*mc_cipher = mc_enc_type->encryptionType[idx];
+				break;
+			}
+		}
+		if (!match)
+			return match;
+
+		match = false;
+		/* Check Auth list. It should contain AuthOpen. */
+		for (idx = 0; idx < auth_type->numEntries; idx++) {
+			if ((eCSR_AUTH_TYPE_OPEN_SYSTEM ==
+				auth_type->authType[idx]) ||
+				(eCSR_AUTH_TYPE_AUTOSWITCH ==
+				auth_type->authType[idx])) {
+				match = true;
+				*neg_auth_type =
+					eCSR_AUTH_TYPE_OPEN_SYSTEM;
+				break;
+			}
+		}
+		if (!match)
+			return match;
+
+	}
+	return match;
+}
+
+/**
+ * csr_validate_any_default() - Check if the security is matching
+ * @hal:               Global HAL handle
+ * @auth_type:         Authentication type
+ * @mc_enc_type:       Multicast encryption type
+ * @mfp_enabled:       Management frame protection feature
+ * @mfp_required:      Mangement frame protection mandatory
+ * @mfp_capable:       Device capable of MFP
+ * @ies_ptr:           Pointer to the IE fields
+ * @neg_auth_type:     Negotiated Auth type with the AP
+ * @bss_desc:          BSS Descriptor
+ * @neg_uc_cipher:     Negotiated unicast cipher suite
+ * @neg_mc_cipher:     Negotiated multicast cipher
+ *
+ * Return: Boolean value to tell if matched or not.
+ */
+static bool csr_validate_any_default(tHalHandle hal, tCsrAuthList *auth_type,
+	tCsrEncryptionList *mc_enc_type, bool *mfp_enabled,
+	uint8_t *mfp_required, uint8_t *mfp_capable,
+	tDot11fBeaconIEs *ies_ptr, eCsrAuthType *neg_auth_type,
+	tSirBssDescription *bss_desc, eCsrEncryptionType *uc_cipher,
+	eCsrEncryptionType *mc_cipher)
+{
+	bool match_any = false;
+	bool match = true;
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	/* It is allowed to match anything. Try the more secured ones first. */
+	if (ies_ptr) {
+		/* Check AES first */
+		*uc_cipher = eCSR_ENCRYPT_TYPE_AES;
+		match_any = csr_is_rsn_match(hal, auth_type,
+				*uc_cipher, mc_enc_type, mfp_enabled,
+				mfp_required, mfp_capable, ies_ptr,
+				neg_auth_type, mc_cipher);
+		if (!match_any) {
+			/* Check TKIP */
+			*uc_cipher = eCSR_ENCRYPT_TYPE_TKIP;
+			match_any = csr_is_rsn_match(hal, auth_type, *uc_cipher,
+					mc_enc_type, mfp_enabled, mfp_required,
+					mfp_capable, ies_ptr, neg_auth_type,
+					mc_cipher);
+		}
+#ifdef FEATURE_WLAN_WAPI
+		if (!match_any) {
+			/* Check WAPI */
+			*uc_cipher = eCSR_ENCRYPT_TYPE_WPI;
+			match_any = csr_is_wapi_match(hal, auth_type,
+					*uc_cipher, mc_enc_type, ies_ptr,
+					neg_auth_type, mc_cipher);
+		}
+#endif
+	}
+	if (match_any)
+		return match;
+	*uc_cipher = eCSR_ENCRYPT_TYPE_WEP104;
+	if (csr_validate_wep(mac_ctx, *uc_cipher, auth_type, mc_enc_type,
+			neg_auth_type, mc_cipher, bss_desc, ies_ptr))
+		return match;
+	*uc_cipher = eCSR_ENCRYPT_TYPE_WEP40;
+	if (csr_validate_wep(mac_ctx, *uc_cipher, auth_type, mc_enc_type,
+			neg_auth_type, mc_cipher, bss_desc, ies_ptr))
+		return match;
+	*uc_cipher = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
+	if (csr_validate_wep(mac_ctx, *uc_cipher, auth_type, mc_enc_type,
+			neg_auth_type, mc_cipher, bss_desc, ies_ptr))
+		return match;
+	*uc_cipher = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
+	if (csr_validate_wep(mac_ctx, *uc_cipher, auth_type, mc_enc_type,
+			neg_auth_type, mc_cipher, bss_desc, ies_ptr))
+		return match;
+	/* It must be open and no enc */
+	if (csr_is_privacy(bss_desc)) {
+		match = false;
+		return match;
+	}
+
+	*neg_auth_type = eCSR_AUTH_TYPE_OPEN_SYSTEM;
+	*mc_cipher = eCSR_ENCRYPT_TYPE_NONE;
+	*uc_cipher = eCSR_ENCRYPT_TYPE_NONE;
+	return match;
+
+}
+
+/**
+ * csr_is_security_match() - Check if the security is matching
+ * @hal:               Global HAL handle
+ * @auth_type:         Authentication type
+ * @uc_enc_type:       Unicast Encryption type
+ * @mc_enc_type:       Multicast encryption type
+ * @mfp_enabled:       Management frame protection feature
+ * @mfp_required:      Mangement frame protection mandatory
+ * @mfp_capable:       Device capable of MFP
+ * @bss_desc:          BSS Descriptor
+ * @ies_ptr:           Pointer to the IE fields
+ * @neg_auth_type:     Negotiated Auth type with the AP
+ * @neg_uc_cipher:     Negotiated unicast cipher suite
+ * @neg_mc_cipher:     Negotiated multicast cipher
+ *
+ * Return: Boolean value to tell if matched or not.
+ */
+bool csr_is_security_match(tHalHandle hal, tCsrAuthList *auth_type,
+	tCsrEncryptionList *uc_enc_type,
+	tCsrEncryptionList *mc_enc_type, bool *mfp_enabled,
+	uint8_t *mfp_required, uint8_t *mfp_capable,
+	tSirBssDescription *bss_desc, tDot11fBeaconIEs *ies_ptr,
+	eCsrAuthType *neg_auth_type,
+	eCsrEncryptionType *neg_uc_cipher,
+	eCsrEncryptionType *neg_mc_cipher)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	bool match = false;
+	uint8_t i;
+	eCsrEncryptionType mc_cipher = eCSR_ENCRYPT_TYPE_UNKNOWN;
+	eCsrEncryptionType uc_cipher = eCSR_ENCRYPT_TYPE_UNKNOWN;
+	eCsrAuthType local_neg_auth_type = eCSR_AUTH_TYPE_UNKNOWN;
+
+	for (i = 0; ((i < uc_enc_type->numEntries) && (!match)); i++) {
+		uc_cipher = uc_enc_type->encryptionType[i];
+		/*
+		 * If the Bss description shows the Privacy bit is on, then we
+		 * must have some sort of encryption configured for the profile
+		 * to work.  Don't attempt to join networks with Privacy bit
+		 * set when profiles say NONE for encryption type.
+		 */
+		switch (uc_cipher) {
+		case eCSR_ENCRYPT_TYPE_NONE:
+			match = csr_validate_open_none(bss_desc, mc_enc_type,
+					&mc_cipher, auth_type,
+					&local_neg_auth_type);
+			break;
+
+		case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
+		case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
+			/*
+			 * !! might want to check for WEP keys set in the
+			 * Profile.... ? !! don't need to have the privacy bit
+			 * in the Bss description.  Many AP policies make
+			 * legacy encryption 'optional' so we don't know if we
+			 * can associate or not.  The AP will reject if
+			 * encryption is not allowed without the Privacy bit
+			 * turned on.
+			 */
+			match = csr_validate_wep(mac_ctx, uc_cipher, auth_type,
+					mc_enc_type, &local_neg_auth_type,
+					&mc_cipher, bss_desc, ies_ptr);
+
+			break;
+		/* these are all of the WPA encryption types... */
+		case eCSR_ENCRYPT_TYPE_WEP40:
+		case eCSR_ENCRYPT_TYPE_WEP104:
+			match = csr_validate_wep(mac_ctx, uc_cipher, auth_type,
+					mc_enc_type, &local_neg_auth_type,
+					&mc_cipher, bss_desc, ies_ptr);
+			break;
+
+		case eCSR_ENCRYPT_TYPE_TKIP:
+		case eCSR_ENCRYPT_TYPE_AES:
+			if (!ies_ptr) {
+				match = false;
+				break;
+			}
+			/* First check if there is a RSN match */
+			match = csr_is_rsn_match(mac_ctx, auth_type,
+					uc_cipher, mc_enc_type,
+					mfp_enabled, mfp_required,
+					mfp_capable, ies_ptr,
+					&local_neg_auth_type,
+					&mc_cipher);
+			/* If not RSN, then check WPA match */
+			if (!match)
+				match = csr_is_wpa_encryption_match(
+						mac_ctx, auth_type,
+						uc_cipher, mc_enc_type,
+						ies_ptr,
+						&local_neg_auth_type,
+						&mc_cipher);
+			break;
+#ifdef FEATURE_WLAN_WAPI
+		case eCSR_ENCRYPT_TYPE_WPI:     /* WAPI */
+			if (ies_ptr)
+				match = csr_is_wapi_match(hal, auth_type,
+						uc_cipher, mc_enc_type, ies_ptr,
+						&local_neg_auth_type,
+						&mc_cipher);
+			else
+				match = false;
+			break;
+#endif /* FEATURE_WLAN_WAPI */
+		case eCSR_ENCRYPT_TYPE_ANY:
+		default:
+			match  = csr_validate_any_default(hal, auth_type,
+					mc_enc_type, mfp_enabled, mfp_required,
+					mfp_capable, ies_ptr,
+					&local_neg_auth_type, bss_desc,
+					&uc_cipher, &mc_cipher);
+			break;
+		}
+
+	}
+
+	if (match) {
+		if (neg_uc_cipher)
+			*neg_uc_cipher = uc_cipher;
+		if (neg_mc_cipher)
+			*neg_mc_cipher = mc_cipher;
+		if (neg_auth_type)
+			*neg_auth_type = local_neg_auth_type;
+	}
+	return match;
+}
+
+bool csr_is_ssid_match(tpAniSirGlobal pMac, uint8_t *ssid1, uint8_t ssid1Len,
+		       uint8_t *bssSsid, uint8_t bssSsidLen, bool fSsidRequired)
+{
+	bool fMatch = false;
+
+	do {
+		/*
+		 * Check for the specification of the Broadcast SSID at the
+		 * beginning of the list. If specified, then all SSIDs are
+		 * matches (broadcast SSID means accept all SSIDs).
+		 */
+		if (ssid1Len == 0) {
+			fMatch = true;
+			break;
+		}
+
+		/* There are a few special cases.  If the Bss description has a Broadcast SSID, */
+		/* then our Profile must have a single SSID without Wildcards so we can program */
+		/* the SSID. */
+		/* SSID could be suppressed in beacons. In that case SSID IE has valid length */
+		/* but the SSID value is all NULL characters. That condition is trated same */
+		/* as NULL SSID */
+		if (csr_is_nullssid(bssSsid, bssSsidLen)) {
+			if (false == fSsidRequired) {
+				fMatch = true;
+				break;
+			}
+		}
+
+		if (ssid1Len != bssSsidLen)
+			break;
+		if (cdf_mem_compare(bssSsid, ssid1, bssSsidLen)) {
+			fMatch = true;
+			break;
+		}
+
+	} while (0);
+
+	return fMatch;
+}
+
+/* Null ssid means match */
+bool csr_is_ssid_in_list(tHalHandle hHal, tSirMacSSid *pSsid,
+			 tCsrSSIDs *pSsidList)
+{
+	bool fMatch = false;
+	uint32_t i;
+
+	if (pSsidList && pSsid) {
+		for (i = 0; i < pSsidList->numOfSSIDs; i++) {
+			if (csr_is_nullssid
+				    (pSsidList->SSIDList[i].SSID.ssId,
+				    pSsidList->SSIDList[i].SSID.length)
+			    ||
+			    ((pSsidList->SSIDList[i].SSID.length ==
+			      pSsid->length)
+			     && cdf_mem_compare(pSsid->ssId,
+						pSsidList->SSIDList[i].SSID.
+						ssId, pSsid->length))) {
+				fMatch = true;
+				break;
+			}
+		}
+	}
+
+	return fMatch;
+}
+
+bool csr_is_bssid_match(tHalHandle hHal, struct cdf_mac_addr *pProfBssid,
+			struct cdf_mac_addr *BssBssid)
+{
+	bool fMatch = false;
+	struct cdf_mac_addr ProfileBssid;
+
+	/* for efficiency of the MAC_ADDRESS functions, move the */
+	/* Bssid's into MAC_ADDRESS structs. */
+	cdf_mem_copy(&ProfileBssid, pProfBssid, sizeof(struct cdf_mac_addr));
+
+	do {
+
+		/* Give the profile the benefit of the doubt... accept either all 0 or */
+		/* the real broadcast Bssid (all 0xff) as broadcast Bssids (meaning to */
+		/* match any Bssids). */
+		if (cdf_is_macaddr_zero(&ProfileBssid) ||
+		    cdf_is_macaddr_broadcast(&ProfileBssid)) {
+			fMatch = true;
+			break;
+		}
+
+		if (cdf_is_macaddr_equal(BssBssid, &ProfileBssid)) {
+			fMatch = true;
+			break;
+		}
+
+	} while (0);
+
+	return fMatch;
+}
+
+bool csr_is_bss_type_match(eCsrRoamBssType bssType1, eCsrRoamBssType bssType2)
+{
+	if ((eCSR_BSS_TYPE_ANY != bssType1 && eCSR_BSS_TYPE_ANY != bssType2)
+	    && (bssType1 != bssType2))
+		return false;
+	else
+		return true;
+}
+
+bool csr_is_bss_type_ibss(eCsrRoamBssType bssType)
+{
+	return (bool)
+		(eCSR_BSS_TYPE_START_IBSS == bssType
+		 || eCSR_BSS_TYPE_IBSS == bssType);
+}
+
+bool csr_is_bss_type_wds(eCsrRoamBssType bssType)
+{
+	return (bool)
+		(eCSR_BSS_TYPE_WDS_STA == bssType
+		 || eCSR_BSS_TYPE_WDS_AP == bssType);
+}
+
+bool csr_is_bss_type_caps_match(eCsrRoamBssType bssType,
+				tSirBssDescription *pSirBssDesc)
+{
+	bool fMatch = true;
+
+	do {
+		switch (bssType) {
+		case eCSR_BSS_TYPE_ANY:
+			break;
+
+		case eCSR_BSS_TYPE_INFRASTRUCTURE:
+		case eCSR_BSS_TYPE_WDS_STA:
+			if (!csr_is_infra_bss_desc(pSirBssDesc))
+				fMatch = false;
+
+			break;
+
+		case eCSR_BSS_TYPE_IBSS:
+		case eCSR_BSS_TYPE_START_IBSS:
+			if (!csr_is_ibss_bss_desc(pSirBssDesc))
+				fMatch = false;
+
+			break;
+
+		case eCSR_BSS_TYPE_WDS_AP:      /* For WDS AP, no need to match anything */
+		default:
+			fMatch = false;
+			break;
+		}
+	} while (0);
+
+	return fMatch;
+}
+
+static bool csr_is_capabilities_match(tpAniSirGlobal pMac, eCsrRoamBssType bssType,
+				      tSirBssDescription *pSirBssDesc)
+{
+	return csr_is_bss_type_caps_match(bssType, pSirBssDesc);
+}
+
+static bool csr_is_specific_channel_match(tpAniSirGlobal pMac,
+					  tSirBssDescription *pSirBssDesc,
+					  uint8_t Channel)
+{
+	bool fMatch = true;
+
+	do {
+		/* if the channel is ANY, then always match... */
+		if (eCSR_OPERATING_CHANNEL_ANY == Channel)
+			break;
+		if (Channel == pSirBssDesc->channelId)
+			break;
+
+		/* didn't match anything.. so return NO match */
+		fMatch = false;
+
+	} while (0);
+
+	return fMatch;
+}
+
+bool csr_is_channel_band_match(tpAniSirGlobal pMac, uint8_t channelId,
+			       tSirBssDescription *pSirBssDesc)
+{
+	bool fMatch = true;
+
+	do {
+		/* if the profile says Any channel AND the global settings says ANY channel, then we */
+		/* always match... */
+		if (eCSR_OPERATING_CHANNEL_ANY == channelId)
+			break;
+
+		if (eCSR_OPERATING_CHANNEL_ANY != channelId) {
+			fMatch =
+				csr_is_specific_channel_match(pMac, pSirBssDesc,
+							      channelId);
+		}
+
+	} while (0);
+
+	return fMatch;
+}
+
+/**
+ * csr_is_aggregate_rate_supported() - to check if aggregate rate is supported
+ * @mac_ctx: pointer to mac context
+ * @rate: A rate in units of 500kbps
+ *
+ *
+ * The rate encoding  is just as in 802.11  Information Elements, except
+ * that the high bit is \em  not interpreted as indicating a Basic Rate,
+ * and proprietary rates are allowed, too.
+ *
+ * Note  that if the  adapter's dot11Mode  is g,  we don't  restrict the
+ * rates.  According to hwReadEepromParameters, this will happen when:
+ * ... the  card is  configured for ALL  bands through  the property
+ * page.  If this occurs, and the card is not an ABG card ,then this
+ * code  is  setting the  dot11Mode  to  assume  the mode  that  the
+ * hardware can support.   For example, if the card  is an 11BG card
+ * and we  are configured to support  ALL bands, then  we change the
+ * dot11Mode  to 11g  because  ALL in  this  case is  only what  the
+ * hardware can support.
+ *
+ * Return: true if  the adapter is currently capable of supporting this rate
+ */
+
+static bool csr_is_aggregate_rate_supported(tpAniSirGlobal mac_ctx,
+			uint16_t rate)
+{
+	bool supported = false;
+	uint16_t idx, new_rate;
+
+	/* In case basic rate flag is set */
+	new_rate = BITS_OFF(rate, CSR_DOT11_BASIC_RATE_MASK);
+	if (eCSR_CFG_DOT11_MODE_11A ==
+			mac_ctx->roam.configParam.uCfgDot11Mode) {
+		switch (new_rate) {
+		case eCsrSuppRate_6Mbps:
+		case eCsrSuppRate_9Mbps:
+		case eCsrSuppRate_12Mbps:
+		case eCsrSuppRate_18Mbps:
+		case eCsrSuppRate_24Mbps:
+		case eCsrSuppRate_36Mbps:
+		case eCsrSuppRate_48Mbps:
+		case eCsrSuppRate_54Mbps:
+			supported = true;
+			break;
+		default:
+			supported = false;
+			break;
+		}
+
+	} else if (eCSR_CFG_DOT11_MODE_11B ==
+		   mac_ctx->roam.configParam.uCfgDot11Mode) {
+		switch (new_rate) {
+		case eCsrSuppRate_1Mbps:
+		case eCsrSuppRate_2Mbps:
+		case eCsrSuppRate_5_5Mbps:
+		case eCsrSuppRate_11Mbps:
+			supported = true;
+			break;
+		default:
+			supported = false;
+			break;
+		}
+	} else if (!mac_ctx->roam.configParam.ProprietaryRatesEnabled) {
+
+		switch (new_rate) {
+		case eCsrSuppRate_1Mbps:
+		case eCsrSuppRate_2Mbps:
+		case eCsrSuppRate_5_5Mbps:
+		case eCsrSuppRate_6Mbps:
+		case eCsrSuppRate_9Mbps:
+		case eCsrSuppRate_11Mbps:
+		case eCsrSuppRate_12Mbps:
+		case eCsrSuppRate_18Mbps:
+		case eCsrSuppRate_24Mbps:
+		case eCsrSuppRate_36Mbps:
+		case eCsrSuppRate_48Mbps:
+		case eCsrSuppRate_54Mbps:
+			supported = true;
+			break;
+		default:
+			supported = false;
+			break;
+		}
+	} else if (eCsrSuppRate_1Mbps == new_rate ||
+			eCsrSuppRate_2Mbps == new_rate ||
+			eCsrSuppRate_5_5Mbps == new_rate ||
+			eCsrSuppRate_11Mbps == new_rate) {
+			supported = true;
+	} else {
+		idx = 0x1;
+
+		switch (new_rate) {
+		case eCsrSuppRate_6Mbps:
+			supported = g_phy_rates_suppt[0][idx];
+			break;
+		case eCsrSuppRate_9Mbps:
+			supported = g_phy_rates_suppt[1][idx];
+			break;
+		case eCsrSuppRate_12Mbps:
+			supported = g_phy_rates_suppt[2][idx];
+			break;
+		case eCsrSuppRate_18Mbps:
+			supported = g_phy_rates_suppt[3][idx];
+			break;
+		case eCsrSuppRate_20Mbps:
+			supported = g_phy_rates_suppt[4][idx];
+			break;
+		case eCsrSuppRate_24Mbps:
+			supported = g_phy_rates_suppt[5][idx];
+			break;
+		case eCsrSuppRate_36Mbps:
+			supported = g_phy_rates_suppt[6][idx];
+			break;
+		case eCsrSuppRate_40Mbps:
+			supported = g_phy_rates_suppt[7][idx];
+			break;
+		case eCsrSuppRate_42Mbps:
+			supported = g_phy_rates_suppt[8][idx];
+			break;
+		case eCsrSuppRate_48Mbps:
+			supported = g_phy_rates_suppt[9][idx];
+			break;
+		case eCsrSuppRate_54Mbps:
+			supported = g_phy_rates_suppt[10][idx];
+			break;
+		case eCsrSuppRate_72Mbps:
+			supported = g_phy_rates_suppt[11][idx];
+			break;
+		case eCsrSuppRate_80Mbps:
+			supported = g_phy_rates_suppt[12][idx];
+			break;
+		case eCsrSuppRate_84Mbps:
+			supported = g_phy_rates_suppt[13][idx];
+			break;
+		case eCsrSuppRate_96Mbps:
+			supported = g_phy_rates_suppt[14][idx];
+			break;
+		case eCsrSuppRate_108Mbps:
+			supported = g_phy_rates_suppt[15][idx];
+			break;
+		case eCsrSuppRate_120Mbps:
+			supported = g_phy_rates_suppt[16][idx];
+			break;
+		case eCsrSuppRate_126Mbps:
+			supported = g_phy_rates_suppt[17][idx];
+			break;
+		case eCsrSuppRate_144Mbps:
+			supported = g_phy_rates_suppt[18][idx];
+			break;
+		case eCsrSuppRate_160Mbps:
+			supported = g_phy_rates_suppt[19][idx];
+			break;
+		case eCsrSuppRate_168Mbps:
+			supported = g_phy_rates_suppt[20][idx];
+			break;
+		case eCsrSuppRate_192Mbps:
+			supported = g_phy_rates_suppt[21][idx];
+			break;
+		case eCsrSuppRate_216Mbps:
+			supported = g_phy_rates_suppt[22][idx];
+			break;
+		case eCsrSuppRate_240Mbps:
+			supported = g_phy_rates_suppt[23][idx];
+			break;
+		default:
+			supported = false;
+			break;
+		}
+	}
+	return supported;
+}
+
+/**
+ * csr_is_rate_set_match() - to check if rate set is matching
+ * @mac_ctx: pointer to mac context
+ * @bss_supported_rates: supported rates of BSS
+ * @bss_ext_supp_rates: extended rates of bss
+ *
+ * This routine is to checke if rate set is matched or no
+ *
+ * Return: bool
+ */
+static bool csr_is_rate_set_match(tpAniSirGlobal mac_ctx,
+				  tDot11fIESuppRates *bss_supported_rates,
+				  tDot11fIEExtSuppRates *bss_ext_supp_rates)
+{
+	bool match = true;
+	uint32_t i;
+
+	/*
+	 * Validate that all of the Basic rates advertised in the Bss
+	 * description are supported
+	 */
+	if (bss_supported_rates) {
+		for (i = 0; i < bss_supported_rates->num_rates; i++) {
+			if (!CSR_IS_BASIC_RATE(bss_supported_rates->rates[i]))
+				continue;
+			if (!csr_is_aggregate_rate_supported(mac_ctx,
+					bss_supported_rates->rates[i])) {
+				match = false;
+				break;
+			}
+		}
+	}
+	if (match && bss_ext_supp_rates) {
+		for (i = 0; i < bss_ext_supp_rates->num_rates; i++) {
+			if (!CSR_IS_BASIC_RATE(bss_ext_supp_rates->rates[i]))
+				continue;
+			if (!csr_is_aggregate_rate_supported(mac_ctx,
+					bss_ext_supp_rates->rates[i])) {
+				match = false;
+				break;
+			}
+		}
+	}
+	return match;
+}
+
+/**
+ * csr_match_bss() - to compare the bss
+ * @hal: pointer to hal context
+ * @bss_descr: pointer bss description
+ * @filter: scan filter
+ * @neg_auth: negotiated auth
+ * @neg_uc: negotiated for unicast
+ * @neg_mc: negotiated for multicast
+ * @ie_dblptr: double pointer to IE
+ *
+ * This routine will be called to match the bss
+ * If caller want to get the *ie_dblptr allocated by this function,
+ * pass in *ie_dblptr = NULL
+ *
+ * Return: bool
+ */
+bool csr_match_bss(tHalHandle hal, tSirBssDescription *bss_descr,
+		   tCsrScanResultFilter *filter, eCsrAuthType *neg_auth,
+		   eCsrEncryptionType *neg_uc, eCsrEncryptionType *neg_mc,
+		   tDot11fBeaconIEs **ie_dblptr)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	bool rc = false, check, blacklist_check;
+	uint32_t i;
+	tDot11fBeaconIEs *ie_ptr = NULL;
+	uint8_t *pb;
+	struct roam_ext_params *roam_params;
+	uint8_t *p2p_macaddr = NULL;
+
+	roam_params = &mac_ctx->roam.configParam.roam_params;
+	if ((NULL == ie_dblptr) || (*ie_dblptr) == NULL) {
+		/* If no IEs passed in, get our own. */
+		if (!CDF_IS_STATUS_SUCCESS(
+			csr_get_parsed_bss_description_ies(mac_ctx,
+				bss_descr, &ie_ptr))) {
+			goto end;
+		}
+	} else {
+		/* Save the one pass in for local use */
+		ie_ptr = *ie_dblptr;
+	}
+
+	/* Check if caller wants P2P */
+	check = (!filter->p2pResult || ie_ptr->P2PBeaconProbeRes.present);
+	if (!check)
+		goto end;
+
+	/* Check for Blacklist BSSID's and avoid connections */
+	blacklist_check = false;
+	for (i = 0; i < roam_params->num_bssid_avoid_list; i++) {
+		if (cdf_is_macaddr_equal((struct cdf_mac_addr *)
+					&roam_params->bssid_avoid_list[i],
+				(struct cdf_mac_addr *)bss_descr->bssId)) {
+			blacklist_check = true;
+			break;
+		}
+	}
+	if (blacklist_check) {
+		sms_log(mac_ctx, LOGE,
+			FL("Don't Attempt connect to blacklist bssid"));
+		goto end;
+	}
+
+	if (ie_ptr->SSID.present) {
+		for (i = 0; i < filter->SSIDs.numOfSSIDs; i++) {
+			check = csr_is_ssid_match(mac_ctx,
+					filter->SSIDs.SSIDList[i].SSID.ssId,
+					filter->SSIDs.SSIDList[i].SSID.length,
+					ie_ptr->SSID.ssid,
+					ie_ptr->SSID.num_ssid, true);
+			if (check)
+				break;
+		}
+		if (!check)
+			goto end;
+	}
+	check = true;
+	p2p_macaddr = ie_ptr->P2PBeaconProbeRes.P2PDeviceInfo.P2PDeviceAddress;
+	for (i = 0; i < filter->BSSIDs.numOfBSSIDs; i++) {
+		check = csr_is_bssid_match(mac_ctx,
+				(struct cdf_mac_addr *)&filter->BSSIDs.bssid[i],
+				(struct cdf_mac_addr *)bss_descr->bssId);
+		if (check)
+			break;
+
+		if (filter->p2pResult && ie_ptr->P2PBeaconProbeRes.present) {
+			check = csr_is_bssid_match(mac_ctx,
+					(struct cdf_mac_addr *)
+						&filter->BSSIDs.bssid[i],
+					(struct cdf_mac_addr *)p2p_macaddr);
+			if (check)
+				break;
+		}
+	}
+	if (!check)
+		goto end;
+
+	check = true;
+	for (i = 0; i < filter->ChannelInfo.numOfChannels; i++) {
+		check = csr_is_channel_band_match(mac_ctx,
+				filter->ChannelInfo.ChannelList[i], bss_descr);
+		if (check)
+			break;
+	}
+	if (!check)
+		goto end;
+#if defined WLAN_FEATURE_VOWIFI
+	/* If this is for measurement filtering */
+	if (filter->fMeasurement) {
+		rc = true;
+		goto end;
+	}
+#endif
+	if (!csr_is_phy_mode_match(mac_ctx, filter->phyMode, bss_descr,
+			NULL, NULL, ie_ptr))
+		goto end;
+
+#ifdef WLAN_FEATURE_11W
+	if ((!filter->bWPSAssociation) && (!filter->bOSENAssociation) &&
+			!csr_is_security_match(mac_ctx, &filter->authType,
+				&filter->EncryptionType,
+				&filter->mcEncryptionType,
+				&filter->MFPEnabled,
+				&filter->MFPRequired,
+				&filter->MFPCapable,
+				bss_descr, ie_ptr, neg_auth,
+				neg_uc, neg_mc))
+#else
+	if ((!filter->bWPSAssociation) && (!filter->bOSENAssociation) &&
+			!csr_is_security_match(mac_ctx, &filter->authType,
+				&filter->EncryptionType,
+				&filter->mcEncryptionType,
+				NULL, NULL, NULL,
+				bss_descr, ie_ptr, neg_auth,
+				neg_uc, neg_mc))
+#endif
+		goto end;
+	if (!csr_is_capabilities_match(mac_ctx, filter->BSSType, bss_descr))
+		goto end;
+	if (!csr_is_rate_set_match(mac_ctx, &ie_ptr->SuppRates,
+			&ie_ptr->ExtSuppRates))
+		goto end;
+	if ((eCsrRoamWmmQbssOnly == mac_ctx->roam.configParam.WMMSupportMode)
+			&& !CSR_IS_QOS_BSS(ie_ptr))
+		goto end;
+	/*
+	 * Check country. check even when pb is NULL because we may
+	 * want to make sure
+	 */
+	pb = (filter->countryCode[0]) ? (filter->countryCode) : NULL;
+	check = csr_match_country_code(mac_ctx, pb, ie_ptr);
+	if (!check)
+		goto end;
+
+#ifdef WLAN_FEATURE_VOWIFI_11R
+	if (filter->MDID.mdiePresent && csr_roam_is11r_assoc(mac_ctx,
+			mac_ctx->roam.roamSession->sessionId)) {
+		if (bss_descr->mdiePresent) {
+			if (filter->MDID.mobilityDomain !=
+					(bss_descr->mdie[1] << 8 |
+						bss_descr->mdie[0]))
+				goto end;
+		} else {
+			goto end;
+		}
+	}
+#endif
+	rc = true;
+
+end:
+	if (ie_dblptr)
+		*ie_dblptr = ie_ptr;
+	else if (ie_ptr)
+		cdf_mem_free(ie_ptr);
+	return rc;
+}
+
+bool csr_match_connected_bss_security(tpAniSirGlobal pMac,
+				      tCsrRoamConnectedProfile *pProfile,
+				      tSirBssDescription *pBssDesc,
+				      tDot11fBeaconIEs *pIes)
+{
+	tCsrEncryptionList ucEncryptionList, mcEncryptionList;
+	tCsrAuthList authList;
+
+	ucEncryptionList.numEntries = 1;
+	ucEncryptionList.encryptionType[0] = pProfile->EncryptionType;
+
+	mcEncryptionList.numEntries = 1;
+	mcEncryptionList.encryptionType[0] = pProfile->mcEncryptionType;
+
+	authList.numEntries = 1;
+	authList.authType[0] = pProfile->AuthType;
+
+	return csr_is_security_match(pMac, &authList, &ucEncryptionList,
+				      &mcEncryptionList, NULL, NULL, NULL,
+				      pBssDesc, pIes, NULL, NULL, NULL);
+
+}
+
+bool csr_match_bss_to_connect_profile(tHalHandle hHal,
+				      tCsrRoamConnectedProfile *pProfile,
+				      tSirBssDescription *pBssDesc,
+				      tDot11fBeaconIEs *pIes)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	bool fRC = false, fCheck;
+	tDot11fBeaconIEs *pIesLocal = pIes;
+
+	do {
+		if (!pIes) {
+			if (!CDF_IS_STATUS_SUCCESS
+				    (csr_get_parsed_bss_description_ies
+					    (pMac, pBssDesc, &pIesLocal))) {
+				break;
+			}
+		}
+		fCheck = true;
+		if (pIesLocal->SSID.present) {
+			bool fCheckSsid = false;
+			if (pProfile->SSID.length) {
+				fCheckSsid = true;
+			}
+			fCheck =
+				csr_is_ssid_match(pMac, pProfile->SSID.ssId,
+						  pProfile->SSID.length,
+						  pIesLocal->SSID.ssid,
+						  pIesLocal->SSID.num_ssid,
+						  fCheckSsid);
+			if (!fCheck)
+				break;
+		}
+		if (!csr_match_connected_bss_security
+			    (pMac, pProfile, pBssDesc, pIesLocal))
+			break;
+		if (!csr_is_capabilities_match(pMac, pProfile->BSSType, pBssDesc))
+			break;
+		if (!csr_is_rate_set_match
+			    (pMac, &pIesLocal->SuppRates, &pIesLocal->ExtSuppRates))
+			break;
+		fCheck =
+			csr_is_channel_band_match(pMac, pProfile->operationChannel,
+						  pBssDesc);
+		if (!fCheck)
+			break;
+
+		fRC = true;
+
+	} while (0);
+
+	if (!pIes && pIesLocal) {
+		/* locally allocated */
+		cdf_mem_free(pIesLocal);
+	}
+
+	return fRC;
+}
+
+void csr_add_rate_bitmap(uint8_t rate, uint16_t *pRateBitmap)
+{
+	uint16_t rateBitmap;
+	uint16_t n = BITS_OFF(rate, CSR_DOT11_BASIC_RATE_MASK);
+	rateBitmap = *pRateBitmap;
+	switch (n) {
+	case SIR_MAC_RATE_1:
+		rateBitmap |= SIR_MAC_RATE_1_BITMAP;
+		break;
+	case SIR_MAC_RATE_2:
+		rateBitmap |= SIR_MAC_RATE_2_BITMAP;
+		break;
+	case SIR_MAC_RATE_5_5:
+		rateBitmap |= SIR_MAC_RATE_5_5_BITMAP;
+		break;
+	case SIR_MAC_RATE_11:
+		rateBitmap |= SIR_MAC_RATE_11_BITMAP;
+		break;
+	case SIR_MAC_RATE_6:
+		rateBitmap |= SIR_MAC_RATE_6_BITMAP;
+		break;
+	case SIR_MAC_RATE_9:
+		rateBitmap |= SIR_MAC_RATE_9_BITMAP;
+		break;
+	case SIR_MAC_RATE_12:
+		rateBitmap |= SIR_MAC_RATE_12_BITMAP;
+		break;
+	case SIR_MAC_RATE_18:
+		rateBitmap |= SIR_MAC_RATE_18_BITMAP;
+		break;
+	case SIR_MAC_RATE_24:
+		rateBitmap |= SIR_MAC_RATE_24_BITMAP;
+		break;
+	case SIR_MAC_RATE_36:
+		rateBitmap |= SIR_MAC_RATE_36_BITMAP;
+		break;
+	case SIR_MAC_RATE_48:
+		rateBitmap |= SIR_MAC_RATE_48_BITMAP;
+		break;
+	case SIR_MAC_RATE_54:
+		rateBitmap |= SIR_MAC_RATE_54_BITMAP;
+		break;
+	}
+	*pRateBitmap = rateBitmap;
+}
+
+bool csr_check_rate_bitmap(uint8_t rate, uint16_t rateBitmap)
+{
+	uint16_t n = BITS_OFF(rate, CSR_DOT11_BASIC_RATE_MASK);
+
+	switch (n) {
+	case SIR_MAC_RATE_1:
+		rateBitmap &= SIR_MAC_RATE_1_BITMAP;
+		break;
+	case SIR_MAC_RATE_2:
+		rateBitmap &= SIR_MAC_RATE_2_BITMAP;
+		break;
+	case SIR_MAC_RATE_5_5:
+		rateBitmap &= SIR_MAC_RATE_5_5_BITMAP;
+		break;
+	case SIR_MAC_RATE_11:
+		rateBitmap &= SIR_MAC_RATE_11_BITMAP;
+		break;
+	case SIR_MAC_RATE_6:
+		rateBitmap &= SIR_MAC_RATE_6_BITMAP;
+		break;
+	case SIR_MAC_RATE_9:
+		rateBitmap &= SIR_MAC_RATE_9_BITMAP;
+		break;
+	case SIR_MAC_RATE_12:
+		rateBitmap &= SIR_MAC_RATE_12_BITMAP;
+		break;
+	case SIR_MAC_RATE_18:
+		rateBitmap &= SIR_MAC_RATE_18_BITMAP;
+		break;
+	case SIR_MAC_RATE_24:
+		rateBitmap &= SIR_MAC_RATE_24_BITMAP;
+		break;
+	case SIR_MAC_RATE_36:
+		rateBitmap &= SIR_MAC_RATE_36_BITMAP;
+		break;
+	case SIR_MAC_RATE_48:
+		rateBitmap &= SIR_MAC_RATE_48_BITMAP;
+		break;
+	case SIR_MAC_RATE_54:
+		rateBitmap &= SIR_MAC_RATE_54_BITMAP;
+		break;
+	}
+	return !!rateBitmap;
+}
+
+bool csr_rates_is_dot11_rate_supported(tHalHandle hHal, uint8_t rate)
+{
+	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	uint16_t n = BITS_OFF(rate, CSR_DOT11_BASIC_RATE_MASK);
+
+	return csr_is_aggregate_rate_supported(pMac, n);
+}
+
+uint16_t csr_rates_mac_prop_to_dot11(uint16_t Rate)
+{
+	uint16_t ConvertedRate = Rate;
+
+	switch (Rate) {
+	case SIR_MAC_RATE_1:
+		ConvertedRate = 2;
+		break;
+	case SIR_MAC_RATE_2:
+		ConvertedRate = 4;
+		break;
+	case SIR_MAC_RATE_5_5:
+		ConvertedRate = 11;
+		break;
+	case SIR_MAC_RATE_11:
+		ConvertedRate = 22;
+		break;
+
+	case SIR_MAC_RATE_6:
+		ConvertedRate = 12;
+		break;
+	case SIR_MAC_RATE_9:
+		ConvertedRate = 18;
+		break;
+	case SIR_MAC_RATE_12:
+		ConvertedRate = 24;
+		break;
+	case SIR_MAC_RATE_18:
+		ConvertedRate = 36;
+		break;
+	case SIR_MAC_RATE_24:
+		ConvertedRate = 48;
+		break;
+	case SIR_MAC_RATE_36:
+		ConvertedRate = 72;
+		break;
+	case SIR_MAC_RATE_42:
+		ConvertedRate = 84;
+		break;
+	case SIR_MAC_RATE_48:
+		ConvertedRate = 96;
+		break;
+	case SIR_MAC_RATE_54:
+		ConvertedRate = 108;
+		break;
+
+	case SIR_MAC_RATE_72:
+		ConvertedRate = 144;
+		break;
+	case SIR_MAC_RATE_84:
+		ConvertedRate = 168;
+		break;
+	case SIR_MAC_RATE_96:
+		ConvertedRate = 192;
+		break;
+	case SIR_MAC_RATE_108:
+		ConvertedRate = 216;
+		break;
+	case SIR_MAC_RATE_126:
+		ConvertedRate = 252;
+		break;
+	case SIR_MAC_RATE_144:
+		ConvertedRate = 288;
+		break;
+	case SIR_MAC_RATE_168:
+		ConvertedRate = 336;
+		break;
+	case SIR_MAC_RATE_192:
+		ConvertedRate = 384;
+		break;
+	case SIR_MAC_RATE_216:
+		ConvertedRate = 432;
+		break;
+	case SIR_MAC_RATE_240:
+		ConvertedRate = 480;
+		break;
+
+	case 0xff:
+		ConvertedRate = 0;
+		break;
+	}
+
+	return ConvertedRate;
+}
+
+uint16_t csr_rates_find_best_rate(tSirMacRateSet *pSuppRates,
+				  tSirMacRateSet *pExtRates,
+				  tSirMacPropRateSet *pPropRates)
+{
+	uint8_t i;
+	uint16_t nBest;
+
+	nBest = pSuppRates->rate[0] & (~CSR_DOT11_BASIC_RATE_MASK);
+
+	if (pSuppRates->numRates > SIR_MAC_RATESET_EID_MAX) {
+		pSuppRates->numRates = SIR_MAC_RATESET_EID_MAX;
+	}
+
+	for (i = 1U; i < pSuppRates->numRates; ++i) {
+		nBest =
+			(uint16_t) CSR_MAX(nBest,
+					   pSuppRates->
+					   rate[i] & (~CSR_DOT11_BASIC_RATE_MASK));
+	}
+
+	if (NULL != pExtRates) {
+		for (i = 0U; i < pExtRates->numRates; ++i) {
+			nBest =
+				(uint16_t) CSR_MAX(nBest,
+						   pExtRates->
+						   rate[i] &
+						   (~CSR_DOT11_BASIC_RATE_MASK));
+		}
+	}
+
+	if (NULL != pPropRates) {
+		for (i = 0U; i < pPropRates->numPropRates; ++i) {
+			nBest =
+				(uint16_t) CSR_MAX(nBest,
+						   csr_rates_mac_prop_to_dot11
+							   (pPropRates->propRate[i]));
+		}
+	}
+
+	return nBest;
+}
+
+void csr_release_profile(tpAniSirGlobal pMac, tCsrRoamProfile *pProfile)
+{
+	if (pProfile) {
+		if (pProfile->BSSIDs.bssid) {
+			cdf_mem_free(pProfile->BSSIDs.bssid);
+			pProfile->BSSIDs.bssid = NULL;
+		}
+		if (pProfile->SSIDs.SSIDList) {
+			cdf_mem_free(pProfile->SSIDs.SSIDList);
+			pProfile->SSIDs.SSIDList = NULL;
+		}
+		if (pProfile->pWPAReqIE) {
+			cdf_mem_free(pProfile->pWPAReqIE);
+			pProfile->pWPAReqIE = NULL;
+		}
+		if (pProfile->pRSNReqIE) {
+			cdf_mem_free(pProfile->pRSNReqIE);
+			pProfile->pRSNReqIE = NULL;
+		}
+#ifdef FEATURE_WLAN_WAPI
+		if (pProfile->pWAPIReqIE) {
+			cdf_mem_free(pProfile->pWAPIReqIE);
+			pProfile->pWAPIReqIE = NULL;
+		}
+#endif /* FEATURE_WLAN_WAPI */
+
+		if (pProfile->pAddIEScan) {
+			cdf_mem_free(pProfile->pAddIEScan);
+			pProfile->pAddIEScan = NULL;
+		}
+
+		if (pProfile->pAddIEAssoc) {
+			cdf_mem_free(pProfile->pAddIEAssoc);
+			pProfile->pAddIEAssoc = NULL;
+		}
+		if (pProfile->ChannelInfo.ChannelList) {
+			cdf_mem_free(pProfile->ChannelInfo.ChannelList);
+			pProfile->ChannelInfo.ChannelList = NULL;
+		}
+		cdf_mem_set(pProfile, sizeof(tCsrRoamProfile), 0);
+	}
+}
+
+void csr_free_scan_filter(tpAniSirGlobal pMac, tCsrScanResultFilter *pScanFilter)
+{
+	if (pScanFilter->BSSIDs.bssid) {
+		cdf_mem_free(pScanFilter->BSSIDs.bssid);
+		pScanFilter->BSSIDs.bssid = NULL;
+	}
+	if (pScanFilter->ChannelInfo.ChannelList) {
+		cdf_mem_free(pScanFilter->ChannelInfo.ChannelList);
+		pScanFilter->ChannelInfo.ChannelList = NULL;
+	}
+	if (pScanFilter->SSIDs.SSIDList) {
+		cdf_mem_free(pScanFilter->SSIDs.SSIDList);
+		pScanFilter->SSIDs.SSIDList = NULL;
+	}
+}
+
+void csr_free_roam_profile(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	tCsrRoamSession *pSession = &pMac->roam.roamSession[sessionId];
+
+	if (pSession->pCurRoamProfile) {
+		csr_release_profile(pMac, pSession->pCurRoamProfile);
+		cdf_mem_free(pSession->pCurRoamProfile);
+		pSession->pCurRoamProfile = NULL;
+	}
+}
+
+void csr_free_connect_bss_desc(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	tCsrRoamSession *pSession = &pMac->roam.roamSession[sessionId];
+
+	if (pSession->pConnectBssDesc) {
+		cdf_mem_free(pSession->pConnectBssDesc);
+		pSession->pConnectBssDesc = NULL;
+	}
+}
+
+tSirResultCodes csr_get_disassoc_rsp_status_code(tSirSmeDisassocRsp *
+						 pSmeDisassocRsp)
+{
+	uint8_t *pBuffer = (uint8_t *) pSmeDisassocRsp;
+	uint32_t ret;
+
+	pBuffer += (sizeof(uint16_t) + sizeof(uint16_t) + sizeof(tSirMacAddr));
+	/* tSirResultCodes is an enum, assuming is 32bit */
+	/* If we cannot make this assumption, use copymemory */
+	cdf_get_u32(pBuffer, &ret);
+
+	return (tSirResultCodes) ret;
+}
+
+tSirResultCodes csr_get_de_auth_rsp_status_code(tSirSmeDeauthRsp *pSmeRsp)
+{
+	uint8_t *pBuffer = (uint8_t *) pSmeRsp;
+	uint32_t ret;
+
+	pBuffer +=
+		(sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint8_t) +
+		 sizeof(uint16_t));
+	/* tSirResultCodes is an enum, assuming is 32bit */
+	/* If we cannot make this assumption, use copymemory */
+	cdf_get_u32(pBuffer, &ret);
+
+	return (tSirResultCodes) ret;
+}
+
+tSirScanType csr_get_scan_type(tpAniSirGlobal pMac, uint8_t chnId)
+{
+	tSirScanType scanType = eSIR_PASSIVE_SCAN;
+	CHANNEL_STATE channelEnabledType;
+
+	channelEnabledType = cds_get_channel_state(chnId);
+	if (CHANNEL_STATE_ENABLE == channelEnabledType) {
+		scanType = eSIR_ACTIVE_SCAN;
+	}
+	return scanType;
+}
+
+uint8_t csr_to_upper(uint8_t ch)
+{
+	uint8_t chOut;
+
+	if (ch >= 'a' && ch <= 'z') {
+		chOut = ch - 'a' + 'A';
+	} else {
+		chOut = ch;
+	}
+	return chOut;
+}
+
+tSirBssType csr_translate_bsstype_to_mac_type(eCsrRoamBssType csrtype)
+{
+	tSirBssType ret;
+
+	switch (csrtype) {
+	case eCSR_BSS_TYPE_INFRASTRUCTURE:
+		ret = eSIR_INFRASTRUCTURE_MODE;
+		break;
+	case eCSR_BSS_TYPE_IBSS:
+	case eCSR_BSS_TYPE_START_IBSS:
+		ret = eSIR_IBSS_MODE;
+		break;
+	case eCSR_BSS_TYPE_WDS_AP:
+		ret = eSIR_BTAMP_AP_MODE;
+		break;
+	case eCSR_BSS_TYPE_WDS_STA:
+		ret = eSIR_BTAMP_STA_MODE;
+		break;
+	case eCSR_BSS_TYPE_INFRA_AP:
+		ret = eSIR_INFRA_AP_MODE;
+		break;
+	case eCSR_BSS_TYPE_ANY:
+	default:
+		ret = eSIR_AUTO_MODE;
+		break;
+	}
+
+	return ret;
+}
+
+/* This function use the parameters to decide the CFG value. */
+/* CSR never sets WNI_CFG_DOT11_MODE_ALL to the CFG */
+/* So PE should not see WNI_CFG_DOT11_MODE_ALL when it gets the CFG value */
+eCsrCfgDot11Mode csr_get_cfg_dot11_mode_from_csr_phy_mode(tCsrRoamProfile *pProfile,
+							  eCsrPhyMode phyMode,
+							  bool fProprietary)
+{
+	uint32_t cfgDot11Mode = eCSR_CFG_DOT11_MODE_ABG;
+
+	switch (phyMode) {
+	case eCSR_DOT11_MODE_11a:
+		cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A;
+		break;
+	case eCSR_DOT11_MODE_11b:
+	case eCSR_DOT11_MODE_11b_ONLY:
+		cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B;
+		break;
+	case eCSR_DOT11_MODE_11g:
+	case eCSR_DOT11_MODE_11g_ONLY:
+		if (pProfile && (CSR_IS_INFRA_AP(pProfile))
+		    && (phyMode == eCSR_DOT11_MODE_11g_ONLY))
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G_ONLY;
+		else
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G;
+		break;
+	case eCSR_DOT11_MODE_11n:
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N;
+		break;
+	case eCSR_DOT11_MODE_11n_ONLY:
+		if (pProfile && CSR_IS_INFRA_AP(pProfile))
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N_ONLY;
+		else
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N;
+		break;
+	case eCSR_DOT11_MODE_abg:
+		cfgDot11Mode = eCSR_CFG_DOT11_MODE_ABG;
+		break;
+	case eCSR_DOT11_MODE_AUTO:
+		cfgDot11Mode = eCSR_CFG_DOT11_MODE_AUTO;
+		break;
+
+#ifdef WLAN_FEATURE_11AC
+	case eCSR_DOT11_MODE_11ac:
+		if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) {
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC;
+		} else {
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N;
+		}
+		break;
+	case eCSR_DOT11_MODE_11ac_ONLY:
+		if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) {
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC_ONLY;
+		} else {
+			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N;
+		}
+		break;
+#endif
+	default:
+		/* No need to assign anything here */
+		break;
+	}
+
+	return cfgDot11Mode;
+}
+
+CDF_STATUS csr_get_regulatory_domain_for_country
+	(tpAniSirGlobal pMac,
+	uint8_t *pCountry,
+	v_REGDOMAIN_t *pDomainId, v_CountryInfoSource_t source) {
+	CDF_STATUS status = CDF_STATUS_E_INVAL;
+	CDF_STATUS cdf_status;
+	country_code_t countryCode;
+	v_REGDOMAIN_t domainId;
+
+	if (pCountry) {
+		countryCode[0] = pCountry[0];
+		countryCode[1] = pCountry[1];
+		cdf_status = cds_get_reg_domain_from_country_code(&domainId,
+								  countryCode,
+								  source);
+
+		if (CDF_IS_STATUS_SUCCESS(cdf_status)) {
+			if (pDomainId) {
+				*pDomainId = domainId;
+			}
+			status = CDF_STATUS_SUCCESS;
+		} else {
+			sms_log(pMac, LOGW,
+				FL
+					(" Couldn't find domain for country code  %c%c"),
+				pCountry[0], pCountry[1]);
+			status = CDF_STATUS_E_INVAL;
+		}
+	}
+
+	return status;
+}
+
+/* To check whether a country code matches the one in the IE */
+/* Only check the first two characters, ignoring in/outdoor */
+/* pCountry -- caller allocated buffer contain the country code that is checking against */
+/* the one in pIes. It can be NULL. */
+/* caller must provide pIes, it cannot be NULL */
+/* This function always return true if 11d support is not turned on. */
+bool csr_match_country_code(tpAniSirGlobal pMac, uint8_t *pCountry,
+			    tDot11fBeaconIEs *pIes)
+{
+	bool fRet = true;
+
+	do {
+		if (!csr_is11d_supported(pMac)) {
+			break;
+		}
+		if (!pIes) {
+			sms_log(pMac, LOGE, FL("  No IEs"));
+			break;
+		}
+
+		if (pCountry) {
+			uint32_t i;
+
+			if (!pIes->Country.present) {
+				fRet = false;
+				break;
+			}
+			/* Convert the CountryCode characters to upper */
+			for (i = 0; i < WNI_CFG_COUNTRY_CODE_LEN - 1; i++) {
+				pCountry[i] = csr_to_upper(pCountry[i]);
+			}
+			if (!cdf_mem_compare(pIes->Country.country, pCountry,
+					     WNI_CFG_COUNTRY_CODE_LEN - 1)) {
+				fRet = false;
+				break;
+			}
+		}
+	} while (0);
+
+	return fRet;
+}
+
+CDF_STATUS csr_get_modify_profile_fields(tpAniSirGlobal pMac, uint32_t sessionId,
+					 tCsrRoamModifyProfileFields *
+					 pModifyProfileFields)
+{
+
+	if (!pModifyProfileFields) {
+		return CDF_STATUS_E_FAILURE;
+	}
+
+	cdf_mem_copy(pModifyProfileFields,
+		     &pMac->roam.roamSession[sessionId].connectedProfile.
+		     modifyProfileFields, sizeof(tCsrRoamModifyProfileFields));
+
+	return CDF_STATUS_SUCCESS;
+}
+
+CDF_STATUS csr_set_modify_profile_fields(tpAniSirGlobal pMac, uint32_t sessionId,
+					 tCsrRoamModifyProfileFields *
+					 pModifyProfileFields)
+{
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	cdf_mem_copy(&pSession->connectedProfile.modifyProfileFields,
+		     pModifyProfileFields, sizeof(tCsrRoamModifyProfileFields));
+
+	return CDF_STATUS_SUCCESS;
+}
+
+
+bool csr_is_set_key_allowed(tpAniSirGlobal pMac, uint32_t sessionId)
+{
+	bool fRet = true;
+	tCsrRoamSession *pSession;
+
+	pSession = CSR_GET_SESSION(pMac, sessionId);
+
+	/*
+	 * This condition is not working for infra state. When infra is in
+	 * not-connected state the pSession->pCurRoamProfile is NULL, this
+	 * function returns true, that is incorrect.
+	 * Since SAP requires to set key without any BSS started, it needs
+	 * this condition to be met. In other words, this function is useless.
+	 * The current work-around is to process setcontext_rsp no matter
+	 * what the state is.
+	 */
+	sms_log(pMac, LOG2,
+		FL(" is not what it intends to. Must be revisit or removed"));
+	if ((NULL == pSession)
+	    || (csr_is_conn_state_disconnected(pMac, sessionId)
+		&& (pSession->pCurRoamProfile != NULL)
+		&& (!(CSR_IS_INFRA_AP(pSession->pCurRoamProfile))))
+	    ) {
+		fRet = false;
+	}
+
+	return fRet;
+}
+
+/* no need to acquire lock for this basic function */
+uint16_t sme_chn_to_freq(uint8_t chanNum)
+{
+	int i;
+
+	for (i = 0; i < NUM_RF_CHANNELS; i++) {
+		if (rf_channels[i].channelNum == chanNum) {
+			return rf_channels[i].targetFreq;
+		}
+	}
+
+	return 0;
+}
+
+/* Disconnect all active sessions by sending disassoc. This is mainly used to disconnect the remaining session when we
+ * transition from concurrent sessions to a single session. The use case is Infra STA and wifi direct multiple sessions are up and
+ * P2P session is removed. The Infra STA session remains and should resume BMPS if BMPS is enabled by default. However, there
+ * are some issues seen with BMPS resume during this transition and this is a workaround which will allow the Infra STA session to
+ * disconnect and auto connect back and enter BMPS this giving the same effect as resuming BMPS
+ */
+
+/* Remove this code once SLM_Sessionization is supported */
+/* BMPS_WORKAROUND_NOT_NEEDED */
+void csr_disconnect_all_active_sessions(tpAniSirGlobal pMac)
+{
+	uint8_t i;
+
+	/* Disconnect all the active sessions */
+	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
+		if (CSR_IS_SESSION_VALID(pMac, i)
+		    && !csr_is_conn_state_disconnected(pMac, i)) {
+			csr_roam_disconnect_internal(pMac, i,
+						     eCSR_DISCONNECT_REASON_UNSPECIFIED);
+		}
+	}
+}
+
+#ifdef FEATURE_WLAN_LFR
+bool csr_is_channel_present_in_list(uint8_t *pChannelList,
+				    int numChannels, uint8_t channel)
+{
+	int i = 0;
+
+	/* Check for NULL pointer */
+	if (!pChannelList || (numChannels == 0)) {
+		return false;
+	}
+	/* Look for the channel in the list */
+	for (i = 0; (i < numChannels) &&
+	     (i < WNI_CFG_VALID_CHANNEL_LIST_LEN); i++) {
+		if (pChannelList[i] == channel)
+			return true;
+	}
+
+	return false;
+}
+
+CDF_STATUS csr_add_to_channel_list_front(uint8_t *pChannelList,
+					 int numChannels, uint8_t channel)
+{
+	int i = 0;
+
+	/* Check for NULL pointer */
+	if (!pChannelList)
+		return CDF_STATUS_E_NULL_VALUE;
+
+	/* Make room for the addition.  (Start moving from the back.) */
+	for (i = numChannels; i > 0; i--) {
+		pChannelList[i] = pChannelList[i - 1];
+	}
+
+	/* Now add the NEW channel...at the front */
+	pChannelList[0] = channel;
+
+	return CDF_STATUS_SUCCESS;
+}
+#endif
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+/**
+ * csr_diag_event_report() - send PE diag event
+ * @pmac:        pointer to global MAC context.
+ * @event_typev: sub event type for DIAG event.
+ * @status:      status of the event
+ * @reasoncode:  reasoncode for the given status
+ *
+ * This function is called to send diag event
+ *
+ * Return:   NA
+ */
+void csr_diag_event_report(tpAniSirGlobal pmac, uint16_t event_type,
+			   uint16_t status, uint16_t reasoncode)
+{
+	WLAN_HOST_DIAG_EVENT_DEF(diag_event, host_event_wlan_pe_payload_type);
+
+	cdf_mem_zero(&diag_event, sizeof(host_event_wlan_pe_payload_type));
+
+	/* diag_event.bssid is already all zeroes */
+	diag_event.sme_state = sme_get_lim_sme_state(pmac);
+	diag_event.mlm_state = sme_get_lim_mlm_state(pmac);
+	diag_event.event_type = event_type;
+	diag_event.status = status;
+	diag_event.reason_code = reasoncode;
+
+	WLAN_HOST_DIAG_EVENT_REPORT(&diag_event, EVENT_WLAN_PE);
+	return;
+}
+#endif