/*
 * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved.
 *
 * 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.
 */

/*
 * DOC: 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 "csr_inside_api.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 "wlan_policy_mgr_api.h"

static const char *lfr_get_config_item_string(uint8_t reason)
{
	switch (reason) {
	CASE_RETURN_STRING(REASON_LOOKUP_THRESH_CHANGED);
	CASE_RETURN_STRING(REASON_OPPORTUNISTIC_THRESH_DIFF_CHANGED);
	CASE_RETURN_STRING(REASON_ROAM_RESCAN_RSSI_DIFF_CHANGED);
	CASE_RETURN_STRING(REASON_ROAM_BMISS_FIRST_BCNT_CHANGED);
	CASE_RETURN_STRING(REASON_ROAM_BMISS_FINAL_BCNT_CHANGED);
	CASE_RETURN_STRING(REASON_ROAM_BEACON_RSSI_WEIGHT_CHANGED);
	default:
		return "unknown";
	}
}

static void csr_neighbor_roam_reset_channel_info(tpCsrNeighborRoamChannelInfo
						 rChInfo);

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)
{
	struct csr_roam_info *roam_info;

	roam_info = qdf_mem_malloc(sizeof(struct csr_roam_info));
	if (roam_info) {
		qdf_mem_copy((void *)roam_info->bssid.bytes,
			     (void *)bssid, sizeof(struct qdf_mac_addr));
		csr_roam_call_callback(mac_ctx, session_id, roam_info, 0,
			status, 0);
		qdf_mem_free(roam_info);
	}
}
#endif

/**
 * csr_neighbor_roam_update_fast_roaming_enabled() - update roaming capability
 *
 * @mac_ctx: Global MAC context
 * @session_id: Session
 * @fast_roam_enabled: Is fast roaming enabled on this device?
 *                     This capability can be changed dynamically.
 *
 * Return: None
 */
QDF_STATUS csr_neighbor_roam_update_fast_roaming_enabled(tpAniSirGlobal mac_ctx,
						uint8_t session_id,
						const bool fast_roam_enabled)
{
	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
	tpCsrNeighborRoamControlInfo neighbor_roam_info =
		&mac_ctx->roam.neighborRoamInfo[session_id];

	switch (neighbor_roam_info->neighborRoamState) {
	case eCSR_NEIGHBOR_ROAM_STATE_CONNECTED:
		qdf_status = sme_acquire_global_lock(&mac_ctx->sme);
		if (QDF_IS_STATUS_SUCCESS(qdf_status)) {
			if (fast_roam_enabled) {
				csr_roam_offload_scan(mac_ctx, session_id,
						ROAM_SCAN_OFFLOAD_START,
						REASON_CONNECT);
			} else {
				csr_roam_offload_scan(mac_ctx, session_id,
						ROAM_SCAN_OFFLOAD_STOP,
						REASON_DISCONNECTED);
			}
			sme_release_global_lock(&mac_ctx->sme);
		} else {
			sme_err("Failed to acquire SME lock");
		}
	break;
	case eCSR_NEIGHBOR_ROAM_STATE_INIT:
		sme_debug("Currently in INIT state, Nothing to do");
		break;
	default:
		sme_err("Unexpected state %s, returning failure",
			    mac_trace_get_neighbour_roam_state
			    (neighbor_roam_info->neighborRoamState));
		qdf_status = QDF_STATUS_E_FAILURE;
		break;
	}
	return qdf_status;
}
QDF_STATUS csr_neighbor_roam_update_config(tpAniSirGlobal mac_ctx,
		uint8_t session_id, uint8_t value, uint8_t reason)
{
	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
	    &mac_ctx->roam.neighborRoamInfo[session_id];
	tpCsrNeighborRoamCfgParams cfg_params;
	eCsrNeighborRoamState state;
	uint8_t old_value;

	if (NULL == pNeighborRoamInfo) {
		sme_err("Invalid Session ID %d", session_id);
		return QDF_STATUS_E_FAILURE;
	}
	cfg_params = &pNeighborRoamInfo->cfgParams;
	state = pNeighborRoamInfo->neighborRoamState;
	if ((state == eCSR_NEIGHBOR_ROAM_STATE_CONNECTED) ||
			state == eCSR_NEIGHBOR_ROAM_STATE_INIT) {
		switch (reason) {
		case REASON_LOOKUP_THRESH_CHANGED:
			old_value = cfg_params->neighborLookupThreshold;
			cfg_params->neighborLookupThreshold = value;
			pNeighborRoamInfo->currentNeighborLookupThreshold =
				value;
			break;
		case REASON_OPPORTUNISTIC_THRESH_DIFF_CHANGED:
			old_value = cfg_params->nOpportunisticThresholdDiff;
			cfg_params->nOpportunisticThresholdDiff = value;
			pNeighborRoamInfo->currentOpportunisticThresholdDiff =
				value;
			break;
		case REASON_ROAM_RESCAN_RSSI_DIFF_CHANGED:
			old_value = cfg_params->nRoamRescanRssiDiff;
			cfg_params->nRoamRescanRssiDiff = value;
			pNeighborRoamInfo->currentRoamRescanRssiDiff = value;
			break;
		case REASON_ROAM_BMISS_FIRST_BCNT_CHANGED:
			old_value = cfg_params->nRoamBmissFirstBcnt;
			cfg_params->nRoamBmissFirstBcnt = value;
			pNeighborRoamInfo->currentRoamBmissFirstBcnt = value;
			break;
		case REASON_ROAM_BMISS_FINAL_BCNT_CHANGED:
			old_value = cfg_params->nRoamBmissFinalBcnt;
			cfg_params->nRoamBmissFinalBcnt = value;
			pNeighborRoamInfo->currentRoamBmissFinalBcnt = value;
			break;
		case REASON_ROAM_BEACON_RSSI_WEIGHT_CHANGED:
			old_value = cfg_params->nRoamBeaconRssiWeight;
			cfg_params->nRoamBeaconRssiWeight = value;
			pNeighborRoamInfo->currentRoamBeaconRssiWeight = value;
			break;
		default:
			sme_debug("Unknown update cfg reason");
			return QDF_STATUS_E_FAILURE;
		}
	} else {
		sme_err("Unexpected state %s, return fail",
			mac_trace_get_neighbour_roam_state(state));
		return QDF_STATUS_E_FAILURE;
	}
	if (state == eCSR_NEIGHBOR_ROAM_STATE_CONNECTED) {
		sme_debug("CONNECTED, send update cfg cmd");
		csr_roam_offload_scan(mac_ctx, session_id,
			ROAM_SCAN_OFFLOAD_UPDATE_CFG, reason);
	}
	sme_debug("LFR config for %s changed from %d to %d",
			lfr_get_config_item_string(reason), old_value, value);
	return QDF_STATUS_SUCCESS;
}

/*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
 */
static void csr_neighbor_roam_reset_connected_state_control_info(
							tpAniSirGlobal mac,
							uint8_t sessionId)
{
	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
		&mac->roam.neighborRoamInfo[sessionId];

	csr_neighbor_roam_reset_channel_info(&pNeighborRoamInfo->
					roamChannelInfo);
	csr_neighbor_roam_free_roamable_bss_list(mac,
					&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));
}

static void csr_neighbor_roam_reset_report_scan_state_control_info(
							tpAniSirGlobal mac,
							uint8_t sessionId)
{
	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
		&mac->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(mac,
					&pNeighborRoamInfo->roamableAPList);
}

/**
 * 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
 */
static void csr_neighbor_roam_reset_init_state_control_info(tpAniSirGlobal mac,
							    uint8_t sessionId)
{
	csr_neighbor_roam_reset_connected_state_control_info(mac, 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(mac, sessionId);
}

/**
 * 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 mac,
					      tCsrScanResultFilter *pScanFilter,
					      uint8_t sessionId)
{
	tpCsrNeighborRoamControlInfo nbr_roam_info =
		&mac->roam.neighborRoamInfo[sessionId];
	tCsrRoamConnectedProfile *pCurProfile =
		&mac->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 = &mac->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) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
			FL("OS Requested Handoff"));
		pScanFilter->BSSIDs.numOfBSSIDs = 1;
		pScanFilter->BSSIDs.bssid =
			qdf_mem_malloc(sizeof(tSirMacAddr) *
				       pScanFilter->BSSIDs.numOfBSSIDs);
		if (!pScanFilter->BSSIDs.bssid)
			return QDF_STATUS_E_NOMEM;

		/* 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 (!pScanFilter->SSIDs.SSIDList)
			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 (!pScanFilter->SSIDs.SSIDList)
			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);

		sme_debug("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 (!pScanFilter->ChannelInfo.ChannelList) {
			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;
}

enum band_info csr_get_rf_band(uint8_t channel)
{
	if ((channel >= SIR_11A_CHANNEL_BEGIN) &&
	    (channel <= SIR_11A_CHANNEL_END))
		return BAND_5G;

	if ((channel >= SIR_11B_CHANNEL_BEGIN) &&
	    (channel <= SIR_11B_CHANNEL_END))
		return BAND_2G;

	return BAND_UNKNOWN;
}

/**
 * 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
						mac,
						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 =
		mac->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 (csr_get_rf_band(currAPoperationChannel) ==
		    csr_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 mac,
						 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_DEBUG,
					  "%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_DEBUG,
				  "%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_is_ssid_and_security_match() - to match ssid/security
 * @mac: Pointer to mac context
 * @pCurProfile: pointer to current roam profile
 * @pBssDesc: pointer to bss description
 * @pIes: pointer to local ies
 * @session_id: Session ID
 *
 * This routine will be called to see if SSID and security parameters
 * are matching.
 *
 * Return: bool
 */
static bool csr_neighbor_roam_is_ssid_and_security_match(tpAniSirGlobal mac,
		tCsrRoamConnectedProfile *pCurProfile,
		tSirBssDescription *pBssDesc, tDot11fBeaconIEs *pIes,
		uint8_t session_id)
{
	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(mac,
			(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(mac, &authType,
				&uCEncryptionType, &mCEncryptionType,
				&pCurProfile->MFPEnabled,
				&pCurProfile->MFPRequired,
				&pCurProfile->MFPCapable,
				pBssDesc, pIes, session_id);
#else
		fMatch = csr_is_security_match(mac, &authType,
				&uCEncryptionType,
				&mCEncryptionType, NULL,
				NULL, NULL, pBssDesc,
				pIes, session_id);
#endif
		return fMatch;
	} else {
		return fMatch;
	}

}

bool csr_neighbor_roam_is_new_connected_profile(tpAniSirGlobal mac,
						uint8_t sessionId)
{
	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
		&mac->roam.neighborRoamInfo[sessionId];
	tCsrRoamConnectedProfile *pCurrProfile = NULL;
	tCsrRoamConnectedProfile *pPrevProfile = NULL;
	tDot11fBeaconIEs *pIes = NULL;
	tSirBssDescription *pBssDesc = NULL;
	bool fNew = true;

	if (!(mac->roam.roamSession && CSR_IS_SESSION_VALID(mac, sessionId)))
		return fNew;

	pCurrProfile = &mac->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(mac, pBssDesc, &pIes))
		    && csr_neighbor_roam_is_ssid_and_security_match(mac,
				pCurrProfile, pBssDesc, pIes, sessionId)) {
			fNew = false;
		}
		if (pIes)
			qdf_mem_free(pIes);
	}

	sme_debug("roam profile match: %d", !fNew);

	return fNew;
}

bool csr_neighbor_roam_connected_profile_match(tpAniSirGlobal mac,
					       uint8_t sessionId,
					       struct tag_csrscan_result
						*pResult,
					       tDot11fBeaconIEs *pIes)
{
	tCsrRoamConnectedProfile *pCurProfile = NULL;
	tSirBssDescription *pBssDesc = &pResult->Result.BssDescriptor;

	if (!(mac->roam.roamSession && CSR_IS_SESSION_VALID(mac, sessionId)))
		return false;

	pCurProfile = &mac->roam.roamSession[sessionId].connectedProfile;

	if (!pCurProfile)
		return false;

	return csr_neighbor_roam_is_ssid_and_security_match(mac, pCurProfile,
							    pBssDesc, pIes,
							    sessionId);
}

/**
 * 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
 * @mac: 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 mac,
						 uint8_t sessionId)
{
	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
			&mac->roam.neighborRoamInfo[sessionId];
	tCsrRoamConnectedProfile *pPrevProfile =
			&pNeighborRoamInfo->prevConnProfile;
	struct csr_roam_session *pSession = CSR_GET_SESSION(mac, sessionId);
	struct csr_roam_session *roam_session = NULL;

	if (NULL == pSession) {
		sme_err("pSession is NULL");
		return QDF_STATUS_E_FAILURE;
	}
	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
			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(mac, 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(mac, sessionId))
		csr_roam_reset_roam_params(mac);
	if (NULL != pSession) {
		roam_session = &mac->roam.roamSession[sessionId];
		if (NULL != pSession->pCurRoamProfile && (QDF_STA_MODE !=
			roam_session->pCurRoamProfile->csrPersona)) {
			sme_err("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(mac, 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(mac,
				eCSR_NEIGHBOR_ROAM_STATE_INIT, sessionId);
			pNeighborRoamInfo->roamChannelInfo.
				IAPPNeighborListReceived = false;
			pNeighborRoamInfo->uOsRequestedHandoff = 0;
		}
		break;

	case eCSR_NEIGHBOR_ROAM_STATE_INIT:
		csr_neighbor_roam_reset_init_state_control_info(mac,
				sessionId);
		break;

	case eCSR_NEIGHBOR_ROAM_STATE_CONNECTED:
		csr_neighbor_roam_state_transition(mac,
				eCSR_NEIGHBOR_ROAM_STATE_INIT, sessionId);
		pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived =
				false;
		csr_neighbor_roam_reset_connected_state_control_info(mac,
				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(mac,
				eCSR_NEIGHBOR_ROAM_STATE_INIT, sessionId);
		pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived =
				false;
		csr_neighbor_roam_reset_preauth_control_info(mac, sessionId);
		csr_neighbor_roam_reset_report_scan_state_control_info(mac,
				sessionId);
		break;
	default:
		sme_debug("Received disconnect event in state %s",
			mac_trace_get_neighbour_roam_state(
				pNeighborRoamInfo->neighborRoamState));
		sme_debug("Transit to INIT state");
		csr_neighbor_roam_state_transition(mac,
				eCSR_NEIGHBOR_ROAM_STATE_INIT, sessionId);
			pNeighborRoamInfo->roamChannelInfo.
			IAPPNeighborListReceived = false;
			pNeighborRoamInfo->uOsRequestedHandoff = 0;
		break;
	}
	/*Inform the Firmware to STOP Scanning as the host has a disconnect. */
	if (csr_roam_is_sta_mode(mac, sessionId)) {
		csr_roam_offload_scan(mac, sessionId, ROAM_SCAN_OFFLOAD_STOP,
				REASON_DISCONNECTED);
	}

	return QDF_STATUS_SUCCESS;
}

/**
 * csr_neighbor_roam_info_ctx_init() - Initialize neighbor roam struct
 * @mac: 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 mac,
		uint8_t session_id)
{
	tpCsrNeighborRoamControlInfo ngbr_roam_info =
		&mac->roam.neighborRoamInfo[session_id];
	struct csr_roam_session *session = &mac->roam.roamSession[session_id];
	struct csr_roam_profile *roam_profile = session->pCurRoamProfile;
	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(mac, session_id);
	csr_neighbor_roam_state_transition(mac,
			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(mac,
		&ngbr_roam_info->FTRoamInfo.preAuthDoneList);

	/* Based on the auth scheme tell if we are 11r */
	if (csr_is_auth_type11r
		(mac, session->connectedProfile.AuthType,
		session->connectedProfile.MDID.mdiePresent)) {
		if (mac->roam.configParam.isFastTransitionEnabled)
			init_ft_flag = true;
		ngbr_roam_info->is11rAssoc = true;
	} else
		ngbr_roam_info->is11rAssoc = false;
	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
			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 (mac->roam.configParam.isFastTransitionEnabled)
			init_ft_flag = true;
		ngbr_roam_info->isESEAssoc = true;
	} else
		ngbr_roam_info->isESEAssoc = false;
	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
			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(mac, 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(mac);
	if (csr_roam_is_roam_offload_scan_enabled(mac)) {
		/*
		 * 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(mac, 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 (mac->roam.pReassocResp != NULL) {
				QDF_TRACE(QDF_MODULE_ID_SME,
					QDF_TRACE_LEVEL_DEBUG,
					"Free Reassoc Rsp");
				qdf_mem_free(mac->roam.pReassocResp);
				mac->roam.pReassocResp = NULL;
			}
		} else
#endif
		{
			csr_roam_offload_scan(mac, session_id,
				ROAM_SCAN_OFFLOAD_START,
				REASON_CTX_INIT);

			if (roam_profile &&
				roam_profile->supplicant_disabled_roaming) {
				sme_debug("Supplicant disabled driver roaming");
				csr_roam_offload_scan(mac, session_id,
					ROAM_SCAN_OFFLOAD_STOP,
					REASON_SUPPLICANT_DISABLED_ROAMING);
			}
		}
	}
}

/**
 * csr_neighbor_roam_indicate_connect()
 * @mac: 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 mac, uint8_t session_id,
		QDF_STATUS qdf_status)
{
	tpCsrNeighborRoamControlInfo ngbr_roam_info =
		&mac->roam.neighborRoamInfo[session_id];
	struct csr_roam_session *session = &mac->roam.roamSession[session_id];
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
	struct csr_roam_info roamInfo;
#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(mac, session_id)
	|| (NULL == mac->roam.roamSession[session_id].pCurRoamProfile)) {
		return QDF_STATUS_E_FAILURE;
	}

	sme_debug("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 (mac->roam.roamSession[session_id].pCurRoamProfile->csrPersona !=
	QDF_STA_MODE) {
		sme_err("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(mac)) &&
		(csr_is_concurrent_session_running(mac))) {
		sme_err("Ignoring Connect ind. received in multisession %d",
			csr_is_concurrent_session_running(mac));
		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)) {
		sme_debug("LFR3: Authenticated");
		qdf_copy_macaddr(&roamInfo.peerMac,
			&session->connectedProfile.bssid);
		roamInfo.roamSynchInProgress =
			session->roam_synch_in_progress;
		csr_roam_call_callback(mac, session_id, &roamInfo, 0,
			eCSR_ROAM_SET_KEY_COMPLETE,
			eCSR_ROAM_RESULT_AUTHENTICATED);
		csr_neighbor_roam_reset_init_state_control_info(mac,
			session_id);
		csr_neighbor_roam_info_ctx_init(mac, 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(mac,
				eCSR_NEIGHBOR_ROAM_STATE_INIT, session_id);
			ngbr_roam_info->roamChannelInfo.
					IAPPNeighborListReceived = false;
			ngbr_roam_info->uOsRequestedHandoff = 0;
			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(mac,
			session_id);
		csr_neighbor_roam_info_ctx_init(mac, session_id);
		break;
	default:
		sme_err("Connect evt received in invalid state %s Ignoring",
			mac_trace_get_neighbour_roam_state(
			ngbr_roam_info->neighborRoamState));
		break;
	}
	return status;
}

/*
 * csr_neighbor_roam_init11r_assoc_info -
 * This function initializes 11r related neighbor roam data structures
 *
 * @mac: The handle returned by mac_open.
 *
 * return QDF_STATUS_SUCCESS on success, corresponding error code otherwise
 */
static QDF_STATUS csr_neighbor_roam_init11r_assoc_info(tpAniSirGlobal mac)
{
	QDF_STATUS status;
	uint8_t i;
	tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL;
	tpCsr11rAssocNeighborInfo pFTRoamInfo = NULL;

	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
		pNeighborRoamInfo = &mac->roam.neighborRoamInfo[i];
		pFTRoamInfo = &pNeighborRoamInfo->FTRoamInfo;

		pNeighborRoamInfo->is11rAssoc = false;

		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(&pFTRoamInfo->preAuthDoneList);
		if (QDF_STATUS_SUCCESS != status) {
			sme_err("LL Open of preauth done AP List failed");
			return QDF_STATUS_E_RESOURCES;
		}
	}
	return status;
}

/*
 * csr_neighbor_roam_init() -
 * This function initializes neighbor roam data structures
 *
 * @mac: The handle returned by mac_open.
 * sessionId: Session identifier
 *
 * Return QDF_STATUS_SUCCESS on success, corresponding error code otherwise
 */
QDF_STATUS csr_neighbor_roam_init(tpAniSirGlobal mac, uint8_t sessionId)
{
	QDF_STATUS status;
	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
		&mac->roam.neighborRoamInfo[sessionId];

	pNeighborRoamInfo->neighborRoamState = eCSR_NEIGHBOR_ROAM_STATE_CLOSED;
	pNeighborRoamInfo->prevNeighborRoamState =
		eCSR_NEIGHBOR_ROAM_STATE_CLOSED;
	pNeighborRoamInfo->cfgParams.maxChannelScanTime =
		mac->roam.configParam.neighborRoamConfig.
		nNeighborScanMaxChanTime;
	pNeighborRoamInfo->cfgParams.minChannelScanTime =
		mac->roam.configParam.neighborRoamConfig.
		nNeighborScanMinChanTime;
	pNeighborRoamInfo->cfgParams.neighborLookupThreshold =
		mac->roam.configParam.neighborRoamConfig.
		nNeighborLookupRssiThreshold;
	pNeighborRoamInfo->cfgParams.rssi_thresh_offset_5g =
		mac->mlme_cfg->lfr.rssi_threshold_offset_5g;
	pNeighborRoamInfo->cfgParams.delay_before_vdev_stop =
		mac->roam.configParam.neighborRoamConfig.
		delay_before_vdev_stop;
	pNeighborRoamInfo->cfgParams.nOpportunisticThresholdDiff =
		mac->roam.configParam.neighborRoamConfig.
		nOpportunisticThresholdDiff;
	pNeighborRoamInfo->cfgParams.nRoamRescanRssiDiff =
		mac->roam.configParam.neighborRoamConfig.nRoamRescanRssiDiff;
	pNeighborRoamInfo->cfgParams.nRoamBmissFirstBcnt =
		mac->roam.configParam.neighborRoamConfig.nRoamBmissFirstBcnt;
	pNeighborRoamInfo->cfgParams.nRoamBmissFinalBcnt =
		mac->roam.configParam.neighborRoamConfig.nRoamBmissFinalBcnt;
	pNeighborRoamInfo->cfgParams.nRoamBeaconRssiWeight =
		mac->roam.configParam.neighborRoamConfig.nRoamBeaconRssiWeight;
	pNeighborRoamInfo->cfgParams.neighborScanPeriod =
		mac->roam.configParam.neighborRoamConfig.
		nNeighborScanTimerPeriod;
	pNeighborRoamInfo->cfgParams.neighbor_scan_min_period =
		mac->roam.configParam.neighborRoamConfig.
		neighbor_scan_min_timer_period;
	pNeighborRoamInfo->cfgParams.neighborResultsRefreshPeriod =
		mac->roam.configParam.neighborRoamConfig.
		nNeighborResultsRefreshPeriod;
	pNeighborRoamInfo->cfgParams.emptyScanRefreshPeriod =
		mac->roam.configParam.neighborRoamConfig.
		nEmptyScanRefreshPeriod;

	pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels =
		mac->roam.configParam.neighborRoamConfig.neighborScanChanList.
		numChannels;
	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
			FL("number of channels: %u"),
			pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels);
	if (pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels != 0) {
		pNeighborRoamInfo->cfgParams.channelInfo.ChannelList =
		qdf_mem_malloc(mac->roam.configParam.neighborRoamConfig.
				neighborScanChanList.numChannels);
		if (!pNeighborRoamInfo->cfgParams.channelInfo.ChannelList)
			return QDF_STATUS_E_NOMEM;

	} else {
		pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL;
	}

	/* Update the roam global structure from CFG */
	qdf_mem_copy(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList,
		     mac->roam.configParam.neighborRoamConfig.
		     neighborScanChanList.channelList,
		     mac->roam.configParam.neighborRoamConfig.
		     neighborScanChanList.numChannels);
	pNeighborRoamInfo->cfgParams.hi_rssi_scan_max_count =
		mac->roam.configParam.neighborRoamConfig.
			nhi_rssi_scan_max_count;
	pNeighborRoamInfo->cfgParams.hi_rssi_scan_rssi_delta =
		mac->roam.configParam.neighborRoamConfig.
			nhi_rssi_scan_rssi_delta;
	pNeighborRoamInfo->cfgParams.hi_rssi_scan_delay =
		mac->roam.configParam.neighborRoamConfig.
			nhi_rssi_scan_delay;
	pNeighborRoamInfo->cfgParams.hi_rssi_scan_rssi_ub =
		mac->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(&pNeighborRoamInfo->roamableAPList);
	if (QDF_STATUS_SUCCESS != status) {
		sme_err("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(mac);
	if (QDF_STATUS_SUCCESS != status) {
		sme_err("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(mac,
			eCSR_NEIGHBOR_ROAM_STATE_INIT, sessionId);
	pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = false;
	pNeighborRoamInfo->uOsRequestedHandoff = 0;
	/* Set the Last Sent Cmd as RSO_STOP */
	pNeighborRoamInfo->last_sent_cmd = ROAM_SCAN_OFFLOAD_STOP;
	return QDF_STATUS_SUCCESS;
}

/*
 * csr_neighbor_roam_close() -
 * This function closes/frees all the neighbor roam data structures
 *
 * @mac: The handle returned by mac_open.
 * @sessionId: Session identifier
 *
 * Return VOID
 */
void csr_neighbor_roam_close(tpAniSirGlobal mac, uint8_t sessionId)
{
	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
		&mac->roam.neighborRoamInfo[sessionId];

	if (eCSR_NEIGHBOR_ROAM_STATE_CLOSED ==
	    pNeighborRoamInfo->neighborRoamState) {
		sme_warn("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(mac,
					&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(mac, &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(mac,
						 &pNeighborRoamInfo->FTRoamInfo.
						 preAuthDoneList);
	csr_ll_close(&pNeighborRoamInfo->FTRoamInfo.preAuthDoneList);
	pNeighborRoamInfo->b_roam_scan_offload_started = false;

	csr_neighbor_roam_state_transition(mac,
		eCSR_NEIGHBOR_ROAM_STATE_CLOSED, sessionId);

}

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

/*
 * csr_neighbor_middle_of_roaming() -
 * This function returns true if STA is in the middle of roaming states
 *
 * @halHandle: The handle from HDD context.
 * @sessionId: Session identifier
 *
 * Return bool
 */
bool csr_neighbor_middle_of_roaming(tpAniSirGlobal mac, uint8_t sessionId)
{
	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
		&mac->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
 */
static 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;
	struct csr_roam_profile *profile = NULL;
	struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, session_id);
	uint8_t i = 0;
	uint8_t roam_now = 0;
	uint8_t roamable_ap_count = 0;
	tCsrScanResultFilter    scan_filter;
	tScanResultHandle       scan_result;

	if (NULL == session) {
		sme_err("session is NULL");
		return QDF_STATUS_E_FAILURE;
	}

	roam_id = GET_NEXT_ROAM_ID(&mac_ctx->roam);
	profile = qdf_mem_malloc(sizeof(struct csr_roam_profile));
	if (!profile)
		return QDF_STATUS_E_NOMEM;

	status =
		csr_roam_copy_profile(mac_ctx, profile,
				      session->pCurRoamProfile);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		sme_err("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 (!profile->BSSIDs.bssid) {
			status = QDF_STATUS_E_NOMEM;
			goto end;
		}
	}

	/* 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 (!profile->ChannelInfo.ChannelList) {
			status = QDF_STATUS_E_NOMEM;
			goto end;
		}
	}
	profile->ChannelInfo.ChannelList[0] =
		roam_ctrl_info->handoffReqInfo.channel;

	/*
	 * For User space connect requests, the scan has already been done.
	 * So, check if the BSS descriptor exists in the scan cache and
	 * proceed with the handoff instead of a redundant scan again.
	 */
	if (roam_ctrl_info->handoffReqInfo.src == CONNECT_CMD_USERSPACE) {
		sme_debug("Connect cmd with bssid within same ESS");
		status = csr_neighbor_roam_prepare_scan_profile_filter(mac_ctx,
								&scan_filter,
								session_id);
		sme_debug("Filter creation status: %d", status);
		status = csr_scan_get_result(mac_ctx, &scan_filter,
					     &scan_result);
		csr_neighbor_roam_process_scan_results(mac_ctx, session_id,
							&scan_result);
		roamable_ap_count = csr_ll_count(
					&roam_ctrl_info->roamableAPList);
		csr_free_scan_filter(mac_ctx, &scan_filter);
		sme_debug("roam_now=%d, roamable_ap_count=%d",
			roam_now, roamable_ap_count);
	}
	if (roam_now && roamable_ap_count) {
		csr_neighbor_roam_trigger_handoff(mac_ctx, session_id);
	} else {
		status = csr_scan_for_ssid(mac_ctx, session_id, profile,
					   roam_id, false);
		if (status != QDF_STATUS_SUCCESS)
			sme_err("SSID scan failed");
	}

end:
	if (NULL != profile) {
		csr_release_profile(mac_ctx, profile);
		qdf_mem_free(profile);
	}

	return status;
}

/*
 * csr_neighbor_roam_sssid_scan_done() -
 * 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

 * @mac: The handle returned by mac_open.
 * @session_id  SME session id
 *
 * Return QDF_STATUS_SUCCESS on success, corresponding error code otherwise
 */
QDF_STATUS csr_neighbor_roam_sssid_scan_done(tpAniSirGlobal mac,
					   uint8_t sessionId, QDF_STATUS status)
{
	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
		&mac->roam.neighborRoamInfo[sessionId];
	QDF_STATUS hstatus;

	/* we must be in connected state, if not ignore it */
	if (eCSR_NEIGHBOR_ROAM_STATE_CONNECTED !=
	    pNeighborRoamInfo->neighborRoamState) {
		sme_err("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)) {
		sme_err("Add an entry to csr scan cache");
		hstatus = csr_scan_create_entry_in_scan_cache(mac, sessionId,
							pNeighborRoamInfo->
							handoffReqInfo.bssid,
							pNeighborRoamInfo->
							handoffReqInfo.channel);
		if (QDF_STATUS_SUCCESS != hstatus) {
			sme_err(
				"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(mac, sessionId);

	if (QDF_STATUS_SUCCESS != hstatus) {
		sme_err("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) {
		sme_err("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) {
		sme_err("Received msg is NULL");
		return QDF_STATUS_E_FAILURE;
	}

	/* sanity check */
	if (!qdf_mem_cmp(handoff_req->bssid,
		roam_ctrl_info->currAPbssid.bytes,
		sizeof(tSirMacAddr))) {
		sme_err("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) {
		sme_err("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 mac,
						      uint8_t sessionId)
{
	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
		&mac->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)) {
		sme_err(
			"Received in not CONNECTED state(%d) or uOsRequestedHandoff(%d) is not set. Ignore it",
			pNeighborRoamInfo->neighborRoamState,
			pNeighborRoamInfo->uOsRequestedHandoff);
		status = QDF_STATUS_E_FAILURE;
	} else
		/* Let's go ahead with handoff */
		status = csr_neighbor_roam_process_handoff_req(mac, sessionId);

	if (!QDF_IS_STATUS_SUCCESS(status))
		pNeighborRoamInfo->uOsRequestedHandoff = 0;

	return status;
}

/*
 * csr_neighbor_roam_start_lfr_scan() -
 * 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.

 * @mac: The handle returned by mac_open.
 * @session_id: Session ID
 *
 * Return QDF_STATUS_SUCCESS on success, corresponding error code otherwise
 */
QDF_STATUS csr_neighbor_roam_start_lfr_scan(tpAniSirGlobal mac,
						uint8_t sessionId)
{
	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
		&mac->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(mac, sessionId, ROAM_SCAN_OFFLOAD_START,
			      REASON_NO_CAND_FOUND_OR_NOT_ROAMING_NOW);

	return QDF_STATUS_SUCCESS;



}
