/*
 * Copyright (c) 2011-2016 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.
   ========================================================================== */

#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"
#include "cds_concurrency.h"

#define NEIGHBOR_ROAM_DEBUG sms_log

static void csr_neighbor_roam_reset_channel_info(tpCsrNeighborRoamChannelInfo
						 rChInfo);

QDF_STATUS csr_roam_copy_connected_profile(tpAniSirGlobal pMac, uint32_t sessionId,
					   tCsrRoamProfile *pDstProfile);

void csr_neighbor_roam_state_transition(tpAniSirGlobal mac_ctx,
		uint8_t newstate, uint8_t session)
{
	mac_ctx->roam.neighborRoamInfo[session].prevNeighborRoamState =
		mac_ctx->roam.neighborRoamInfo[session].neighborRoamState;
	mac_ctx->roam.neighborRoamInfo[session].neighborRoamState = newstate;
	QDF_TRACE(QDF_MODULE_ID_SME, QDF_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
 */

void csr_neighbor_roam_send_lfr_metric_event(
				tpAniSirGlobal mac_ctx,
				uint8_t session_id,
				tSirMacAddr bssid,
				eRoamCmdStatus status)
{
	tCsrRoamInfo *roam_info;

	roam_info = qdf_mem_malloc(sizeof(tCsrRoamInfo));
	if (NULL == roam_info) {
		sms_log(mac_ctx, LOG1, FL("Memory allocation failed!"));
	} else {
		qdf_mem_copy((void *)roam_info->bssid,
			     (void *)bssid, sizeof(*roam_info));
		csr_roam_call_callback(mac_ctx, session_id, roam_info, 0,
			status, 0);
		qdf_mem_free(roam_info);
	}
}
#endif

QDF_STATUS
csr_neighbor_roam_update_fast_roaming_enabled(tpAniSirGlobal pMac,
					      uint8_t sessionId,
					      const bool fastRoamEnabled)
{
	QDF_STATUS qdf_status = QDF_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));
		qdf_status = QDF_STATUS_E_FAILURE;
		break;
	}
	return qdf_status;
}

#ifdef FEATURE_WLAN_ESE
QDF_STATUS csr_neighbor_roam_update_ese_mode_enabled(tpAniSirGlobal pMac,
						     uint8_t sessionId,
						     const bool eseMode)
{
	QDF_STATUS qdf_status = QDF_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 qdf_status;
}
#endif

QDF_STATUS csr_neighbor_roam_set_lookup_rssi_threshold(tpAniSirGlobal pMac,
						uint8_t sessionId,
						uint8_t
						  neighborLookupRssiThreshold)
{
	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
	    &pMac->roam.neighborRoamInfo[sessionId];
	QDF_STATUS qdf_status = QDF_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));
		qdf_status = QDF_STATUS_E_FAILURE;
		break;
	}
	return qdf_status;
}

QDF_STATUS
csr_neighbor_roam_set_opportunistic_scan_threshold_diff(tpAniSirGlobal pMac,
						uint8_t sessionId,
						uint8_t
						    nOpportunisticThresholdDiff)
{
	QDF_STATUS qdf_status = QDF_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);
		qdf_status = QDF_STATUS_E_FAILURE;
		break;
	}
	return qdf_status;
}

QDF_STATUS
csr_neighbor_roam_set_roam_rescan_rssi_diff(tpAniSirGlobal pMac,
					    uint8_t sessionId,
					    uint8_t nRoamRescanRssiDiff)
{
	QDF_STATUS qdf_status = QDF_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);
		qdf_status = QDF_STATUS_E_FAILURE;
		break;
	}
	return qdf_status;
}

QDF_STATUS
csr_neighbor_roam_set_roam_bmiss_first_bcnt(tpAniSirGlobal pMac,
					    uint8_t sessionId,
					    uint8_t nRoamBmissFirstBcnt)
{
	QDF_STATUS qdf_status = QDF_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);
		qdf_status = QDF_STATUS_E_FAILURE;
		break;
	}
	return qdf_status;
}

QDF_STATUS
csr_neighbor_roam_set_roam_bmiss_final_bcnt(tpAniSirGlobal pMac,
					    uint8_t sessionId,
					    uint8_t nRoamBmissFinalBcnt)
{
	QDF_STATUS qdf_status = QDF_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);
		qdf_status = QDF_STATUS_E_FAILURE;
		break;
	}
	return qdf_status;
}

QDF_STATUS
csr_neighbor_roam_set_roam_beacon_rssi_weight(tpAniSirGlobal pMac,
					      uint8_t sessionId,
					      uint8_t nRoamBeaconRssiWeight)
{
	QDF_STATUS qdf_status = QDF_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);
		qdf_status = QDF_STATUS_E_FAILURE;
		break;
	}
	return qdf_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)
			qdf_mem_free(rChInfo->currentChannelListInfo.
				     ChannelList);

		rChInfo->currentChannelListInfo.ChannelList = NULL;
	} else {
		rChInfo->currentChanIndex = 0;
	}
}

/**
 * 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);

	/* 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;
	qdf_mem_zero(pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo,
		     sizeof(tCsrNeighborReportBssInfo) *
		     MAX_BSS_IN_NEIGHBOR_RPT);
	pNeighborRoamInfo->uOsRequestedHandoff = 0;
	qdf_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];

	qdf_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_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: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE otherwise
 */
QDF_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 QDF_STATUS_E_FAILURE;
	}

	bss_info_ptr = qdf_mem_malloc(sizeof(tCsrNeighborRoamBSSInfo));
	if (NULL == bss_info_ptr) {
		sms_log(pMac, LOGE,
		FL("LFR3:Memory allocation for Neighbor Roam BSS Info failed"));
		return QDF_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 = qdf_mem_malloc(bss_desc_len);
	if (bss_info_ptr->pBssDescription != NULL) {
		qdf_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"));
		qdf_mem_free(bss_info_ptr);
		return QDF_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;
	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
		  "LFR3:Entry added to Auth Done List");

	return QDF_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: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE otherwise
 */
QDF_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;

	QDF_ASSERT(pScanFilter != NULL);
	if (pScanFilter == NULL)
		return QDF_STATUS_E_FAILURE;

	qdf_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 =
			qdf_mem_malloc(sizeof(tSirMacAddr) *
				       pScanFilter->BSSIDs.numOfBSSIDs);
		if (NULL == pScanFilter->BSSIDs.bssid) {
			sms_log(pMac, LOGE,
				FL("Scan Filter BSSID mem alloc failed"));
			return QDF_STATUS_E_NOMEM;
		}

		qdf_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++) {
			qdf_copy_macaddr(&pScanFilter->BSSIDs.bssid[i],
				 &nbr_roam_info->handoffReqInfo.bssid);
		}
	}
	QDF_TRACE(QDF_MODULE_ID_SME, QDF_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 =
			qdf_mem_malloc(sizeof(tCsrSSIDInfo) *
				pScanFilter->SSIDs.numOfSSIDs);
		if (NULL == pScanFilter->SSIDs.SSIDList) {
			sms_log(pMac, LOGE,
				FL("Scan Filter SSID mem alloc failed"));
			return QDF_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;
			qdf_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 =
			qdf_mem_malloc(sizeof(tCsrSSIDInfo));
		if (NULL == pScanFilter->SSIDs.SSIDList) {
			sms_log(pMac, LOGE,
				FL("Scan Filter SSID mem alloc failed"));
			return QDF_STATUS_E_NOMEM;
		}
		pScanFilter->SSIDs.SSIDList->handoffPermitted = 1;
		pScanFilter->SSIDs.SSIDList->ssidHidden = 0;
		pScanFilter->SSIDs.SSIDList->SSID.length =
			pCurProfile->SSID.length;
		qdf_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 =
			qdf_mem_malloc(num_ch * sizeof(uint8_t));
		if (NULL == pScanFilter->ChannelInfo.ChannelList) {
			sms_log(pMac, LOGE,
				FL("Scan Filter Ch list mem alloc failed"));
			qdf_mem_free(pScanFilter->SSIDs.SSIDList);
			pScanFilter->SSIDs.SSIDList = NULL;
			return QDF_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;
	}

	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;
	}

#ifdef WLAN_FEATURE_11W
	pScanFilter->MFPEnabled = pCurProfile->MFPEnabled;
	pScanFilter->MFPRequired = pCurProfile->MFPRequired;
	pScanFilter->MFPCapable = pCurProfile->MFPCapable;
#endif
	return QDF_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 !=
		    qdf_mem_cmp(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_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: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE otherwise
 */
QDF_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 QDF_STATUS_E_INVAL;

	/* Check for NULL pointer */
	if (!pOutputChannelList)
		return QDF_STATUS_E_INVAL;

	if (inputNumOfChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "%s: Wrong Number of Input Channels %d",
			  __func__, inputNumOfChannels);
		return QDF_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 QDF_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: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE otherwise
 */
QDF_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 QDF_STATUS_E_INVAL;

	/* Check for NULL pointer */
	if (!pOutputChannelList)
		return QDF_STATUS_E_INVAL;

	if (inputNumOfChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "%s: Wrong Number of Input Channels %d",
			  __func__, inputNumOfChannels);
		return QDF_STATUS_E_INVAL;
	}
	if (outputNumOfChannels >= WNI_CFG_VALID_CHANNEL_LIST_LEN) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "%s: Wrong Number of Output Channels %d",
			  __func__, outputNumOfChannels);
		return QDF_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]) {
				QDF_TRACE(QDF_MODULE_ID_SME,
					  QDF_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) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
				  "%s: Merge Neighbor channel list reached Max "
				  "limit %d", __func__, numChannels);
			break;
		}
	}

	/* Return final number of channels */
	*pMergedOutputNumOfChannels = numChannels;

	return QDF_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: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE otherwise
 */
QDF_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;
		qdf_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)) {
						QDF_TRACE(QDF_MODULE_ID_SME,
							  QDF_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 {
					QDF_TRACE(QDF_MODULE_ID_SME,
						  QDF_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) {
		qdf_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 =
			qdf_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 QDF_STATUS_E_NOMEM;
	}

	qdf_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 QDF_STATUS_SUCCESS;
}

/**
 * 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) {
#ifdef WLAN_FEATURE_11W
		/*
		 * We are sending current connected APs profile setting
		 * if other AP doesn't have the same PMF setting as currently
		 * connected AP then we will have some issues in roaming.
		 *
		 * Make sure all the APs have same PMF settings to avoid
		 * any corner cases.
		 */
		fMatch = csr_is_security_match(pMac, &authType,
				&uCEncryptionType, &mCEncryptionType,
				&pCurProfile->MFPEnabled,
				&pCurProfile->MFPRequired,
				&pCurProfile->MFPCapable,
				pBssDesc, pIes, NULL, NULL, NULL);
#else
		fMatch = csr_is_security_match(pMac, &authType,
				&uCEncryptionType,
				&mCEncryptionType, NULL,
				NULL, NULL, pBssDesc,
				pIes, NULL, NULL, NULL);
#endif
		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 (QDF_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) {
			qdf_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 QDF_STATUS
 */
QDF_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 QDF_STATUS_SUCCESS;
}

/**
 * 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.
	 */
	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
		FL("Roaming parameters are reset"));
	roam_params = &mac_ctx->roam.configParam.roam_params;
	roam_params->num_ssid_allowed_list = 0;
	qdf_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: QDF_STATUS
 */
QDF_STATUS csr_neighbor_roam_indicate_disconnect(tpAniSirGlobal pMac,
						 uint8_t sessionId)
{
	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
			&pMac->roam.neighborRoamInfo[sessionId];
	tCsrRoamConnectedProfile *pPrevProfile =
			&pNeighborRoamInfo->prevConnProfile;
	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
	tCsrRoamSession *roam_session = NULL;

	if (NULL == pSession) {
		sms_log(pMac, LOGE, FL("pSession is NULL"));
		return QDF_STATUS_E_FAILURE;
	}
	QDF_TRACE(QDF_MODULE_ID_SME, QDF_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));
	/*
	 * Free the current previous profile and move
	 * the current profile to prev profile.
	 */
	csr_roam_free_connect_profile(pPrevProfile);
	csr_roam_copy_connect_profile(pMac, sessionId, pPrevProfile);
	/*
	 * 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 && (QDF_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 QDF_STATUS_SUCCESS;
		}
#ifdef FEATURE_WLAN_ESE
		if (pSession->connectedProfile.isESEAssoc) {
			qdf_mem_copy(&pSession->prevApSSID,
				&pSession->connectedProfile.SSID,
				sizeof(tSirMacSSid));
			qdf_copy_macaddr(&pSession->prevApBssid,
					&pSession->connectedProfile.bssid);
			pSession->prevOpChannel =
				pSession->connectedProfile.operationChannel;
			pSession->isPrevApInfoValid = true;
			pSession->roamTS1 = qdf_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 */
		qdf_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 QDF_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: QDF 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];

	int init_ft_flag = false;

	/*
	 * 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);
	csr_neighbor_roam_state_transition(pMac,
			eCSR_NEIGHBOR_ROAM_STATE_CONNECTED, session_id);

	qdf_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;

	/**
	 * 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);

	/* 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);

#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
	/* If "Legacy Fast Roaming" is enabled */
	if (csr_roam_is_fast_roam_enabled(pMac, session_id))
		init_ft_flag = true;
	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)) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
				"Wrong Mode %d",
				session->connectedProfile.BSSType);
			return;
		}
		ngbr_roam_info->uOsRequestedHandoff = 0;
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
		if (session->roam_synch_in_progress) {
			if (pMac->roam.pReassocResp != NULL) {
				QDF_TRACE(QDF_MODULE_ID_SME,
					QDF_TRACE_LEVEL_DEBUG,
					"Free Reassoc Rsp");
				qdf_mem_free(pMac->roam.pReassocResp);
				pMac->roam.pReassocResp = NULL;
			}
		} else
#endif
			csr_roam_offload_scan(pMac, session_id,
				ROAM_SCAN_OFFLOAD_START,
				REASON_CONNECT);
	}
}

/**
 * csr_neighbor_roam_indicate_connect()
 * @pMac: mac context
 * @session_id: Session Id
 * @qdf_status: QDF 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: QDF status
 */
QDF_STATUS csr_neighbor_roam_indicate_connect(
		tpAniSirGlobal pMac, uint8_t session_id,
		QDF_STATUS qdf_status)
{
	tpCsrNeighborRoamControlInfo ngbr_roam_info =
		&pMac->roam.neighborRoamInfo[session_id];
	tCsrRoamSession *session = &pMac->roam.roamSession[session_id];
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
	tCsrRoamInfo roamInfo;
	tpSirSetActiveModeSetBncFilterReq msg;
#endif
	QDF_STATUS status = QDF_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 QDF_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 !=
	QDF_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 QDF_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 QDF_STATUS_SUCCESS;
	}
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
	if (session->roam_synch_in_progress &&
		(eSIR_ROAM_AUTH_STATUS_AUTHENTICATED ==
		session->roam_synch_data->authStatus)) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
			"LFR3:csr_neighbor_roam_indicate_connect");
		msg = qdf_mem_malloc(sizeof(tSirSetActiveModeSetBncFilterReq));
		if (msg == NULL) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				"LFR3:Mem Alloc failed for beacon Filter Req");
			return QDF_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);
		qdf_copy_macaddr(&roamInfo.peerMac,
			&session->connectedProfile.bssid);
		roamInfo.roamSynchInProgress =
			session->roam_synch_in_progress;
		csr_roam_call_callback(pMac, session_id, &roamInfo, 0,
			eCSR_ROAM_SET_KEY_COMPLETE,
			eCSR_ROAM_RESULT_AUTHENTICATED);
		csr_neighbor_roam_reset_init_state_control_info(pMac,
			session_id);
		csr_neighbor_roam_info_ctx_init(pMac, session_id);

		return status;
	}
#endif

	switch (ngbr_roam_info->neighborRoamState) {
	case eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING:
		if (QDF_STATUS_SUCCESS != qdf_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;
}

/* ---------------------------------------------------------------------------

    \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 QDF_STATUS_SUCCESS on success, corresponding error code otherwise

   ---------------------------------------------------------------------------*/
QDF_STATUS csr_neighbor_roam_init11r_assoc_info(tpAniSirGlobal pMac)
{
	QDF_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;

		qdf_mem_zero(pFTRoamInfo->neighboReportBssInfo,
			     sizeof(tCsrNeighborReportBssInfo) *
			     MAX_BSS_IN_NEIGHBOR_RPT);

		status = csr_ll_open(pMac->hHdd, &pFTRoamInfo->preAuthDoneList);
		if (QDF_STATUS_SUCCESS != status) {
			sms_log(pMac, LOGE,
				FL("LL Open of preauth done AP List failed"));
			return QDF_STATUS_E_RESOURCES;
		}
	}
	return status;
}

/* ---------------------------------------------------------------------------

    \fn csr_neighbor_roam_init

    \brief  This function initializes neighbor roam data structures

    \param  pMac - The handle returned by mac_open.

    \return QDF_STATUS_SUCCESS on success, corresponding error code otherwise

   ---------------------------------------------------------------------------*/
QDF_STATUS csr_neighbor_roam_init(tpAniSirGlobal pMac, uint8_t sessionId)
{
	QDF_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;
	if (pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels != 0) {
		pNeighborRoamInfo->cfgParams.channelInfo.ChannelList =
		qdf_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 QDF_STATUS_E_NOMEM;
		}
	} else {
		pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL;
		sms_log(pMac, LOGE,
			FL("invalid neighbor roam channel list: %u"),
			pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels);
	}

	/* Update the roam global structure from CFG */
	qdf_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;

	qdf_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;
	qdf_mem_set(&pNeighborRoamInfo->prevConnProfile,
		    sizeof(tCsrRoamConnectedProfile), 0);

	status = csr_ll_open(pMac->hHdd, &pNeighborRoamInfo->roamableAPList);
	if (QDF_STATUS_SUCCESS != status) {
		sms_log(pMac, LOGE, FL("LL Open of roam able AP List failed"));
		qdf_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.
			     ChannelList);
		pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL;
		return QDF_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;

	status = csr_neighbor_roam_init11r_assoc_info(pMac);
	if (QDF_STATUS_SUCCESS != status) {
		sms_log(pMac, LOGE, FL("LL Open of roam able AP List failed"));
		qdf_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.
			     ChannelList);
		pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL;
		csr_ll_close(&pNeighborRoamInfo->roamableAPList);
		return QDF_STATUS_E_RESOURCES;
	}

	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 QDF_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)
		qdf_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) {
		qdf_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.IAPPNeighborListReceived = false;

	/* Free the profile.. */
	csr_release_profile(pMac, &pNeighborRoamInfo->csrNeighborRoamProfile);
	csr_roam_free_connect_profile(&pNeighborRoamInfo->prevConnProfile);
	pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum = 0;
	pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport = 0;
	qdf_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);

	csr_neighbor_roam_state_transition(pMac,
		eCSR_NEIGHBOR_ROAM_STATE_CLOSED, sessionId);

	return;
}

/**
 * csr_neighbor_roam_is11r_assoc() - Check if association type is 11R
 * @mac_ctx: MAC Global context
 * @session_id: Session ID
 *
 * Return: true if 11r Association, false otherwise.
 */
bool csr_neighbor_roam_is11r_assoc(tpAniSirGlobal mac_ctx, uint8_t session_id)
{
	return mac_ctx->roam.neighborRoamInfo[session_id].is11rAssoc;
}

/* ---------------------------------------------------------------------------
    \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_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
 */
QDF_STATUS csr_neighbor_roam_process_handoff_req(
			tpAniSirGlobal mac_ctx,
			uint8_t session_id)
{
	tpCsrNeighborRoamControlInfo roam_ctrl_info =
		&mac_ctx->roam.neighborRoamInfo[session_id];
	QDF_STATUS status = QDF_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 QDF_STATUS_E_FAILURE;
	}

	roam_id = GET_NEXT_ROAM_ID(&mac_ctx->roam);
	profile = qdf_mem_malloc(sizeof(tCsrRoamProfile));
	if (NULL == profile) {
		sms_log(mac_ctx, LOGE, FL("Memory alloc failed"));
		return QDF_STATUS_E_NOMEM;
	}
	qdf_mem_set(profile, sizeof(tCsrRoamProfile), 0);
	status =
		csr_roam_copy_profile(mac_ctx, profile,
				      session->pCurRoamProfile);
	if (!QDF_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 =
			qdf_mem_malloc(sizeof(tSirMacAddr) *
				profile->BSSIDs.numOfBSSIDs);
		if (NULL == profile->BSSIDs.bssid) {
			sms_log(mac_ctx, LOGE, FL("mem alloc failed for BSSID"));
			status = QDF_STATUS_E_NOMEM;
			goto end;
		}
	}

	qdf_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++) {
		qdf_copy_macaddr(&profile->BSSIDs.bssid[i],
				&roam_ctrl_info->handoffReqInfo.bssid);
	}

	profile->ChannelInfo.numOfChannels = 1;
	if (NULL == profile->ChannelInfo.ChannelList) {
		profile->ChannelInfo.ChannelList =
			qdf_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 = QDF_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 (!QDF_IS_STATUS_SUCCESS(status)) {
		sms_log(mac_ctx, LOGE, FL("SSID scan failed"));
	}

end:
	if (NULL != profile) {
		csr_release_profile(mac_ctx, profile);
		qdf_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 QDF_STATUS_SUCCESS on success, corresponding error code otherwise

   ---------------------------------------------------------------------------*/
QDF_STATUS csr_neighbor_roam_sssid_scan_done(tpAniSirGlobal pMac,
					     uint8_t sessionId, QDF_STATUS status)
{
	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
		&pMac->roam.neighborRoamInfo[sessionId];
	QDF_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 QDF_STATUS_E_FAILURE;
	}
	/* if SSID scan failed to find our candidate add an entry to csr scan cache ourself */
	if (!QDF_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 (QDF_STATUS_SUCCESS != hstatus) {
			sms_log(pMac, LOGE,
				FL
					("csr_scan_create_entry_in_scan_cache failed with status %d"),
				hstatus);
			return QDF_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 (QDF_STATUS_SUCCESS != hstatus) {
		sms_log(pMac, LOGE,
			FL
				("Neighbor scan process complete failed with status %d"),
			hstatus);
		return QDF_STATUS_E_FAILURE;
	}
	return QDF_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
 */
QDF_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];
	QDF_STATUS status = QDF_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 QDF_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 QDF_STATUS_E_FAILURE;
	}

	/* sanity check */
	if (true != qdf_mem_cmp(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 QDF_STATUS_E_FAILURE;
	}
	roam_ctrl_info->handoffReqInfo.channel =
		handoff_req->channel;
	roam_ctrl_info->handoffReqInfo.src =
		handoff_req->handoff_src;
	qdf_mem_copy(&roam_ctrl_info->handoffReqInfo.bssid.bytes,
			&handoff_req->bssid, QDF_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 (QDF_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: QDF_STATUS_SUCCESS on success, corresponding error code otherwise
 */
QDF_STATUS csr_neighbor_roam_proceed_with_handoff_req(tpAniSirGlobal pMac,
						      uint8_t sessionId)
{
	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
		&pMac->roam.neighborRoamInfo[sessionId];
	QDF_STATUS status = QDF_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 = QDF_STATUS_E_FAILURE;
	} else {
		/* Let's go ahead with handoff */
		status = csr_neighbor_roam_process_handoff_req(pMac, sessionId);
	}
	if (!QDF_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 QDF_STATUS_SUCCESS on success, corresponding error code otherwise

   ---------------------------------------------------------------------------*/
QDF_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 QDF_STATUS_SUCCESS;
}
