/*
 * Copyright (c) 2012-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  smeApi.c

   \brief Definitions for SME APIs

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

/*--------------------------------------------------------------------------
   Include Files
   ------------------------------------------------------------------------*/

#include "sms_debug.h"
#include "sme_api.h"
#include "csr_inside_api.h"
#include "sme_inside.h"
#include "csr_internal.h"
#include "wma_types.h"
#include "wma_if.h"
#include "qdf_trace.h"
#include "sme_trace.h"
#include "qdf_types.h"
#include "qdf_trace.h"
#include "cds_utils.h"
#include "sap_api.h"
#include "mac_trace.h"
#ifdef WLAN_FEATURE_NAN
#include "nan_api.h"
#endif
#include "cds_regdomain.h"
#include "cfg_api.h"
#include "sme_power_save_api.h"
#include "wma.h"
#include "sch_api.h"
#include "sme_nan_datapath.h"

extern tSirRetStatus u_mac_post_ctrl_msg(void *pSirGlobal, tSirMbMsg *pMb);

#define LOG_SIZE 256

static tSelfRecoveryStats g_self_recovery_stats;
/* TxMB Functions */
extern QDF_STATUS pmc_prepare_command(tpAniSirGlobal pMac, uint32_t sessionId,
				      eSmeCommandType cmdType, void *pvParam,
				      uint32_t size, tSmeCmd **ppCmd);
extern void pmc_release_command(tpAniSirGlobal pMac, tSmeCmd *pCommand);
extern void qos_release_command(tpAniSirGlobal pMac, tSmeCmd *pCommand);
extern QDF_STATUS p2p_process_remain_on_channel_cmd(tpAniSirGlobal pMac,
						    tSmeCmd *p2pRemainonChn);
extern QDF_STATUS sme_remain_on_chn_rsp(tpAniSirGlobal pMac, uint8_t *pMsg);
extern QDF_STATUS sme_remain_on_chn_ready(tHalHandle hHal, uint8_t *pMsg);

static QDF_STATUS init_sme_cmd_list(tpAniSirGlobal pMac);
static void sme_abort_command(tpAniSirGlobal pMac, tSmeCmd *pCommand,
			      bool fStopping);

eCsrPhyMode sme_get_phy_mode(tHalHandle hHal);

QDF_STATUS sme_handle_change_country_code(tpAniSirGlobal pMac, void *pMsgBuf);

void sme_disconnect_connected_sessions(tpAniSirGlobal pMac);

QDF_STATUS sme_handle_generic_change_country_code(tpAniSirGlobal pMac,
						  void *pMsgBuf);

QDF_STATUS sme_process_nss_update_resp(tpAniSirGlobal mac, uint8_t *msg);

#ifdef FEATURE_WLAN_ESE
bool csr_is_supported_channel(tpAniSirGlobal pMac, uint8_t channelId);
#endif

#ifdef WLAN_FEATURE_11W
QDF_STATUS sme_unprotected_mgmt_frm_ind(tHalHandle hHal,
					tpSirSmeUnprotMgmtFrameInd pSmeMgmtFrm);
#endif

/* Message processor for events from DFS */
QDF_STATUS dfs_msg_processor(tpAniSirGlobal pMac,
			     uint16_t msg_type, void *pMsgBuf);

/* Channel Change Response Indication Handler */
QDF_STATUS sme_process_channel_change_resp(tpAniSirGlobal pMac,
					   uint16_t msg_type, void *pMsgBuf);

/* Internal SME APIs */
QDF_STATUS sme_acquire_global_lock(tSmeStruct *psSme)
{
	QDF_STATUS status = QDF_STATUS_E_INVAL;

	if (psSme) {
		if (QDF_IS_STATUS_SUCCESS
			    (qdf_mutex_acquire(&psSme->lkSmeGlobalLock))) {
			status = QDF_STATUS_SUCCESS;
		}
	}

	return status;
}

QDF_STATUS sme_release_global_lock(tSmeStruct *psSme)
{
	QDF_STATUS status = QDF_STATUS_E_INVAL;

	if (psSme) {
		if (QDF_IS_STATUS_SUCCESS
			    (qdf_mutex_release(&psSme->lkSmeGlobalLock))) {
			status = QDF_STATUS_SUCCESS;
		}
	}

	return status;
}

/**
 * sme_process_set_hw_mode_resp() - Process set HW mode response
 * @mac: Global MAC pointer
 * @msg: HW mode response
 *
 * Processes the HW mode response and invokes the HDD callback
 * to process further
 */
static QDF_STATUS sme_process_set_hw_mode_resp(tpAniSirGlobal mac, uint8_t *msg)
{
	tListElem *entry = NULL;
	tSmeCmd *command = NULL;
	bool found;
	hw_mode_cb callback = NULL;
	struct sir_set_hw_mode_resp *param;
	enum sir_conn_update_reason reason;
	tSmeCmd *saved_cmd;

	sms_log(mac, LOG1, FL("%s"), __func__);
	param = (struct sir_set_hw_mode_resp *)msg;
	if (!param) {
		sms_log(mac, LOGE, FL("HW mode resp param is NULL"));
		/* Not returning. Need to check if active command list
		 * needs to be freed
		 */
	}

	entry = csr_ll_peek_head(&mac->sme.smeCmdActiveList,
			LL_ACCESS_LOCK);
	if (!entry) {
		sms_log(mac, LOGE, FL("No cmd found in active list"));
		return QDF_STATUS_E_FAILURE;
	}

	command = GET_BASE_ADDR(entry, tSmeCmd, Link);
	if (!command) {
		sms_log(mac, LOGE, FL("Base address is NULL"));
		return QDF_STATUS_E_FAILURE;
	}

	if (e_sme_command_set_hw_mode != command->command) {
		sms_log(mac, LOGE, FL("Command mismatch!"));
		return QDF_STATUS_E_FAILURE;
	}

	callback = command->u.set_hw_mode_cmd.set_hw_mode_cb;
	reason = command->u.set_hw_mode_cmd.reason;

	sms_log(mac, LOG1, FL("reason:%d session:%d"),
		command->u.set_hw_mode_cmd.reason,
		command->u.set_hw_mode_cmd.session_id);

	if (!callback) {
		sms_log(mac, LOGE, FL("Callback does not exist"));
		goto end;
	}

	if (!param) {
		sms_log(mac, LOGE,
			FL("Callback failed since HW mode params is NULL"));
		goto end;
	}

	/* Irrespective of the reason for which the hw mode change request
	 * was issued, the policy manager connection table needs to be updated
	 * with the new vdev-mac id mapping, tx/rx spatial streams etc., if the
	 * set hw mode was successful.
	 */
	callback(param->status,
			param->cfgd_hw_mode_index,
			param->num_vdev_mac_entries,
			param->vdev_mac_map);

	if (reason == SIR_UPDATE_REASON_HIDDEN_STA) {
		/* In the case of hidden SSID, connection update
		 * (set hw mode) is done after the scan with reason
		 * code eCsrScanForSsid completes. The connect/failure
		 * needs to be handled after the response of set hw
		 * mode
		 */
		saved_cmd = (tSmeCmd *)mac->sme.saved_scan_cmd;
		if (!saved_cmd) {
			sms_log(mac, LOGP,
					FL("saved cmd is NULL, Check this"));
			goto end;
		}
		if (param->status == SET_HW_MODE_STATUS_OK) {
			sms_log(mac, LOG1,
					FL("search for ssid success"));
			csr_scan_handle_search_for_ssid(mac,
					saved_cmd);
		} else {
			sms_log(mac, LOG1,
					FL("search for ssid failure"));
			csr_scan_handle_search_for_ssid_failure(mac,
					saved_cmd);
		}
		if (saved_cmd->u.roamCmd.pRoamBssEntry)
			qdf_mem_free(
					saved_cmd->u.roamCmd.pRoamBssEntry);
		if (saved_cmd->u.scanCmd.u.scanRequest.SSIDs.SSIDList)
			qdf_mem_free(saved_cmd->u.scanCmd.u.
					scanRequest.SSIDs.SSIDList);
		if (saved_cmd->u.scanCmd.pToRoamProfile)
			qdf_mem_free(saved_cmd->u.scanCmd.
					pToRoamProfile);
		if (saved_cmd) {
			qdf_mem_free(saved_cmd);
			saved_cmd = NULL;
			mac->sme.saved_scan_cmd = NULL;
		}
	}

end:
	found = csr_ll_remove_entry(&mac->sme.smeCmdActiveList, entry,
			LL_ACCESS_LOCK);
	if (found) {
		/* Now put this command back on the avilable command list */
		sme_release_command(mac, command);
	}
	sme_process_pending_queue(mac);
	return QDF_STATUS_SUCCESS;
}

/**
 * sme_process_hw_mode_trans_ind() - Process HW mode transition indication
 * @mac: Global MAC pointer
 * @msg: HW mode transition response
 *
 * Processes the HW mode transition indication and invoke the HDD callback
 * to process further
 */
static QDF_STATUS sme_process_hw_mode_trans_ind(tpAniSirGlobal mac,
						uint8_t *msg)
{
	hw_mode_transition_cb callback = NULL;
	struct sir_hw_mode_trans_ind *param;

	param = (struct sir_hw_mode_trans_ind *)msg;
	if (!param) {
		sms_log(mac, LOGE, FL("HW mode trans ind param is NULL"));
		return QDF_STATUS_E_FAILURE;
	}

	callback = mac->sme.sme_hw_mode_trans_cb;
	if (callback) {
		sms_log(mac, LOGE, FL("Calling registered callback..."));
		callback(param->old_hw_mode_index,
			param->new_hw_mode_index,
			param->num_vdev_mac_entries,
			param->vdev_mac_map);
	}

	return QDF_STATUS_SUCCESS;
}

/**
 * free_sme_cmds() - This function frees memory allocated for SME commands
 * @mac_ctx:      Pointer to Global MAC structure
 *
 * This function frees memory allocated for SME commands
 *
 * @Return: void
 */
static void free_sme_cmds(tpAniSirGlobal mac_ctx)
{
	uint32_t idx;
	if (NULL == mac_ctx->sme.pSmeCmdBufAddr)
		return;

	for (idx = 0; idx < mac_ctx->sme.totalSmeCmd; idx++)
		qdf_mem_free(mac_ctx->sme.pSmeCmdBufAddr[idx]);

	qdf_mem_free(mac_ctx->sme.pSmeCmdBufAddr);
	mac_ctx->sme.pSmeCmdBufAddr = NULL;
}

static QDF_STATUS init_sme_cmd_list(tpAniSirGlobal pMac)
{
	QDF_STATUS status;
	tSmeCmd *pCmd;
	uint32_t cmd_idx;
	QDF_STATUS qdf_status;
	qdf_mc_timer_t *cmdTimeoutTimer = NULL;
	uint32_t sme_cmd_ptr_ary_sz;

	pMac->sme.totalSmeCmd = SME_TOTAL_COMMAND;

	status = csr_ll_open(pMac->hHdd, &pMac->sme.smeCmdActiveList);
	if (!QDF_IS_STATUS_SUCCESS(status))
		goto end;

	status = csr_ll_open(pMac->hHdd, &pMac->sme.smeCmdPendingList);
	if (!QDF_IS_STATUS_SUCCESS(status))
		goto end;

	status = csr_ll_open(pMac->hHdd, &pMac->sme.smeScanCmdActiveList);
	if (!QDF_IS_STATUS_SUCCESS(status))
		goto end;

	status = csr_ll_open(pMac->hHdd, &pMac->sme.smeScanCmdPendingList);
	if (!QDF_IS_STATUS_SUCCESS(status))
		goto end;

	status = csr_ll_open(pMac->hHdd, &pMac->sme.smeCmdFreeList);
	if (!QDF_IS_STATUS_SUCCESS(status))
		goto end;

	/* following pointer contains array of pointers for tSmeCmd* */
	sme_cmd_ptr_ary_sz = sizeof(void *) * pMac->sme.totalSmeCmd;
	pMac->sme.pSmeCmdBufAddr = qdf_mem_malloc(sme_cmd_ptr_ary_sz);
	if (NULL == pMac->sme.pSmeCmdBufAddr) {
		status = QDF_STATUS_E_NOMEM;
		goto end;
	}

	status = QDF_STATUS_SUCCESS;
	qdf_mem_set(pMac->sme.pSmeCmdBufAddr, sme_cmd_ptr_ary_sz, 0);
	for (cmd_idx = 0; cmd_idx < pMac->sme.totalSmeCmd; cmd_idx++) {
		/*
		 * Since total size of all commands together can be huge chunk
		 * of memory, allocate SME cmd individually. These SME CMDs are
		 * moved between pending and active queues. And these freeing of
		 * these queues just manipulates the list but does not actually
		 * frees SME CMD pointers. Hence store each SME CMD address in
		 * the array, sme.pSmeCmdBufAddr. This will later facilitate
		 * freeing up of all SME CMDs with just a for loop.
		 */
		pMac->sme.pSmeCmdBufAddr[cmd_idx] =
						qdf_mem_malloc(sizeof(tSmeCmd));
		if (NULL == pMac->sme.pSmeCmdBufAddr[cmd_idx]) {
			status = QDF_STATUS_E_NOMEM;
			free_sme_cmds(pMac);
			goto end;
		}
		pCmd = (tSmeCmd *)pMac->sme.pSmeCmdBufAddr[cmd_idx];
		csr_ll_insert_tail(&pMac->sme.smeCmdFreeList,
				&pCmd->Link, LL_ACCESS_LOCK);
	}

	/* This timer is only to debug the active list command timeout */

	cmdTimeoutTimer =
		(qdf_mc_timer_t *) qdf_mem_malloc(sizeof(qdf_mc_timer_t));
	if (cmdTimeoutTimer) {
		pMac->sme.smeCmdActiveList.cmdTimeoutTimer = cmdTimeoutTimer;
		qdf_status =
			qdf_mc_timer_init(pMac->sme.smeCmdActiveList.
					  cmdTimeoutTimer, QDF_TIMER_TYPE_SW,
					  active_list_cmd_timeout_handle, (void *)pMac);

		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				  "Init Timer fail for active list command process time out");
			qdf_mem_free(pMac->sme.smeCmdActiveList.
				     cmdTimeoutTimer);
			pMac->sme.smeCmdActiveList.cmdTimeoutTimer = NULL;
		} else {
			pMac->sme.smeCmdActiveList.cmdTimeoutDuration =
				CSR_ACTIVE_LIST_CMD_TIMEOUT_VALUE;
		}
	}

end:
	if (!QDF_IS_STATUS_SUCCESS(status))
		sms_log(pMac, LOGE, "failed to initialize sme command list:%d\n",
			status);

	return status;
}

void sme_release_command(tpAniSirGlobal pMac, tSmeCmd *pCmd)
{
	pCmd->command = eSmeNoCommand;
	csr_ll_insert_tail(&pMac->sme.smeCmdFreeList, &pCmd->Link, LL_ACCESS_LOCK);
}

static void sme_release_cmd_list(tpAniSirGlobal pMac, tDblLinkList *pList)
{
	tListElem *pEntry;
	tSmeCmd *pCommand;

	while ((pEntry = csr_ll_remove_head(pList, LL_ACCESS_LOCK)) != NULL) {
		/* TODO: base on command type to call release functions */
		/* reinitialize different command types so they can be reused */
		pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
		sme_abort_command(pMac, pCommand, true);
	}
}

static void purge_sme_cmd_list(tpAniSirGlobal pMac)
{
	/* release any out standing commands back to free command list */
	sme_release_cmd_list(pMac, &pMac->sme.smeCmdPendingList);
	sme_release_cmd_list(pMac, &pMac->sme.smeCmdActiveList);
	sme_release_cmd_list(pMac, &pMac->sme.smeScanCmdPendingList);
	sme_release_cmd_list(pMac, &pMac->sme.smeScanCmdActiveList);
}

void purge_sme_session_cmd_list(tpAniSirGlobal pMac, uint32_t sessionId,
				tDblLinkList *pList)
{
	/* release any out standing commands back to free command list */
	tListElem *pEntry, *pNext;
	tSmeCmd *pCommand;
	tDblLinkList localList;

	qdf_mem_zero(&localList, sizeof(tDblLinkList));
	if (!QDF_IS_STATUS_SUCCESS(csr_ll_open(pMac->hHdd, &localList))) {
		sms_log(pMac, LOGE, FL(" failed to open list"));
		return;
	}

	csr_ll_lock(pList);
	pEntry = csr_ll_peek_head(pList, LL_ACCESS_NOLOCK);
	while (pEntry != NULL) {
		pNext = csr_ll_next(pList, pEntry, LL_ACCESS_NOLOCK);
		pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
		if (pCommand->sessionId == sessionId) {
			if (csr_ll_remove_entry(pList, pEntry, LL_ACCESS_NOLOCK)) {
				csr_ll_insert_tail(&localList, pEntry,
						   LL_ACCESS_NOLOCK);
			}
		}
		pEntry = pNext;
	}
	csr_ll_unlock(pList);

	while ((pEntry = csr_ll_remove_head(&localList, LL_ACCESS_NOLOCK))) {
		pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
		sme_abort_command(pMac, pCommand, true);
	}
	csr_ll_close(&localList);
}

static QDF_STATUS free_sme_cmd_list(tpAniSirGlobal pMac)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;

	purge_sme_cmd_list(pMac);
	csr_ll_close(&pMac->sme.smeCmdPendingList);
	csr_ll_close(&pMac->sme.smeCmdActiveList);
	csr_ll_close(&pMac->sme.smeScanCmdPendingList);
	csr_ll_close(&pMac->sme.smeScanCmdActiveList);
	csr_ll_close(&pMac->sme.smeCmdFreeList);

	/*destroy active list command time out timer */
	qdf_mc_timer_destroy(pMac->sme.smeCmdActiveList.cmdTimeoutTimer);
	qdf_mem_free(pMac->sme.smeCmdActiveList.cmdTimeoutTimer);
	pMac->sme.smeCmdActiveList.cmdTimeoutTimer = NULL;

	status = qdf_mutex_acquire(&pMac->sme.lkSmeGlobalLock);
	if (status != QDF_STATUS_SUCCESS) {
		sms_log(pMac, LOGE,
			FL("Failed to acquire the lock status = %d"), status);
		goto done;
	}

	free_sme_cmds(pMac);

	status = qdf_mutex_release(&pMac->sme.lkSmeGlobalLock);
	if (status != QDF_STATUS_SUCCESS) {
		sms_log(pMac, LOGE,
			FL("Failed to release the lock status = %d"), status);
	}
done:
	return status;
}

void dump_csr_command_info(tpAniSirGlobal pMac, tSmeCmd *pCmd)
{
	switch (pCmd->command) {
	case eSmeCommandScan:
		sms_log(pMac, LOGE, " scan command reason is %d",
			pCmd->u.scanCmd.reason);
		break;

	case eSmeCommandRoam:
		sms_log(pMac, LOGE, " roam command reason is %d",
			pCmd->u.roamCmd.roamReason);
		break;

	case eSmeCommandWmStatusChange:
		sms_log(pMac, LOGE, " WMStatusChange command type is %d",
			pCmd->u.wmStatusChangeCmd.Type);
		break;

	case eSmeCommandSetKey:
		sms_log(pMac, LOGE, " setKey command auth(%d) enc(%d)",
			pCmd->u.setKeyCmd.authType, pCmd->u.setKeyCmd.encType);
		break;

	default:
		sms_log(pMac, LOGE, " default: Unhandled command %d",
			pCmd->command);
		break;
	}
}

tSmeCmd *sme_get_command_buffer(tpAniSirGlobal pMac)
{
	tSmeCmd *pRetCmd = NULL, *pTempCmd = NULL;
	tListElem *pEntry;
	static int sme_command_queue_full;

	pEntry = csr_ll_remove_head(&pMac->sme.smeCmdFreeList, LL_ACCESS_LOCK);

	/* If we can get another MS Msg buffer, then we are ok.  Just link */
	/* the entry onto the linked list.  (We are using the linked list */
	/* to keep track of tfhe message buffers). */
	if (pEntry) {
		pRetCmd = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
		/* reset when free list is available */
		sme_command_queue_full = 0;
	} else {
		int idx = 1;

		/* Cannot change pRetCmd here since it needs to return later. */
		pEntry =
			csr_ll_peek_head(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK);
		if (pEntry) {
			pTempCmd = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
		}
		sms_log(pMac, LOGE,
			"Out of command buffer.... command (0x%X) stuck",
			(pTempCmd) ? pTempCmd->command : eSmeNoCommand);
		if (pTempCmd) {
			if (eSmeCsrCommandMask & pTempCmd->command) {
				/* CSR command is stuck. See what the reason code is for that command */
				dump_csr_command_info(pMac, pTempCmd);
			}
		} /* if(pTempCmd) */

		/* dump what is in the pending queue */
		csr_ll_lock(&pMac->sme.smeCmdPendingList);
		pEntry =
			csr_ll_peek_head(&pMac->sme.smeCmdPendingList,
					 LL_ACCESS_NOLOCK);
		while (pEntry && !sme_command_queue_full) {
			pTempCmd = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
			/* Print only 1st five commands from pending queue. */
			if (idx <= 5)
				sms_log(pMac, LOGE,
					"Out of command buffer.... SME pending command #%d (0x%X)",
					idx, pTempCmd->command);
			idx++;
			if (eSmeCsrCommandMask & pTempCmd->command) {
				/* CSR command is stuck. See what the reason code is for that command */
				dump_csr_command_info(pMac, pTempCmd);
			}
			pEntry =
				csr_ll_next(&pMac->sme.smeCmdPendingList, pEntry,
					    LL_ACCESS_NOLOCK);
		}
		csr_ll_unlock(&pMac->sme.smeCmdPendingList);

		idx = 1;
		/* There may be some more command in CSR's own pending queue */
		csr_ll_lock(&pMac->roam.roamCmdPendingList);
		pEntry =
			csr_ll_peek_head(&pMac->roam.roamCmdPendingList,
					 LL_ACCESS_NOLOCK);
		while (pEntry  && !sme_command_queue_full) {
			pTempCmd = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
			/* Print only 1st five commands from CSR pending queue */
			if (idx <= 5)
				sms_log(pMac, LOGE,
					"Out of command buffer.... "
					"CSR roamCmdPendingList command #%d (0x%X)",
					idx, pTempCmd->command);
			idx++;
			dump_csr_command_info(pMac, pTempCmd);
			pEntry =
				csr_ll_next(&pMac->roam.roamCmdPendingList, pEntry,
					    LL_ACCESS_NOLOCK);
		}

		/* Increment static variable so that it prints
		 * pending command only once
		 */
		sme_command_queue_full++;
		csr_ll_unlock(&pMac->roam.roamCmdPendingList);

		if (pMac->roam.configParam.enable_fatal_event)
			cds_flush_logs(WLAN_LOG_TYPE_FATAL,
				WLAN_LOG_INDICATOR_HOST_DRIVER,
				WLAN_LOG_REASON_SME_OUT_OF_CMD_BUF,
				false,
				pMac->sme.enableSelfRecovery ? true : false);
		else if (pMac->sme.enableSelfRecovery)
			cds_trigger_recovery();
		else
			QDF_BUG(0);
	}

	/* memset to zero */
	if (pRetCmd) {
		qdf_mem_set((uint8_t *)&pRetCmd->command,
			    sizeof(pRetCmd->command), 0);
		qdf_mem_set((uint8_t *)&pRetCmd->sessionId,
			    sizeof(pRetCmd->sessionId), 0);
		qdf_mem_set((uint8_t *)&pRetCmd->u, sizeof(pRetCmd->u), 0);
	}

	return pRetCmd;
}

void sme_push_command(tpAniSirGlobal pMac, tSmeCmd *pCmd, bool fHighPriority)
{
	if (!SME_IS_START(pMac)) {
		sms_log(pMac, LOGE, FL("Sme in stop state"));
		QDF_ASSERT(0);
		return;
	}

	if (fHighPriority) {
		csr_ll_insert_head(&pMac->sme.smeCmdPendingList, &pCmd->Link,
				   LL_ACCESS_LOCK);
	} else {
		csr_ll_insert_tail(&pMac->sme.smeCmdPendingList, &pCmd->Link,
				   LL_ACCESS_LOCK);
	}

	/* process the command queue... */
	sme_process_pending_queue(pMac);

	return;
}

/* For commands that need to do extra cleanup. */
static void sme_abort_command(tpAniSirGlobal pMac, tSmeCmd *pCommand,
			      bool fStopping)
{
	if (eSmePmcCommandMask & pCommand->command) {
		sms_log(pMac, LOG1,
				"No need to process PMC commands");
		return;
	}
	if (eSmeCsrCommandMask & pCommand->command) {
		csr_abort_command(pMac, pCommand, fStopping);
		return;
	}
	switch (pCommand->command) {
	case eSmeCommandRemainOnChannel:
		if (NULL != pCommand->u.remainChlCmd.callback) {
			remainOnChanCallback callback =
				pCommand->u.remainChlCmd.callback;
			/* process the msg */
			if (callback) {
				callback(pMac, pCommand->u.remainChlCmd.
					callbackCtx, eCSR_SCAN_ABORT,
					pCommand->u.remainChlCmd.scan_id);
			}
		}
		sme_release_command(pMac, pCommand);
		break;
	default:
		sme_release_command(pMac, pCommand);
		break;
	}

}

tListElem *csr_get_cmd_to_process(tpAniSirGlobal pMac, tDblLinkList *pList,
				  uint8_t sessionId, bool fInterlocked)
{
	tListElem *pCurEntry = NULL;
	tSmeCmd *pCommand;

	/* Go through the list and return the command whose session id is not
	 * matching with the current ongoing scan cmd sessionId */
	pCurEntry = csr_ll_peek_head(pList, LL_ACCESS_LOCK);
	while (pCurEntry) {
		pCommand = GET_BASE_ADDR(pCurEntry, tSmeCmd, Link);
		if (pCommand->sessionId != sessionId) {
			sms_log(pMac, LOG1,
				"selected the command with different sessionId");
			return pCurEntry;
		}

		pCurEntry = csr_ll_next(pList, pCurEntry, fInterlocked);
	}

	sms_log(pMac, LOG1, "No command pending with different sessionId");
	return NULL;
}

bool sme_process_scan_queue(tpAniSirGlobal pMac)
{
	tListElem *pEntry;
	tSmeCmd *pCommand;
	tListElem *pSmeEntry = NULL;
	tSmeCmd *pSmeCommand = NULL;
	bool status = true;

	if ((!csr_ll_is_list_empty(&pMac->sme.smeCmdActiveList,
				   LL_ACCESS_LOCK))) {
		pSmeEntry = csr_ll_peek_head(&pMac->sme.smeCmdActiveList,
					LL_ACCESS_LOCK);
		if (pSmeEntry)
			pSmeCommand = GET_BASE_ADDR(pSmeEntry, tSmeCmd, Link);
	}
	csr_ll_lock(&pMac->sme.smeScanCmdActiveList);
	if (csr_ll_is_list_empty(&pMac->sme.smeScanCmdPendingList,
				 LL_ACCESS_LOCK))
		goto end;
	pEntry = csr_ll_peek_head(&pMac->sme.smeScanCmdPendingList,
				  LL_ACCESS_LOCK);
	if (!pEntry)
		goto end;

	sms_log(pMac, LOGE,
		FL("scan_count in active scanlist %d "),
		pMac->sme.smeScanCmdActiveList.Count);

	pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
	if (pSmeCommand != NULL) {
		/*
		 * if scan is running on one interface and SME receives
		 * the next command on the same interface then
		 * dont the allow the command to be queued to
		 * smeCmdPendingList. If next scan is allowed on
		 * the same interface the CSR state machine will
		 * get screwed up.
		 */
		if (pSmeCommand->sessionId == pCommand->sessionId) {
			status = false;
			goto end;
		}
	}
	/*
	 * We cannot execute any command in wait-for-key state until setKey is
	 * through.
	 */
	if (CSR_IS_WAIT_FOR_KEY(pMac, pCommand->sessionId)) {
		if (!CSR_IS_SET_KEY_COMMAND(pCommand)) {
			sms_log(pMac, LOGE,
				FL("Can't process cmd(%d), waiting for key"),
				pCommand->command);
			status = false;
			goto end;
		}
	}
	if (csr_ll_remove_entry(&pMac->sme.smeScanCmdPendingList, pEntry,
				LL_ACCESS_LOCK)) {
		csr_ll_insert_head(&pMac->sme.smeScanCmdActiveList,
				   &pCommand->Link, LL_ACCESS_NOLOCK);
		switch (pCommand->command) {
		case eSmeCommandScan:
			sms_log(pMac, LOG1, FL("Processing scan offload cmd."));
			qdf_mc_timer_start(&pCommand->u.scanCmd.csr_scan_timer,
				CSR_ACTIVE_SCAN_LIST_CMD_TIMEOUT);
			csr_process_scan_command(pMac, pCommand);
			break;
		case eSmeCommandRemainOnChannel:
			sms_log(pMac, LOG1,
				FL("Processing remain on channel offload cmd"));
			p2p_process_remain_on_channel_cmd(pMac, pCommand);
			break;
		default:
			sms_log(pMac, LOGE,
				FL("Wrong cmd enqueued to ScanCmdPendingList"));
			pEntry = csr_ll_remove_head(
					&pMac->sme.smeScanCmdActiveList,
					LL_ACCESS_NOLOCK);
			pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
			sme_release_command(pMac, pCommand);
			break;
		}
	}
end:
	csr_ll_unlock(&pMac->sme.smeScanCmdActiveList);
	return status;
}

/**
 * sme_process_command() - processes SME commnd
 * @mac_ctx:       mac global context
 *
 * This function is called by sme_process_pending_queue() in a while loop
 *
 * Return: true indicates that caller function can proceed to next cmd
 *         false otherwise.
 */
bool sme_process_command(tpAniSirGlobal pMac)
{
	bool fContinue = false;
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tListElem *pEntry;
	tSmeCmd *pCommand;
	tListElem *pSmeEntry;
	tSmeCmd *pSmeCommand;

	/*
	 * if the ActiveList is empty, then nothing is active so we can process
	 * a pending command...
	 * alwasy lock active list before locking pending list
	 */
	csr_ll_lock(&pMac->sme.smeCmdActiveList);
	if (!csr_ll_is_list_empty(&pMac->sme.smeCmdActiveList,
				 LL_ACCESS_NOLOCK)) {
		csr_ll_unlock(&pMac->sme.smeCmdActiveList);
		goto process_scan_q;
	}

	if (csr_ll_is_list_empty(&pMac->sme.smeCmdPendingList,
				 LL_ACCESS_LOCK)) {
		/* No command waiting */
		csr_ll_unlock(&pMac->sme.smeCmdActiveList);
		goto process_scan_q;
	}

	/*
	 * If scan command is pending in the smeScanCmdActive list then pick the
	 * command from smeCmdPendingList which is not matching with the scan
	 * command session id. At any point of time only one command will be
	 * allowed on a single session.
	 */
	if (!csr_ll_is_list_empty(
			&pMac->sme.smeScanCmdActiveList, LL_ACCESS_LOCK)) {
		pSmeEntry = csr_ll_peek_head(&pMac->sme.smeScanCmdActiveList,
					     LL_ACCESS_LOCK);
		if (pSmeEntry) {
			pSmeCommand = GET_BASE_ADDR(pSmeEntry, tSmeCmd, Link);
			pEntry = csr_get_cmd_to_process(pMac,
					&pMac->sme.smeCmdPendingList,
					pSmeCommand->sessionId,
					LL_ACCESS_LOCK);
			goto sme_process_cmd;
		}
	}

	/* Peek the command */
	pEntry = csr_ll_peek_head(&pMac->sme.smeCmdPendingList, LL_ACCESS_LOCK);
sme_process_cmd:
	if (!pEntry) {
		csr_ll_unlock(&pMac->sme.smeCmdActiveList);
		goto process_scan_q;
	}
	pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
	/*
	 * Allow only disconnect command in wait-for-key state until setKey is
	 * through.
	 */
	if (CSR_IS_WAIT_FOR_KEY(pMac, pCommand->sessionId)
	    && !CSR_IS_DISCONNECT_COMMAND(pCommand)
	    && !CSR_IS_SET_KEY_COMMAND(pCommand)) {
		if (CSR_IS_CLOSE_SESSION_COMMAND(pCommand)) {
			tSmeCmd *sme_cmd = NULL;

			sms_log(pMac, LOGE,
				FL("SessionId %d: close session command issued while waiting for key, issue disconnect first"),
				pCommand->sessionId);
			status = csr_prepare_disconnect_command(pMac,
					pCommand->sessionId, &sme_cmd);
			if (status == QDF_STATUS_SUCCESS && sme_cmd) {
				csr_ll_lock(&pMac->sme.smeCmdPendingList);
				csr_ll_insert_head(&pMac->sme.smeCmdPendingList,
					&sme_cmd->Link, LL_ACCESS_NOLOCK);
				pEntry = csr_ll_peek_head(
						&pMac->sme.smeCmdPendingList,
						LL_ACCESS_NOLOCK);
				csr_ll_unlock(&pMac->sme.smeCmdPendingList);
				goto sme_process_cmd;
			}
		}

		csr_ll_unlock(&pMac->sme.smeCmdActiveList);
		sms_log(pMac, LOGE,
			FL("SessionId %d: Can't process cmd(%d), waiting for key"),
			pCommand->sessionId, pCommand->command);
		fContinue = false;
		goto process_scan_q;
	}

	if (!csr_ll_remove_entry(&pMac->sme.smeCmdPendingList, pEntry,
				LL_ACCESS_LOCK)) {
		/* This is odd. Some one else pull off the command. */
		csr_ll_unlock(&pMac->sme.smeCmdActiveList);
		goto process_scan_q;
	}
	/* we can reuse the pCommand. Insert the command onto the ActiveList */
	csr_ll_insert_head(&pMac->sme.smeCmdActiveList, &pCommand->Link,
			   LL_ACCESS_NOLOCK);
	/* .... and process the command. */
	MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_COMMAND,
			 pCommand->sessionId, pCommand->command));

	switch (pCommand->command) {
	case eSmeCommandScan:
		csr_ll_unlock(&pMac->sme.smeCmdActiveList);
		status = csr_process_scan_command(pMac, pCommand);
		break;
	case eSmeCommandRoam:
		csr_ll_unlock(&pMac->sme.smeCmdActiveList);
		status = csr_roam_process_command(pMac, pCommand);
		if (!QDF_IS_STATUS_SUCCESS(status)
		    && csr_ll_remove_entry(&pMac->sme.smeCmdActiveList,
				&pCommand->Link, LL_ACCESS_LOCK))
			csr_release_command_roam(pMac, pCommand);
		break;
	case eSmeCommandWmStatusChange:
		csr_ll_unlock(&pMac->sme.smeCmdActiveList);
		csr_roam_process_wm_status_change_command(pMac, pCommand);
		break;
	case eSmeCommandSetKey:
		csr_ll_unlock(&pMac->sme.smeCmdActiveList);
		status = csr_roam_process_set_key_command(pMac, pCommand);
		if (!QDF_IS_STATUS_SUCCESS(status)
		    && csr_ll_remove_entry(&pMac->sme.smeCmdActiveList,
				&pCommand->Link, LL_ACCESS_LOCK)) {
			csr_release_command_set_key(pMac, pCommand);
		}
		break;
	case eSmeCommandAddStaSession:
		csr_ll_unlock(&pMac->sme.smeCmdActiveList);
		csr_process_add_sta_session_command(pMac, pCommand);
		break;
	case eSmeCommandNdpInitiatorRequest:
		csr_ll_unlock(&pMac->sme.smeCmdActiveList);
		if (csr_process_ndp_initiator_request(pMac, pCommand) !=
			QDF_STATUS_SUCCESS)
			if (csr_ll_remove_entry(
				&pMac->sme.smeCmdActiveList,
				&pCommand->Link, LL_ACCESS_LOCK))
				csr_release_command(pMac, pCommand);
		break;
	case eSmeCommandNdpResponderRequest:
		csr_ll_unlock(&pMac->sme.smeCmdActiveList);
		status = csr_process_ndp_responder_request(pMac, pCommand);
		if (status != QDF_STATUS_SUCCESS) {
			if (csr_ll_remove_entry(&pMac->sme.smeCmdActiveList,
					&pCommand->Link, LL_ACCESS_LOCK))
				csr_release_command(pMac, pCommand);
		}
		break;
	case eSmeCommandNdpDataEndInitiatorRequest:
		csr_ll_unlock(&pMac->sme.smeCmdActiveList);
		status = csr_process_ndp_data_end_request(pMac, pCommand);
		if (status != QDF_STATUS_SUCCESS) {
			if (csr_ll_remove_entry(&pMac->sme.smeCmdActiveList,
					&pCommand->Link, LL_ACCESS_LOCK))
				csr_release_command(pMac, pCommand);
		}
		break;
	case eSmeCommandDelStaSession:
		csr_ll_unlock(&pMac->sme.smeCmdActiveList);
		csr_process_del_sta_session_command(pMac, pCommand);
		break;
	case eSmeCommandRemainOnChannel:
		csr_ll_unlock(&pMac->sme.smeCmdActiveList);
		p2p_process_remain_on_channel_cmd(pMac, pCommand);
		break;
	/*
	 * Treat standby differently here because caller may not be able
	 * to handle the failure so we do our best here
	 */
	case eSmeCommandEnterStandby:
		break;
	case eSmeCommandAddTs:
	case eSmeCommandDelTs:
		csr_ll_unlock(&pMac->sme.smeCmdActiveList);
#ifndef WLAN_MDM_CODE_REDUCTION_OPT
		fContinue = qos_process_command(pMac, pCommand);
		if (fContinue && csr_ll_remove_entry(
			&pMac->sme.smeCmdActiveList,
			&pCommand->Link, LL_ACCESS_NOLOCK)) {
			/* The command failed, remove it */
			qos_release_command(pMac, pCommand);
		}
#endif
		break;
#ifdef FEATURE_WLAN_TDLS
	case eSmeCommandTdlsSendMgmt:
	case eSmeCommandTdlsAddPeer:
	case eSmeCommandTdlsDelPeer:
	case eSmeCommandTdlsLinkEstablish:
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
			  FL("sending TDLS Command 0x%x to PE"),
			  pCommand->command);
		csr_ll_unlock(&pMac->sme.smeCmdActiveList);
		status = csr_tdls_process_cmd(pMac, pCommand);
		break;
#endif
	case e_sme_command_set_hw_mode:
		csr_ll_unlock(&pMac->sme.smeCmdActiveList);
		csr_process_set_hw_mode(pMac, pCommand);
		break;
	case e_sme_command_nss_update:
		csr_ll_unlock(&pMac->sme.smeCmdActiveList);
		csr_process_nss_update_req(pMac, pCommand);
		break;
	case e_sme_command_set_dual_mac_config:
		csr_ll_unlock(&pMac->sme.smeCmdActiveList);
		csr_process_set_dual_mac_config(pMac, pCommand);
		break;
	case e_sme_command_set_antenna_mode:
		csr_ll_unlock(&pMac->sme.smeCmdActiveList);
		csr_process_set_antenna_mode(pMac, pCommand);
		break;
	default:
		/* something is wrong */
		/* remove it from the active list */
		sms_log(pMac, LOGE, FL("unknown command %d"),
			pCommand->command);
		pEntry = csr_ll_remove_head(&pMac->sme.smeCmdActiveList,
					    LL_ACCESS_NOLOCK);
		csr_ll_unlock(&pMac->sme.smeCmdActiveList);
		pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
		sme_release_command(pMac, pCommand);
		status = QDF_STATUS_E_FAILURE;
		break;
	}
	if (!QDF_IS_STATUS_SUCCESS(status))
		fContinue = true;
process_scan_q:
	if (!(sme_process_scan_queue(pMac)))
		fContinue = false;
	return fContinue;
}

void sme_process_pending_queue(tpAniSirGlobal pMac)
{
	while (sme_process_command(pMac))
	;
}

bool sme_command_pending(tpAniSirGlobal pMac)
{
	return !csr_ll_is_list_empty(&pMac->sme.smeCmdActiveList, LL_ACCESS_NOLOCK)
		|| !csr_ll_is_list_empty(&pMac->sme.smeCmdPendingList,
					 LL_ACCESS_NOLOCK);
}

/* Global APIs */

/**
 * sme_open() - Initialze all SME modules and put them at idle state
 * @hHal:       The handle returned by mac_open
 *
 * The function initializes each module inside SME, PMC, CSR, etc. Upon
 * successfully return, all modules are at idle state ready to start.
 * smeOpen must be called before any other SME APIs can be involved.
 * smeOpen must be called after mac_open.
 *
 * Return: QDF_STATUS_SUCCESS - SME is successfully initialized.
 *         Other status means SME is failed to be initialized
 */
QDF_STATUS sme_open(tHalHandle hHal)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	pMac->sme.state = SME_STATE_STOP;
	pMac->sme.currDeviceMode = QDF_STA_MODE;
	if (!QDF_IS_STATUS_SUCCESS(qdf_mutex_create(
					&pMac->sme.lkSmeGlobalLock))) {
		sms_log(pMac, LOGE, FL("sme_open failed init lock"));
		return  QDF_STATUS_E_FAILURE;
	}
	status = csr_open(pMac);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		sms_log(pMac, LOGE, FL("csr_open failed, status=%d"), status);
		return status;
	}

	status = sme_ps_open(hHal);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		sms_log(pMac, LOGE,
		FL("sme_ps_open failed during initialization with status=%d"),
			status);
		return status;
	}
#ifdef FEATURE_WLAN_TDLS
	pMac->is_tdls_power_save_prohibited = 0;
#endif

#ifndef WLAN_MDM_CODE_REDUCTION_OPT
	status = sme_qos_open(pMac);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		sms_log(pMac, LOGE, FL("Qos open, status=%d"), status);
		return status;
	}
#endif
	status = init_sme_cmd_list(pMac);
	if (!QDF_IS_STATUS_SUCCESS(status))
		return status;

	status = rrm_open(pMac);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		sms_log(pMac, LOGE, FL("rrm_open failed, status=%d"), status);
		return status;
	}
	sme_p2p_open(pMac);
	sme_trace_init(pMac);
	return status;
}

/*
 * sme_init_chan_list, triggers channel setup based on country code.
 */
QDF_STATUS sme_init_chan_list(tHalHandle hal, uint8_t *alpha2,
			      enum country_src cc_src)
{
	tpAniSirGlobal pmac = PMAC_STRUCT(hal);

	if ((cc_src == SOURCE_USERSPACE) &&
	    (pmac->roam.configParam.fSupplicantCountryCodeHasPriority)) {
		pmac->roam.configParam.Is11dSupportEnabled = false;
	}

	return csr_init_chan_list(pmac, alpha2);
}

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

   \brief sme_set11dinfo() - Set the 11d information about valid channels
   and there power using information from nvRAM
   This function is called only for AP.

   This is a synchronous call

   \param hHal - The handle returned by mac_open.
   \Param pSmeConfigParams - a pointer to a caller allocated object of
   typedef struct _smeConfigParams.

   \return QDF_STATUS_SUCCESS - SME update the config parameters successfully.

   Other status means SME is failed to update the config parameters.
   \sa
   --------------------------------------------------------------------------*/

QDF_STATUS sme_set11dinfo(tHalHandle hHal, tpSmeConfigParams pSmeConfigParams)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_MSG_SET_11DINFO, NO_SESSION, 0));
	if (NULL == pSmeConfigParams) {
		sms_log(pMac, LOGE,
			"Empty config param structure for SME, nothing to update");
		return status;
	}

	status = csr_set_channels(hHal, &pSmeConfigParams->csrConfig);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		sms_log(pMac, LOGE,
			"csr_change_default_config_param failed with status=%d",
			status);
	}
	return status;
}

/**
 * sme_set_scan_disable() - Dynamically enable/disable scan
 * @h_hal: Handle to HAL
 *
 * This command gives the user an option to dynamically
 * enable or disable scans.
 *
 * Return: None
 */
void sme_set_scan_disable(tHalHandle h_hal, int value)
{
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(h_hal);
	mac_ctx->lim.scan_disabled = value;
	sms_log(mac_ctx, LOG1, FL("value=%d"), value);
}
/*--------------------------------------------------------------------------

   \brief sme_get_soft_ap_domain() - Get the current regulatory domain of softAp.

   This is a synchronous call

   \param hHal - The handle returned by HostapdAdapter.
   \Param v_REGDOMAIN_t - The current Regulatory Domain requested for SoftAp.

   \return QDF_STATUS_SUCCESS - SME successfully completed the request.

   Other status means, failed to get the current regulatory domain.
   \sa
   --------------------------------------------------------------------------*/

QDF_STATUS sme_get_soft_ap_domain(tHalHandle hHal, v_REGDOMAIN_t *domainIdSoftAp)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_MSG_GET_SOFTAP_DOMAIN,
			 NO_SESSION, 0));
	if (NULL == domainIdSoftAp) {
		sms_log(pMac, LOGE, "Uninitialized domain Id");
		return status;
	}

	*domainIdSoftAp = pMac->scan.domainIdCurrent;
	status = QDF_STATUS_SUCCESS;

	return status;
}

QDF_STATUS sme_set_reg_info(tHalHandle hHal, uint8_t *apCntryCode)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_MSG_SET_REGINFO, NO_SESSION, 0));
	if (NULL == apCntryCode) {
		sms_log(pMac, LOGE, "Empty Country Code, nothing to update");
		return status;
	}

	status = csr_set_reg_info(hHal, apCntryCode);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		sms_log(pMac, LOGE, "csr_set_reg_info failed with status=%d",
			status);
	}
	return status;
}

/**
 * sme_update_fine_time_measurement_capab() - Update the FTM capabitlies from
 * incoming val
 * @hal: Handle for Hal layer
 * @val: New FTM capability value
 *
 * Return: None
 */
void sme_update_fine_time_measurement_capab(tHalHandle hal, uint32_t val)
{
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
	mac_ctx->fine_time_meas_cap = val;

	if (val == 0) {
		mac_ctx->rrm.rrmPEContext.rrmEnabledCaps.fine_time_meas_rpt = 0;
		((tpRRMCaps)mac_ctx->rrm.rrmSmeContext.
			rrmConfig.rm_capability)->fine_time_meas_rpt = 0;
	} else {
		mac_ctx->rrm.rrmPEContext.rrmEnabledCaps.fine_time_meas_rpt = 1;
		((tpRRMCaps)mac_ctx->rrm.rrmSmeContext.
			rrmConfig.rm_capability)->fine_time_meas_rpt = 1;
	}
}

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

   \brief sme_update_config() - Change configurations for all SME moduels

   The function updates some configuration for modules in SME, CSR, etc
   during SMEs close open sequence.

   Modules inside SME apply the new configuration at the next transaction.

   This is a synchronous call

   \param hHal - The handle returned by mac_open.
   \Param pSmeConfigParams - a pointer to a caller allocated object of
   typedef struct _smeConfigParams.

   \return QDF_STATUS_SUCCESS - SME update the config parameters successfully.

   Other status means SME is failed to update the config parameters.
   \sa

   --------------------------------------------------------------------------*/
QDF_STATUS sme_update_config(tHalHandle hHal, tpSmeConfigParams pSmeConfigParams)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_MSG_UPDATE_CONFIG, NO_SESSION,
			 0));
	if (NULL == pSmeConfigParams) {
		sms_log(pMac, LOGE,
			"Empty config param structure for SME, nothing to update");
		return status;
	}

	status =
		csr_change_default_config_param(pMac, &pSmeConfigParams->csrConfig);

	if (!QDF_IS_STATUS_SUCCESS(status)) {
		sms_log(pMac, LOGE,
			"csr_change_default_config_param failed with status=%d",
			status);
	}
	status =
		rrm_change_default_config_param(hHal, &pSmeConfigParams->rrmConfig);

	if (!QDF_IS_STATUS_SUCCESS(status)) {
		sms_log(pMac, LOGE,
			"rrm_change_default_config_param failed with status=%d",
			status);
	}
	/* For SOC, CFG is set before start */
	/* We don't want to apply global CFG in connect state because that may cause some side affect */
	if (csr_is_all_session_disconnected(pMac)) {
		csr_set_global_cfgs(pMac);
	}

	/*
	 * If scan offload is enabled then lim has allow the sending of
	 * scan request to firmware even in powersave mode. The firmware has
	 * to take care of exiting from power save mode
	 */
	status = sme_cfg_set_int(hHal, WNI_CFG_SCAN_IN_POWERSAVE, true);

	if (QDF_STATUS_SUCCESS != status) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "Could not pass on WNI_CFG_SCAN_IN_POWERSAVE to CFG");
	}
	return status;
}

/**
 * sme_update_roam_params() - Store/Update the roaming params
 * @hal:                      Handle for Hal layer
 * @session_id:               SME Session ID
 * @roam_params_src:          The source buffer to copy
 * @update_param:             Type of parameter to be updated
 *
 * Return: Return the status of the updation.
 */
QDF_STATUS sme_update_roam_params(tHalHandle hal,
	uint8_t session_id, struct roam_ext_params roam_params_src,
	int update_param)
{
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
	struct roam_ext_params *roam_params_dst;
	uint8_t i;

	roam_params_dst = &mac_ctx->roam.configParam.roam_params;
	switch (update_param) {
	case REASON_ROAM_EXT_SCAN_PARAMS_CHANGED:
		roam_params_dst->raise_rssi_thresh_5g =
			roam_params_src.raise_rssi_thresh_5g;
		roam_params_dst->drop_rssi_thresh_5g =
			roam_params_src.drop_rssi_thresh_5g;
		roam_params_dst->raise_factor_5g =
			roam_params_src.raise_factor_5g;
		roam_params_dst->drop_factor_5g =
			roam_params_src.drop_factor_5g;
		roam_params_dst->max_raise_rssi_5g =
			roam_params_src.max_raise_rssi_5g;
		roam_params_dst->max_drop_rssi_5g =
			roam_params_src.max_drop_rssi_5g;
		roam_params_dst->alert_rssi_threshold =
			roam_params_src.alert_rssi_threshold;
		roam_params_dst->is_5g_pref_enabled = true;
		break;
	case REASON_ROAM_SET_SSID_ALLOWED:
		qdf_mem_set(&roam_params_dst->ssid_allowed_list, 0,
				sizeof(tSirMacSSid) * MAX_SSID_ALLOWED_LIST);
		roam_params_dst->num_ssid_allowed_list =
			roam_params_src.num_ssid_allowed_list;
		for (i = 0; i < roam_params_dst->num_ssid_allowed_list; i++) {
			roam_params_dst->ssid_allowed_list[i].length =
				roam_params_src.ssid_allowed_list[i].length;
			qdf_mem_copy(roam_params_dst->ssid_allowed_list[i].ssId,
				roam_params_src.ssid_allowed_list[i].ssId,
				roam_params_dst->ssid_allowed_list[i].length);
		}
		break;
	case REASON_ROAM_SET_FAVORED_BSSID:
		qdf_mem_set(&roam_params_dst->bssid_favored, 0,
			sizeof(tSirMacAddr) * MAX_BSSID_FAVORED);
		roam_params_dst->num_bssid_favored =
			roam_params_src.num_bssid_favored;
		for (i = 0; i < roam_params_dst->num_bssid_favored; i++) {
			qdf_mem_copy(&roam_params_dst->bssid_favored[i],
				&roam_params_src.bssid_favored[i],
				sizeof(tSirMacAddr));
			roam_params_dst->bssid_favored_factor[i] =
				roam_params_src.bssid_favored_factor[i];
		}
		break;
	case REASON_ROAM_SET_BLACKLIST_BSSID:
		qdf_mem_set(&roam_params_dst->bssid_avoid_list, 0,
			QDF_MAC_ADDR_SIZE * MAX_BSSID_AVOID_LIST);
		roam_params_dst->num_bssid_avoid_list =
			roam_params_src.num_bssid_avoid_list;
		for (i = 0; i < roam_params_dst->num_bssid_avoid_list; i++) {
			qdf_copy_macaddr(&roam_params_dst->bssid_avoid_list[i],
					&roam_params_src.bssid_avoid_list[i]);
		}
		break;
	case REASON_ROAM_GOOD_RSSI_CHANGED:
		roam_params_dst->good_rssi_roam =
			roam_params_src.good_rssi_roam;
		break;
	default:
		break;
	}
	csr_roam_offload_scan(mac_ctx, session_id, ROAM_SCAN_OFFLOAD_UPDATE_CFG,
			update_param);
	return 0;
}

#ifdef WLAN_FEATURE_GTK_OFFLOAD
void sme_process_get_gtk_info_rsp(tHalHandle hHal,
				  tpSirGtkOffloadGetInfoRspParams
				  pGtkOffloadGetInfoRsp)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	if (NULL == pMac) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_FATAL,
			  "%s: pMac is null", __func__);
		return;
	}
	if (pMac->sme.gtk_offload_get_info_cb == NULL) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "%s: HDD callback is null", __func__);
		return;
	}
	pMac->sme.gtk_offload_get_info_cb(
			pMac->sme.gtk_offload_get_info_cb_context,
			pGtkOffloadGetInfoRsp);
}
#endif

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

   \fn    - sme_process_ready_to_suspend
   \brief - On getting ready to suspend indication, this function calls
	    callback registered (HDD callbacks) with SME to inform
	    ready to suspend indication.

   \param hHal - Handle returned by mac_open.
	  pReadyToSuspend - Parameter received along with ready to suspend
			    indication from WMA.

   \return None

   \sa

   --------------------------------------------------------------------------*/
void sme_process_ready_to_suspend(tHalHandle hHal,
				  tpSirReadyToSuspendInd pReadyToSuspend)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	if (NULL == pMac) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_FATAL,
			  "%s: pMac is null", __func__);
		return;
	}

	if (NULL != pMac->readyToSuspendCallback) {
		pMac->readyToSuspendCallback(pMac->readyToSuspendContext,
					     pReadyToSuspend->suspended);
		pMac->readyToSuspendCallback = NULL;
	}
}

#ifdef WLAN_FEATURE_EXTWOW_SUPPORT

/**
 * sme_process_ready_to_ext_wow() - inform ready to ExtWoW indication.
 * @hHal - Handle returned by mac_open.
 * @pReadyToExtWoW - Parameter received along with ready to Ext WoW
 *		     indication from WMA.
 *
 * On getting ready to Ext WoW indication, this function calls callback
 * registered (HDD callback)with SME to inform ready to ExtWoW indication.
 *
 * Return: None
 */
void sme_process_ready_to_ext_wow(tHalHandle hHal,
				   tpSirReadyToExtWoWInd pReadyToExtWoW)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	if (NULL == pMac) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_FATAL,
			  "%s: pMac is null", __func__);
		return;
	}

	if (NULL != pMac->readyToExtWoWCallback) {
		pMac->readyToExtWoWCallback(pMac->readyToExtWoWContext,
					    pReadyToExtWoW->status);
		pMac->readyToExtWoWCallback = NULL;
		pMac->readyToExtWoWContext = NULL;
	}

}
#endif

/* ---------------------------------------------------------------------------
    \fn sme_change_config_params
    \brief The SME API exposed for HDD to provide config params to SME during
    SMEs stop -> start sequence.

    If HDD changed the domain that will cause a reset. This function will
    provide the new set of 11d information for the new domain. Currrently this
    API provides info regarding 11d only at reset but we can extend this for
    other params (PMC, QoS) which needs to be initialized again at reset.

    This is a synchronous call

    \param hHal - The handle returned by mac_open.

    \Param
    pUpdateConfigParam - a pointer to a structure (tCsrUpdateConfigParam) that
		currently provides 11d related information like Country code,
		Regulatory domain, valid channel list, Tx power per channel, a
		list with active/passive scan allowed per valid channel.

    \return QDF_STATUS
   ---------------------------------------------------------------------------*/
QDF_STATUS sme_change_config_params(tHalHandle hHal,
				    tCsrUpdateConfigParam *pUpdateConfigParam)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	if (NULL == pUpdateConfigParam) {
		sms_log(pMac, LOGE,
			"Empty config param structure for SME, nothing to reset");
		return status;
	}

	status = csr_change_config_params(pMac, pUpdateConfigParam);

	if (!QDF_IS_STATUS_SUCCESS(status)) {
		sms_log(pMac, LOGE, "csrUpdateConfigParam failed with status=%d",
			status);
	}

	return status;

}

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

   \brief sme_hdd_ready_ind() - SME sends eWNI_SME_SYS_READY_IND to PE to inform
   that the NIC is ready tio run.

   The function is called by HDD at the end of initialization stage so PE/HAL can
   enable the NIC to running state.

   This is a synchronous call
   \param hHal - The handle returned by mac_open.

   \return QDF_STATUS_SUCCESS - eWNI_SME_SYS_READY_IND is sent to PE
				successfully.

   Other status means SME failed to send the message to PE.
   \sa

   --------------------------------------------------------------------------*/
QDF_STATUS sme_hdd_ready_ind(tHalHandle hHal)
{
	tSirSmeReadyReq Msg;
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_MSG_HDDREADYIND, NO_SESSION, 0));
	do {

		Msg.messageType = eWNI_SME_SYS_READY_IND;
		Msg.length = sizeof(tSirSmeReadyReq);
		Msg.add_bssdescr_cb = csr_scan_process_single_bssdescr;
		Msg.csr_roam_synch_cb = csr_roam_synch_callback;


		if (eSIR_FAILURE != u_mac_post_ctrl_msg(hHal, (tSirMbMsg *) &Msg)) {
			status = QDF_STATUS_SUCCESS;
		} else {
			sms_log(pMac, LOGE,
				"u_mac_post_ctrl_msg failed to send eWNI_SME_SYS_READY_IND");
			break;
		}

		status = csr_ready(pMac);
		if (!QDF_IS_STATUS_SUCCESS(status)) {
			sms_log(pMac, LOGE,
				"csr_ready failed with status=%d",
				status);
			break;
		}

		if (QDF_STATUS_SUCCESS != rrm_ready(hHal)) {
			status = QDF_STATUS_E_FAILURE;
			sms_log(pMac, LOGE, "rrm_ready failed");
			break;
		}
		pMac->sme.state = SME_STATE_READY;
	} while (0);

	return status;
}

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

   \brief sme_start() - Put all SME modules at ready state.

   The function starts each module in SME, PMC, CSR, etc. . Upon
   successfully return, all modules are ready to run.
   This is a synchronous call
   \param hHal - The handle returned by mac_open.

   \return QDF_STATUS_SUCCESS - SME is ready.

   Other status means SME is failed to start
   \sa

   --------------------------------------------------------------------------*/
QDF_STATUS sme_start(tHalHandle hHal)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	do {
		status = csr_start(pMac);
		if (!QDF_IS_STATUS_SUCCESS(status)) {
			sms_log(pMac, LOGE,
				"csr_start failed during smeStart with status=%d",
				status);
			break;
		}
		pMac->sme.state = SME_STATE_START;
	} while (0);

	return status;
}

/**
 * sme_handle_scan_req() - Scan request handler
 * @mac_ctx: MAC global context
 * @msg: message buffer
 *
 * Scan request message from upper layer is handled as
 * part of this API
 *
 * Return: QDF_STATUS
 */
static QDF_STATUS sme_handle_scan_req(tpAniSirGlobal mac_ctx,
					void *msg)
{
	struct ani_scan_req *scan_msg;
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	uint16_t session_id;
	csr_scan_completeCallback callback;

	scan_msg = msg;
	session_id = scan_msg->session_id;
	callback = scan_msg->callback;
	status = csr_scan_request(mac_ctx, session_id,
		scan_msg->scan_param,
		callback, scan_msg->ctx);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		sms_log(mac_ctx, LOGE,
			FL("scan request failed. session_id %d"), session_id);
	}
	csr_scan_free_request(mac_ctx, scan_msg->scan_param);
	qdf_mem_free(scan_msg->scan_param);
	return status;
}

/**
 * sme_handle_roc_req() - Roc request handler
 * @mac_ctx: MAC global context
 * @msg: message buffer
 *
 * Roc request message from upper layer is handled as
 * part of this API
 *
 * Return: QDF_STATUS
 */
static QDF_STATUS sme_handle_roc_req(tHalHandle hal,
					void *msg)
{
	struct ani_roc_req *roc_msg;
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
	remainOnChanCallback callback;

	if (msg == NULL) {
		sms_log(mac_ctx, LOGE, FL("ROC request is NULL"));
		return status;
	}

	roc_msg = msg;
	callback = roc_msg->callback;
	status = p2p_remain_on_channel(hal, roc_msg->session_id,
		roc_msg->channel, roc_msg->duration, callback,
		roc_msg->ctx, roc_msg->is_p2pprobe_allowed,
		roc_msg->scan_id);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		sms_log(mac_ctx, LOGE,
			FL("scan request failed. session_id %d scan_id %d"),
			roc_msg->session_id, roc_msg->scan_id);
	}
	return status;
}

#ifdef WLAN_FEATURE_11W
/*------------------------------------------------------------------
 *
 * Handle the unprotected management frame indication from LIM and
 * forward it to HDD.
 *
 *------------------------------------------------------------------*/

QDF_STATUS sme_unprotected_mgmt_frm_ind(tHalHandle hHal,
					tpSirSmeUnprotMgmtFrameInd pSmeMgmtFrm)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tCsrRoamInfo pRoamInfo = { 0 };
	uint32_t SessionId = pSmeMgmtFrm->sessionId;

	pRoamInfo.nFrameLength = pSmeMgmtFrm->frameLen;
	pRoamInfo.pbFrames = pSmeMgmtFrm->frameBuf;
	pRoamInfo.frameType = pSmeMgmtFrm->frameType;

	/* forward the mgmt frame to HDD */
	csr_roam_call_callback(pMac, SessionId, &pRoamInfo, 0,
			       eCSR_ROAM_UNPROT_MGMT_FRAME_IND, 0);

	return status;
}
#endif

/*------------------------------------------------------------------
 *
 * Handle the DFS Radar Event and indicate it to the SAP
 *
 *------------------------------------------------------------------*/
QDF_STATUS dfs_msg_processor(tpAniSirGlobal pMac, uint16_t msgType, void *pMsgBuf)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tCsrRoamInfo roamInfo = { 0 };
	tSirSmeDfsEventInd *dfs_event;
	tSirSmeCSAIeTxCompleteRsp *csaIeTxCompleteRsp;
	uint32_t sessionId = 0;
	eRoamCmdStatus roamStatus;
	eCsrRoamResult roamResult;
	int i;

	switch (msgType) {
	case eWNI_SME_DFS_RADAR_FOUND:
	{
		/* Radar found !! */
		dfs_event = (tSirSmeDfsEventInd *) pMsgBuf;
		if (NULL == dfs_event) {
			sms_log(pMac, LOGE,
				"%s: pMsg is NULL for eWNI_SME_DFS_RADAR_FOUND message",
				__func__);
			return QDF_STATUS_E_FAILURE;
		}
		sessionId = dfs_event->sessionId;
		roamInfo.dfs_event.sessionId = sessionId;
		roamInfo.dfs_event.chan_list.nchannels =
			dfs_event->chan_list.nchannels;
		for (i = 0; i < dfs_event->chan_list.nchannels; i++) {
			roamInfo.dfs_event.chan_list.channels[i] =
				dfs_event->chan_list.channels[i];
		}

		roamInfo.dfs_event.dfs_radar_status =
			dfs_event->dfs_radar_status;
		roamInfo.dfs_event.use_nol = dfs_event->use_nol;

		roamStatus = eCSR_ROAM_DFS_RADAR_IND;
		roamResult = eCSR_ROAM_RESULT_DFS_RADAR_FOUND_IND;
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO_MED,
			  "sapdfs: Radar indication event occurred");
		break;
	}
	case eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND:
	{
		csaIeTxCompleteRsp =
			(tSirSmeCSAIeTxCompleteRsp *) pMsgBuf;
		if (NULL == csaIeTxCompleteRsp) {
			sms_log(pMac, LOGE,
				"%s: pMsg is NULL for eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND",
				__func__);
			return QDF_STATUS_E_FAILURE;
		}
		sessionId = csaIeTxCompleteRsp->sessionId;
		roamStatus = eCSR_ROAM_DFS_CHAN_SW_NOTIFY;
		roamResult = eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_SUCCESS;
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO_MED,
			  "sapdfs: Received eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND for session id [%d]",
			  sessionId);
		break;
	}
	default:
	{
		sms_log(pMac, LOG1, "%s: Invalid DFS message = 0x%x",
			__func__, msgType);
		status = QDF_STATUS_E_FAILURE;
		return status;
	}
	}

	/* Indicate Radar Event to SAP */
	csr_roam_call_callback(pMac, sessionId, &roamInfo, 0,
			       roamStatus, roamResult);
	return status;
}

/**
 * sme_extended_change_channel_ind()- function to indicate ECSA
 * action frame is received in lim to SAP
 * @mac_ctx:  pointer to global mac structure
 * @msg_buf: contain new channel and session id.
 *
 * This function is called to post ECSA action frame
 * receive event to SAP.
 *
 * Return: success if msg indicated to SAP else return failure
 */
static QDF_STATUS sme_extended_change_channel_ind(tpAniSirGlobal mac_ctx,
						void *msg_buf)
{
	struct sir_sme_ext_cng_chan_ind *ext_chan_ind;
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	uint32_t session_id = 0;
	tCsrRoamInfo roamInfo = {0};
	eRoamCmdStatus roam_status;
	eCsrRoamResult roam_result;


	ext_chan_ind = msg_buf;
	if (NULL == ext_chan_ind) {
		sms_log(mac_ctx, LOGE,
			FL("pMsg is NULL for eWNI_SME_EXT_CHANGE_CHANNEL_IND"));
		return QDF_STATUS_E_FAILURE;
	}
	session_id = ext_chan_ind->session_id;
	roamInfo.target_channel = ext_chan_ind->new_channel;
	roam_status = eCSR_ROAM_EXT_CHG_CHNL_IND;
	roam_result = eCSR_ROAM_EXT_CHG_CHNL_UPDATE_IND;
	sms_log(mac_ctx, LOG1,
		FL("sapdfs: Received eWNI_SME_EXT_CHANGE_CHANNEL_IND for session id [%d]"),
		session_id);

	/* Indicate Ext Channel Change event to SAP */
	csr_roam_call_callback(mac_ctx, session_id, &roamInfo, 0,
					roam_status, roam_result);
	return status;
}

/**
 * sme_process_fw_mem_dump_rsp - process fw memory dump response from WMA
 *
 * @mac_ctx: pointer to MAC handle.
 * @msg: pointer to received SME msg.
 *
 * This function process the received SME message and calls the corresponding
 * callback which was already registered with SME.
 *
 * Return: None
 */
#ifdef WLAN_FEATURE_MEMDUMP
static void sme_process_fw_mem_dump_rsp(tpAniSirGlobal mac_ctx, cds_msg_t *msg)
{
	if (msg->bodyptr) {
		if (mac_ctx->sme.fw_dump_callback)
			mac_ctx->sme.fw_dump_callback(mac_ctx->hHdd,
				(struct fw_dump_rsp *) msg->bodyptr);
		qdf_mem_free(msg->bodyptr);
	}
}
#else
static void sme_process_fw_mem_dump_rsp(tpAniSirGlobal mac_ctx, cds_msg_t *msg)
{
}
#endif

#ifdef FEATURE_WLAN_ESE
/**
 * sme_update_is_ese_feature_enabled() - enable/disable ESE support at runtime
 * @hHal: HAL handle
 * @sessionId: session id
 * @isEseIniFeatureEnabled: ese ini enabled
 *
 * It is used at in the REG_DYNAMIC_VARIABLE macro definition of
 * isEseIniFeatureEnabled. This is a synchronous call
 *
 * Return: QDF_STATUS enumeration
 */
QDF_STATUS sme_update_is_ese_feature_enabled(tHalHandle hHal,
			uint8_t sessionId, const bool isEseIniFeatureEnabled)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	if (pMac->roam.configParam.isEseIniFeatureEnabled ==
	    isEseIniFeatureEnabled) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
			  "%s: ESE Mode is already enabled or disabled, nothing to do (returning) old(%d) new(%d)",
			  __func__,
			  pMac->roam.configParam.isEseIniFeatureEnabled,
			  isEseIniFeatureEnabled);
		return QDF_STATUS_SUCCESS;
	}

	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
		  "%s: EseEnabled is changed from %d to %d", __func__,
		  pMac->roam.configParam.isEseIniFeatureEnabled,
		  isEseIniFeatureEnabled);
	pMac->roam.configParam.isEseIniFeatureEnabled = isEseIniFeatureEnabled;
	csr_neighbor_roam_update_fast_roaming_enabled(
			pMac, sessionId, isEseIniFeatureEnabled);

	if (true == isEseIniFeatureEnabled)
		sme_update_fast_transition_enabled(hHal, true);

	if (pMac->roam.configParam.isRoamOffloadScanEnabled)
		csr_roam_offload_scan(pMac, sessionId,
				      ROAM_SCAN_OFFLOAD_UPDATE_CFG,
				      REASON_ESE_INI_CFG_CHANGED);

	return QDF_STATUS_SUCCESS;
}

/**
 * sme_set_plm_request() - set plm request
 * @hHal: HAL handle
 * @pPlmReq: Pointer to input plm request
 *
 * Return: QDF_STATUS enumeration
 */
QDF_STATUS sme_set_plm_request(tHalHandle hHal, tpSirPlmReq pPlmReq)
{
	QDF_STATUS status;
	bool ret = false;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	uint8_t ch_list[WNI_CFG_VALID_CHANNEL_LIST] = { 0 };
	uint8_t count, valid_count = 0;
	cds_msg_t msg;
	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, pPlmReq->sessionId);

	status = sme_acquire_global_lock(&pMac->sme);
	if (!QDF_IS_STATUS_SUCCESS(status))
		return status;

	if (!pSession) {
		sms_log(pMac, LOGE, FL("session %d not found"),
			pPlmReq->sessionId);
		sme_release_global_lock(&pMac->sme);
		return QDF_STATUS_E_FAILURE;
	}

	if (!pSession->sessionActive) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  FL("Invalid Sessionid"));
		sme_release_global_lock(&pMac->sme);
		return QDF_STATUS_E_FAILURE;
	}

	if (!pPlmReq->enable)
		goto send_plm_start;
	/* validating channel numbers */
	for (count = 0; count < pPlmReq->plmNumCh; count++) {
		ret = csr_is_supported_channel(pMac, pPlmReq->plmChList[count]);
		if (ret && pPlmReq->plmChList[count] > 14) {
			if (CHANNEL_STATE_DFS == cds_get_channel_state(
						pPlmReq->plmChList[count])) {
				/* DFS channel is provided, no PLM bursts can be
				 * transmitted. Ignoring these channels.
				 */
				QDF_TRACE(QDF_MODULE_ID_SME,
					  QDF_TRACE_LEVEL_INFO,
					  FL("DFS channel %d ignored for PLM"),
					  pPlmReq->plmChList[count]);
				continue;
			}
		} else if (!ret) {
			/* Not supported, ignore the channel */
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
				  FL("Unsupported channel %d ignored for PLM"),
				  pPlmReq->plmChList[count]);
			continue;
		}
		ch_list[valid_count] = pPlmReq->plmChList[count];
		valid_count++;
	} /* End of for () */

	/* Copying back the valid channel list to plm struct */
	qdf_mem_set((void *)pPlmReq->plmChList,
		    pPlmReq->plmNumCh, 0);
	if (valid_count)
		qdf_mem_copy(pPlmReq->plmChList, ch_list,
			     valid_count);
	/* All are invalid channels, FW need to send the PLM
	 *  report with "incapable" bit set.
	 */
	pPlmReq->plmNumCh = valid_count;

send_plm_start:
	/* PLM START */
	msg.type = WMA_SET_PLM_REQ;
	msg.reserved = 0;
	msg.bodyptr = pPlmReq;

	if (!QDF_IS_STATUS_SUCCESS(cds_mq_post_message(QDF_MODULE_ID_WMA,
						       &msg))) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  FL("Not able to post WMA_SET_PLM_REQ to WMA"));
		sme_release_global_lock(&pMac->sme);
		return QDF_STATUS_E_FAILURE;
	}

	sme_release_global_lock(&pMac->sme);
	return status;
}

/**
 * sme_tsm_ie_ind() - sme tsm ie indication
 * @hHal: HAL handle
 * @pSmeTsmIeInd: Pointer to tsm ie indication
 *
 * Handle the tsm ie indication from  LIM and forward it to HDD.
 *
 * Return: QDF_STATUS enumeration
 */
static QDF_STATUS sme_tsm_ie_ind(tHalHandle hHal, tSirSmeTsmIEInd *pSmeTsmIeInd)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tCsrRoamInfo pRoamInfo = { 0 };
	uint32_t SessionId = pSmeTsmIeInd->sessionId;
	pRoamInfo.tsmIe.tsid = pSmeTsmIeInd->tsmIe.tsid;
	pRoamInfo.tsmIe.state = pSmeTsmIeInd->tsmIe.state;
	pRoamInfo.tsmIe.msmt_interval = pSmeTsmIeInd->tsmIe.msmt_interval;
	/* forward the tsm ie information to HDD */
	csr_roam_call_callback(pMac,
			       SessionId, &pRoamInfo, 0, eCSR_ROAM_TSM_IE_IND, 0);
	return status;
}

/**
 * sme_set_cckm_ie() - set cckm ie
 * @hHal: HAL handle
 * @sessionId: session id
 * @pCckmIe: Pointer to CCKM Ie
 * @cckmIeLen: Length of @pCckmIe
 *
 * Function to store the CCKM IE passed from supplicant and use
 * it while packing reassociation request.
 *
 * Return: QDF_STATUS enumeration
 */
QDF_STATUS sme_set_cckm_ie(tHalHandle hHal, uint8_t sessionId,
			   uint8_t *pCckmIe, uint8_t cckmIeLen)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		csr_set_cckm_ie(pMac, sessionId, pCckmIe, cckmIeLen);
		sme_release_global_lock(&pMac->sme);
	}
	return status;
}

/**
 * sme_set_ese_beacon_request() - set ese beacon request
 * @hHal: HAL handle
 * @sessionId: session id
 * @pEseBcnReq: Ese beacon report
 *
 * function to set ESE beacon request parameters
 *
 * Return: QDF_STATUS enumeration
 */
QDF_STATUS sme_set_ese_beacon_request(tHalHandle hHal, const uint8_t sessionId,
				      const tCsrEseBeaconReq *pEseBcnReq)
{
	QDF_STATUS status = eSIR_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	tpSirBeaconReportReqInd pSmeBcnReportReq = NULL;
	tCsrEseBeaconReqParams *pBeaconReq = NULL;
	uint8_t counter = 0;
	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
	tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext;

	if (pSmeRrmContext->eseBcnReqInProgress == true) {
		sms_log(pMac, LOGE,
			"A Beacon Report Req is already in progress");
		return QDF_STATUS_E_RESOURCES;
	}

	/* Store the info in RRM context */
	qdf_mem_copy(&pSmeRrmContext->eseBcnReqInfo, pEseBcnReq,
		     sizeof(tCsrEseBeaconReq));

	/* Prepare the request to send to SME. */
	pSmeBcnReportReq = qdf_mem_malloc(sizeof(tSirBeaconReportReqInd));
	if (NULL == pSmeBcnReportReq) {
		sms_log(pMac, LOGP,
			"Memory Allocation Failure!!! ESE  BcnReq Ind to SME");
		return QDF_STATUS_E_NOMEM;
	}

	pSmeRrmContext->eseBcnReqInProgress = true;

	sms_log(pMac, LOGE, "Sending Beacon Report Req to SME");
	qdf_mem_zero(pSmeBcnReportReq, sizeof(tSirBeaconReportReqInd));

	pSmeBcnReportReq->messageType = eWNI_SME_BEACON_REPORT_REQ_IND;
	pSmeBcnReportReq->length = sizeof(tSirBeaconReportReqInd);
	qdf_mem_copy(pSmeBcnReportReq->bssId,
		     pSession->connectedProfile.bssid.bytes,
		     sizeof(tSirMacAddr));
	pSmeBcnReportReq->channelInfo.channelNum = 255;
	pSmeBcnReportReq->channelList.numChannels = pEseBcnReq->numBcnReqIe;
	pSmeBcnReportReq->msgSource = eRRM_MSG_SOURCE_ESE_UPLOAD;

	for (counter = 0; counter < pEseBcnReq->numBcnReqIe; counter++) {
		pBeaconReq =
			(tCsrEseBeaconReqParams *) &pEseBcnReq->bcnReq[counter];
		pSmeBcnReportReq->fMeasurementtype[counter] =
			pBeaconReq->scanMode;
		pSmeBcnReportReq->measurementDuration[counter] =
			SYS_TU_TO_MS(pBeaconReq->measurementDuration);
		pSmeBcnReportReq->channelList.channelNumber[counter] =
			pBeaconReq->channel;
	}

	status = sme_rrm_process_beacon_report_req_ind(pMac, pSmeBcnReportReq);

	if (status != QDF_STATUS_SUCCESS)
		pSmeRrmContext->eseBcnReqInProgress = false;

	qdf_mem_free(pSmeBcnReportReq);

	return status;
}

/**
 * sme_get_tsm_stats() - SME get tsm stats
 * @hHal: HAL handle
 * @callback: SME sends back the requested stats using the callback
 * @staId: The station ID for which the stats is requested for
 * @bssId: bssid
 * @pContext: user context to be passed back along with the callback
 * @p_cds_context: CDS context
 * @tid: Traffic id
 *
 * API register a callback to get TSM Stats.
 *
 * Return: QDF_STATUS enumeration
 */
QDF_STATUS sme_get_tsm_stats(tHalHandle hHal,
			     tCsrTsmStatsCallback callback,
			     uint8_t staId, struct qdf_mac_addr bssId,
			     void *pContext, void *p_cds_context, uint8_t tid)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		status = csr_get_tsm_stats(pMac, callback,
					   staId, bssId, pContext,
					   p_cds_context, tid);
		sme_release_global_lock(&pMac->sme);
	}
	return status;
}

/**
 * sme_set_ese_roam_scan_channel_list() - To set ese roam scan channel list
 * @hHal: pointer HAL handle returned by mac_open
 * @sessionId: sme session id
 * @pChannelList: Output channel list
 * @numChannels: Output number of channels
 *
 * This routine is called to set ese roam scan channel list.
 * This is a synchronous call
 *
 * Return: QDF_STATUS
 */
QDF_STATUS sme_set_ese_roam_scan_channel_list(tHalHandle hHal,
					      uint8_t sessionId,
					      uint8_t *pChannelList,
					      uint8_t numChannels)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tpCsrNeighborRoamControlInfo pNeighborRoamInfo
		= &pMac->roam.neighborRoamInfo[sessionId];
	tpCsrChannelInfo curchnl_list_info
		= &pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo;
	uint8_t oldChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN * 2] = { 0 };
	uint8_t newChannelList[128] = { 0 };
	uint8_t i = 0, j = 0;

	status = sme_acquire_global_lock(&pMac->sme);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		if (pMac->roam.configParam.isRoamOffloadScanEnabled)
			csr_roam_offload_scan(pMac, sessionId,
					ROAM_SCAN_OFFLOAD_UPDATE_CFG,
					REASON_CHANNEL_LIST_CHANGED);
		return status;
	}
	if (NULL != curchnl_list_info->ChannelList) {
		for (i = 0; i < curchnl_list_info->numOfChannels; i++) {
			j += snprintf(oldChannelList + j,
				sizeof(oldChannelList) - j, "%d",
				curchnl_list_info->ChannelList[i]);
		}
	}
	status = csr_create_roam_scan_channel_list(pMac, sessionId,
				pChannelList, numChannels,
				csr_get_current_band(hHal));
	if (QDF_IS_STATUS_SUCCESS(status)) {
		if (NULL != curchnl_list_info->ChannelList) {
			j = 0;
			for (i = 0; i < curchnl_list_info->numOfChannels; i++) {
				j += snprintf(newChannelList + j,
					sizeof(newChannelList) - j, "%d",
					curchnl_list_info->ChannelList[i]);
			}
		}
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
			"ESE roam scan chnl list successfully set to %s-old value is %s-roam state is %d",
			newChannelList, oldChannelList,
			pNeighborRoamInfo->neighborRoamState);
	}
	sme_release_global_lock(&pMac->sme);
	if (pMac->roam.configParam.isRoamOffloadScanEnabled)
		csr_roam_offload_scan(pMac, sessionId,
				ROAM_SCAN_OFFLOAD_UPDATE_CFG,
				REASON_CHANNEL_LIST_CHANGED);
	return status;
}

#endif /* FEATURE_WLAN_ESE */

QDF_STATUS sme_ibss_peer_info_response_handleer(tHalHandle hHal,
						tpSirIbssGetPeerInfoRspParams
						pIbssPeerInfoParams)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	if (NULL == pMac) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_FATAL,
			  "%s: pMac is null", __func__);
		return QDF_STATUS_E_FAILURE;
	}
	if (pMac->sme.peerInfoParams.peerInfoCbk == NULL) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "%s: HDD callback is null", __func__);
		return QDF_STATUS_E_FAILURE;
	}
	pMac->sme.peerInfoParams.peerInfoCbk(pMac->sme.peerInfoParams.pUserData,
					     &pIbssPeerInfoParams->
					     ibssPeerInfoRspParams);
	return QDF_STATUS_SUCCESS;
}

/**
 * sme_process_dual_mac_config_resp() - Process set Dual mac config response
 * @mac: Global MAC pointer
 * @msg: Dual mac config response
 *
 * Processes the dual mac configuration response and invokes the HDD callback
 * to process further
 */
static QDF_STATUS sme_process_dual_mac_config_resp(tpAniSirGlobal mac,
		uint8_t *msg)
{
	tListElem *entry = NULL;
	tSmeCmd *command = NULL;
	bool found;
	dual_mac_cb callback = NULL;
	struct sir_dual_mac_config_resp *param;

	param = (struct sir_dual_mac_config_resp *)msg;
	if (!param) {
		sms_log(mac, LOGE, FL("Dual mac config resp param is NULL"));
		/* Not returning. Need to check if active command list
		 * needs to be freed
		 */
	}

	entry = csr_ll_peek_head(&mac->sme.smeCmdActiveList,
			LL_ACCESS_LOCK);
	if (!entry) {
		sms_log(mac, LOGE, FL("No cmd found in active list"));
		return QDF_STATUS_E_FAILURE;
	}

	command = GET_BASE_ADDR(entry, tSmeCmd, Link);
	if (!command) {
		sms_log(mac, LOGE, FL("Base address is NULL"));
		return QDF_STATUS_E_FAILURE;
	}

	if (e_sme_command_set_dual_mac_config != command->command) {
		sms_log(mac, LOGE, FL("Command mismatch!"));
		return QDF_STATUS_E_FAILURE;
	}

	callback = command->u.set_dual_mac_cmd.set_dual_mac_cb;
	if (callback) {
		if (!param) {
			sms_log(mac, LOGE,
				FL("Callback failed-Dual mac config is NULL"));
		} else {
			sms_log(mac, LOG1,
				FL("Calling HDD callback for Dual mac config"));
			callback(param->status,
				command->u.set_dual_mac_cmd.scan_config,
				command->u.set_dual_mac_cmd.fw_mode_config);
		}
	} else {
		sms_log(mac, LOGE, FL("Callback does not exist"));
	}

	found = csr_ll_remove_entry(&mac->sme.smeCmdActiveList, entry,
			LL_ACCESS_LOCK);
	if (found)
		/* Now put this command back on the available command list */
		sme_release_command(mac, command);

	sme_process_pending_queue(mac);
	return QDF_STATUS_SUCCESS;
}

/**
 * sme_process_antenna_mode_resp() - Process set antenna mode
 * response
 * @mac: Global MAC pointer
 * @msg: antenna mode response
 *
 * Processes the antenna mode response and invokes the HDD
 * callback to process further
 */
static QDF_STATUS sme_process_antenna_mode_resp(tpAniSirGlobal mac,
		uint8_t *msg)
{
	tListElem *entry;
	tSmeCmd *command;
	bool found;
	antenna_mode_cb callback;
	struct sir_antenna_mode_resp *param;

	param = (struct sir_antenna_mode_resp *)msg;
	if (!param) {
		sms_log(mac, LOGE, FL("set antenna mode resp is NULL"));
		/* Not returning. Need to check if active command list
		 * needs to be freed
		 */
	}

	entry = csr_ll_peek_head(&mac->sme.smeCmdActiveList,
			LL_ACCESS_LOCK);
	if (!entry) {
		sms_log(mac, LOGE, FL("No cmd found in active list"));
		return QDF_STATUS_E_FAILURE;
	}

	command = GET_BASE_ADDR(entry, tSmeCmd, Link);
	if (!command) {
		sms_log(mac, LOGE, FL("Base address is NULL"));
		return QDF_STATUS_E_FAILURE;
	}

	if (e_sme_command_set_antenna_mode != command->command) {
		sms_log(mac, LOGE, FL("Command mismatch!"));
		return QDF_STATUS_E_FAILURE;
	}

	callback =
		command->u.set_antenna_mode_cmd.set_antenna_mode_resp;
	if (callback) {
		if (!param) {
			sms_log(mac, LOGE,
				FL("Set antenna mode call back is NULL"));
		} else {
			sms_log(mac, LOG1,
				FL("HDD callback for set antenna mode"));
			callback(param->status);
		}
	} else {
		sms_log(mac, LOGE, FL("Callback does not exist"));
	}

	found = csr_ll_remove_entry(&mac->sme.smeCmdActiveList, entry,
			LL_ACCESS_LOCK);
	if (found)
		/* Now put this command back on the available command list */
		sme_release_command(mac, command);

	sme_process_pending_queue(mac);
	return QDF_STATUS_SUCCESS;
}

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

   \brief sme_process_msg() - The main message processor for SME.

   The function is called by a message dispatcher when to process a message
   targeted for SME.

   This is a synchronous call
   \param hHal - The handle returned by mac_open.
   \param pMsg - A pointer to a caller allocated object of tSirMsgQ.

   \return QDF_STATUS_SUCCESS - SME successfully process the message.

   Other status means SME failed to process the message to HAL.
   \sa

   --------------------------------------------------------------------------*/
QDF_STATUS sme_process_msg(tHalHandle hHal, cds_msg_t *pMsg)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	if (pMsg == NULL) {
		sms_log(pMac, LOGE, "Empty message for SME");
		return status;
	}
	status = sme_acquire_global_lock(&pMac->sme);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		sms_log(pMac, LOGW, FL("Locking failed, bailing out"));
		if (pMsg->bodyptr)
			qdf_mem_free(pMsg->bodyptr);
		return status;
	}
	if (!SME_IS_START(pMac)) {
		sms_log(pMac, LOGW, FL("message type %d in stop state ignored"),
			pMsg->type);
		if (pMsg->bodyptr)
			qdf_mem_free(pMsg->bodyptr);
		goto release_lock;
	}
	switch (pMsg->type) {
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
	case eWNI_SME_HO_FAIL_IND:
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  FL("LFR3: Rcvd eWNI_SME_HO_FAIL_IND"));
		csr_process_ho_fail_ind(pMac, pMsg->bodyptr);
		qdf_mem_free(pMsg->bodyptr);
		break;
#endif
	case eWNI_PMC_SMPS_STATE_IND:
		break;
	case WNI_CFG_SET_CNF:
	case WNI_CFG_DNLD_CNF:
	case WNI_CFG_GET_RSP:
	case WNI_CFG_ADD_GRP_ADDR_CNF:
	case WNI_CFG_DEL_GRP_ADDR_CNF:
		break;
	case eWNI_SME_ADDTS_RSP:
	case eWNI_SME_DELTS_RSP:
	case eWNI_SME_DELTS_IND:
	case eWNI_SME_FT_AGGR_QOS_RSP:
		/* QoS */
		if (pMsg->bodyptr) {
#ifndef WLAN_MDM_CODE_REDUCTION_OPT
			status = sme_qos_msg_processor(pMac, pMsg->type,
						       pMsg->bodyptr);
			qdf_mem_free(pMsg->bodyptr);
#endif
		} else {
			sms_log(pMac, LOGE, FL("Empty message for %d"),
				pMsg->type);
		}
		break;
	case eWNI_SME_NEIGHBOR_REPORT_IND:
	case eWNI_SME_BEACON_REPORT_REQ_IND:
		if (pMsg->bodyptr) {
			status = sme_rrm_msg_processor(pMac, pMsg->type,
						       pMsg->bodyptr);
			qdf_mem_free(pMsg->bodyptr);
		} else {
			sms_log(pMac, LOGE, FL("Empty message for %d"),
				pMsg->type);
		}
		break;
	case eWNI_SME_ADD_STA_SELF_RSP:
		if (pMsg->bodyptr) {
			status = csr_process_add_sta_session_rsp(pMac,
								pMsg->bodyptr);
			qdf_mem_free(pMsg->bodyptr);
		} else {
			sms_log(pMac, LOGE, FL("Empty message for %d"),
				pMsg->type);
		}
		break;
	case eWNI_SME_DEL_STA_SELF_RSP:
		if (pMsg->bodyptr) {
			status = csr_process_del_sta_session_rsp(pMac,
								pMsg->bodyptr);
			qdf_mem_free(pMsg->bodyptr);
		} else {
			sms_log(pMac, LOGE, FL("Empty message for %d"),
				pMsg->type);
		}
		break;
	case eWNI_SME_REMAIN_ON_CHN_RSP:
		if (pMsg->bodyptr) {
			status = sme_remain_on_chn_rsp(pMac, pMsg->bodyptr);
			qdf_mem_free(pMsg->bodyptr);
		} else {
			sms_log(pMac, LOGE, FL("Empty message for %d"),
				pMsg->type);
		}
		break;
	case eWNI_SME_REMAIN_ON_CHN_RDY_IND:
		if (pMsg->bodyptr) {
			status = sme_remain_on_chn_ready(pMac, pMsg->bodyptr);
			qdf_mem_free(pMsg->bodyptr);
		} else {
			sms_log(pMac, LOGE, FL("Empty message for %d"),
				pMsg->type);
		}
		break;
#ifdef FEATURE_WLAN_SCAN_PNO
	case eWNI_SME_PREF_NETWORK_FOUND_IND:
		MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_RX_WMA_MSG,
				 NO_SESSION, pMsg->type));
		if (pMsg->bodyptr) {
			status = sme_preferred_network_found_ind((void *)pMac,
								 pMsg->bodyptr);
			qdf_mem_free(pMsg->bodyptr);
		} else {
			sms_log(pMac, LOGE, FL("Empty message for %d"),
				pMsg->type);
		}
		break;
#endif /* FEATURE_WLAN_SCAN_PNO */
	case eWNI_SME_CHANGE_COUNTRY_CODE:
		if (pMsg->bodyptr) {
			status = sme_handle_change_country_code((void *)pMac,
								pMsg->bodyptr);
			qdf_mem_free(pMsg->bodyptr);
		} else {
			sms_log(pMac, LOGE, FL("Empty message for %d"),
				pMsg->type);
		}
		break;
	case eWNI_SME_GENERIC_CHANGE_COUNTRY_CODE:
		if (pMsg->bodyptr) {
			status = sme_handle_generic_change_country_code(
						(void *)pMac, pMsg->bodyptr);
			qdf_mem_free(pMsg->bodyptr);
		} else {
			sms_log(pMac, LOGE, FL("Empty message for %d"),
				pMsg->type);
		}
		break;
	case eWNI_SME_SCAN_CMD:
		if (pMsg->bodyptr) {
			status = sme_handle_scan_req(pMac, pMsg->bodyptr);
			qdf_mem_free(pMsg->bodyptr);
		} else {
			sms_log(pMac, LOGE, FL("Empty message for %d"),
				pMsg->type);
		}
		break;
	case eWNI_SME_ROC_CMD:
		if (pMsg->bodyptr) {
			status = sme_handle_roc_req(hHal, pMsg->bodyptr);
			qdf_mem_free(pMsg->bodyptr);
		} else {
			sms_log(pMac, LOGE, FL("Empty message for %d"),
				pMsg->type);
		}
		break;
#ifdef FEATURE_WLAN_TDLS
	/*
	 * command rescived from PE, SME tdls msg processor shall be called
	 * to process commands recieved from PE
	 */
	case eWNI_SME_TDLS_SEND_MGMT_RSP:
	case eWNI_SME_TDLS_ADD_STA_RSP:
	case eWNI_SME_TDLS_DEL_STA_RSP:
	case eWNI_SME_TDLS_DEL_STA_IND:
	case eWNI_SME_TDLS_DEL_ALL_PEER_IND:
	case eWNI_SME_MGMT_FRM_TX_COMPLETION_IND:
	case eWNI_SME_TDLS_LINK_ESTABLISH_RSP:
	case eWNI_SME_TDLS_SHOULD_DISCOVER:
	case eWNI_SME_TDLS_SHOULD_TEARDOWN:
	case eWNI_SME_TDLS_PEER_DISCONNECTED:
		if (pMsg->bodyptr) {
			status = tdls_msg_processor(pMac, pMsg->type,
						    pMsg->bodyptr);
			qdf_mem_free(pMsg->bodyptr);
		} else {
			sms_log(pMac, LOGE, FL("Empty message for %d"),
				pMsg->type);
		}
		break;
#endif
#ifdef WLAN_FEATURE_11W
	case eWNI_SME_UNPROT_MGMT_FRM_IND:
		if (pMsg->bodyptr) {
			sme_unprotected_mgmt_frm_ind(pMac, pMsg->bodyptr);
			qdf_mem_free(pMsg->bodyptr);
		} else {
			sms_log(pMac, LOGE, FL("Empty message for %d"),
				pMsg->type);
		}
		break;
#endif
#ifdef FEATURE_WLAN_ESE
	case eWNI_SME_TSM_IE_IND:
		if (pMsg->bodyptr) {
			sme_tsm_ie_ind(pMac, pMsg->bodyptr);
			qdf_mem_free(pMsg->bodyptr);
		} else {
			sms_log(pMac, LOGE, FL("Empty message for %d"),
				pMsg->type);
		}
		break;
#endif /* FEATURE_WLAN_ESE */
	case eWNI_SME_ROAM_SCAN_OFFLOAD_RSP:
		status = csr_roam_offload_scan_rsp_hdlr((void *)pMac,
							pMsg->bodyptr);
		qdf_mem_free(pMsg->bodyptr);
		break;
#ifdef WLAN_FEATURE_GTK_OFFLOAD
	case eWNI_PMC_GTK_OFFLOAD_GETINFO_RSP:
		MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_RX_WMA_MSG,
				 NO_SESSION, pMsg->type));
		if (pMsg->bodyptr) {
			sme_process_get_gtk_info_rsp(pMac, pMsg->bodyptr);
			qdf_mem_free(pMsg->bodyptr);
		} else {
			sms_log(pMac, LOGE, FL("Empty message for %d"),
				pMsg->type);
		}
		break;
#endif
#ifdef FEATURE_WLAN_LPHB
	/* LPHB timeout indication arrived, send IND to client */
	case eWNI_SME_LPHB_IND:
		MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_RX_WMA_MSG,
				 NO_SESSION, pMsg->type));
		if (pMac->sme.pLphbIndCb)
			pMac->sme.pLphbIndCb(pMac->hHdd, pMsg->bodyptr);
		qdf_mem_free(pMsg->bodyptr);
		break;
#endif /* FEATURE_WLAN_LPHB */
	case eWNI_SME_IBSS_PEER_INFO_RSP:
		if (pMsg->bodyptr) {
			sme_ibss_peer_info_response_handleer(pMac,
							     pMsg->
							     bodyptr);
			qdf_mem_free(pMsg->bodyptr);
		} else {
			sms_log(pMac, LOGE, FL("Empty message for %d"),
				pMsg->type);
		}
		break;
	case eWNI_SME_READY_TO_SUSPEND_IND:
		if (pMsg->bodyptr) {
			sme_process_ready_to_suspend(pMac, pMsg->bodyptr);
			qdf_mem_free(pMsg->bodyptr);
		} else {
			sms_log(pMac, LOGE, FL("Empty message for %d"),
				pMsg->type);
		}
		break;
#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
	case eWNI_SME_READY_TO_EXTWOW_IND:
		if (pMsg->bodyptr) {
			sme_process_ready_to_ext_wow(pMac, pMsg->bodyptr);
			qdf_mem_free(pMsg->bodyptr);
		} else {
			sms_log(pMac, LOGE, FL("Empty message for %d"),
				pMsg->type);
		}
		break;
#endif
#ifdef FEATURE_WLAN_CH_AVOID
	/* channel avoid message arrived, send IND to client */
	case eWNI_SME_CH_AVOID_IND:
		MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_RX_WMA_MSG,
				 NO_SESSION, pMsg->type));
		if (pMac->sme.pChAvoidNotificationCb) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
				  FL("CH avoid notification"));
			pMac->sme.pChAvoidNotificationCb(pMac->hHdd,
							 pMsg->bodyptr);
		}
		qdf_mem_free(pMsg->bodyptr);
		break;
#endif /* FEATURE_WLAN_CH_AVOID */
#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
	case eWNI_SME_AUTO_SHUTDOWN_IND:
		if (pMac->sme.pAutoShutdownNotificationCb) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
				  FL("Auto shutdown notification"));
			pMac->sme.pAutoShutdownNotificationCb();
		}
		qdf_mem_free(pMsg->bodyptr);
		break;
#endif
	case eWNI_SME_DFS_RADAR_FOUND:
	case eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND:
		status = dfs_msg_processor(pMac, pMsg->type, pMsg->bodyptr);
		qdf_mem_free(pMsg->bodyptr);
		break;
	case eWNI_SME_CHANNEL_CHANGE_RSP:
		if (pMsg->bodyptr) {
			status = sme_process_channel_change_resp(pMac,
								 pMsg->type,
								 pMsg->bodyptr);
			qdf_mem_free(pMsg->bodyptr);
		} else {
			sms_log(pMac, LOGE, FL("Empty message for %d"),
				pMsg->type);
		}
		break;
#ifdef WLAN_FEATURE_STATS_EXT
	case eWNI_SME_STATS_EXT_EVENT:
		if (pMsg->bodyptr) {
			status = sme_stats_ext_event(hHal, pMsg->bodyptr);
			qdf_mem_free(pMsg->bodyptr);
		} else {
			sms_log(pMac, LOGE, FL("Empty message for %d"),
				pMsg->type);
		}
		break;
#endif
	case eWNI_SME_LINK_SPEED_IND:
		if (pMac->sme.pLinkSpeedIndCb)
			pMac->sme.pLinkSpeedIndCb(pMsg->bodyptr,
						pMac->sme.pLinkSpeedCbContext);
		if (pMsg->bodyptr)
			qdf_mem_free(pMsg->bodyptr);
		break;
	case eWNI_SME_CSA_OFFLOAD_EVENT:
		if (pMsg->bodyptr) {
			csr_scan_flush_bss_entry(pMac, pMsg->bodyptr);
			qdf_mem_free(pMsg->bodyptr);
		}
		break;
	case eWNI_SME_TSF_EVENT:
		if (pMac->sme.get_tsf_cb) {
			pMac->sme.get_tsf_cb(pMac->sme.get_tsf_cxt,
					(struct stsf *)pMsg->bodyptr);
		}
		if (pMsg->bodyptr)
			qdf_mem_free(pMsg->bodyptr);
		break;
#ifdef WLAN_FEATURE_NAN
	case eWNI_SME_NAN_EVENT:
		MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_RX_WMA_MSG,
				 NO_SESSION, pMsg->type));
		if (pMsg->bodyptr) {
			sme_nan_event(hHal, pMsg->bodyptr);
			qdf_mem_free(pMsg->bodyptr);
		}
		break;
#endif /* WLAN_FEATURE_NAN */
	case eWNI_SME_LINK_STATUS_IND:
	{
		tAniGetLinkStatus *pLinkStatus =
			(tAniGetLinkStatus *) pMsg->bodyptr;
		if (pLinkStatus) {
			if (pMac->sme.linkStatusCallback) {
				pMac->sme.linkStatusCallback(
					pLinkStatus->linkStatus,
					pMac->sme.linkStatusContext);
			}
			pMac->sme.linkStatusCallback = NULL;
			pMac->sme.linkStatusContext = NULL;
			qdf_mem_free(pLinkStatus);
		}
		break;
	}
	case eWNI_SME_MSG_GET_TEMPERATURE_IND:
		if (pMac->sme.pGetTemperatureCb) {
			pMac->sme.pGetTemperatureCb(pMsg->bodyval,
					pMac->sme.pTemperatureCbContext);
		}
		break;
	case eWNI_SME_SNR_IND:
	{
		tAniGetSnrReq *pSnrReq = (tAniGetSnrReq *) pMsg->bodyptr;
		if (pSnrReq) {
			if (pSnrReq->snrCallback) {
				((tCsrSnrCallback)
				 (pSnrReq->snrCallback))
					(pSnrReq->snr, pSnrReq->staId,
					pSnrReq->pDevContext);
			}
			qdf_mem_free(pSnrReq);
		}
		break;
	}
#ifdef FEATURE_WLAN_EXTSCAN
	case eWNI_SME_EXTSCAN_FULL_SCAN_RESULT_IND:
		if (pMac->sme.pExtScanIndCb)
			pMac->sme.pExtScanIndCb(pMac->hHdd,
					eSIR_EXTSCAN_FULL_SCAN_RESULT_IND,
					pMsg->bodyptr);
		else
			sms_log(pMac, LOGE,
				FL("callback not registered to process %d"),
				pMsg->type);

		qdf_mem_free(pMsg->bodyptr);
		break;
	case eWNI_SME_EPNO_NETWORK_FOUND_IND:
		if (pMac->sme.pExtScanIndCb)
			pMac->sme.pExtScanIndCb(pMac->hHdd,
					eSIR_EPNO_NETWORK_FOUND_IND,
					pMsg->bodyptr);
		else
			sms_log(pMac, LOGE,
				FL("callback not registered to process %d"),
				pMsg->type);

		qdf_mem_free(pMsg->bodyptr);
		break;
#endif
	case eWNI_SME_FW_DUMP_IND:
		sme_process_fw_mem_dump_rsp(pMac, pMsg);
		break;
	case eWNI_SME_SET_HW_MODE_RESP:
		if (pMsg->bodyptr) {
			status = sme_process_set_hw_mode_resp(pMac,
								pMsg->bodyptr);
			qdf_mem_free(pMsg->bodyptr);
		} else {
			sms_log(pMac, LOGE, FL("Empty message for %d"),
				pMsg->type);
		}
		break;
	case eWNI_SME_HW_MODE_TRANS_IND:
		if (pMsg->bodyptr) {
			status = sme_process_hw_mode_trans_ind(pMac,
								pMsg->bodyptr);
			qdf_mem_free(pMsg->bodyptr);
		} else {
			sms_log(pMac, LOGE, FL("Empty message for %d"),
				pMsg->type);
		}
		break;
	case eWNI_SME_NSS_UPDATE_RSP:
		if (pMsg->bodyptr) {
			status = sme_process_nss_update_resp(pMac,
								pMsg->bodyptr);
			qdf_mem_free(pMsg->bodyptr);
		} else {
			sms_log(pMac, LOGE, FL("Empty message for %d"),
				pMsg->type);
		}
		break;
	case eWNI_SME_OCB_SET_CONFIG_RSP:
		if (pMac->sme.ocb_set_config_callback) {
			pMac->sme.ocb_set_config_callback(
				pMac->sme.ocb_set_config_context,
				pMsg->bodyptr);
		} else {
			sms_log(pMac, LOGE, FL(
				"Message error. The callback is NULL."));
		}
		pMac->sme.ocb_set_config_callback = NULL;
		pMac->sme.ocb_set_config_context = NULL;
		qdf_mem_free(pMsg->bodyptr);
		break;
	case eWNI_SME_OCB_GET_TSF_TIMER_RSP:
		if (pMac->sme.ocb_get_tsf_timer_callback) {
			pMac->sme.ocb_get_tsf_timer_callback(
				pMac->sme.ocb_get_tsf_timer_context,
				pMsg->bodyptr);
		} else {
			sms_log(pMac, LOGE, FL(
				"Message error. The callback is NULL."));
		}
		pMac->sme.ocb_get_tsf_timer_callback = NULL;
		pMac->sme.ocb_get_tsf_timer_context = NULL;
		qdf_mem_free(pMsg->bodyptr);
		break;
	case eWNI_SME_DCC_GET_STATS_RSP:
		if (pMac->sme.dcc_get_stats_callback) {
			pMac->sme.dcc_get_stats_callback(
				pMac->sme.dcc_get_stats_context,
				pMsg->bodyptr);
		} else {
			sms_log(pMac, LOGE, FL(
				"Message error. The callback is NULL."));
		}
		pMac->sme.dcc_get_stats_callback = NULL;
		pMac->sme.dcc_get_stats_context = NULL;
		qdf_mem_free(pMsg->bodyptr);
		break;
	case eWNI_SME_DCC_UPDATE_NDL_RSP:
		if (pMac->sme.dcc_update_ndl_callback) {
			pMac->sme.dcc_update_ndl_callback(
				pMac->sme.dcc_update_ndl_context,
				pMsg->bodyptr);
		} else {
			sms_log(pMac, LOGE, FL(
				"Message error. The callback is NULL."));
		}
		pMac->sme.dcc_update_ndl_callback = NULL;
		pMac->sme.dcc_update_ndl_context = NULL;
		qdf_mem_free(pMsg->bodyptr);
		break;
	case eWNI_SME_DCC_STATS_EVENT:
		if (pMac->sme.dcc_stats_event_callback) {
			pMac->sme.dcc_stats_event_callback(
				pMac->sme.dcc_stats_event_context,
				pMsg->bodyptr);
		} else {
			sms_log(pMac, LOGE, FL(
				"Message error. The callback is NULL."));
		}
		qdf_mem_free(pMsg->bodyptr);
		break;
	case eWNI_SME_SET_DUAL_MAC_CFG_RESP:
		if (pMsg->bodyptr) {
			status = sme_process_dual_mac_config_resp(pMac,
					pMsg->bodyptr);
			qdf_mem_free(pMsg->bodyptr);
		} else {
			sms_log(pMac, LOGE, FL("Empty message for %d"),
					pMsg->type);
		}
	case eWNI_SME_SET_THERMAL_LEVEL_IND:
		if (pMac->sme.set_thermal_level_cb)
			pMac->sme.set_thermal_level_cb(pMac->hHdd,
								pMsg->bodyval);
		break;
	case eWNI_SME_EXT_CHANGE_CHANNEL_IND:
		 status = sme_extended_change_channel_ind(pMac, pMsg->bodyptr);
		 qdf_mem_free(pMsg->bodyptr);
		 break;
	case eWNI_SME_SET_ANTENNA_MODE_RESP:
		if (pMsg->bodyptr) {
			status = sme_process_antenna_mode_resp(pMac,
					pMsg->bodyptr);
			qdf_mem_free(pMsg->bodyptr);
		} else {
			sms_log(pMac, LOGE, FL("Empty message for %d"),
					pMsg->type);
		}
		break;
	case eWNI_SME_NDP_CONFIRM_IND:
	case eWNI_SME_NDP_NEW_PEER_IND:
	case eWNI_SME_NDP_INITIATOR_RSP:
	case eWNI_SME_NDP_INDICATION:
	case eWNI_SME_NDP_RESPONDER_RSP:
	case eWNI_SME_NDP_END_RSP:
	case eWNI_SME_NDP_END_IND:
	case eWNI_SME_NDP_PEER_DEPARTED_IND:
		sme_ndp_msg_processor(pMac, pMsg);
		break;
	default:

		if ((pMsg->type >= eWNI_SME_MSG_TYPES_BEGIN)
		    && (pMsg->type <= eWNI_SME_MSG_TYPES_END)) {
			/* CSR */
			if (pMsg->bodyptr) {
				status = csr_msg_processor(hHal, pMsg->bodyptr);
				qdf_mem_free(pMsg->bodyptr);
			} else {
				sms_log(pMac, LOGE, FL("Empty message for %d"),
				pMsg->type);
			}
		} else {
			sms_log(pMac, LOGW, FL("Unknown message type %d"),
				pMsg->type);
			if (pMsg->bodyptr)
				qdf_mem_free(pMsg->bodyptr);
		}
	} /* switch */
release_lock:
	sme_release_global_lock(&pMac->sme);
	return status;
}

/**
 * sme_process_nss_update_resp() - Process nss update response
 * @mac: Global MAC pointer
 * @msg: nss update response
 *
 * Processes the nss update response and invokes the HDD
 * callback to process further
 */
QDF_STATUS sme_process_nss_update_resp(tpAniSirGlobal mac, uint8_t *msg)
{
	tListElem *entry = NULL;
	tSmeCmd *command = NULL;
	bool found;
	nss_update_cb callback = NULL;
	struct sir_beacon_tx_complete_rsp *param;

	param = (struct sir_beacon_tx_complete_rsp *)msg;
	if (!param) {
		sms_log(mac, LOGE, FL("nss update resp param is NULL"));
		/* Not returning. Need to check if active command list
		 * needs to be freed
		 */
	}

	entry = csr_ll_peek_head(&mac->sme.smeCmdActiveList,
			LL_ACCESS_LOCK);
	if (!entry) {
		sms_log(mac, LOGE, FL("No cmd found in active list"));
		return QDF_STATUS_E_FAILURE;
	}

	command = GET_BASE_ADDR(entry, tSmeCmd, Link);
	if (!command) {
		sms_log(mac, LOGE, FL("Base address is NULL"));
		return QDF_STATUS_E_FAILURE;
	}

	if (e_sme_command_nss_update != command->command) {
		sms_log(mac, LOGE, FL("Command mismatch!"));
		return QDF_STATUS_E_FAILURE;
	}

	callback = command->u.nss_update_cmd.nss_update_cb;
	if (callback) {
		if (!param) {
			sms_log(mac, LOGE,
				FL("Callback failed since nss update params is NULL"));
		} else {
			sms_log(mac, LOGE,
				FL("Calling HDD callback for nss update response"));
			callback(command->u.nss_update_cmd.context,
				param->tx_status,
				param->session_id,
				command->u.nss_update_cmd.next_action,
				command->u.nss_update_cmd.reason);
		}
	} else {
		sms_log(mac, LOGE, FL("Callback does not exisit"));
	}

	found = csr_ll_remove_entry(&mac->sme.smeCmdActiveList, entry,
			LL_ACCESS_LOCK);
	if (found) {
		/* Now put this command back on the avilable command list */
		sme_release_command(mac, command);
	}
	sme_process_pending_queue(mac);
	return QDF_STATUS_SUCCESS;
}

/* No need to hold the global lock here because this function can only be called */
/* after sme_stop. */
void sme_free_msg(tHalHandle hHal, cds_msg_t *pMsg)
{
	if (pMsg) {
		if (pMsg->bodyptr) {
			qdf_mem_free(pMsg->bodyptr);
		}
	}

}

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

   \brief sme_stop() - Stop all SME modules and put them at idle state

   The function stops each module in SME, PMC, CSR, etc. . Upon
   return, all modules are at idle state ready to start.

   This is a synchronous call
   \param hHal - The handle returned by mac_open
   \param tHalStopType - reason for stopping

   \return QDF_STATUS_SUCCESS - SME is stopped.

   Other status means SME is failed to stop but caller should still
   consider SME is stopped.
   \sa

   --------------------------------------------------------------------------*/
QDF_STATUS sme_stop(tHalHandle hHal, tHalStopType stopType)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	QDF_STATUS fail_status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	p2p_stop(hHal);

	status = csr_stop(pMac, stopType);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		sms_log(pMac, LOGE,
			"csr_stop failed during smeStop with status=%d", status);
		fail_status = status;
	}

	purge_sme_cmd_list(pMac);

	if (!QDF_IS_STATUS_SUCCESS(fail_status)) {
		status = fail_status;
	}

	pMac->sme.state = SME_STATE_STOP;

	return status;
}

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

   \brief sme_close() - Release all SME modules and their resources.

   The function release each module in SME, PMC, CSR, etc. . Upon
   return, all modules are at closed state.

   No SME APIs can be involved after smeClose except smeOpen.
   smeClose must be called before mac_close.
   This is a synchronous call
   \param hHal - The handle returned by mac_open

   \return QDF_STATUS_SUCCESS - SME is successfully close.

   Other status means SME is failed to be closed but caller still cannot
   call any other SME functions except smeOpen.
   \sa

   --------------------------------------------------------------------------*/
QDF_STATUS sme_close(tHalHandle hHal)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	QDF_STATUS fail_status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	if (!pMac)
		return QDF_STATUS_E_FAILURE;

	/* Note: pSession will be invalid from here on, do not access */
	status = csr_close(pMac);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		sms_log(pMac, LOGE,
			"csr_close failed during sme close with status=%d",
			status);
		fail_status = status;
	}
#ifndef WLAN_MDM_CODE_REDUCTION_OPT
	status = sme_qos_close(pMac);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		sms_log(pMac, LOGE,
			"Qos close failed during sme close with status=%d",
			status);
		fail_status = status;
	}
#endif
	status = sme_ps_close(hHal);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		sms_log(pMac, LOGE,
				"sme_ps_close failed during smeClose status=%d",
				status);
		fail_status = status;
	}

	status = rrm_close(hHal);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		sms_log(pMac, LOGE,
			"RRM close failed during sme close with status=%d",
			status);
		fail_status = status;
	}

	sme_p2p_close(hHal);

	free_sme_cmd_list(pMac);

	if (!QDF_IS_STATUS_SUCCESS
		    (qdf_mutex_destroy(&pMac->sme.lkSmeGlobalLock))) {
		fail_status = QDF_STATUS_E_FAILURE;
	}

	if (!QDF_IS_STATUS_SUCCESS(fail_status)) {
		status = fail_status;
	}

	pMac->sme.state = SME_STATE_STOP;

	return status;
}

/**
 * sme_remove_bssid_from_scan_list() - wrapper to remove the bssid from
 * scan list
 * @hal: hal context.
 * @bssid: bssid to be removed
 *
 * This function remove the given bssid from scan list.
 *
 * Return: QDF status.
 */
QDF_STATUS sme_remove_bssid_from_scan_list(tHalHandle hal,
	tSirMacAddr bssid)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);

	status = sme_acquire_global_lock(&mac_ctx->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		csr_remove_bssid_from_scan_list(mac_ctx, bssid);
		sme_release_global_lock(&mac_ctx->sme);
	}

	return status;
}

/**
 * sme_scan_request() - wrapper function to Request a 11d or full scan from CSR.
 * @hal:          hal global context
 * @session_id:   session id
 * @scan_req:     scan req
 * @callback:     a callback function that scan calls upon finish, will not
 *                be called if csr_scan_request returns error
 * @ctx:          a pointer passed in for the callback
 *
 * This is a wrapper function to Request a 11d or full scan from CSR. This is
 * an asynchronous call
 *
 * Return: Status of operation
 */
QDF_STATUS sme_scan_request(tHalHandle hal, uint8_t session_id,
		tCsrScanRequest *scan_req,
		csr_scan_completeCallback callback, void *ctx)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
	struct ani_scan_req *scan_msg;
	cds_msg_t msg;
	uint32_t scan_req_id, scan_count;

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
		 TRACE_CODE_SME_RX_HDD_MSG_SCAN_REQ, session_id,
		 scan_req->scanType));

	if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
		sms_log(mac_ctx, LOGE, FL("Invalid session id:%d"),
				session_id);
		return status;
	}

	if (!mac_ctx->scan.fScanEnable) {
		sms_log(mac_ctx, LOGE, FL("fScanEnable false"));
		return status;
	}

	scan_count = csr_ll_count(&mac_ctx->sme.smeScanCmdActiveList);
	if (scan_count >= mac_ctx->scan.max_scan_count) {
		sms_log(mac_ctx, LOGE, FL("Max scan reached"));
		return QDF_STATUS_E_FAILURE;
	}
	wma_get_scan_id(&scan_req_id);
	scan_req->scan_id = scan_req_id;

	status = sme_acquire_global_lock(&mac_ctx->sme);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		sms_log(mac_ctx, LOGE, FL("Unable to acquire lock"));
		return status;
	}
	sms_log(mac_ctx, LOG1, FL(" called"));
	scan_msg = qdf_mem_malloc(sizeof(struct ani_scan_req));
	if (NULL == scan_msg) {
		sms_log(mac_ctx, LOGE,
			" scan_req: failed to allocate mem for msg");
		sme_release_global_lock(&mac_ctx->sme);
		return QDF_STATUS_E_NOMEM;
	}
	scan_msg->msg_type = eWNI_SME_SCAN_CMD;
	scan_msg->msg_len = (uint16_t) sizeof(struct ani_scan_req);
	scan_msg->session_id = session_id;
	scan_msg->callback = callback;
	scan_msg->ctx = ctx;
	scan_msg->scan_param = qdf_mem_malloc(sizeof(tCsrScanRequest));
	if (NULL == scan_msg->scan_param) {
		sms_log(mac_ctx, LOGE,
			"scan_req:failed to allocate mem for scanreq");
		sme_release_global_lock(&mac_ctx->sme);
		qdf_mem_free(scan_msg);
		return QDF_STATUS_E_NOMEM;
	}
	csr_scan_copy_request(mac_ctx, scan_msg->scan_param, scan_req);
	msg.type = eWNI_SME_SCAN_CMD;
	msg.bodyptr = scan_msg;
	msg.reserved = 0;
	msg.bodyval = 0;
	if (QDF_STATUS_SUCCESS !=
		cds_mq_post_message(CDS_MQ_ID_SME, &msg)) {
		sms_log(mac_ctx, LOGE,
			" sme_scan_req failed to post msg");
		csr_scan_free_request(mac_ctx, scan_msg->scan_param);
		qdf_mem_free(scan_msg->scan_param);
		qdf_mem_free(scan_msg);
		status = QDF_STATUS_E_FAILURE;
	}
	sme_release_global_lock(&mac_ctx->sme);
	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_scan_get_result
    \brief a wrapper function to request scan results from CSR.
    This is a synchronous call
    \param pFilter - If pFilter is NULL, all cached results are returned
    \param phResult - an object for the result.
    \return QDF_STATUS
   ---------------------------------------------------------------------------*/
QDF_STATUS sme_scan_get_result(tHalHandle hHal, uint8_t sessionId,
			       tCsrScanResultFilter *pFilter,
			       tScanResultHandle *phResult)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_MSG_SCAN_GET_RESULTS, sessionId,
			 0));
	sms_log(pMac, LOG2, FL("enter"));
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		status = csr_scan_get_result(hHal, pFilter, phResult);
		sme_release_global_lock(&pMac->sme);
	}
	sms_log(pMac, LOG2, FL("exit status %d"), status);

	return status;
}

/**
 * sme_get_ap_channel_from_scan_cache() - a wrapper function to get AP's
 *                                        channel id from CSR by filtering the
 *                                        result which matches our roam profile.
 * @profile: SAP adapter
 * @ap_chnl_id: pointer to channel id of SAP. Fill the value after finding the
 *              best ap from scan cache.
 *
 * This function is written to get AP's channel id from CSR by filtering
 * the result which matches our roam profile. This is a synchronous call.
 *
 * Return: QDF_STATUS.
 */
QDF_STATUS sme_get_ap_channel_from_scan_cache(tHalHandle hal_handle,
					tCsrRoamProfile *profile,
					tScanResultHandle *scan_cache,
					uint8_t *ap_chnl_id)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_handle);
	tCsrScanResultFilter *scan_filter = NULL;
	tScanResultHandle filtered_scan_result = NULL;
	tSirBssDescription first_ap_profile;

	if (NULL == mac_ctx) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				FL("mac_ctx is NULL"));
		return QDF_STATUS_E_FAILURE;
	}
	scan_filter = qdf_mem_malloc(sizeof(tCsrScanResultFilter));
	if (NULL == scan_filter) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				FL("scan_filter mem alloc failed"));
		return QDF_STATUS_E_FAILURE;
	} else {
		qdf_mem_set(scan_filter, sizeof(tCsrScanResultFilter), 0);
		qdf_mem_set(&first_ap_profile, sizeof(tSirBssDescription), 0);

		if (NULL == profile) {
			scan_filter->EncryptionType.numEntries = 1;
			scan_filter->EncryptionType.encryptionType[0]
				= eCSR_ENCRYPT_TYPE_NONE;
		} else {
			/* Here is the profile we need to connect to */
			status = csr_roam_prepare_filter_from_profile(mac_ctx,
					profile,
					scan_filter);
		}

		if (QDF_STATUS_SUCCESS == status) {
			/* Save the WPS info */
			if (NULL != profile) {
				scan_filter->bWPSAssociation =
						 profile->bWPSAssociation;
				scan_filter->bOSENAssociation =
						 profile->bOSENAssociation;
			} else {
				scan_filter->bWPSAssociation = 0;
				scan_filter->bOSENAssociation = 0;
			}
		} else {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				FL("Preparing the profile filter failed"));
			qdf_mem_free(scan_filter);
			return QDF_STATUS_E_FAILURE;
		}
	}
	status = sme_acquire_global_lock(&mac_ctx->sme);
	if (QDF_STATUS_SUCCESS == status) {
		status = csr_scan_get_result(hal_handle, scan_filter,
					  &filtered_scan_result);
		if (QDF_STATUS_SUCCESS == status) {
			csr_get_bssdescr_from_scan_handle(filtered_scan_result,
					&first_ap_profile);
			*scan_cache = filtered_scan_result;
			if (0 != first_ap_profile.channelId) {
				*ap_chnl_id = first_ap_profile.channelId;
				QDF_TRACE(QDF_MODULE_ID_SME,
					  QDF_TRACE_LEVEL_ERROR,
					  FL("Found best AP & its on chnl[%d]"),
					  first_ap_profile.channelId);
			} else {
				/*
				 * This means scan result is empty
				 * so set the channel to zero, caller should
				 * take of zero channel id case.
				 */
				*ap_chnl_id = 0;
				QDF_TRACE(QDF_MODULE_ID_SME,
					  QDF_TRACE_LEVEL_ERROR,
					  FL("Scan is empty, set chnl to 0"));
				status = QDF_STATUS_E_FAILURE;
			}
		} else {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
					FL("Failed to get scan get result"));
			status = QDF_STATUS_E_FAILURE;
		}
		csr_free_scan_filter(mac_ctx, scan_filter);
		sme_release_global_lock(&mac_ctx->sme);
	} else {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				FL("Aquiring lock failed"));
		csr_free_scan_filter(mac_ctx, scan_filter);
		status = QDF_STATUS_E_FAILURE;
	}
	qdf_mem_free(scan_filter);
	return status;
}

/**
 * sme_store_joinreq_param() - This function will pass station's join
 * request to store to csr.
 * @hal_handle: pointer to hal context.
 * @profile: pointer to station's roam profile.
 * @scan_cache: pointer to station's scan cache.
 * @roam_id: reference to roam_id variable being passed.
 * @session_id: station's session id.
 *
 * This function will pass station's join request further down to csr
 * to store it. this stored parameter will be used later.
 *
 * Return: true or false based on function's overall success.
 **/
bool sme_store_joinreq_param(tHalHandle hal_handle,
		tCsrRoamProfile *profile,
		tScanResultHandle scan_cache,
		uint32_t *roam_id,
		uint32_t session_id)
{
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_handle);
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	bool ret_status = true;

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			TRACE_CODE_SME_RX_HDD_STORE_JOIN_REQ,
			session_id, 0));
	status = sme_acquire_global_lock(&mac_ctx->sme);
	if (QDF_STATUS_SUCCESS == status) {
		if (false == csr_store_joinreq_param(mac_ctx, profile,
					scan_cache, roam_id, session_id)) {
			ret_status = false;
		}
		sme_release_global_lock(&mac_ctx->sme);
	} else {
		ret_status = false;
	}

	return ret_status;
}

/**
 * sme_clear_joinreq_param() - This function will pass station's clear
 * the join request to csr.
 * @hal_handle: pointer to hal context.
 * @session_id: station's session id.
 *
 * This function will pass station's clear join request further down to csr
 * to cleanup.
 *
 * Return: true or false based on function's overall success.
 **/
bool sme_clear_joinreq_param(tHalHandle hal_handle,
		uint32_t session_id)
{
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_handle);
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	bool ret_status = true;

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
				TRACE_CODE_SME_RX_HDD_CLEAR_JOIN_REQ,
				session_id, 0));
	status = sme_acquire_global_lock(&mac_ctx->sme);
	if (QDF_STATUS_SUCCESS == status) {
		if (false == csr_clear_joinreq_param(mac_ctx,
					session_id)) {
			ret_status = false;
		}
		sme_release_global_lock(&mac_ctx->sme);
	} else {
		ret_status = false;
	}

	return ret_status;
}

/**
 * sme_issue_stored_joinreq() - This function will issues station's stored
 * the join request to csr.
 * @hal_handle: pointer to hal context.
 * @roam_id: reference to roam_id variable being passed.
 * @session_id: station's session id.
 *
 * This function will issue station's stored join request further down to csr
 * to proceed forward.
 *
 * Return: QDF_STATUS_SUCCESS or QDF_STATUS_E_FAILURE.
 **/
QDF_STATUS sme_issue_stored_joinreq(tHalHandle hal_handle,
		uint32_t *roam_id,
		uint32_t session_id)
{
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_handle);
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	QDF_STATUS ret_status = QDF_STATUS_SUCCESS;

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
				TRACE_CODE_SME_RX_HDD_ISSUE_JOIN_REQ,
				session_id, 0));
	status = sme_acquire_global_lock(&mac_ctx->sme);
	if (QDF_STATUS_SUCCESS == status) {
		if (QDF_STATUS_SUCCESS != csr_issue_stored_joinreq(mac_ctx,
					roam_id,
					session_id)) {
			ret_status = QDF_STATUS_E_FAILURE;
		}
		sme_release_global_lock(&mac_ctx->sme);
	} else {
		csr_clear_joinreq_param(mac_ctx, session_id);
		ret_status = QDF_STATUS_E_FAILURE;
	}
	return ret_status;
}

/* ---------------------------------------------------------------------------
    \fn sme_scan_flush_result
    \brief a wrapper function to request CSR to clear scan results.
    This is a synchronous call
    \return QDF_STATUS
   ---------------------------------------------------------------------------*/
QDF_STATUS sme_scan_flush_result(tHalHandle hHal)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_MSG_SCAN_FLUSH_RESULTS,
			 0, 0));
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		status = csr_scan_flush_result(hHal);
		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_filter_scan_results
    \brief a wrapper function to request CSR to clear scan results.
    This is a synchronous call
    \param tHalHandle - HAL context handle
    \param sessionId - session id
    \return QDF_STATUS
   ---------------------------------------------------------------------------*/
QDF_STATUS sme_filter_scan_results(tHalHandle hHal, uint8_t sessionId)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_MSG_SCAN_FLUSH_RESULTS,
			 sessionId, 0));
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		csr_scan_filter_results(pMac);
		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

QDF_STATUS sme_scan_flush_p2p_result(tHalHandle hHal, uint8_t sessionId)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_MSG_SCAN_FLUSH_P2PRESULTS,
			 sessionId, 0));
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		status = csr_scan_flush_selective_result(hHal, true);
		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_scan_result_get_first
    \brief a wrapper function to request CSR to returns the first element of
	scan result.
    This is a synchronous call
    \param hScanResult - returned from csr_scan_get_result
    \return tCsrScanResultInfo * - NULL if no result
   ---------------------------------------------------------------------------*/
tCsrScanResultInfo *sme_scan_result_get_first(tHalHandle hHal,
					      tScanResultHandle hScanResult)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	tCsrScanResultInfo *pRet = NULL;

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_MSG_SCAN_RESULT_GETFIRST,
			 NO_SESSION, 0));
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		pRet = csr_scan_result_get_first(pMac, hScanResult);
		sme_release_global_lock(&pMac->sme);
	}

	return pRet;
}

/* ---------------------------------------------------------------------------
    \fn sme_scan_result_get_next
    \brief a wrapper function to request CSR to returns the next element of
	scan result. It can be called without calling csr_scan_result_get_first
	first
    This is a synchronous call
    \param hScanResult - returned from csr_scan_get_result
    \return Null if no result or reach the end
   ---------------------------------------------------------------------------*/
tCsrScanResultInfo *sme_scan_result_get_next(tHalHandle hHal,
					     tScanResultHandle hScanResult)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	tCsrScanResultInfo *pRet = NULL;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		pRet = csr_scan_result_get_next(pMac, hScanResult);
		sme_release_global_lock(&pMac->sme);
	}

	return pRet;
}

/* ---------------------------------------------------------------------------
    \fn sme_scan_result_purge
    \brief a wrapper function to request CSR to remove all items(tCsrScanResult)
	in the list and free memory for each item
    This is a synchronous call
    \param hScanResult - returned from csr_scan_get_result. hScanResult is
			 considered gone by
    calling this function and even before this function reutrns.
    \return QDF_STATUS
   ---------------------------------------------------------------------------*/
QDF_STATUS sme_scan_result_purge(tHalHandle hHal, tScanResultHandle hScanResult)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_MSG_SCAN_RESULT_PURGE,
			 NO_SESSION, 0));
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		status = csr_scan_result_purge(hHal, hScanResult);
		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_scan_get_pmkid_candidate_list
    \brief a wrapper function to return the PMKID candidate list
    This is a synchronous call
    \param pPmkidList - caller allocated buffer point to an array of
			tPmkidCandidateInfo
    \param pNumItems - pointer to a variable that has the number of
		       tPmkidCandidateInfo allocated when retruning, this is
		       either the number needed or number of items put into
		       pPmkidList
    \return QDF_STATUS - when fail, it usually means the buffer allocated is not
			 big enough and pNumItems
			 has the number of tPmkidCandidateInfo.
    \Note: pNumItems is a number of tPmkidCandidateInfo,
	   not sizeof(tPmkidCandidateInfo) * something
   ---------------------------------------------------------------------------*/
QDF_STATUS sme_scan_get_pmkid_candidate_list(tHalHandle hHal, uint8_t sessionId,
					     tPmkidCandidateInfo *pPmkidList,
					     uint32_t *pNumItems)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		status =
			csr_scan_get_pmkid_candidate_list(pMac, sessionId,
							  pPmkidList,
							  pNumItems);
		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

eCsrPhyMode sme_get_phy_mode(tHalHandle hHal)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	return pMac->roam.configParam.phyMode;
}

/* ---------------------------------------------------------------------------
    \fn sme_get_channel_bonding_mode5_g
    \brief get the channel bonding mode for 5G band
    \param hHal - HAL handle
    \return channel bonding mode for 5G
   ---------------------------------------------------------------------------*/
uint32_t sme_get_channel_bonding_mode5_g(tHalHandle hHal)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	tSmeConfigParams smeConfig;

	sme_get_config_param(pMac, &smeConfig);

	return smeConfig.csrConfig.channelBondingMode5GHz;
}

/* ---------------------------------------------------------------------------
    \fn sme_get_channel_bonding_mode24_g
    \brief get the channel bonding mode for 2.4G band
    \param hHal - HAL handle
    \return channel bonding mode for 2.4G
   ---------------------------------------------------------------------------*/
uint32_t sme_get_channel_bonding_mode24_g(tHalHandle hHal)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	tSmeConfigParams smeConfig;

	sme_get_config_param(pMac, &smeConfig);

	return smeConfig.csrConfig.channelBondingMode24GHz;
}

/* ---------------------------------------------------------------------------
    \fn sme_roam_connect
    \brief a wrapper function to request CSR to inititiate an association
    This is an asynchronous call.
    \param sessionId - the sessionId returned by sme_open_session.
    \param pProfile - description of the network to which to connect
    \param hBssListIn - a list of BSS descriptor to roam to. It is returned
			from csr_scan_get_result
    \param pRoamId - to get back the request ID
    \return QDF_STATUS
   ---------------------------------------------------------------------------*/
QDF_STATUS sme_roam_connect(tHalHandle hHal, uint8_t sessionId,
			    tCsrRoamProfile *pProfile, uint32_t *pRoamId)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	if (!pMac) {
		return QDF_STATUS_E_FAILURE;
	}

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_MSG_CONNECT, sessionId, 0));
	sms_log(pMac, LOG2, FL("enter"));
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
			status =
				csr_roam_connect(pMac, sessionId, pProfile,
						 pRoamId);
		} else {
			sms_log(pMac, LOGE, FL("invalid sessionID %d"),
				sessionId);
			status = QDF_STATUS_E_INVAL;
		}
		sme_release_global_lock(&pMac->sme);
	} else {
		sms_log(pMac, LOGE, FL("sme_acquire_global_lock failed"));
	}

	return status;
}

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

    \fn sme_set_phy_mode

    \brief Changes the PhyMode.

    \param hHal - The handle returned by mac_open.

    \param phyMode new phyMode which is to set

    \return QDF_STATUS  SUCCESS.

   -------------------------------------------------------------------------------*/
QDF_STATUS sme_set_phy_mode(tHalHandle hHal, eCsrPhyMode phyMode)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	if (NULL == pMac) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "%s: invalid context", __func__);
		return QDF_STATUS_E_FAILURE;
	}

	pMac->roam.configParam.phyMode = phyMode;
	pMac->roam.configParam.uCfgDot11Mode =
		csr_get_cfg_dot11_mode_from_csr_phy_mode(NULL,
							 pMac->roam.configParam.phyMode,
							 pMac->roam.configParam.
							 ProprietaryRatesEnabled);

	return QDF_STATUS_SUCCESS;
}

/* ---------------------------------------------------------------------------
    \fn sme_roam_reassoc
    \brief a wrapper function to request CSR to inititiate a re-association
    \param pProfile - can be NULL to join the currently connected AP. In that
    case modProfileFields should carry the modified field(s) which could trigger
    reassoc
    \param modProfileFields - fields which are part of tCsrRoamConnectedProfile
    that might need modification dynamically once STA is up & running and this
    could trigger a reassoc
    \param pRoamId - to get back the request ID
    \return QDF_STATUS
   -------------------------------------------------------------------------------*/
QDF_STATUS sme_roam_reassoc(tHalHandle hHal, uint8_t sessionId,
			    tCsrRoamProfile *pProfile,
			    tCsrRoamModifyProfileFields modProfileFields,
			    uint32_t *pRoamId, bool fForce)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_ROAM_REASSOC, sessionId, 0));
	sms_log(pMac, LOG2, FL("enter"));
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
			if ((NULL == pProfile) && (fForce == 1)) {
				status =
					csr_reassoc(pMac, sessionId,
						    &modProfileFields, pRoamId,
						    fForce);
			} else {
				status =
					csr_roam_reassoc(pMac, sessionId, pProfile,
							 modProfileFields, pRoamId);
			}
		} else {
			status = QDF_STATUS_E_INVAL;
		}
		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_roam_connect_to_last_profile
    \brief a wrapper function to request CSR to disconnect and reconnect with
	the same profile
    This is an asynchronous call.
    \return QDF_STATUS. It returns fail if currently connected
   ---------------------------------------------------------------------------*/
QDF_STATUS sme_roam_connect_to_last_profile(tHalHandle hHal, uint8_t sessionId)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_ROAM_GET_CONNECTPROFILE,
			 sessionId, 0));
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
			status = csr_roam_connect_to_last_profile(pMac, sessionId);
		} else {
			status = QDF_STATUS_E_INVAL;
		}
		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_roam_disconnect
    \brief a wrapper function to request CSR to disconnect from a network
    This is an asynchronous call.
    \param reason -- To indicate the reason for disconnecting. Currently, only
		     eCSR_DISCONNECT_REASON_MIC_ERROR is meanful.
    \return QDF_STATUS
   ---------------------------------------------------------------------------*/
QDF_STATUS sme_roam_disconnect(tHalHandle hHal, uint8_t sessionId,
			       eCsrRoamDisconnectReason reason)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_ROAM_DISCONNECT, sessionId,
			 reason));
	sms_log(pMac, LOG2, FL("enter"));
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
			status = csr_roam_disconnect(pMac, sessionId, reason);
		} else {
			status = QDF_STATUS_E_INVAL;
		}
		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_roam_stop_bss
    \brief To stop BSS for Soft AP. This is an asynchronous API.
    \param hHal - Global structure
    \param sessionId - sessionId of SoftAP
    \return QDF_STATUS  SUCCESS  Roam callback will be called to indicate actual results
   -------------------------------------------------------------------------------*/
QDF_STATUS sme_roam_stop_bss(tHalHandle hHal, uint8_t sessionId)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	sms_log(pMac, LOG2, FL("enter"));
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
			status = csr_roam_issue_stop_bss_cmd(pMac, sessionId, true);
		} else {
			status = QDF_STATUS_E_INVAL;
		}
		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

/**
 * sme_roam_disconnect_sta() - disassociate a station
 * @hHal:          Global structure
 * @sessionId:     SessionId of SoftAP
 * @p_del_sta_params: Pointer to parameters of the station to disassoc
 *
 * To disassociate a station. This is an asynchronous API.
 *
 * Return: QDF_STATUS_SUCCESS on success.Roam callback will
 *         be called to indicate actual result.
 */
QDF_STATUS sme_roam_disconnect_sta(tHalHandle hHal, uint8_t sessionId,
				   struct tagCsrDelStaParams *p_del_sta_params)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	if (NULL == pMac) {
		QDF_ASSERT(0);
		return status;
	}

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
			status = csr_roam_issue_disassociate_sta_cmd(pMac,
					sessionId, p_del_sta_params);
		} else {
			status = QDF_STATUS_E_INVAL;
		}
		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

/**
 * sme_roam_deauth_sta() - deauthenticate a station
 * @hHal:          Global structure
 * @sessionId:     SessionId of SoftAP
 * @pDelStaParams: Pointer to parameters of the station to deauthenticate
 *
 * To disassociate a station. This is an asynchronous API.
 *
 * Return: QDF_STATUS_SUCCESS on success or another QDF_STATUS error
 *         code on error. Roam callback will be called to indicate actual
 *         result
 */
QDF_STATUS sme_roam_deauth_sta(tHalHandle hHal, uint8_t sessionId,
			       struct tagCsrDelStaParams *pDelStaParams)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	if (NULL == pMac) {
		QDF_ASSERT(0);
		return status;
	}

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_MSG_DEAUTH_STA,
			 sessionId, pDelStaParams->reason_code));
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
			status =
				csr_roam_issue_deauth_sta_cmd(pMac, sessionId,
							      pDelStaParams);
		} else {
			status = QDF_STATUS_E_INVAL;
		}
		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_roam_tkip_counter_measures
    \brief To start or stop TKIP counter measures. This is an asynchronous API.
    \param sessionId - sessionId of SoftAP
    \param pPeerMacAddr - Caller allocated memory filled with peer MAC address (6 bytes)
    \return QDF_STATUS
   -------------------------------------------------------------------------------*/
QDF_STATUS sme_roam_tkip_counter_measures(tHalHandle hHal, uint8_t sessionId,
					  bool bEnable)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	if (NULL == pMac) {
		QDF_ASSERT(0);
		return status;
	}

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
			status =
				csr_roam_issue_tkip_counter_measures(pMac, sessionId,
								     bEnable);
		} else {
			status = QDF_STATUS_E_INVAL;
		}
		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_roam_get_associated_stas
    \brief To probe the list of associated stations from various modules
	 of CORE stack.
    \This is an asynchronous API.
    \param sessionId    - sessionId of SoftAP
    \param modId        - Module from whom list of associtated stations is
			  to be probed. If an invalid module is passed then
			  by default QDF_MODULE_ID_PE will be probed.
    \param pUsrContext  - Opaque HDD context
    \param pfnSapEventCallback  - Sap event callback in HDD
    \param pAssocBuf    - Caller allocated memory to be filled with associatd
			  stations info
    \return QDF_STATUS
   -------------------------------------------------------------------------------*/
QDF_STATUS sme_roam_get_associated_stas(tHalHandle hHal, uint8_t sessionId,
					QDF_MODULE_ID modId, void *pUsrContext,
					void *pfnSapEventCallback,
					uint8_t *pAssocStasBuf)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	if (NULL == pMac) {
		QDF_ASSERT(0);
		return status;
	}

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
			status =
				csr_roam_get_associated_stas(pMac, sessionId, modId,
							     pUsrContext,
							     pfnSapEventCallback,
							     pAssocStasBuf);
		} else {
			status = QDF_STATUS_E_INVAL;
		}
		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_roam_get_wps_session_overlap
    \brief To get the WPS PBC session overlap information.
    \This is an asynchronous API.
    \param sessionId    - sessionId of SoftAP
    \param pUsrContext  - Opaque HDD context
    \param pfnSapEventCallback  - Sap event callback in HDD
    \pRemoveMac - pointer to Mac address which needs to be removed from session
    \return QDF_STATUS
   -------------------------------------------------------------------------------*/
QDF_STATUS sme_roam_get_wps_session_overlap(tHalHandle hHal, uint8_t sessionId,
					    void *pUsrContext, void
					    *pfnSapEventCallback,
					    struct qdf_mac_addr pRemoveMac)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	if (NULL == pMac) {
		QDF_ASSERT(0);
		return status;
	}

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
			status =
				csr_roam_get_wps_session_overlap(pMac, sessionId,
								 pUsrContext,
								 pfnSapEventCallback,
								 pRemoveMac);
		} else {
			status = QDF_STATUS_E_INVAL;
		}
		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_roam_get_connect_state
    \brief a wrapper function to request CSR to return the current connect state
	of Roaming
    This is a synchronous call.
    \return QDF_STATUS
   ---------------------------------------------------------------------------*/
QDF_STATUS sme_roam_get_connect_state(tHalHandle hHal, uint8_t sessionId,
				      eCsrConnectState *pState)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
			status =
				csr_roam_get_connect_state(pMac, sessionId, pState);
		} else {
			status = QDF_STATUS_E_INVAL;
		}
		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_roam_get_connect_profile
    \brief a wrapper function to request CSR to return the current connect
	profile. Caller must call csr_roam_free_connect_profile after it is done
	and before reuse for another csr_roam_get_connect_profile call.
    This is a synchronous call.
    \param pProfile - pointer to a caller allocated structure
		      tCsrRoamConnectedProfile
    \return QDF_STATUS. Failure if not connected
   ---------------------------------------------------------------------------*/
QDF_STATUS sme_roam_get_connect_profile(tHalHandle hHal, uint8_t sessionId,
					tCsrRoamConnectedProfile *pProfile)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_ROAM_GET_CONNECTPROFILE,
			 sessionId, 0));
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
			status =
				csr_roam_get_connect_profile(pMac, sessionId, pProfile);
		} else {
			status = QDF_STATUS_E_INVAL;
		}
		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

/**
 * sme_roam_free_connect_profile - a wrapper function to request CSR to free and
 * reinitialize the profile returned previously by csr_roam_get_connect_profile.
 *
 * @profile - pointer to a caller allocated structure tCsrRoamConnectedProfile
 *
 * Return: none
 */
void sme_roam_free_connect_profile(tCsrRoamConnectedProfile *profile)
{
	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_ROAM_FREE_CONNECTPROFILE,
			 NO_SESSION, 0));
	csr_roam_free_connect_profile(profile);
}

/* ---------------------------------------------------------------------------
    \fn sme_roam_set_pmkid_cache
    \brief a wrapper function to request CSR to return the PMKID candidate list
    This is a synchronous call.
    \param pPMKIDCache - caller allocated buffer point to an array of
			 tPmkidCacheInfo
    \param numItems - a variable that has the number of tPmkidCacheInfo
		      allocated when retruning, this is either the number needed
		      or number of items put into pPMKIDCache
    \param update_entire_cache - this bool value specifies if the entire pmkid
				 cache should be overwritten or should it be
				 updated entry by entry.
    \return QDF_STATUS - when fail, it usually means the buffer allocated is not
			 big enough and pNumItems has the number of
			 tPmkidCacheInfo.
    \Note: pNumItems is a number of tPmkidCacheInfo,
	   not sizeof(tPmkidCacheInfo) * something
   ---------------------------------------------------------------------------*/
QDF_STATUS sme_roam_set_pmkid_cache(tHalHandle hHal, uint8_t sessionId,
				    tPmkidCacheInfo *pPMKIDCache,
				    uint32_t numItems, bool update_entire_cache)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_ROAM_SET_PMKIDCACHE, sessionId,
			 numItems));
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
			status =
				csr_roam_set_pmkid_cache(pMac, sessionId, pPMKIDCache,
							 numItems, update_entire_cache);
		} else {
			status = QDF_STATUS_E_INVAL;
		}
		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

QDF_STATUS sme_roam_del_pmkid_from_cache(tHalHandle hHal, uint8_t sessionId,
					 const uint8_t *pBSSId, bool flush_cache)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_ROAM_DEL_PMKIDCACHE,
			 sessionId, flush_cache));
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
			status = csr_roam_del_pmkid_from_cache(pMac, sessionId,
							       pBSSId, flush_cache);
		} else {
			status = QDF_STATUS_E_INVAL;
		}
		sme_release_global_lock(&pMac->sme);
	}
	return status;
}

#ifdef WLAN_FEATURE_ROAM_OFFLOAD
/* ---------------------------------------------------------------------------
 * \fn sme_roam_set_psk_pmk
 * \brief a wrapper function to request CSR to save PSK/PMK
 *  This is a synchronous call.
 * \param hHal - Global structure
 * \param sessionId - SME sessionId
 * \param pPSK_PMK - pointer to an array of Psk[]/Pmk
 * \param pmk_len - Length could be only 16 bytes in case if LEAP
 *                  connections. Need to pass this information to
 *                  firmware.
 * \return QDF_STATUS -status whether PSK/PMK is set or not
 *---------------------------------------------------------------------------
 */
QDF_STATUS sme_roam_set_psk_pmk(tHalHandle hHal, uint8_t sessionId,
				uint8_t *pPSK_PMK, size_t pmk_len)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
			status =
				csr_roam_set_psk_pmk(pMac, sessionId, pPSK_PMK,
						     pmk_len);
		} else {
			status = QDF_STATUS_E_INVAL;
		}
		sme_release_global_lock(&pMac->sme);
	}
	return status;
}
#endif
/* ---------------------------------------------------------------------------
    \fn sme_roam_get_security_req_ie
    \brief a wrapper function to request CSR to return the WPA or RSN or WAPI IE CSR
	passes to PE to JOIN request or START_BSS request
    This is a synchronous call.
    \param pLen - caller allocated memory that has the length of pBuf as input.
		  Upon returned, *pLen has the needed or IE length in pBuf.
    \param pBuf - Caller allocated memory that contain the IE field, if any,
		  upon return
    \param secType - Specifies whether looking for WPA/WPA2/WAPI IE
    \return QDF_STATUS - when fail, it usually means the buffer allocated is not
			 big enough
   ---------------------------------------------------------------------------*/
QDF_STATUS sme_roam_get_security_req_ie(tHalHandle hHal, uint8_t sessionId,
					uint32_t *pLen, uint8_t *pBuf,
					eCsrSecurityType secType)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
			status =
				csr_roam_get_wpa_rsn_req_ie(hHal, sessionId, pLen, pBuf);
		} else {
			status = QDF_STATUS_E_INVAL;
		}
		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_roam_get_security_rsp_ie
    \brief a wrapper function to request CSR to return the WPA or RSN or
	 WAPI IE from the beacon or probe rsp if connected
    This is a synchronous call.
    \param pLen - caller allocated memory that has the length of pBuf as input.
		  Upon returned, *pLen has the needed or IE length in pBuf.
    \param pBuf - Caller allocated memory that contain the IE field, if any,
		  upon return
    \param secType - Specifies whether looking for WPA/WPA2/WAPI IE
    \return QDF_STATUS - when fail, it usually means the buffer allocated is not
			 big enough
   ---------------------------------------------------------------------------*/
QDF_STATUS sme_roam_get_security_rsp_ie(tHalHandle hHal, uint8_t sessionId,
					uint32_t *pLen, uint8_t *pBuf,
					eCsrSecurityType secType)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
			status =
				csr_roam_get_wpa_rsn_rsp_ie(pMac, sessionId, pLen, pBuf);
		} else {
			status = QDF_STATUS_E_INVAL;
		}
		sme_release_global_lock(&pMac->sme);
	}

	return status;

}

/* ---------------------------------------------------------------------------
    \fn sme_roam_get_num_pmkid_cache
    \brief a wrapper function to request CSR to return number of PMKID cache
	entries
    This is a synchronous call.
    \return uint32_t - the number of PMKID cache entries
   ---------------------------------------------------------------------------*/
uint32_t sme_roam_get_num_pmkid_cache(tHalHandle hHal, uint8_t sessionId)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	uint32_t numPmkidCache = 0;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
			numPmkidCache =
				csr_roam_get_num_pmkid_cache(pMac, sessionId);
			status = QDF_STATUS_SUCCESS;
		} else {
			status = QDF_STATUS_E_INVAL;
		}
		sme_release_global_lock(&pMac->sme);
	}

	return numPmkidCache;
}

/* ---------------------------------------------------------------------------
    \fn sme_roam_get_pmkid_cache
    \brief a wrapper function to request CSR to return PMKID cache from CSR
    This is a synchronous call.
    \param pNum - caller allocated memory that has the space of the number of
		  pBuf tPmkidCacheInfo as input. Upon returned, *pNum has the
		  needed or actually number in tPmkidCacheInfo.
    \param pPmkidCache - Caller allocated memory that contains PMKID cache, if
			 any, upon return
    \return QDF_STATUS - when fail, it usually means the buffer allocated is not
			 big enough
   ---------------------------------------------------------------------------*/
QDF_STATUS sme_roam_get_pmkid_cache(tHalHandle hHal, uint8_t sessionId,
				    uint32_t *pNum, tPmkidCacheInfo *pPmkidCache)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_ROAM_GET_PMKIDCACHE, sessionId,
			 0));
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
			status =
				csr_roam_get_pmkid_cache(pMac, sessionId, pNum,
							 pPmkidCache);
		} else {
			status = QDF_STATUS_E_INVAL;
		}
		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_get_config_param
    \brief a wrapper function that HDD calls to get the global settings
	currently maintained by CSR.
    This is a synchronous call.
    \param pParam - caller allocated memory
    \return QDF_STATUS
   ---------------------------------------------------------------------------*/
QDF_STATUS sme_get_config_param(tHalHandle hHal, tSmeConfigParams *pParam)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_GET_CONFIGPARAM, NO_SESSION, 0));
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		status = csr_get_config_param(pMac, &pParam->csrConfig);
		if (status != QDF_STATUS_SUCCESS) {
			sms_log(pMac, LOGE, "%s csr_get_config_param failed",
				__func__);
			sme_release_global_lock(&pMac->sme);
			return status;
		}
		qdf_mem_copy(&pParam->rrmConfig,
				&pMac->rrm.rrmSmeContext.rrmConfig,
				sizeof(pMac->rrm.rrmSmeContext.rrmConfig));
		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

/**
 * sme_cfg_set_int() - Sets the cfg parameter value.
 * @hal:	Handle to hal.
 * @cfg_id:	Configuration parameter ID.
 * @value: 	value to be saved in the cfg parameter.
 *
 * This function sets the string value in cfg parameter.
 *
 * Return: QDF_STATUS
 */
QDF_STATUS sme_cfg_set_int(tHalHandle hal, uint16_t cfg_id, uint32_t value)
{
	tpAniSirGlobal pmac = PMAC_STRUCT(hal);
	QDF_STATUS status = QDF_STATUS_SUCCESS;

	if (eSIR_SUCCESS != cfg_set_int(pmac, cfg_id, value))
		status = QDF_STATUS_E_FAILURE;

	return status;
}

/**
 * sme_cfg_set_str() - Sets the cfg parameter string.
 * @hal:	Handle to hal.
 * @cfg_id:	Configuration parameter ID.
 * @str:	Pointer to the string buffer.
 * @length:	Length of the string.
 *
 * This function sets the string value in cfg parameter.
 *
 * Return: QDF_STATUS
 */
QDF_STATUS sme_cfg_set_str(tHalHandle hal, uint16_t cfg_id, uint8_t *str,
			   uint32_t length)
{
	tpAniSirGlobal pmac = PMAC_STRUCT(hal);
	QDF_STATUS status = QDF_STATUS_SUCCESS;

	if (eSIR_SUCCESS != cfg_set_str(pmac, cfg_id, str, length))
		status = QDF_STATUS_E_FAILURE;

	return status;
}

/**
 * sme_cfg_get_int() -  Gets the cfg parameter value.
 * @hal:	Handle to hal.
 * @cfg_id:	Configuration parameter ID.
 * @cfg_value:	Pointer to variable in which cfg value
 * 		will be saved.
 *
 * This function gets the value of the cfg parameter.
 *
 * Return: QDF_STATUS
 */
QDF_STATUS sme_cfg_get_int(tHalHandle hal, uint16_t cfg_id, uint32_t *cfg_value)
{
	tpAniSirGlobal pmac = PMAC_STRUCT(hal);
	QDF_STATUS status = QDF_STATUS_SUCCESS;

	if (eSIR_SUCCESS != wlan_cfg_get_int(pmac, cfg_id, cfg_value))
		status = QDF_STATUS_E_FAILURE;

	return status;
}

/**
 * sme_cfg_get_str() - Gets the cfg parameter string.
 * @hal:	Handle to hal.
 * @cfg_id:	Configuration parameter ID.
 * @str:	Pointer to the string buffer.
 * @length:	Pointer to length of the string.
 *
 * This function gets the string value of the cfg parameter.
 *
 * Return: QDF_STATUS
 */
QDF_STATUS sme_cfg_get_str(tHalHandle hal, uint16_t cfg_id, uint8_t *str,
			   uint32_t *length)
{
	tpAniSirGlobal pmac = PMAC_STRUCT(hal);
	QDF_STATUS status = QDF_STATUS_SUCCESS;

	if (eSIR_SUCCESS != wlan_cfg_get_str(pmac, cfg_id, str, length))
		status = QDF_STATUS_E_INVAL;

	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_get_modify_profile_fields
    \brief HDD or SME - QOS calls this function to get the current values of
    connected profile fields, changing which can cause reassoc.
    This function must be called after CFG is downloaded and STA is in connected
    state. Also, make sure to call this function to get the current profile
    fields before calling the reassoc. So that pModifyProfileFields will have
    all the latest values plus the one(s) has been updated as part of reassoc
    request.
    \param pModifyProfileFields - pointer to the connected profile fields
    changing which can cause reassoc

    \return QDF_STATUS
   -------------------------------------------------------------------------------*/
QDF_STATUS sme_get_modify_profile_fields(tHalHandle hHal, uint8_t sessionId,
					 tCsrRoamModifyProfileFields *
					 pModifyProfileFields)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_GET_MODPROFFIELDS, sessionId,
			 0));
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
			status =
				csr_get_modify_profile_fields(pMac, sessionId,
							      pModifyProfileFields);
		} else {
			status = QDF_STATUS_E_INVAL;
		}
		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

/* ---------------------------------------------------------------------------
    \fn  sme_set_dhcp_till_power_active_flag
    \brief  Sets/Clears DHCP related flag to disable/enable auto PS
    \param  hal - The handle returned by mac_open.
   ---------------------------------------------------------------------------*/
void sme_set_dhcp_till_power_active_flag(tHalHandle hal, uint8_t flag)
{
	tpAniSirGlobal mac = PMAC_STRUCT(hal);
	struct ps_global_info *ps_global_info = &mac->sme.ps_global_info;

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
				TRACE_CODE_SME_RX_HDD_SET_DHCP_FLAG, NO_SESSION,
				flag));
	/* Set/Clear the DHCP flag which will disable/enable auto PS */
	ps_global_info->remain_in_power_active_till_dhcp = flag;
}

/* ---------------------------------------------------------------------------
    \fn sme_register11d_scan_done_callback
    \brief  Register a routine of type csr_scan_completeCallback which is
	called whenever an 11d scan is done
    \param  hHal - The handle returned by mac_open.
    \param  callback -  11d scan complete routine to be registered
    \return QDF_STATUS
   ---------------------------------------------------------------------------*/
QDF_STATUS sme_register11d_scan_done_callback(tHalHandle hHal,
					      csr_scan_completeCallback callback)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	pMac->scan.callback11dScanDone = callback;

	return status;
}

/**
 * sme_deregister11d_scan_done_callback() - De-register scandone callback
 * @h_hal: Handler return by mac_open
 *
 * This function De-registers the scandone callback  to SME
 *
 * Return: None
 */
void sme_deregister11d_scan_done_callback(tHalHandle h_hal)
{
	tpAniSirGlobal pmac;

	if (!h_hal) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  FL("hHal is not valid"));
		return;
	}

	pmac = PMAC_STRUCT(h_hal);
	pmac->scan.callback11dScanDone = NULL;
}


#ifdef FEATURE_OEM_DATA_SUPPORT
/**
 * sme_register_oem_data_rsp_callback() - Register a routine of
 *                                        type send_oem_data_rsp_msg
 * @h_hal:                                Handle returned by mac_open.
 * @callback:                             Callback to send response
 *                                        to oem application.
 *
 * sme_oem_data_rsp_callback is used to register sme_send_oem_data_rsp_msg
 * callback function.
 *
 * Return: QDF_STATUS.
 */
QDF_STATUS sme_register_oem_data_rsp_callback(tHalHandle h_hal,
				sme_send_oem_data_rsp_msg callback)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pmac = PMAC_STRUCT(h_hal);

	pmac->sme.oem_data_rsp_callback = callback;

	return status;

}

/**
 * sme_deregister_oem_data_rsp_callback() - De-register OEM datarsp callback
 * @h_hal: Handler return by mac_open
 * This function De-registers the OEM data response callback  to SME
 *
 * Return: None
 */
void  sme_deregister_oem_data_rsp_callback(tHalHandle h_hal)
{
	tpAniSirGlobal pmac;

	if (!h_hal) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				  FL("hHal is not valid"));
		return;
	}
	pmac = PMAC_STRUCT(h_hal);

	pmac->sme.oem_data_rsp_callback = NULL;
}
#endif

/**
 * sme_oem_update_capability() - update UMAC's oem related capability.
 * @hal: Handle returned by mac_open
 * @oem_cap: pointer to oem_capability
 *
 * This function updates OEM capability to UMAC. Currently RTT
 * related capabilities are updated. More capabilities can be
 * added in future.
 *
 * Return: QDF_STATUS
 */
QDF_STATUS sme_oem_update_capability(tHalHandle hal,
				     struct sme_oem_capability *cap)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pmac = PMAC_STRUCT(hal);
	uint8_t *bytes;

	bytes = pmac->rrm.rrmSmeContext.rrmConfig.rm_capability;

	if (cap->ftm_rr)
		bytes[4] |= RM_CAP_FTM_RANGE_REPORT;
	if (cap->lci_capability)
		bytes[4] |= RM_CAP_CIVIC_LOC_MEASUREMENT;

	return status;
}

/**
 * sme_oem_get_capability() - get oem capability
 * @hal: Handle returned by mac_open
 * @oem_cap: pointer to oem_capability
 *
 * This function is used to get the OEM capability from UMAC.
 * Currently RTT related capabilities are received. More
 * capabilities can be added in future.
 *
 * Return: QDF_STATUS
 */
QDF_STATUS sme_oem_get_capability(tHalHandle hal,
				  struct sme_oem_capability *cap)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pmac = PMAC_STRUCT(hal);
	uint8_t *bytes;

	bytes = pmac->rrm.rrmSmeContext.rrmConfig.rm_capability;

	cap->ftm_rr = bytes[4] & RM_CAP_FTM_RANGE_REPORT;
	cap->lci_capability = bytes[4] & RM_CAP_CIVIC_LOC_MEASUREMENT;

	return status;
}

/**
 * sme_register_ftm_msg_processor() - registers hdd ftm message processor
 * function to MAC/SYS
 *
 * @hal:        hal handle
 * @callback:   hdd function that has to be registered
 *
 * Return: void
 */
void sme_register_ftm_msg_processor(tHalHandle hal,
				    hdd_ftm_msg_processor callback)
{
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);

	if (mac_ctx == NULL) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			FL("mac ctx is NULL"));
		return;
	}

	mac_ctx->ftm_msg_processor_callback = callback;
	return;
}

/**
 * sme_wow_add_pattern() - add a wow pattern in fw
 * @hHal: handle returned by mac_open
 * @pattern: pointer to input pattern
 *
 * Add a pattern for Pattern Byte Matching in WoW mode. Firmware will
 * do a pattern match on these patterns when WoW is enabled during system
 * suspend.
 *
 * Return: QDF_STATUS
 */
QDF_STATUS sme_wow_add_pattern(tHalHandle hal,
			struct wow_add_pattern *pattern,
			uint8_t session_id)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hal);
	struct wow_add_pattern *ptrn;
	tSirRetStatus ret_code = eSIR_SUCCESS;
	tSirMsgQ msg_q;
	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			TRACE_CODE_SME_RX_HDD_WOWL_ADDBCAST_PATTERN, session_id,
			0));
	ptrn = qdf_mem_malloc(sizeof(*ptrn));
	if (NULL == ptrn) {
		sms_log(pMac, LOGP,
			FL("Fail to allocate memory for WoWLAN Add Bcast Pattern "));
		return QDF_STATUS_E_NOMEM;
	}
	(void)qdf_mem_copy(ptrn, pattern, sizeof(*ptrn));

	msg_q.type = WMA_WOW_ADD_PTRN;
	msg_q.reserved = 0;
	msg_q.bodyptr = ptrn;
	msg_q.bodyval = 0;

	sms_log(pMac, LOG1, FL("Sending WMA_WOWL_ADD_BCAST_PTRN to HAL"));
	ret_code = wma_post_ctrl_msg(pMac, &msg_q);
	if (eSIR_SUCCESS != ret_code) {
		sms_log(pMac, LOGE,
			FL("Posting WMA_WOWL_ADD_BCAST_PTRN failed, reason=%X"),
			ret_code);
	}
	return ret_code;
}

/**
 * sme_wow_delete_pattern() - delete user configured wow pattern in target
 * @hHal: handle returned by mac_open.
 * @pattern: pointer to delete pattern parameter
 * @sessionId: session id
 *
 * Return: QDF_STATUS
 */
QDF_STATUS sme_wow_delete_pattern(tHalHandle hal,
		struct wow_delete_pattern *pattern, uint8_t sessionId)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hal);
	struct wow_delete_pattern *delete_ptrn;
	tSirRetStatus ret_code = eSIR_SUCCESS;
	tSirMsgQ msg_q;
	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_WOWL_DELBCAST_PATTERN, sessionId,
			 0));
	delete_ptrn = qdf_mem_malloc(sizeof(*delete_ptrn));
	if (NULL == delete_ptrn) {
		sms_log(pMac, LOGP,
			FL("Fail to allocate memory for WoWLAN Delete Bcast Pattern "));
		return QDF_STATUS_E_NOMEM;
	}
	(void)qdf_mem_copy(delete_ptrn, pattern, sizeof(*delete_ptrn));
	msg_q.type = WMA_WOW_DEL_PTRN;
	msg_q.reserved = 0;
	msg_q.bodyptr = delete_ptrn;
	msg_q.bodyval = 0;

	sms_log(pMac, LOG1, FL("Sending WMA_WOWL_DEL_BCAST_PTRN"));

	ret_code = wma_post_ctrl_msg(pMac, &msg_q);
	if (eSIR_SUCCESS != ret_code) {
		sms_log(pMac, LOGE,
			FL("Posting WMA_WOWL_DEL_BCAST_PTRN failed, reason=%X"),
			ret_code);
	}
	return ret_code;
}

/**
 * sme_enter_wowl(): SME API exposed to HDD to request enabling of WOWL mode.
 * @hal_ctx - The handle returned by mac_open.
 * @enter_wowl_callback_routine -  Callback routine provided by HDD.
 *		Used for success/failure notification by SME
 * @enter_wowl_callback_context - A cookie passed by HDD, that is passed
 *		back to HDD at the time of callback.
 * @wake_reason_ind_cb -  Callback routine provided by HDD.
 *		Used for Wake Reason Indication by SME
 * @wake_reason_ind_cb_ctx - A cookie passed by HDD, that is passed
 *		back to HDD at the time of callback.
 *
 * WoWLAN works on top of BMPS mode.
 * If the device is not in BMPS mode,
 * SME will will cache the information that
 * WOWL has been enabled and attempt to put the device
 * in BMPS. On entry into BMPS, SME will enable the
 * WOWL mode.
 * Note 1: If we exit BMPS mode (someone requests full power),
 * we will NOT resume WOWL when we go back to BMPS again.
 * Request for full power (while in WOWL mode) means disable
 * WOWL and go to full power.
 * Note 2: Both UAPSD and WOWL work on top of BMPS.
 * On entry into BMPS, SME will give priority to UAPSD and
 * enable only UAPSD if both UAPSD and WOWL are required.
 * Currently there is no requirement or use case to support
 * UAPSD and WOWL at the same time.
 *
 * Return: QDF_STATUS
 *	QDF_STATUS_SUCCESS  Device is already in WoWLAN mode
 *	QDF_STATUS_E_FAILURE  Device cannot enter WoWLAN mode.
 *	QDF_STATUS_PMC_PENDING  Request accepted. SME will enable
 *			WOWL after BMPS mode is entered.
 */
QDF_STATUS sme_enter_wowl(tHalHandle hal_ctx,
		void (*enter_wowl_callback_routine)(void
			*callback_context,
			QDF_STATUS status),
		void *enter_wowl_callback_context,
#ifdef WLAN_WAKEUP_EVENTS
		void (*wakeIndicationCB)(void *callback_context,
			tpSirWakeReasonInd
			wake_reason_ind),
		void *wakeIndicationCBContext,
#endif /* WLAN_WAKEUP_EVENTS */
		tpSirSmeWowlEnterParams wowl_enter_params,
		uint8_t session_id)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_ctx);
	struct ps_global_info *ps_global_info = &mac_ctx->sme.ps_global_info;
	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			TRACE_CODE_SME_RX_HDD_ENTER_WOWL, session_id, 0));

	/* cache the WOWL information */
	ps_global_info->ps_params[session_id].wowl_enter_params =
		*wowl_enter_params;
	ps_global_info->ps_params[session_id].enter_wowl_callback_routine =
		enter_wowl_callback_routine;
	ps_global_info->ps_params[session_id].enter_wowl_callback_context =
		enter_wowl_callback_context;
#ifdef WLAN_WAKEUP_EVENTS
	/* Cache the Wake Reason Indication callback information */
	ps_global_info->ps_params[session_id].wake_reason_ind_cb =
		wakeIndicationCB;
	ps_global_info->ps_params[session_id].wake_reason_ind_cb_ctx =
		wakeIndicationCBContext;
#endif /* WLAN_WAKEUP_EVENTS */

	status = sme_ps_process_command(mac_ctx, session_id, SME_PS_WOWL_ENTER);
	return status;
}
/**
 *sme_exit_wowl(): SME API exposed to HDD to request exit from WoWLAN mode.
 * @hal_ctx - The handle returned by mac_open.
 * @wowl_exit_params - Carries info on which smesession
 *			wowl exit is requested.
 *
 * SME will initiate exit from WoWLAN mode and device will be
 * put in BMPS mode.
 * Return QDF_STATUS
 *	QDF_STATUS_E_FAILURE  Device cannot exit WoWLAN mode.
 *	QDF_STATUS_SUCCESS  Request accepted to exit WoWLAN mode.
 */
QDF_STATUS sme_exit_wowl(tHalHandle hal_ctx,
		tpSirSmeWowlExitParams wowl_exit_params)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_ctx);
	uint8_t session_id;
	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			TRACE_CODE_SME_RX_HDD_EXIT_WOWL, NO_SESSION, 0));
	session_id = wowl_exit_params->sessionId;
	status = sme_ps_process_command(mac_ctx, session_id, SME_PS_WOWL_EXIT);
	return status;
}

/**
 * sme_roam_set_key() - To set encryption key.
 * @hal:           hal global context
 * @session_id:    session id
 * @set_key:       pointer to a caller allocated object of tCsrSetContextInfo
 * @ptr_roam_id:       Upon success return, this is the id caller can use to
 *                 identify the request in roamcallback
 *
 * This function should be called only when connected. This is an asynchronous
 * API.
 *
 * Return: Status of operation
 */
QDF_STATUS sme_roam_set_key(tHalHandle hal,  uint8_t session_id,
			    tCsrRoamSetKey *set_key, uint32_t *ptr_roam_id)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
	uint32_t roam_id;
	uint32_t i;
	tCsrRoamSession *session = NULL;
	struct ps_global_info *ps_global_info = &mac_ctx->sme.ps_global_info;

	MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_RX_HDD_SET_KEY,
			 session_id, 0));
	if (set_key->keyLength > CSR_MAX_KEY_LEN) {
		sms_log(mac_ctx, LOGE, FL("Invalid key length %d"),
			set_key->keyLength);
		return QDF_STATUS_E_FAILURE;
	}
	/*Once Setkey is done, we can go in BMPS */
	if (set_key->keyLength)
		ps_global_info->remain_in_power_active_till_dhcp = false;

	status = sme_acquire_global_lock(&mac_ctx->sme);
	if (!QDF_IS_STATUS_SUCCESS(status))
		return status;

	roam_id = GET_NEXT_ROAM_ID(&mac_ctx->roam);
	if (ptr_roam_id)
		*ptr_roam_id = roam_id;

	sms_log(mac_ctx, LOG2, FL("keyLength %d"), set_key->keyLength);
	for (i = 0; i < set_key->keyLength; i++)
		sms_log(mac_ctx, LOG2, FL("%02x"), set_key->Key[i]);

	sms_log(mac_ctx, LOG2, "\n session_id=%d roam_id=%d", session_id,
		roam_id);
	session = CSR_GET_SESSION(mac_ctx, session_id);
	if (!session) {
		sms_log(mac_ctx, LOGE, FL("session %d not found"), session_id);
		sme_release_global_lock(&mac_ctx->sme);
		return QDF_STATUS_E_FAILURE;
	}
	if (CSR_IS_INFRA_AP(&session->connectedProfile)
	    && set_key->keyDirection == eSIR_TX_DEFAULT) {
		if ((eCSR_ENCRYPT_TYPE_WEP40 == set_key->encType)
		    || (eCSR_ENCRYPT_TYPE_WEP40_STATICKEY ==
			set_key->encType)) {
			session->pCurRoamProfile->negotiatedUCEncryptionType =
				eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
		}
		if ((eCSR_ENCRYPT_TYPE_WEP104 == set_key->encType)
		    || (eCSR_ENCRYPT_TYPE_WEP104_STATICKEY ==
			set_key->encType)) {
			session->pCurRoamProfile->negotiatedUCEncryptionType =
				eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
		}
	}
	status = csr_roam_set_key(mac_ctx, session_id, set_key, roam_id);
	sme_release_global_lock(&mac_ctx->sme);
	return status;
}

/**
 * sme_roam_set_default_key_index - To set default wep key idx
 * @hal: pointer to hal handler
 * @session_id: session id
 * @default_idx: default wep key index
 *
 * This function prepares a message and post to WMA to set wep default
 * key index
 *
 * Return: Success:QDF_STATUS_SUCCESS Failure: Error value
 */
QDF_STATUS sme_roam_set_default_key_index(tHalHandle hal, uint8_t session_id,
					  uint8_t default_idx)
{
	cds_msg_t msg;
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
	struct wep_update_default_key_idx *update_key;

	update_key = qdf_mem_malloc(sizeof(*update_key));
	if (!update_key) {
		sms_log(mac_ctx, LOGE,
			FL("Failed to allocate memory for update key"));
		return QDF_STATUS_E_NOMEM;
	}

	update_key->session_id = session_id;
	update_key->default_idx = default_idx;

	msg.type = WMA_UPDATE_WEP_DEFAULT_KEY;
	msg.reserved = 0;
	msg.bodyptr = (void *)update_key;

	if (QDF_STATUS_SUCCESS !=
	    cds_mq_post_message(QDF_MODULE_ID_WMA, &msg)) {
		sms_log(mac_ctx, LOGE,
			FL("Failed to post WMA_UPDATE_WEP_DEFAULT_KEY to WMA"));
		qdf_mem_free(update_key);
		return QDF_STATUS_E_FAILURE;
	}

	return QDF_STATUS_SUCCESS;
}


/* ---------------------------------------------------------------------------
    \fn sme_get_rssi
    \brief a wrapper function that client calls to register a callback to get
	RSSI

    \param hHal - HAL handle for device
    \param callback - SME sends back the requested stats using the callback
    \param staId -    The station ID for which the stats is requested for
    \param bssid - The bssid of the connected session
    \param lastRSSI - RSSI value at time of request. In case fw cannot provide
		      RSSI, do not hold up but return this value.
    \param pContext - user context to be passed back along with the callback
    \param p_cds_context - cds context
    \return QDF_STATUS
   ---------------------------------------------------------------------------*/
QDF_STATUS sme_get_rssi(tHalHandle hHal,
			tCsrRssiCallback callback,
			uint8_t staId, struct qdf_mac_addr bssId, int8_t lastRSSI,
			void *pContext, void *p_cds_context)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_GET_RSSI, NO_SESSION, 0));
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		status = csr_get_rssi(pMac, callback,
				      staId, bssId, lastRSSI,
				      pContext, p_cds_context);
		sme_release_global_lock(&pMac->sme);
	}
	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_get_snr
    \brief a wrapper function that client calls to register a callback to
	get SNR

    \param callback - SME sends back the requested stats using the callback
    \param staId - The station ID for which the stats is requested for
    \param pContext - user context to be passed back along with the callback
    \param p_cds_context - cds context
    \return QDF_STATUS
   ---------------------------------------------------------------------------*/
QDF_STATUS sme_get_snr(tHalHandle hHal,
		       tCsrSnrCallback callback,
		       uint8_t staId, struct qdf_mac_addr bssId, void *pContext)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		status = csr_get_snr(pMac, callback, staId, bssId, pContext);
		sme_release_global_lock(&pMac->sme);
	}
	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_get_statistics
    \brief a wrapper function that client calls to register a callback to get
    different PHY level statistics from CSR.

    \param requesterId - different client requesting for statistics,
	HDD, UMA/GAN etc
    \param statsMask - The different category/categories of stats requester
	is looking for
    \param callback - SME sends back the requested stats using the callback
    \param periodicity - If requester needs periodic update in millisec, 0 means
			 it's an one time request
    \param cache - If requester is happy with cached stats
    \param staId - The station ID for which the stats is requested for
    \param pContext - user context to be passed back along with the callback
    \param sessionId - sme session interface
    \return QDF_STATUS
   ---------------------------------------------------------------------------*/
QDF_STATUS sme_get_statistics(tHalHandle hHal,
			      eCsrStatsRequesterType requesterId,
			      uint32_t statsMask, tCsrStatsCallback callback,
			      uint32_t periodicity, bool cache, uint8_t staId,
			      void *pContext, uint8_t sessionId)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_GET_STATS, NO_SESSION,
			 periodicity));
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		status =
			csr_get_statistics(pMac, requesterId, statsMask, callback,
					   periodicity, cache, staId, pContext,
					   sessionId);
		sme_release_global_lock(&pMac->sme);
	}

	return status;

}

QDF_STATUS sme_get_link_status(tHalHandle hHal,
			       tCsrLinkStatusCallback callback,
			       void *pContext, uint8_t sessionId)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	tAniGetLinkStatus *pMsg;
	cds_msg_t cds_message;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		pMsg = qdf_mem_malloc(sizeof(tAniGetLinkStatus));
		if (NULL == pMsg) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				  "%s: Not able to allocate memory for link status",
				  __func__);
			sme_release_global_lock(&pMac->sme);
			return QDF_STATUS_E_NOMEM;
		}

		pMsg->msgType = WMA_LINK_STATUS_GET_REQ;
		pMsg->msgLen = (uint16_t) sizeof(tAniGetLinkStatus);
		pMsg->sessionId = sessionId;
		pMac->sme.linkStatusContext = pContext;
		pMac->sme.linkStatusCallback = callback;

		cds_message.type = WMA_LINK_STATUS_GET_REQ;
		cds_message.bodyptr = pMsg;
		cds_message.reserved = 0;

		if (!QDF_IS_STATUS_SUCCESS
			    (cds_mq_post_message(QDF_MODULE_ID_WMA, &cds_message))) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				  "%s: Post LINK STATUS MSG fail", __func__);
			qdf_mem_free(pMsg);
			pMac->sme.linkStatusContext = NULL;
			pMac->sme.linkStatusCallback = NULL;
			status = QDF_STATUS_E_FAILURE;
		}

		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

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

    \fn sme_get_country_code

    \brief To return the current country code. If no country code is applied,
	default country code is used to fill the buffer.
	If 11d supported is turned off, an error is return and the last
	applied/default country code is used.
	This is a synchronous API.

    \param pBuf - pointer to a caller allocated buffer for returned country code.

    \param pbLen  For input, this parameter indicates how big is the buffer.
		  Upon return, this parameter has the number of bytes for
		  country. If pBuf doesn't have enough space, this function
		  returns fail status and this parameter contains the number
		  that is needed.

    \return QDF_STATUS  SUCCESS.

			FAILURE or RESOURCES  The API finished and failed.

   -------------------------------------------------------------------------------*/
QDF_STATUS sme_get_country_code(tHalHandle hHal, uint8_t *pBuf, uint8_t *pbLen)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_GET_CNTRYCODE, NO_SESSION, 0));

	return csr_get_country_code(pMac, pBuf, pbLen);
}

/**
 * sme_apply_channel_power_info_to_fw() - sends channel info to fw
 * @hHal: hal handle
 *
 * This function sends the channel power info to firmware
 *
 * Return: none
 */
void sme_apply_channel_power_info_to_fw(tHalHandle hHal)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	csr_apply_channel_power_info_wrapper(pMac);
}

/* some support functions */
bool sme_is11d_supported(tHalHandle hHal)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	return csr_is11d_supported(pMac);
}

bool sme_is11h_supported(tHalHandle hHal)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	return csr_is11h_supported(pMac);
}

bool sme_is_wmm_supported(tHalHandle hHal)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	return csr_is_wmm_supported(pMac);
}

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

    \fn sme_change_country_code

    \brief Change Country code from upperlayer during WLAN driver operation.
	This is a synchronous API.

    \param hHal - The handle returned by mac_open.

    \param pCountry New Country Code String

    \param sendRegHint If we want to send reg hint to nl80211

    \return QDF_STATUS  SUCCESS.

			FAILURE or RESOURCES  The API finished and failed.

   -------------------------------------------------------------------------------*/
QDF_STATUS sme_change_country_code(tHalHandle hHal,
				   tSmeChangeCountryCallback callback,
				   uint8_t *pCountry,
				   void *pContext,
				   void *p_cds_context,
				   tAniBool countryFromUserSpace,
				   tAniBool sendRegHint)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	cds_msg_t msg;
	tAniChangeCountryCodeReq *pMsg;

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_CHANGE_CNTRYCODE, NO_SESSION,
			 0));
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		sms_log(pMac, LOG1, FL(" called"));

		if ((pMac->roam.configParam.Is11dSupportEnabledOriginal == true)
		    && (!pMac->roam.configParam.
			fSupplicantCountryCodeHasPriority)) {

			sms_log(pMac, LOGW,
				"Set Country Code Fail since the STA is associated and userspace does not have priority ");

			sme_release_global_lock(&pMac->sme);
			status = QDF_STATUS_E_FAILURE;
			return status;
		}

		pMsg = qdf_mem_malloc(sizeof(tAniChangeCountryCodeReq));
		if (NULL == pMsg) {
			sms_log(pMac, LOGE,
				" csrChangeCountryCode: failed to allocate mem for req");
			sme_release_global_lock(&pMac->sme);
			return QDF_STATUS_E_NOMEM;
		}

		pMsg->msgType = eWNI_SME_CHANGE_COUNTRY_CODE;
		pMsg->msgLen = (uint16_t) sizeof(tAniChangeCountryCodeReq);
		qdf_mem_copy(pMsg->countryCode, pCountry, 3);
		pMsg->countryFromUserSpace = countryFromUserSpace;
		pMsg->sendRegHint = sendRegHint;
		pMsg->changeCCCallback = callback;
		pMsg->pDevContext = pContext;
		pMsg->p_cds_context = p_cds_context;

		msg.type = eWNI_SME_CHANGE_COUNTRY_CODE;
		msg.bodyptr = pMsg;
		msg.reserved = 0;

		if (QDF_STATUS_SUCCESS !=
		    cds_mq_post_message(CDS_MQ_ID_SME, &msg)) {
			sms_log(pMac, LOGE,
				" sme_change_country_code failed to post msg to self ");
			qdf_mem_free((void *)pMsg);
			status = QDF_STATUS_E_FAILURE;
		}
		sms_log(pMac, LOG1, FL(" returned"));
		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

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

    \fn sme_generic_change_country_code

    \brief Change Country code from upperlayer during WLAN driver operation.
	This is a synchronous API.

    \param hHal - The handle returned by mac_open.

    \param pCountry New Country Code String

    \param reg_domain regulatory domain

    \return QDF_STATUS  SUCCESS.

			FAILURE or RESOURCES  The API finished and failed.

   -----------------------------------------------------------------------------*/
QDF_STATUS sme_generic_change_country_code(tHalHandle hHal,
					   uint8_t *pCountry)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	cds_msg_t msg;
	tAniGenericChangeCountryCodeReq *pMsg;

	if (NULL == pMac) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_FATAL,
			  "%s: pMac is null", __func__);
		return status;
	}

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		sms_log(pMac, LOG1, FL(" called"));
		pMsg = qdf_mem_malloc(sizeof(tAniGenericChangeCountryCodeReq));

		if (NULL == pMsg) {
			sms_log(pMac, LOGE,
				" sme_generic_change_country_code: failed to allocate mem for req");
			sme_release_global_lock(&pMac->sme);
			return QDF_STATUS_E_NOMEM;
		}

		pMsg->msgType = eWNI_SME_GENERIC_CHANGE_COUNTRY_CODE;
		pMsg->msgLen =
			(uint16_t) sizeof(tAniGenericChangeCountryCodeReq);
		qdf_mem_copy(pMsg->countryCode, pCountry, 2);
		pMsg->countryCode[2] = ' ';

		msg.type = eWNI_SME_GENERIC_CHANGE_COUNTRY_CODE;
		msg.bodyptr = pMsg;
		msg.reserved = 0;

		if (QDF_STATUS_SUCCESS !=
		    cds_mq_post_message(CDS_MQ_ID_SME, &msg)) {
			sms_log(pMac, LOGE,
				"sme_generic_change_country_code failed to post msg to self");
			qdf_mem_free(pMsg);
			status = QDF_STATUS_E_FAILURE;
		}
		sms_log(pMac, LOG1, FL(" returned"));
		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

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

    \fn sme_dhcp_start_ind

    \brief API to signal the FW about the DHCP Start event.

    \param hHal - HAL handle for device.

    \param device_mode - mode(AP,SAP etc) of the device.

    \param macAddr - MAC address of the adapter.

    \param sessionId - session ID.

    \return QDF_STATUS  SUCCESS.

			FAILURE or RESOURCES  The API finished and failed.
   --------------------------------------------------------------------------*/
QDF_STATUS sme_dhcp_start_ind(tHalHandle hHal,
			      uint8_t device_mode,
			      uint8_t *macAddr, uint8_t sessionId)
{
	QDF_STATUS status;
	QDF_STATUS qdf_status;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	cds_msg_t cds_message;
	tAniDHCPInd *pMsg;
	tCsrRoamSession *pSession;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_STATUS_SUCCESS == status) {
		pSession = CSR_GET_SESSION(pMac, sessionId);

		if (!pSession) {
			sms_log(pMac, LOGE, FL("session %d not found "),
				sessionId);
			sme_release_global_lock(&pMac->sme);
			return QDF_STATUS_E_FAILURE;
		}

		pMsg = (tAniDHCPInd *) qdf_mem_malloc(sizeof(tAniDHCPInd));
		if (NULL == pMsg) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				  "%s: Not able to allocate memory for dhcp start",
				  __func__);
			sme_release_global_lock(&pMac->sme);
			return QDF_STATUS_E_NOMEM;
		}
		pMsg->msgType = WMA_DHCP_START_IND;
		pMsg->msgLen = (uint16_t) sizeof(tAniDHCPInd);
		pMsg->device_mode = device_mode;
		qdf_mem_copy(pMsg->adapterMacAddr.bytes, macAddr,
			     QDF_MAC_ADDR_SIZE);
		qdf_copy_macaddr(&pMsg->peerMacAddr,
				 &pSession->connectedProfile.bssid);

		cds_message.type = WMA_DHCP_START_IND;
		cds_message.bodyptr = pMsg;
		cds_message.reserved = 0;
		MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
				 sessionId, cds_message.type));
		qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				  "%s: Post DHCP Start MSG fail", __func__);
			qdf_mem_free(pMsg);
			status = QDF_STATUS_E_FAILURE;
		}
		sme_release_global_lock(&pMac->sme);
	}
	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_dhcp_stop_ind

    \brief API to signal the FW about the DHCP complete event.

    \param hHal - HAL handle for device.

    \param device_mode - mode(AP, SAP etc) of the device.

    \param macAddr - MAC address of the adapter.

    \param sessionId - session ID.

    \return QDF_STATUS  SUCCESS.
			FAILURE or RESOURCES  The API finished and failed.
   --------------------------------------------------------------------------*/
QDF_STATUS sme_dhcp_stop_ind(tHalHandle hHal,
			     uint8_t device_mode,
			     uint8_t *macAddr, uint8_t sessionId)
{
	QDF_STATUS status;
	QDF_STATUS qdf_status;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	cds_msg_t cds_message;
	tAniDHCPInd *pMsg;
	tCsrRoamSession *pSession;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_STATUS_SUCCESS == status) {
		pSession = CSR_GET_SESSION(pMac, sessionId);

		if (!pSession) {
			sms_log(pMac, LOGE, FL("session %d not found "),
				sessionId);
			sme_release_global_lock(&pMac->sme);
			return QDF_STATUS_E_FAILURE;
		}

		pMsg = (tAniDHCPInd *) qdf_mem_malloc(sizeof(tAniDHCPInd));
		if (NULL == pMsg) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				  "%s: Not able to allocate memory for dhcp stop",
				  __func__);
			sme_release_global_lock(&pMac->sme);
			return QDF_STATUS_E_NOMEM;
		}

		pMsg->msgType = WMA_DHCP_STOP_IND;
		pMsg->msgLen = (uint16_t) sizeof(tAniDHCPInd);
		pMsg->device_mode = device_mode;
		qdf_mem_copy(pMsg->adapterMacAddr.bytes, macAddr,
			     QDF_MAC_ADDR_SIZE);
		qdf_copy_macaddr(&pMsg->peerMacAddr,
				 &pSession->connectedProfile.bssid);

		cds_message.type = WMA_DHCP_STOP_IND;
		cds_message.bodyptr = pMsg;
		cds_message.reserved = 0;
		MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
				 sessionId, cds_message.type));
		qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				  "%s: Post DHCP Stop MSG fail", __func__);
			qdf_mem_free(pMsg);
			status = QDF_STATUS_E_FAILURE;
		}

		sme_release_global_lock(&pMac->sme);
	}
	return status;
}

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

    \fn sme_TXFailMonitorStopInd

    \brief API to signal the FW to start monitoring TX failures

    \return QDF_STATUS  SUCCESS.

			FAILURE or RESOURCES  The API finished and failed.
   --------------------------------------------------------------------------*/
QDF_STATUS sme_tx_fail_monitor_start_stop_ind(tHalHandle hHal, uint8_t tx_fail_count,
					      void *txFailIndCallback)
{
	QDF_STATUS status;
	QDF_STATUS qdf_status;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	cds_msg_t cds_message;
	tAniTXFailMonitorInd *pMsg;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_STATUS_SUCCESS == status) {
		pMsg = (tAniTXFailMonitorInd *)
		       qdf_mem_malloc(sizeof(tAniTXFailMonitorInd));
		if (NULL == pMsg) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				  "%s: Failed to allocate memory", __func__);
			sme_release_global_lock(&pMac->sme);
			return QDF_STATUS_E_NOMEM;
		}

		pMsg->msgType = WMA_TX_FAIL_MONITOR_IND;
		pMsg->msgLen = (uint16_t) sizeof(tAniTXFailMonitorInd);

		/* tx_fail_count = 0 should disable the Monitoring in FW */
		pMsg->tx_fail_count = tx_fail_count;
		pMsg->txFailIndCallback = txFailIndCallback;

		cds_message.type = WMA_TX_FAIL_MONITOR_IND;
		cds_message.bodyptr = pMsg;
		cds_message.reserved = 0;

		qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				  "%s: Post TX Fail monitor Start MSG fail",
				  __func__);
			qdf_mem_free(pMsg);
			status = QDF_STATUS_E_FAILURE;
		}
		sme_release_global_lock(&pMac->sme);
	}
	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_set_cfg_privacy
    \brief  API to set configure privacy parameters
    \param  hHal - The handle returned by mac_open.
    \param  pProfile - Pointer CSR Roam profile.
    \param  fPrivacy - This parameter indicates status of privacy

    \return void
   ---------------------------------------------------------------------------*/
void sme_set_cfg_privacy(tHalHandle hHal,
			 tCsrRoamProfile *pProfile, bool fPrivacy)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_SET_CFGPRIVACY, NO_SESSION, 0));
	if (QDF_STATUS_SUCCESS == sme_acquire_global_lock(&pMac->sme)) {
		csr_set_cfg_privacy(pMac, pProfile, fPrivacy);
		sme_release_global_lock(&pMac->sme);
	}
}

/* ---------------------------------------------------------------------------
    \fn sme_neighbor_report_request
    \brief  API to request neighbor report.
    \param  hHal - The handle returned by mac_open.
    \param  pRrmNeighborReq - Pointer to a caller allocated object of type
			      tRrmNeighborReq. Caller owns the memory and is
			      responsible for freeing it.
    \return QDF_STATUS
	    QDF_STATUS_E_FAILURE - failure
	    QDF_STATUS_SUCCESS  success
   ---------------------------------------------------------------------------*/
QDF_STATUS sme_neighbor_report_request(tHalHandle hHal, uint8_t sessionId,
				       tpRrmNeighborReq pRrmNeighborReq,
				       tpRrmNeighborRspCallbackInfo callbackInfo)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_NEIGHBOR_REPORTREQ, NO_SESSION,
			 0));

	if (QDF_STATUS_SUCCESS == sme_acquire_global_lock(&pMac->sme)) {
		status =
			sme_rrm_neighbor_report_request(hHal, sessionId,
							pRrmNeighborReq, callbackInfo);
		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

void sms_log(tpAniSirGlobal pMac, uint32_t loglevel, const char *pString, ...)
{
#ifdef WLAN_DEBUG
	/* Verify against current log level */
	if (loglevel >
	    pMac->utils.gLogDbgLevel[LOG_INDEX_FOR_MODULE(SIR_SMS_MODULE_ID)])
		return;
	else {
		va_list marker;

		va_start(marker, pString);      /* Initialize variable arguments. */

		log_debug(pMac, SIR_SMS_MODULE_ID, loglevel, pString, marker);

		va_end(marker); /* Reset variable arguments.      */
	}
#endif
}

/* ---------------------------------------------------------------------------
    \fn sme_get_wcnss_wlan_compiled_version
    \brief  This API returns the version of the WCNSS WLAN API with
	which the HOST driver was built
    \param  hHal - The handle returned by mac_open.
    \param  pVersion - Points to the Version structure to be filled
    \return QDF_STATUS
	    QDF_STATUS_E_INVAL - failure
	    QDF_STATUS_SUCCESS  success
   ---------------------------------------------------------------------------*/
QDF_STATUS sme_get_wcnss_wlan_compiled_version(tHalHandle hHal,
					       tSirVersionType *pVersion)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	if (QDF_STATUS_SUCCESS == sme_acquire_global_lock(&pMac->sme)) {
		if (pVersion != NULL)
			status = QDF_STATUS_SUCCESS;
		else
			status = QDF_STATUS_E_INVAL;

		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_get_wcnss_wlan_reported_version
    \brief  This API returns the version of the WCNSS WLAN API with
	which the WCNSS driver reports it was built
    \param  hHal - The handle returned by mac_open.
    \param  pVersion - Points to the Version structure to be filled
    \return QDF_STATUS
	    QDF_STATUS_E_INVAL - failure
	    QDF_STATUS_SUCCESS  success
   ---------------------------------------------------------------------------*/
QDF_STATUS sme_get_wcnss_wlan_reported_version(tHalHandle hHal,
					       tSirVersionType *pVersion)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	if (QDF_STATUS_SUCCESS == sme_acquire_global_lock(&pMac->sme)) {
		if (pVersion != NULL)
			status = QDF_STATUS_SUCCESS;
		else
			status = QDF_STATUS_E_INVAL;

		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_get_wcnss_software_version
    \brief  This API returns the version string of the WCNSS driver
    \param  hHal - The handle returned by mac_open.
    \param  pVersion - Points to the Version string buffer to be filled
    \param  versionBufferSize - THe size of the Version string buffer
    \return QDF_STATUS
	    QDF_STATUS_E_INVAL - failure
	    QDF_STATUS_SUCCESS  success
   ---------------------------------------------------------------------------*/
QDF_STATUS sme_get_wcnss_software_version(tHalHandle hHal,
					  uint8_t *pVersion,
					  uint32_t versionBufferSize)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	v_CONTEXT_t cds_context = cds_get_global_context();

	if (QDF_STATUS_SUCCESS == sme_acquire_global_lock(&pMac->sme)) {
		if (pVersion != NULL) {
			status =
				wma_get_wcnss_software_version(cds_context,
							    pVersion,
							    versionBufferSize);
		} else {
			status = QDF_STATUS_E_INVAL;
		}
		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_get_wcnss_hardware_version
    \brief  This API returns the version string of the WCNSS hardware
    \param  hHal - The handle returned by mac_open.
    \param  pVersion - Points to the Version string buffer to be filled
    \param  versionBufferSize - THe size of the Version string buffer
    \return QDF_STATUS
	    QDF_STATUS_E_INVAL - failure
	    QDF_STATUS_SUCCESS  success
   ---------------------------------------------------------------------------*/
QDF_STATUS sme_get_wcnss_hardware_version(tHalHandle hHal,
					  uint8_t *pVersion,
					  uint32_t versionBufferSize)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	if (QDF_STATUS_SUCCESS == sme_acquire_global_lock(&pMac->sme)) {
		if (pVersion != NULL)
			status = QDF_STATUS_SUCCESS;
		else
			status = QDF_STATUS_E_INVAL;

		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

#ifdef FEATURE_WLAN_WAPI

/* ---------------------------------------------------------------------------
    \fn sme_scan_get_bkid_candidate_list
    \brief a wrapper function to return the BKID candidate list
    \param pBkidList - caller allocated buffer point to an array of
		       tBkidCandidateInfo
    \param pNumItems - pointer to a variable that has the number of
		       tBkidCandidateInfo allocated when retruning, this is
		       either the number needed or number of items put into
		       pPmkidList
    \return QDF_STATUS - when fail, it usually means the buffer allocated is not
			 big enough and pNumItems
			 has the number of tBkidCandidateInfo.
    \Note: pNumItems is a number of tBkidCandidateInfo,
	   not sizeof(tBkidCandidateInfo) * something
   ---------------------------------------------------------------------------*/
QDF_STATUS sme_scan_get_bkid_candidate_list(tHalHandle hHal, uint32_t sessionId,
					    tBkidCandidateInfo *pBkidList,
					    uint32_t *pNumItems)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		status =
			csr_scan_get_bkid_candidate_list(pMac, sessionId, pBkidList,
							 pNumItems);
		sme_release_global_lock(&pMac->sme);
	}

	return status;
}
#endif /* FEATURE_WLAN_WAPI */

#ifdef FEATURE_OEM_DATA_SUPPORT
/**
 * sme_oem_data_req() - send oem data request to WMA
 * @hal: HAL handle
 * @hdd_oem_req: OEM data request from HDD
 *
 * Return: QDF_STATUS
 */
QDF_STATUS sme_oem_data_req(tHalHandle hal, struct oem_data_req *hdd_oem_req)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
	struct oem_data_req *oem_data_req;
	void *wma_handle;

	sms_log(mac_ctx, LOG1, FL("enter"));
	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
	if (!wma_handle) {
		sms_log(mac_ctx, LOGE, FL("wma_handle is NULL"));
		return QDF_STATUS_E_FAILURE;
	}

	oem_data_req = qdf_mem_malloc(sizeof(*oem_data_req));
	if (!oem_data_req) {
		sms_log(mac_ctx, LOGE, FL("mem alloc failed"));
		return QDF_STATUS_E_NOMEM;
	}

	oem_data_req->data_len = hdd_oem_req->data_len;
	oem_data_req->data = qdf_mem_malloc(oem_data_req->data_len);
	if (!oem_data_req->data) {
		sms_log(mac_ctx, LOGE, FL("mem alloc failed"));
		return QDF_STATUS_E_NOMEM;
	}

	qdf_mem_copy(oem_data_req->data, hdd_oem_req->data,
		     oem_data_req->data_len);

	status = wma_start_oem_data_req(wma_handle, oem_data_req);

	if (!QDF_IS_STATUS_SUCCESS(status)) {
		sms_log(mac_ctx, LOGE, FL("Post oem data request msg fail"));
	} else {
		sms_log(mac_ctx, LOG1,
			FL("OEM request(length: %d) sent to WMA"),
			oem_data_req->data_len);
	}

	if (oem_data_req->data_len)
		qdf_mem_free(oem_data_req->data);
	qdf_mem_free(oem_data_req);

	sms_log(mac_ctx, LOG1, FL("exit"));
	return status;
}
#endif /*FEATURE_OEM_DATA_SUPPORT */

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

   \brief sme_open_session() - Open a session for scan/roam operation.

   This is a synchronous API.

   \param hHal - The handle returned by mac_open.
   \param callback - A pointer to the function caller specifies for
		     roam/connect status indication
   \param pContext - The context passed with callback
   \param pSelfMacAddr - Caller allocated memory filled with self MAC address
			 (6 bytes)
   \param pbSessionId - pointer to a caller allocated buffer for returned session ID

   \return QDF_STATUS_SUCCESS - session is opened. sessionId returned.

		Other status means SME is failed to open the session.
		QDF_STATUS_E_RESOURCES - no more session available.
   \sa

   --------------------------------------------------------------------------*/
QDF_STATUS sme_open_session(tHalHandle hHal, csr_roam_completeCallback callback,
			    void *pContext,
			    uint8_t *pSelfMacAddr, uint8_t *pbSessionId,
			    uint32_t type, uint32_t subType)
{
	QDF_STATUS status;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
		  "%s: type=%d, subType=%d addr:%pM",
		  __func__, type, subType, pSelfMacAddr);

	if (NULL == pbSessionId) {
		status = QDF_STATUS_E_INVAL;
	} else {
		status = sme_acquire_global_lock(&pMac->sme);
		if (QDF_IS_STATUS_SUCCESS(status)) {
			status = csr_roam_open_session(pMac, callback, pContext,
						       pSelfMacAddr,
						       pbSessionId, type,
						       subType);

			sme_release_global_lock(&pMac->sme);
		}
	}
	if (NULL != pbSessionId)
		MTRACE(qdf_trace(QDF_MODULE_ID_SME,
				 TRACE_CODE_SME_RX_HDD_OPEN_SESSION,
				 *pbSessionId, 0));

	return status;
}

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

   \brief sme_close_session() - Open a session for scan/roam operation.

   This is a synchronous API.

   \param hHal - The handle returned by mac_open.

   \param sessionId - A previous opened session's ID.

   \return QDF_STATUS_SUCCESS - session is closed.

	Other status means SME is failed to open the session.
	QDF_STATUS_E_INVAL - session is not opened.
   \sa

   --------------------------------------------------------------------------*/
QDF_STATUS sme_close_session(tHalHandle hHal, uint8_t sessionId,
			     csr_roamSessionCloseCallback callback,
			     void *pContext)
{
	QDF_STATUS status;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_CLOSE_SESSION, sessionId, 0));
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		status = csr_roam_close_session(pMac, sessionId, false,
						callback, pContext);

		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

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

    \fn sme_roam_update_apwpsie

    \brief To update AP's WPS IE. This function should be called after SME AP session is created
    This is an asynchronous API.

    \param pAPWPSIES - pointer to a caller allocated object of tSirAPWPSIEs

    \return QDF_STATUS  SUCCESS 

			FAILURE or RESOURCES  The API finished and failed.

   -------------------------------------------------------------------------------*/
QDF_STATUS sme_roam_update_apwpsie(tHalHandle hHal, uint8_t sessionId,
				   tSirAPWPSIEs *pAPWPSIES)
{

	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {

		status = csr_roam_update_apwpsie(pMac, sessionId, pAPWPSIES);

		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

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

    \fn sme_roam_update_apwparsni_es

    \brief To update AP's WPA/RSN IEs. This function should be called after SME AP session is created
    This is an asynchronous API.

    \param pAPSirRSNie - pointer to a caller allocated object of tSirRSNie with WPS/RSN IEs

    \return QDF_STATUS  SUCCESS 

			FAILURE or RESOURCES  The API finished and failed.

   -------------------------------------------------------------------------------*/
QDF_STATUS sme_roam_update_apwparsni_es(tHalHandle hHal, uint8_t sessionId,
					tSirRSNie *pAPSirRSNie)
{

	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {

		status = csr_roam_update_wparsni_es(pMac, sessionId, pAPSirRSNie);

		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

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

    \fn sme_change_mcc_beacon_interval

    \brief To update P2P-GO beaconInterval. This function should be called after
    disassociating all the station is done
    This is an asynchronous API.

    \param

    \return QDF_STATUS  SUCCESS
			FAILURE or RESOURCES
			The API finished and failed.

   -------------------------------------------------------------------------------*/
QDF_STATUS sme_change_mcc_beacon_interval(tHalHandle hHal, uint8_t sessionId)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	sms_log(pMac, LOG1, FL("Update Beacon PARAMS "));
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		status = csr_send_chng_mcc_beacon_interval(pMac, sessionId);
		sme_release_global_lock(&pMac->sme);
	}
	return status;
}

/**
 * sme_set_host_offload(): API to set the host offload feature.
 * @hHal: The handle returned by mac_open.
 * @sessionId: Session Identifier
 * @request: Pointer to the offload request.
 *
 * Return QDF_STATUS
 */
QDF_STATUS sme_set_host_offload(tHalHandle hHal, uint8_t sessionId,
				tpSirHostOffloadReq request)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	QDF_STATUS status = QDF_STATUS_E_FAILURE;

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_SET_HOSTOFFLOAD, sessionId, 0));
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
#ifdef WLAN_NS_OFFLOAD
		if (SIR_IPV6_NS_OFFLOAD == request->offloadType) {
			status = sme_set_ps_ns_offload(hHal, request,
					sessionId);
		} else
#endif /* WLAN_NS_OFFLOAD */
		{
			status = sme_set_ps_host_offload(hHal, request,
					sessionId);
		}
		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

#ifdef WLAN_FEATURE_GTK_OFFLOAD
/**
 * sme_set_gtk_offload(): API to set GTK offload information.
 * @hHal: The handle returned by mac_open.
 * @sessionId: Session Identifier
 * @pGtkOffload: Pointer to the GTK offload request..
 *
 * Return QDF_STATUS
 */
QDF_STATUS sme_set_gtk_offload(tHalHandle hHal,
		tpSirGtkOffloadParams pGtkOffload,
			       uint8_t sessionId)
{
	tpSirGtkOffloadParams request_buf;
	cds_msg_t msg;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);

	QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO,
		  "%s: KeyReplayCounter: %lld", __func__,
		  pGtkOffload->ullKeyReplayCounter);

	if (NULL == pSession) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "%s: Session not found ", __func__);
		return QDF_STATUS_E_FAILURE;
	}

	request_buf = qdf_mem_malloc(sizeof(*request_buf));
	if (NULL == request_buf) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
		  FL("Not able to allocate memory for GTK offload request"));
		return QDF_STATUS_E_NOMEM;
	}

	qdf_copy_macaddr(&pGtkOffload->bssid,
			 &pSession->connectedProfile.bssid);

	*request_buf = *pGtkOffload;

	msg.type = WMA_GTK_OFFLOAD_REQ;
	msg.reserved = 0;
	msg.bodyptr = request_buf;
	MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
			 sessionId, msg.type));
	if (!QDF_IS_STATUS_SUCCESS
		    (cds_mq_post_message(QDF_MODULE_ID_WMA, &msg))) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			FL("Not able to post SIR_HAL_SET_GTK_OFFLOAD message to HAL"));
		qdf_mem_free(request_buf);
		return QDF_STATUS_E_FAILURE;
	}

	return QDF_STATUS_SUCCESS;
}

/**
 * sme_get_gtk_offload(): API to get GTK offload information
 * @hHal: The handle returned by mac_open.
 * @callback_routine: callback_routine.
 * @sessionId: Session Identifier.
 * callback_context: callback_context.
 *
 * Return QDF_STATUS
 */
QDF_STATUS sme_get_gtk_offload(tHalHandle hHal,
			       gtk_offload_get_info_callback callback_routine,
			       void *callback_context, uint8_t session_id)
{
	tpSirGtkOffloadGetInfoRspParams request_buf;
	cds_msg_t msg;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, session_id);

	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, "%s: Entered",
		  __func__);

	if (NULL == pSession) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "%s: Session not found", __func__);
		return QDF_STATUS_E_FAILURE;
	}

	request_buf = qdf_mem_malloc(sizeof(*request_buf));
	if (NULL == request_buf) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			 FL("Not able to allocate memory for Get GTK offload request"));
		return QDF_STATUS_E_NOMEM;
	}

	qdf_copy_macaddr(&request_buf->bssid,
			 &pSession->connectedProfile.bssid);

	msg.type = WMA_GTK_OFFLOAD_GETINFO_REQ;
	msg.reserved = 0;
	msg.bodyptr = request_buf;

	/* Cache the Get GTK Offload callback information */
	if (NULL != pMac->sme.gtk_offload_get_info_cb) {

		/* Do we need to check if the callback is in use? */
		/* Because we are not sending the same message again
		 * when it is pending,
		 * the only case when the callback is not NULL is that
		 * the previous message was timed out or failed.
		 * So, it will be safe to set the callback in this case.
		 */
	}

	pMac->sme.gtk_offload_get_info_cb = callback_routine;
	pMac->sme.gtk_offload_get_info_cb_context = callback_context;
	MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
			 session_id, msg.type));
	if (!QDF_IS_STATUS_SUCCESS
		    (cds_mq_post_message(QDF_MODULE_ID_WMA, &msg))) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  FL("Not able to post WMA_GTK_OFFLOAD_GETINFO_REQ message to WMA"));
		qdf_mem_free(request_buf);
		return QDF_STATUS_E_FAILURE;
	}

	return QDF_STATUS_SUCCESS;
}
#endif /* WLAN_FEATURE_GTK_OFFLOAD */

/* ---------------------------------------------------------------------------
    \fn sme_set_keep_alive
    \brief  API to set the Keep Alive feature.
    \param  hHal - The handle returned by mac_open.
    \param  request -  Pointer to the Keep Alive request.
    \return QDF_STATUS
   ---------------------------------------------------------------------------*/
QDF_STATUS sme_set_keep_alive(tHalHandle hHal, uint8_t session_id,
			      tpSirKeepAliveReq request)
{
	tpSirKeepAliveReq request_buf;
	cds_msg_t msg;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, session_id);

	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO_LOW,
			FL("WMA_SET_KEEP_ALIVE message"));

	if (pSession == NULL) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				FL("Session not Found"));
		return QDF_STATUS_E_FAILURE;
	}
	request_buf = qdf_mem_malloc(sizeof(tSirKeepAliveReq));
	if (NULL == request_buf) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			FL("Not able to allocate memory for keep alive request"));
		return QDF_STATUS_E_NOMEM;
	}

	qdf_copy_macaddr(&request->bssid, &pSession->connectedProfile.bssid);
	qdf_mem_copy(request_buf, request, sizeof(tSirKeepAliveReq));

	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO_LOW,
			"buff TP %d input TP %d ", request_buf->timePeriod,
		  request->timePeriod);
	request_buf->sessionId = session_id;

	msg.type = WMA_SET_KEEP_ALIVE;
	msg.reserved = 0;
	msg.bodyptr = request_buf;
	MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
			 session_id, msg.type));
	if (QDF_STATUS_SUCCESS !=
			cds_mq_post_message(QDF_MODULE_ID_WMA, &msg)) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				FL("Not able to post WMA_SET_KEEP_ALIVE message to WMA"));
		qdf_mem_free(request_buf);
		return QDF_STATUS_E_FAILURE;
	}

	return QDF_STATUS_SUCCESS;
}

#ifdef FEATURE_WLAN_SCAN_PNO
/* ---------------------------------------------------------------------------
    \fn sme_set_preferred_network_list
    \brief  API to set the Preferred Network List Offload feature.
    \param  hHal - The handle returned by mac_open.
    \param  request -  Pointer to the offload request.
    \return QDF_STATUS
   ---------------------------------------------------------------------------*/
QDF_STATUS sme_set_preferred_network_list(tHalHandle hHal,
		tpSirPNOScanReq request,
		uint8_t sessionId,
		void (*callback_routine)(void *callback_context,
			tSirPrefNetworkFoundInd
			*pPrefNetworkFoundInd),
		void *callback_context)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	QDF_STATUS status;

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_PREF_NET_LIST,
			 sessionId, request->ucNetworksCount));
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		sme_set_ps_preferred_network_list(hHal, request, sessionId,
				callback_routine, callback_context);
		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

#endif /* FEATURE_WLAN_SCAN_PNO */

/* ---------------------------------------------------------------------------
    \fn sme_abort_mac_scan
    \brief  API to cancel MAC scan.
    \param  hHal - The handle returned by mac_open.
    \param  sessionId - sessionId on which we need to abort scan.
    \param  reason - Reason to abort the scan.
    \return QDF_STATUS
	    QDF_STATUS_E_FAILURE - failure
	    QDF_STATUS_SUCCESS  success
   ---------------------------------------------------------------------------*/
QDF_STATUS sme_abort_mac_scan(tHalHandle hHal, uint8_t sessionId,
			      eCsrAbortReason reason)
{
	QDF_STATUS status;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_ABORT_MACSCAN, NO_SESSION, 0));
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		status = csr_scan_abort_mac_scan(pMac, sessionId, reason);

		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

/* ----------------------------------------------------------------------------
    \fn sme_get_operation_channel
    \brief API to get current channel on which STA is parked
    this function gives channel information only of infra station or IBSS station
    \param hHal, pointer to memory location and sessionId
    \returns QDF_STATUS_SUCCESS
	     QDF_STATUS_E_FAILURE
   -------------------------------------------------------------------------------*/
QDF_STATUS sme_get_operation_channel(tHalHandle hHal, uint32_t *pChannel,
				     uint8_t sessionId)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	tCsrRoamSession *pSession;

	if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
		pSession = CSR_GET_SESSION(pMac, sessionId);

		if ((pSession->connectedProfile.BSSType ==
		     eCSR_BSS_TYPE_INFRASTRUCTURE)
		    || (pSession->connectedProfile.BSSType ==
			eCSR_BSS_TYPE_IBSS)
		    || (pSession->connectedProfile.BSSType ==
			eCSR_BSS_TYPE_INFRA_AP)
		    || (pSession->connectedProfile.BSSType ==
			eCSR_BSS_TYPE_START_IBSS)) {
			*pChannel = pSession->connectedProfile.operationChannel;
			return QDF_STATUS_SUCCESS;
		}
	}
	return QDF_STATUS_E_FAILURE;
} /* sme_get_operation_channel ends here */

/**
 * sme_register_p2p_ack_ind_callback() - p2p ack indication callback
 * @hal: hal pointer
 * @callback: callback pointer to be registered
 *
 * This function is used to register a callback to PE for p2p ack
 * indication
 *
 * Return: Success if msg is posted to PE else Failure.
 */
QDF_STATUS sme_register_p2p_ack_ind_callback(tHalHandle hal,
				sir_p2p_ack_ind_callback callback)
{
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
	struct sir_sme_p2p_ack_ind_cb_req *msg;
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	sms_log(mac_ctx, LOG1, FL(": ENTER"));
	status = sme_acquire_global_lock(&mac_ctx->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		msg = qdf_mem_malloc(sizeof(*msg));
		if (NULL == msg) {
			sms_log(mac_ctx, LOGE,
				FL("Failed to allocate memory"));
		sme_release_global_lock(&mac_ctx->sme);
		return QDF_STATUS_E_NOMEM;
		}
		qdf_mem_zero(msg, sizeof(*msg));
		msg->message_type = eWNI_SME_REGISTER_P2P_ACK_CB;
		msg->length = sizeof(*msg);

		msg->callback = callback;
		status = cds_send_mb_message_to_mac(msg);
		sme_release_global_lock(&mac_ctx->sme);
		return status;
	}
	return status;
}

/**
 * sme_register_mgmt_frame_ind_callback() - Register a callback for
 * management frame indication to PE.
 *
 * @hal: hal pointer
 * @callback: callback pointer to be registered
 *
 * This function is used to register a callback for management
 * frame indication to PE.
 *
 * Return: Success if msg is posted to PE else Failure.
 */
QDF_STATUS sme_register_mgmt_frame_ind_callback(tHalHandle hal,
				sir_mgmt_frame_ind_callback callback)
{
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
	struct sir_sme_mgmt_frame_cb_req *msg;
	QDF_STATUS status = QDF_STATUS_SUCCESS;

	sms_log(mac_ctx, LOG1, FL(": ENTER"));

	if (QDF_STATUS_SUCCESS ==
			sme_acquire_global_lock(&mac_ctx->sme)) {
		msg = qdf_mem_malloc(sizeof(*msg));
		if (NULL == msg) {
			sms_log(mac_ctx, LOGE,
				FL("Not able to allocate memory for eWNI_SME_REGISTER_MGMT_FRAME_CB"));
			sme_release_global_lock(&mac_ctx->sme);
			return QDF_STATUS_E_NOMEM;
		}
		qdf_mem_set(msg, sizeof(*msg), 0);
		msg->message_type = eWNI_SME_REGISTER_MGMT_FRAME_CB;
		msg->length          = sizeof(*msg);

		msg->callback = callback;
		status = cds_send_mb_message_to_mac(msg);
		sme_release_global_lock(&mac_ctx->sme);
		return status;
	}
	return QDF_STATUS_E_FAILURE;
}

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

    \fn sme_RegisterMgtFrame

    \brief To register managment frame of specified type and subtype.
    \param frameType - type of the frame that needs to be passed to HDD.
    \param matchData - data which needs to be matched before passing frame
		       to HDD.
    \param matchDataLen - Length of matched data.
    \return QDF_STATUS
   -------------------------------------------------------------------------------*/
QDF_STATUS sme_register_mgmt_frame(tHalHandle hHal, uint8_t sessionId,
				   uint16_t frameType, uint8_t *matchData,
				   uint16_t matchLen)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_REGISTER_MGMTFR, sessionId, 0));
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		tSirRegisterMgmtFrame *pMsg;
		uint16_t len;
		tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);

		if (!CSR_IS_SESSION_ANY(sessionId) && !pSession) {
			sms_log(pMac, LOGE, FL("  session %d not found "),
				sessionId);
			sme_release_global_lock(&pMac->sme);
			return QDF_STATUS_E_FAILURE;
		}

		if (!CSR_IS_SESSION_ANY(sessionId) && !pSession->sessionActive) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				  "%s Invalid Sessionid", __func__);
			sme_release_global_lock(&pMac->sme);
			return QDF_STATUS_E_FAILURE;
		}

		len = sizeof(tSirRegisterMgmtFrame) + matchLen;

		pMsg = qdf_mem_malloc(len);
		if (NULL == pMsg)
			status = QDF_STATUS_E_NOMEM;
		else {
			qdf_mem_set(pMsg, len, 0);
			pMsg->messageType = eWNI_SME_REGISTER_MGMT_FRAME_REQ;
			pMsg->length = len;
			pMsg->sessionId = sessionId;
			pMsg->registerFrame = true;
			pMsg->frameType = frameType;
			pMsg->matchLen = matchLen;
			qdf_mem_copy(pMsg->matchData, matchData, matchLen);
			status = cds_send_mb_message_to_mac(pMsg);
		}
		sme_release_global_lock(&pMac->sme);
	}
	return status;
}

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

    \fn sme_DeregisterMgtFrame

    \brief To De-register managment frame of specified type and subtype.
    \param frameType - type of the frame that needs to be passed to HDD.
    \param matchData - data which needs to be matched before passing frame
		       to HDD.
    \param matchDataLen - Length of matched data.
    \return QDF_STATUS
   -------------------------------------------------------------------------------*/
QDF_STATUS sme_deregister_mgmt_frame(tHalHandle hHal, uint8_t sessionId,
				     uint16_t frameType, uint8_t *matchData,
				     uint16_t matchLen)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_DEREGISTER_MGMTFR, sessionId,
			 0));
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		tSirRegisterMgmtFrame *pMsg;
		uint16_t len;
		tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);

		if (!CSR_IS_SESSION_ANY(sessionId) && !pSession) {
			sms_log(pMac, LOGE, FL("  session %d not found "),
				sessionId);
			sme_release_global_lock(&pMac->sme);
			return QDF_STATUS_E_FAILURE;
		}

		if (!CSR_IS_SESSION_ANY(sessionId) && !pSession->sessionActive) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				  "%s Invalid Sessionid", __func__);
			sme_release_global_lock(&pMac->sme);
			return QDF_STATUS_E_FAILURE;
		}

		len = sizeof(tSirRegisterMgmtFrame) + matchLen;

		pMsg = qdf_mem_malloc(len);
		if (NULL == pMsg)
			status = QDF_STATUS_E_NOMEM;
		else {
			qdf_mem_set(pMsg, len, 0);
			pMsg->messageType = eWNI_SME_REGISTER_MGMT_FRAME_REQ;
			pMsg->length = len;
			pMsg->registerFrame = false;
			pMsg->frameType = frameType;
			pMsg->matchLen = matchLen;
			qdf_mem_copy(pMsg->matchData, matchData, matchLen);
			status = cds_send_mb_message_to_mac(pMsg);
		}
		sme_release_global_lock(&pMac->sme);
	}
	return status;
}

/**
 * sme_remain_on_channel - API to request remain on channel for 'x' duration
 *
 * @hHal: pointer to MAC handle
 * @session_id: Session identifier
 * @channel: channel information
 * @duration: duration in ms
 * @callback: HDD registered callback to process reaminOnChannelRsp
 * @context: HDD Callback param
 * @scan_id: scan identifier
 *
 * This function process the roc request and generates scan identifier.s
 *
 * Return: QDF_STATUS
 */
QDF_STATUS sme_remain_on_channel(tHalHandle hHal, uint8_t session_id,
				 uint8_t channel, uint32_t duration,
				 remainOnChanCallback callback,
				 void *pContext, uint8_t isP2PProbeReqAllowed,
				 uint32_t *scan_id)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hHal);
	uint32_t san_req_id, scan_count;
	struct ani_roc_req *roc_msg;
	cds_msg_t msg;


	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_REMAIN_ONCHAN, session_id, 0));

	scan_count = csr_ll_count(&mac_ctx->sme.smeScanCmdActiveList);
	if (scan_count >= mac_ctx->scan.max_scan_count) {
		sms_log(mac_ctx, LOGE, FL("Max scan reached"));
		return QDF_STATUS_E_FAILURE;
	}

	wma_get_scan_id(&san_req_id);
	*scan_id = san_req_id;
	status = sme_acquire_global_lock(&mac_ctx->sme);

	sms_log(mac_ctx, LOG1, FL(" called"));
	roc_msg = qdf_mem_malloc(sizeof(struct ani_roc_req));
	if (NULL == roc_msg) {
		sms_log(mac_ctx, LOGE,
			" scan_req: failed to allocate mem for msg");
		sme_release_global_lock(&mac_ctx->sme);
		return QDF_STATUS_E_NOMEM;
	}
	roc_msg->msg_type = eWNI_SME_ROC_CMD;
	roc_msg->msg_len = (uint16_t) sizeof(struct ani_roc_req);
	roc_msg->session_id = session_id;
	roc_msg->callback = callback;
	roc_msg->duration = duration;
	roc_msg->channel = channel;
	roc_msg->is_p2pprobe_allowed = isP2PProbeReqAllowed;
	roc_msg->ctx = pContext;
	roc_msg->scan_id = *scan_id;
	msg.type = eWNI_SME_ROC_CMD;
	msg.bodyptr = roc_msg;
	msg.reserved = 0;
	msg.bodyval = 0;
	if (QDF_STATUS_SUCCESS !=
		cds_mq_post_message(CDS_MQ_ID_SME, &msg)) {
		sms_log(mac_ctx, LOGE,
			" sme_scan_req failed to post msg");
		qdf_mem_free(roc_msg);
		status = QDF_STATUS_E_FAILURE;
	}
	sme_release_global_lock(&mac_ctx->sme);
	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_report_probe_req
    \brief  API to enable/disable forwarding of probeReq to apps in p2p.
    \param  hHal - The handle returned by mac_open.
    \param  falg: to set the Probe request forarding to wpa_supplicant in listen state in p2p
    \return QDF_STATUS
   ---------------------------------------------------------------------------*/

#ifndef WLAN_FEATURE_CONCURRENT_P2P
QDF_STATUS sme_report_probe_req(tHalHandle hHal, uint8_t flag)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	do {
		/* acquire the lock for the sme object */
		status = sme_acquire_global_lock(&pMac->sme);
		if (QDF_IS_STATUS_SUCCESS(status)) {
			/* call set in context */
			pMac->p2pContext.probeReqForwarding = flag;
			/* release the lock for the sme object */
			sme_release_global_lock(&pMac->sme);
		}
	} while (0);

	sms_log(pMac, LOGW, "exiting function %s", __func__);

	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_update_p2p_ie
    \brief  API to set the P2p Ie in p2p context
    \param  hHal - The handle returned by mac_open.
    \param  p2pIe -  Ptr to p2pIe from HDD.
    \param p2pIeLength: length of p2pIe
    \return QDF_STATUS
   ---------------------------------------------------------------------------*/

QDF_STATUS sme_update_p2p_ie(tHalHandle hHal, void *p2pIe, uint32_t p2pIeLength)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_UPDATE_P2P_IE, NO_SESSION, 0));
	/* acquire the lock for the sme object */
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		if (NULL != pMac->p2pContext.probeRspIe) {
			qdf_mem_free(pMac->p2pContext.probeRspIe);
			pMac->p2pContext.probeRspIeLength = 0;
		}

		pMac->p2pContext.probeRspIe = qdf_mem_malloc(p2pIeLength);
		if (NULL == pMac->p2pContext.probeRspIe) {
			sms_log(pMac, LOGE, "%s: Unable to allocate P2P IE",
				__func__);
			pMac->p2pContext.probeRspIeLength = 0;
			status = QDF_STATUS_E_NOMEM;
		} else {
			pMac->p2pContext.probeRspIeLength = p2pIeLength;

			sir_dump_buf(pMac, SIR_LIM_MODULE_ID, LOG2,
				     pMac->p2pContext.probeRspIe,
				     pMac->p2pContext.probeRspIeLength);
			qdf_mem_copy((uint8_t *) pMac->p2pContext.probeRspIe,
				     p2pIe, p2pIeLength);
		}

		/* release the lock for the sme object */
		sme_release_global_lock(&pMac->sme);
	}

	sms_log(pMac, LOG2, "exiting function %s", __func__);

	return status;
}
#endif

/* ---------------------------------------------------------------------------
    \fn sme_send_action
    \brief  API to send action frame from supplicant.
    \param  hHal - The handle returned by mac_open.
    \return QDF_STATUS
   ---------------------------------------------------------------------------*/

QDF_STATUS sme_send_action(tHalHandle hHal, uint8_t sessionId,
			   const uint8_t *pBuf, uint32_t len,
			   uint16_t wait, bool noack,
			   uint16_t channel_freq)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_SEND_ACTION, sessionId, 0));
	/* acquire the lock for the sme object */
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		p2p_send_action(hHal, sessionId, pBuf, len, wait, noack,
		channel_freq);
		/* release the lock for the sme object */
		sme_release_global_lock(&pMac->sme);
	}

	sms_log(pMac, LOGW, "exiting function %s", __func__);

	return status;
}

QDF_STATUS sme_cancel_remain_on_channel(tHalHandle hHal,
	uint8_t sessionId, uint32_t scan_id)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_CANCEL_REMAIN_ONCHAN, sessionId,
			 0));
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		status = p2p_cancel_remain_on_channel(hHal, sessionId, scan_id);
		sme_release_global_lock(&pMac->sme);
	}
	return status;
}

/* Power Save Related */
QDF_STATUS sme_p2p_set_ps(tHalHandle hHal, tP2pPsConfig *data)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		status = p2p_set_ps(hHal, data);
		sme_release_global_lock(&pMac->sme);
	}
	return status;
}

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

   \fn    sme_configure_rxp_filter

   \brief
    SME will pass this request to lower mac to set/reset the filter on RXP for
    multicast & broadcast traffic.

   \param

    hHal - The handle returned by mac_open.

    filterMask- Currently the API takes a 1 or 0 (set or reset) as filter.
    Basically to enable/disable the filter (to filter "all" mcbc traffic) based
    on this param. In future we can use this as a mask to set various types of
    filters as suggested below:
    FILTER_ALL_MULTICAST:
    FILTER_ALL_BROADCAST:
    FILTER_ALL_MULTICAST_BROADCAST:

   \return QDF_STATUS

   --------------------------------------------------------------------------- */
QDF_STATUS sme_configure_rxp_filter(tHalHandle hHal,
				    tpSirWlanSetRxpFilters wlanRxpFilterParam)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	cds_msg_t cds_message;

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_CONFIG_RXPFIL, NO_SESSION, 0));
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		/* serialize the req through MC thread */
		cds_message.bodyptr = wlanRxpFilterParam;
		cds_message.type = WMA_CFG_RXP_FILTER_REQ;
		MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
				 NO_SESSION, cds_message.type));
		qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
			status = QDF_STATUS_E_FAILURE;
		}
		sme_release_global_lock(&pMac->sme);
	}
	return status;
}

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

   \fn    sme_configure_suspend_ind

   \brief
    SME will pass this request to lower mac to Indicate that the wlan needs to
    be suspended

   \param

    hHal - The handle returned by mac_open.

    wlanSuspendParam- Depicts the wlan suspend params

    csr_readyToSuspendCallback - Callback to be called when ready to suspend
				 event is received.
	callback_context  - Context associated with csr_readyToSuspendCallback.

   \return QDF_STATUS

   --------------------------------------------------------------------------- */
QDF_STATUS sme_configure_suspend_ind(tHalHandle hHal,
				     uint32_t conn_state_mask,
				     csr_readyToSuspendCallback callback,
				     void *callback_context)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	cds_msg_t cds_message;

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_CONFIG_SUSPENDIND, NO_SESSION,
			 0));

	pMac->readyToSuspendCallback = callback;
	pMac->readyToSuspendContext = callback_context;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		/* serialize the req through MC thread */
		cds_message.bodyval = conn_state_mask;
		cds_message.type = WMA_WLAN_SUSPEND_IND;
		MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
				 NO_SESSION, cds_message.type));
		qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
			pMac->readyToSuspendCallback = NULL;
			pMac->readyToSuspendContext = NULL;
			status = QDF_STATUS_E_FAILURE;
		}
		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

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

   \fn    sme_configure_resume_req

   \brief
    SME will pass this request to lower mac to Indicate that the wlan needs to
    be Resumed

   \param

    hHal - The handle returned by mac_open.

    wlanResumeParam- Depicts the wlan resume params

   \return QDF_STATUS

   --------------------------------------------------------------------------- */
QDF_STATUS sme_configure_resume_req(tHalHandle hHal,
				    tpSirWlanResumeParam wlanResumeParam)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	cds_msg_t cds_message;

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_CONFIG_RESUMEREQ, NO_SESSION,
			 0));
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		/* serialize the req through MC thread */
		cds_message.bodyptr = wlanResumeParam;
		cds_message.type = WMA_WLAN_RESUME_REQ;
		MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
				 NO_SESSION, cds_message.type));
		qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
			status = QDF_STATUS_E_FAILURE;
		}
		sme_release_global_lock(&pMac->sme);
	}
	return status;
}

#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
/**
 * sme_configure_ext_wow() - configure Extr WoW
 * @hHal - The handle returned by mac_open.
 * @wlanExtParams - Depicts the wlan Ext params.
 * @callback - ext_wow callback to be registered.
 * @callback_context - ext_wow callback context
 *
 * SME will pass this request to lower mac to configure Extr WoW
 * Return: QDF_STATUS
 */
QDF_STATUS sme_configure_ext_wow(tHalHandle hHal,
				  tpSirExtWoWParams wlanExtParams,
				  csr_readyToExtWoWCallback callback,
				  void *callback_context)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	cds_msg_t cds_message;
	tpSirExtWoWParams MsgPtr = qdf_mem_malloc(sizeof(*MsgPtr));

	if (!MsgPtr)
		return QDF_STATUS_E_NOMEM;

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_CONFIG_EXTWOW, NO_SESSION, 0));

	pMac->readyToExtWoWCallback = callback;
	pMac->readyToExtWoWContext = callback_context;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {

		/* serialize the req through MC thread */
		qdf_mem_copy(MsgPtr, wlanExtParams, sizeof(*MsgPtr));
		cds_message.bodyptr = MsgPtr;
		cds_message.type = WMA_WLAN_EXT_WOW;
		qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
			pMac->readyToExtWoWCallback = NULL;
			pMac->readyToExtWoWContext = NULL;
			qdf_mem_free(MsgPtr);
			status = QDF_STATUS_E_FAILURE;
		}
		sme_release_global_lock(&pMac->sme);
	} else {
		pMac->readyToExtWoWCallback = NULL;
		pMac->readyToExtWoWContext = NULL;
		qdf_mem_free(MsgPtr);
	}

	return status;
}

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

   \fn    sme_configure_app_type1_params

   \brief
   SME will pass this request to lower mac to configure Indoor WoW parameters.

   \param

    hHal - The handle returned by mac_open.

    wlanAppType1Params- Depicts the wlan App Type 1(Indoor) params

   \return QDF_STATUS

   --------------------------------------------------------------------------- */
QDF_STATUS sme_configure_app_type1_params(tHalHandle hHal,
					  tpSirAppType1Params wlanAppType1Params)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	cds_msg_t cds_message;
	tpSirAppType1Params MsgPtr = qdf_mem_malloc(sizeof(*MsgPtr));

	if (!MsgPtr)
		return QDF_STATUS_E_NOMEM;

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_CONFIG_APP_TYPE1, NO_SESSION,
			 0));

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		/* serialize the req through MC thread */
		qdf_mem_copy(MsgPtr, wlanAppType1Params, sizeof(*MsgPtr));
		cds_message.bodyptr = MsgPtr;
		cds_message.type = WMA_WLAN_SET_APP_TYPE1_PARAMS;
		qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
			qdf_mem_free(MsgPtr);
			status = QDF_STATUS_E_FAILURE;
		}
		sme_release_global_lock(&pMac->sme);
	} else {
		qdf_mem_free(MsgPtr);
	}

	return status;
}

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

   \fn    sme_configure_app_type2_params

   \brief
   SME will pass this request to lower mac to configure Indoor WoW parameters.

   \param

    hHal - The handle returned by mac_open.

    wlanAppType2Params- Depicts the wlan App Type 2 (Outdoor) params

   \return QDF_STATUS

   --------------------------------------------------------------------------- */
QDF_STATUS sme_configure_app_type2_params(tHalHandle hHal,
					  tpSirAppType2Params wlanAppType2Params)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	cds_msg_t cds_message;
	tpSirAppType2Params MsgPtr = qdf_mem_malloc(sizeof(*MsgPtr));

	if (!MsgPtr)
		return QDF_STATUS_E_NOMEM;

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_CONFIG_APP_TYPE2, NO_SESSION,
			 0));

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		/* serialize the req through MC thread */
		qdf_mem_copy(MsgPtr, wlanAppType2Params, sizeof(*MsgPtr));
		cds_message.bodyptr = MsgPtr;
		cds_message.type = WMA_WLAN_SET_APP_TYPE2_PARAMS;
		qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
			qdf_mem_free(MsgPtr);
			status = QDF_STATUS_E_FAILURE;
		}
		sme_release_global_lock(&pMac->sme);
	} else {
		qdf_mem_free(MsgPtr);
	}

	return status;
}
#endif

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

    \fn sme_get_infra_session_id

    \brief To get the session ID for infra session, if connected
    This is a synchronous API.

    \param hHal - The handle returned by mac_open.

    \return sessionid, -1 if infra session is not connected

   -------------------------------------------------------------------------------*/
int8_t sme_get_infra_session_id(tHalHandle hHal)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	int8_t sessionid = -1;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {

		sessionid = csr_get_infra_session_id(pMac);

		sme_release_global_lock(&pMac->sme);
	}

	return sessionid;
}

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

    \fn sme_get_infra_operation_channel

    \brief To get the operating channel for infra session, if connected
    This is a synchronous API.

    \param hHal - The handle returned by mac_open.
    \param sessionId - the sessionId returned by sme_open_session.

    \return operating channel, 0 if infra session is not connected

   -------------------------------------------------------------------------------*/
uint8_t sme_get_infra_operation_channel(tHalHandle hHal, uint8_t sessionId)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	uint8_t channel = 0;
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {

		channel = csr_get_infra_operation_channel(pMac, sessionId);

		sme_release_global_lock(&pMac->sme);
	}

	return channel;
}

/* This routine will return poerating channel on which other BSS is operating to be used for concurrency mode. */
/* If other BSS is not up or not connected it will return 0 */
uint8_t sme_get_concurrent_operation_channel(tHalHandle hHal)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	uint8_t channel = 0;
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {

		channel = csr_get_concurrent_operation_channel(pMac);
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO_HIGH, "%s: "
			  " Other Concurrent Channel = %d", __func__, channel);
		sme_release_global_lock(&pMac->sme);
	}

	return channel;
}

#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
uint16_t sme_check_concurrent_channel_overlap(tHalHandle hHal, uint16_t sap_ch,
					      eCsrPhyMode sapPhyMode,
					      uint8_t cc_switch_mode)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	uint16_t channel = 0;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		channel =
			csr_check_concurrent_channel_overlap(pMac, sap_ch, sapPhyMode,
							     cc_switch_mode);
		sme_release_global_lock(&pMac->sme);
	}

	return channel;
}
#endif

#ifdef FEATURE_WLAN_SCAN_PNO
/**
 * sme_update_roam_pno_channel_prediction_config() - Update PNO config
 * @csr_config:      config from SME context
 * @hal:             Global Hal handle
 * @copy_from_to:    Used to specify the source and destination
 *
 * Copy the PNO channel prediction configuration parameters from
 * SME context to MAC context or vice-versa
 *
 * Return: None
 */
void sme_update_roam_pno_channel_prediction_config(
		tHalHandle hal, tCsrConfigParam *csr_config,
		uint8_t copy_from_to)
{
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
	if (copy_from_to == SME_CONFIG_TO_ROAM_CONFIG) {
		mac_ctx->roam.configParam.pno_channel_prediction =
			csr_config->pno_channel_prediction;
		mac_ctx->roam.configParam.top_k_num_of_channels =
			csr_config->top_k_num_of_channels;
		mac_ctx->roam.configParam.stationary_thresh =
			csr_config->stationary_thresh;
		mac_ctx->roam.configParam.channel_prediction_full_scan =
			csr_config->channel_prediction_full_scan;
		mac_ctx->roam.configParam.pnoscan_adaptive_dwell_mode =
			csr_config->pnoscan_adaptive_dwell_mode;
	} else if (copy_from_to == ROAM_CONFIG_TO_SME_CONFIG) {
		csr_config->pno_channel_prediction =
			mac_ctx->roam.configParam.pno_channel_prediction;
		csr_config->top_k_num_of_channels =
			mac_ctx->roam.configParam.top_k_num_of_channels;
		csr_config->stationary_thresh =
			mac_ctx->roam.configParam.stationary_thresh;
		csr_config->channel_prediction_full_scan =
			mac_ctx->roam.configParam.channel_prediction_full_scan;
		csr_config->pnoscan_adaptive_dwell_mode =
			mac_ctx->roam.configParam.pnoscan_adaptive_dwell_mode;
	}

}
/******************************************************************************
*
* Name: sme_preferred_network_found_ind
*
* Description:
*    Invoke Preferred Network Found Indication
*
* Parameters:
*    hHal - HAL handle for device
*    pMsg - found network description
*
* Returns: QDF_STATUS
*
******************************************************************************/
QDF_STATUS sme_preferred_network_found_ind(tHalHandle hHal, void *pMsg)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tSirPrefNetworkFoundInd *pPrefNetworkFoundInd =
		(tSirPrefNetworkFoundInd *) pMsg;
	uint8_t dumpSsId[SIR_MAC_MAX_SSID_LENGTH + 1];
	uint8_t ssIdLength = 0;

	if (NULL == pMsg) {
		sms_log(pMac, LOGE, "in %s msg ptr is NULL", __func__);
		return QDF_STATUS_E_FAILURE;
	}

	if (pMac->pnoOffload) {
		/* Call Preferred Network Found Indication callback routine. */
		if (pMac->sme.pref_netw_found_cb != NULL) {
			pMac->sme.pref_netw_found_cb(pMac->sme.
					preferred_network_found_ind_cb_ctx,
					pPrefNetworkFoundInd);
		}
		return status;
	}

	if (pPrefNetworkFoundInd->ssId.length > 0) {
		ssIdLength = CSR_MIN(SIR_MAC_MAX_SSID_LENGTH,
				     pPrefNetworkFoundInd->ssId.length);
		qdf_mem_copy(dumpSsId, pPrefNetworkFoundInd->ssId.ssId,
			     ssIdLength);
		dumpSsId[ssIdLength] = 0;
		sms_log(pMac, LOG2, "%s:SSID=%s frame length %d",
			__func__, dumpSsId, pPrefNetworkFoundInd->frameLength);

		/* Flush scan results, So as to avoid indication/updation of
		 * stale entries, which may not have aged out during APPS collapse
		 */
		sme_scan_flush_result(hHal);

		/* Save the frame to scan result */
		if (pPrefNetworkFoundInd->mesgLen >
		    sizeof(tSirPrefNetworkFoundInd)) {
			/* we may have a frame */
			status = csr_scan_save_preferred_network_found(pMac,
					pPrefNetworkFoundInd);
			if (!QDF_IS_STATUS_SUCCESS(status)) {
				sms_log(pMac, LOGE,
					FL(" fail to save preferred network"));
			}
		} else {
			sms_log(pMac, LOGE,
				FL(" not enough data length %d needed %zu"),
				pPrefNetworkFoundInd->mesgLen,
				sizeof(tSirPrefNetworkFoundInd));
		}

		/* Call Preferred Netowrk Found Indication callback routine. */
		if (QDF_IS_STATUS_SUCCESS(status)
		    && (pMac->sme.pref_netw_found_cb != NULL)) {
			pMac->sme.pref_netw_found_cb(pMac->sme.
					preferred_network_found_ind_cb_ctx,
					pPrefNetworkFoundInd);
		}
	} else {
		sms_log(pMac, LOGE, "%s: callback failed - SSID is NULL",
			__func__);
		status = QDF_STATUS_E_FAILURE;
	}

	return status;
}

#endif /* FEATURE_WLAN_SCAN_PNO */

/**
 * sme_set_tsfcb() - Set callback for TSF capture
 * @h_hal: Handler return by mac_open
 * @cb_fn: Callback function pointer
 * @db_ctx: Callback data
 *
 * Return: QDF_STATUS
 */
QDF_STATUS sme_set_tsfcb(tHalHandle h_hal,
	int (*cb_fn)(void *cb_ctx, struct stsf *ptsf), void *cb_ctx)
{
	tpAniSirGlobal mac = PMAC_STRUCT(h_hal);
	QDF_STATUS status;

	status = sme_acquire_global_lock(&mac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		mac->sme.get_tsf_cb = cb_fn;
		mac->sme.get_tsf_cxt = cb_ctx;
		sme_release_global_lock(&mac->sme);
	}
	return status;
}

/**
 * sme_reset_tsfcb() - Reset callback for TSF capture
 * @h_hal: Handler return by mac_open
 *
 * This function reset the tsf capture callback to SME
 *
 * Return: QDF_STATUS
 */
QDF_STATUS sme_reset_tsfcb(tHalHandle h_hal)
{
	tpAniSirGlobal mac;
	QDF_STATUS status;

	if (!h_hal) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				  FL("h_hal is not valid"));
		return QDF_STATUS_E_INVAL;
	}
	mac = PMAC_STRUCT(h_hal);

	status = sme_acquire_global_lock(&mac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		mac->sme.get_tsf_cb = NULL;
		mac->sme.get_tsf_cxt = NULL;
		sme_release_global_lock(&mac->sme);
	}
	return status;
}

#ifdef WLAN_FEATURE_TSF
/*
 * sme_set_tsf_gpio() - set gpio pin that be toggled when capture tef
 * @h_hal: Handler return by mac_open
 * @pinvalue: gpio pin id
 *
 * Return: QDF_STATUS
 */
QDF_STATUS sme_set_tsf_gpio(tHalHandle h_hal, uint32_t pinvalue)
{
	QDF_STATUS status;
	cds_msg_t tsf_msg = {0};
	tpAniSirGlobal mac = PMAC_STRUCT(h_hal);

	status = sme_acquire_global_lock(&mac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		tsf_msg.type = WMA_TSF_GPIO_PIN;
		tsf_msg.reserved = 0;
		tsf_msg.bodyval = pinvalue;

		status = cds_mq_post_message(CDS_MQ_ID_WMA, &tsf_msg);
		if (!QDF_IS_STATUS_SUCCESS(status)) {
			sms_log(mac, LOGE, "Unable to post WMA_TSF_GPIO_PIN");
			status = QDF_STATUS_E_FAILURE;
		}
		sme_release_global_lock(&mac->sme);
	}
	return status;
}
#endif

QDF_STATUS sme_get_cfg_valid_channels(tHalHandle hHal, uint8_t *aValidChannels,
				      uint32_t *len)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		status = csr_get_cfg_valid_channels(pMac, aValidChannels, len);
		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

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

    \fn sme_handle_change_country_code

    \brief Change Country code, Reg Domain and channel list

    \details Country Code Priority
    If Supplicant country code is priority than 11d is disabled.
    If 11D is enabled, we update the country code after every scan.
    Hence when Supplicant country code is priority, we don't need 11D info.
    Country code from Supplicant is set as current courtry code.
    User can send reset command XX (instead of country code) to reset the
    country code to default values.
    If 11D is priority,
    Than Supplicant country code code is set to default code. But 11D code is set as current country code

    \param pMac - The handle returned by mac_open.
    \param pMsgBuf - MSG Buffer

    \return QDF_STATUS

   -------------------------------------------------------------------------------*/
QDF_STATUS sme_handle_change_country_code(tpAniSirGlobal pMac, void *pMsgBuf)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tAniChangeCountryCodeReq *pMsg;
	v_REGDOMAIN_t domainIdIoctl;
	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
	static uint8_t default_country[CDS_COUNTRY_CODE_LEN + 1];
	pMsg = (tAniChangeCountryCodeReq *) pMsgBuf;

	/*
	 * if the reset Supplicant country code command is triggered,
	 * enable 11D, reset the country code and return
	 */
	if (false ==
	    qdf_mem_cmp(pMsg->countryCode, SME_INVALID_COUNTRY_CODE, 2)) {
		pMac->roam.configParam.Is11dSupportEnabled =
			pMac->roam.configParam.Is11dSupportEnabledOriginal;

		qdf_status = cds_read_default_country(default_country);

		/* read the country code and use it */
		if (QDF_IS_STATUS_SUCCESS(qdf_status)) {
			qdf_mem_copy(pMsg->countryCode,
				     default_country,
				     WNI_CFG_COUNTRY_CODE_LEN);
		} else {
			status = QDF_STATUS_E_FAILURE;
			return status;
		}
		/*
		 * Update the 11d country to default country so that when
		 * callback is received for this default country, driver will
		 * not disable the 11d taking it as valid country by user.
		 */
		sms_log(pMac, LOG1,
			FL("Set default country code (%c%c) as invalid country received"),
			pMsg->countryCode[0], pMsg->countryCode[1]);
			qdf_mem_copy(pMac->scan.countryCode11d,
			pMsg->countryCode,
			WNI_CFG_COUNTRY_CODE_LEN);
	} else {
		/* if Supplicant country code has priority, disable 11d */
		if (pMac->roam.configParam.fSupplicantCountryCodeHasPriority &&
		    pMsg->countryFromUserSpace) {
			pMac->roam.configParam.Is11dSupportEnabled = false;
		}
	}

	if (pMac->roam.configParam.Is11dSupportEnabled)
		return QDF_STATUS_SUCCESS;

	/* Set Current Country code and Current Regulatory domain */
	status = csr_set_country_code(pMac, pMsg->countryCode);
	if (QDF_STATUS_SUCCESS != status) {
		/* Supplicant country code failed. So give 11D priority */
		pMac->roam.configParam.Is11dSupportEnabled =
			pMac->roam.configParam.Is11dSupportEnabledOriginal;
		sms_log(pMac, LOGE, "Set Country Code Fail %d", status);
		return status;
	}

	/* overwrite the defualt country code */
	qdf_mem_copy(pMac->scan.countryCodeDefault,
		     pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);

	/* Get Domain ID from country code */
	status = csr_get_regulatory_domain_for_country(pMac,
						       pMac->scan.countryCodeCurrent,
						       (v_REGDOMAIN_t *) &
						       domainIdIoctl,
						       SOURCE_QUERY);
	if (status != QDF_STATUS_SUCCESS) {
		sms_log(pMac, LOGE, FL("  fail to get regId %d"), domainIdIoctl);
		return status;
	} else if (REGDOMAIN_WORLD == domainIdIoctl) {
		/* Supplicant country code is invalid, so we are on world mode now. So
		   give 11D chance to update */
		pMac->roam.configParam.Is11dSupportEnabled =
			pMac->roam.configParam.Is11dSupportEnabledOriginal;
		sms_log(pMac, LOG1, FL("Country Code unrecognized by driver"));
	}

	status = wma_set_reg_domain(pMac, domainIdIoctl);

	if (status != QDF_STATUS_SUCCESS) {
		sms_log(pMac, LOGE, FL("  fail to set regId %d"), domainIdIoctl);
		return status;
	} else {
		/* if 11d has priority, clear currentCountryBssid & countryCode11d to get */
		/* set again if we find AP with 11d info during scan */
		if (!pMac->roam.configParam.fSupplicantCountryCodeHasPriority) {
			sms_log(pMac, LOGW,
				FL
					("Clearing currentCountryBssid, countryCode11d"));
			qdf_mem_zero(&pMac->scan.currentCountryBssid,
				     sizeof(struct qdf_mac_addr));
			qdf_mem_zero(pMac->scan.countryCode11d,
				     sizeof(pMac->scan.countryCode11d));
		}
	}

	if (pMsg->changeCCCallback) {
		((tSmeChangeCountryCallback) (pMsg->changeCCCallback))((void *)
								       pMsg->
								       pDevContext);
	}

	return QDF_STATUS_SUCCESS;
}

/**
 * sme_handle_generic_change_country_code() - handles country ch req
 * @mac_ctx:    mac global context
 * @msg:        request msg packet
 *
 * If Supplicant country code is priority than 11d is disabled.
 * If 11D is enabled, we update the country code after every scan.
 * Hence when Supplicant country code is priority, we don't need 11D info.
 * Country code from Supplicant is set as current country code.
 *
 * Return: status of operation
 */
QDF_STATUS
sme_handle_generic_change_country_code(tpAniSirGlobal mac_ctx,
				       void *pMsgBuf)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	v_REGDOMAIN_t reg_domain_id = 0;
	bool is_11d_country = false;
	bool supplicant_priority =
		mac_ctx->roam.configParam.fSupplicantCountryCodeHasPriority;
	tAniGenericChangeCountryCodeReq *msg = pMsgBuf;

	sms_log(mac_ctx, LOG1, FL(" called"));

	if (memcmp(msg->countryCode, mac_ctx->scan.countryCode11d,
		   CDS_COUNTRY_CODE_LEN) == 0) {
		is_11d_country = true;
	}
	/* Set the country code given by userspace when 11dOriginal is false
	 * when 11doriginal is True,is_11d_country =0 and
	 * fSupplicantCountryCodeHasPriority = 0, then revert the country code,
	 * and return failure
	 */
	if (mac_ctx->roam.configParam.Is11dSupportEnabledOriginal == true
	    && !is_11d_country && !supplicant_priority) {
		sms_log(mac_ctx, LOGW,
			FL("Incorrect country req, nullify this"));

		/* we have got a request for a country that should not have been
		 * added since the STA is associated; nullify this request. If
		 * both countryCode11d[0] and countryCode11d[1] are zero, revert
		 * it to World domain to avoid from causing cfg80211 call trace.
		 */
		if ((mac_ctx->scan.countryCode11d[0] == 0)
		    && (mac_ctx->scan.countryCode11d[1] == 0))
			status = csr_get_regulatory_domain_for_country(mac_ctx,
					"00", (v_REGDOMAIN_t *) &reg_domain_id,
					SOURCE_11D);
		else
			status = csr_get_regulatory_domain_for_country(mac_ctx,
					mac_ctx->scan.countryCode11d,
					(v_REGDOMAIN_t *) &reg_domain_id,
					SOURCE_11D);

		return QDF_STATUS_E_FAILURE;
	}

	/* if Supplicant country code has priority, disable 11d */
	if (!is_11d_country && supplicant_priority)
		mac_ctx->roam.configParam.Is11dSupportEnabled = false;
	qdf_mem_copy(mac_ctx->scan.countryCodeCurrent, msg->countryCode,
		     WNI_CFG_COUNTRY_CODE_LEN);
	status = wma_set_reg_domain(mac_ctx, reg_domain_id);
	if (false == is_11d_country) {
		/* overwrite the defualt country code */
		qdf_mem_copy(mac_ctx->scan.countryCodeDefault,
			     mac_ctx->scan.countryCodeCurrent,
			     WNI_CFG_COUNTRY_CODE_LEN);
		/* set to default domain ID */
		mac_ctx->scan.domainIdDefault = mac_ctx->scan.domainIdCurrent;
	}
	if (status != QDF_STATUS_SUCCESS) {
		sms_log(mac_ctx, LOGE, FL("fail to set regId %d"),
			reg_domain_id);
		return status;
	} else {
		/* if 11d has priority, clear currentCountryBssid &
		 * countryCode11d to get set again if we find AP with 11d info
		 * during scan
		 */
		if (!supplicant_priority && (false == is_11d_country)) {
			sms_log(mac_ctx, LOGW,
				FL("Clearing currentCountryBssid, countryCode11d"));
			qdf_mem_zero(&mac_ctx->scan.currentCountryBssid,
				     sizeof(struct qdf_mac_addr));
			qdf_mem_zero(mac_ctx->scan.countryCode11d,
				     sizeof(mac_ctx->scan.countryCode11d));
		}
	}
	/* get the channels based on new cc */
	status = csr_get_channel_and_power_list(mac_ctx);

	if (status != QDF_STATUS_SUCCESS) {
		sms_log(mac_ctx, LOGE, FL("fail to get Channels"));
		return status;
	}
	/* reset info based on new cc, and we are done */
	csr_apply_channel_power_info_wrapper(mac_ctx);

	/* Country code  Changed, Purge Only scan result
	 * which does not have channel number belong to 11d
	 * channel list
	 */
	csr_scan_filter_results(mac_ctx);
	/* Do active scans after the country is set by User hints or
	 * Country IE
	 */
	mac_ctx->scan.curScanType = eSIR_ACTIVE_SCAN;
	sme_disconnect_connected_sessions(mac_ctx);
	sms_log(mac_ctx, LOG1, FL(" returned"));
	return QDF_STATUS_SUCCESS;
}

static bool
sme_search_in_base_ch_lst(tpAniSirGlobal mac_ctx, uint8_t curr_ch)
{
	uint8_t i;
	tCsrChannel *ch_lst_info;
	ch_lst_info = &mac_ctx->scan.base_channels;
	for (i = 0; i < ch_lst_info->numChannels; i++) {
		if (ch_lst_info->channelList[i] == curr_ch)
			return true;
	}

	return false;
}
/**
 * sme_disconnect_connected_sessions() - Disconnect STA and P2P client session
 * if channel is not supported
 * @mac_ctx:          mac global context
 *
 * If new country code does not support the channel on which STA/P2P client
 * is connetced, it sends the disconnect to the AP/P2P GO
 *
 * Return: void
 */
void sme_disconnect_connected_sessions(tpAniSirGlobal mac_ctx)
{
	uint8_t session_id, found = false;
	uint8_t curr_ch;

	for (session_id = 0; session_id < CSR_ROAM_SESSION_MAX; session_id++) {
		if (!csr_is_session_client_and_connected(mac_ctx, session_id))
			continue;
		found = false;
		/* Session is connected.Check the channel */
		curr_ch = csr_get_infra_operation_channel(mac_ctx,
							  session_id);
		sms_log(mac_ctx, LOGW,
			FL("Current Operating channel : %d, session :%d"),
			curr_ch, session_id);
		found = sme_search_in_base_ch_lst(mac_ctx, curr_ch);
		if (!found) {
			sms_log(mac_ctx, LOGW, FL("Disconnect Session :%d"),
				session_id);
			csr_roam_disconnect(mac_ctx, session_id,
					    eCSR_DISCONNECT_REASON_UNSPECIFIED);
		}
	}
}

#ifdef WLAN_FEATURE_PACKET_FILTERING
QDF_STATUS sme_8023_multicast_list(tHalHandle hHal, uint8_t sessionId,
				   tpSirRcvFltMcAddrList pMulticastAddrs)
{
	tpSirRcvFltMcAddrList request_buf;
	cds_msg_t msg;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	tCsrRoamSession *pSession = NULL;

	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, "%s: "
		  "ulMulticastAddrCnt=%d, multicastAddr[0]=%p", __func__,
		  pMulticastAddrs->ulMulticastAddrCnt,
		  pMulticastAddrs->multicastAddr[0].bytes);

	/* Find the connected Infra / P2P_client connected session */
	if (CSR_IS_SESSION_VALID(pMac, sessionId) &&
			(csr_is_conn_state_infra(pMac, sessionId) ||
			csr_is_ndi_started(pMac, sessionId))) {
		pSession = CSR_GET_SESSION(pMac, sessionId);
	}

	if (pSession == NULL) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_WARN,
			  "%s: Unable to find the session Id: %d", __func__,
			  sessionId);
		return QDF_STATUS_E_FAILURE;
	}

	request_buf = qdf_mem_malloc(sizeof(tSirRcvFltMcAddrList));
	if (NULL == request_buf) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "%s: Not able to "
			  "allocate memory for 8023 Multicast List request",
			  __func__);
		return QDF_STATUS_E_NOMEM;
	}

	if (!csr_is_conn_state_connected_infra(pMac, sessionId) &&
			!csr_is_ndi_started(pMac, sessionId)) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			"%s: Request ignored, session %d is not connected or started",
			__func__, sessionId);
		qdf_mem_free(request_buf);
		return QDF_STATUS_E_FAILURE;
	}

	qdf_mem_copy(request_buf, pMulticastAddrs,
		     sizeof(tSirRcvFltMcAddrList));

	qdf_copy_macaddr(&request_buf->self_macaddr, &pSession->selfMacAddr);
	qdf_copy_macaddr(&request_buf->bssid,
			 &pSession->connectedProfile.bssid);

	msg.type = WMA_8023_MULTICAST_LIST_REQ;
	msg.reserved = 0;
	msg.bodyptr = request_buf;
	MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
			 sessionId, msg.type));
	if (QDF_STATUS_SUCCESS != cds_mq_post_message(QDF_MODULE_ID_WMA, &msg)) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "%s: Not able to "
			  "post WMA_8023_MULTICAST_LIST message to WMA",
			  __func__);
		qdf_mem_free(request_buf);
		return QDF_STATUS_E_FAILURE;
	}

	return QDF_STATUS_SUCCESS;
}

QDF_STATUS sme_receive_filter_set_filter(tHalHandle hHal,
					 tpSirRcvPktFilterCfgType pRcvPktFilterCfg,
					 uint8_t sessionId)
{
	tpSirRcvPktFilterCfgType request_buf;
	int32_t allocSize;
	cds_msg_t msg;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
	uint8_t idx = 0;

	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, "%s: filterType=%d, "
		  "filterId = %d", __func__,
		  pRcvPktFilterCfg->filterType, pRcvPktFilterCfg->filterId);

	allocSize = sizeof(tSirRcvPktFilterCfgType);

	request_buf = qdf_mem_malloc(allocSize);

	if (NULL == request_buf) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "%s: Not able to "
			  "allocate memory for Receive Filter Set Filter request",
			  __func__);
		return QDF_STATUS_E_NOMEM;
	}

	if (NULL == pSession) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "%s: Session Not found ", __func__);
		qdf_mem_free(request_buf);
		return QDF_STATUS_E_FAILURE;
	}

	qdf_copy_macaddr(&pRcvPktFilterCfg->self_macaddr,
			 &pSession->selfMacAddr);
	qdf_copy_macaddr(&pRcvPktFilterCfg->bssid,
			 &pSession->connectedProfile.bssid);
	qdf_mem_copy(request_buf, pRcvPktFilterCfg, allocSize);

	msg.type = WMA_RECEIVE_FILTER_SET_FILTER_REQ;
	msg.reserved = 0;
	msg.bodyptr = request_buf;
	MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
			 sessionId, msg.type));
	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, "Pkt Flt Req : "
		  "FT %d FID %d ",
		  request_buf->filterType, request_buf->filterId);

	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, "Pkt Flt Req : "
		  "params %d CT %d",
		  request_buf->numFieldParams, request_buf->coalesceTime);

	for (idx = 0; idx < request_buf->numFieldParams; idx++) {

		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
			  "Proto %d Comp Flag %d ",
			  request_buf->paramsData[idx].protocolLayer,
			  request_buf->paramsData[idx].cmpFlag);

		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
			  "Data Offset %d Data Len %d",
			  request_buf->paramsData[idx].dataOffset,
			  request_buf->paramsData[idx].dataLength);

		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
			  "CData: %d:%d:%d:%d:%d:%d",
			  request_buf->paramsData[idx].compareData[0],
			  request_buf->paramsData[idx].compareData[1],
			  request_buf->paramsData[idx].compareData[2],
			  request_buf->paramsData[idx].compareData[3],
			  request_buf->paramsData[idx].compareData[4],
			  request_buf->paramsData[idx].compareData[5]);

		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
			  "MData: %d:%d:%d:%d:%d:%d",
			  request_buf->paramsData[idx].dataMask[0],
			  request_buf->paramsData[idx].dataMask[1],
			  request_buf->paramsData[idx].dataMask[2],
			  request_buf->paramsData[idx].dataMask[3],
			  request_buf->paramsData[idx].dataMask[4],
			  request_buf->paramsData[idx].dataMask[5]);

	}

	if (QDF_STATUS_SUCCESS != cds_mq_post_message(QDF_MODULE_ID_WMA, &msg)) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "%s: Not able to post "
			  "WMA_RECEIVE_FILTER_SET_FILTER message to WMA",
			  __func__);
		qdf_mem_free(request_buf);
		return QDF_STATUS_E_FAILURE;
	}

	return QDF_STATUS_SUCCESS;
}

QDF_STATUS sme_receive_filter_clear_filter(tHalHandle hHal,
					   tpSirRcvFltPktClearParam
					   pRcvFltPktClearParam, uint8_t sessionId)
{
	tpSirRcvFltPktClearParam request_buf;
	cds_msg_t msg;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);

	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, "%s: filterId = %d",
		  __func__, pRcvFltPktClearParam->filterId);

	if (NULL == pSession) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "%s: Session Not found", __func__);
		return QDF_STATUS_E_FAILURE;
	}

	request_buf = qdf_mem_malloc(sizeof(tSirRcvFltPktClearParam));
	if (NULL == request_buf) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "%s: Not able to allocate memory for Receive Filter "
			  "Clear Filter request", __func__);
		return QDF_STATUS_E_NOMEM;
	}

	qdf_copy_macaddr(&pRcvFltPktClearParam->self_macaddr,
			 &pSession->selfMacAddr);
	qdf_copy_macaddr(&pRcvFltPktClearParam->bssid,
			 &pSession->connectedProfile.bssid);

	qdf_mem_copy(request_buf, pRcvFltPktClearParam,
		     sizeof(tSirRcvFltPktClearParam));

	msg.type = WMA_RECEIVE_FILTER_CLEAR_FILTER_REQ;
	msg.reserved = 0;
	msg.bodyptr = request_buf;
	MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
			 sessionId, msg.type));
	if (QDF_STATUS_SUCCESS != cds_mq_post_message(QDF_MODULE_ID_WMA, &msg)) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "%s: Not able to post "
			  "WMA_RECEIVE_FILTER_CLEAR_FILTER message to WMA",
			  __func__);
		qdf_mem_free(request_buf);
		return QDF_STATUS_E_FAILURE;
	}

	return QDF_STATUS_SUCCESS;
}
#endif /* WLAN_FEATURE_PACKET_FILTERING */

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

    \fn sme_is_channel_valid

    \brief To check if the channel is valid for currently established domain
    This is a synchronous API.

    \param hHal - The handle returned by mac_open.
    \param channel - channel to verify

    \return true/false, true if channel is valid

   -------------------------------------------------------------------------------*/
bool sme_is_channel_valid(tHalHandle hHal, uint8_t channel)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	bool valid = false;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {

		valid = csr_roam_is_channel_valid(pMac, channel);

		sme_release_global_lock(&pMac->sme);
	}

	return valid;
}

/* ---------------------------------------------------------------------------
    \fn sme_set_freq_band
    \brief  Used to set frequency band.
    \param  hHal
    \param  sessionId - Session Identifier
    \eBand  band value to be configured
   \- return QDF_STATUS
    -------------------------------------------------------------------------*/
QDF_STATUS sme_set_freq_band(tHalHandle hHal, uint8_t sessionId, eCsrBand eBand)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		status = csr_set_band(hHal, sessionId, eBand);
		sme_release_global_lock(&pMac->sme);
	}
	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_get_freq_band
    \brief  Used to get the current band settings.
    \param  hHal
    \pBand  pointer to hold band value
   \- return QDF_STATUS
    -------------------------------------------------------------------------*/
QDF_STATUS sme_get_freq_band(tHalHandle hHal, eCsrBand *pBand)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		*pBand = csr_get_current_band(hHal);
		sme_release_global_lock(&pMac->sme);
	}
	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_set_max_tx_power_per_band

    \brief Set the Maximum Transmit Power specific to band dynamically.
    Note: this setting will not persist over reboots.

    \param band
    \param power to set in dB
  \- return QDF_STATUS

   ----------------------------------------------------------------------------*/
QDF_STATUS sme_set_max_tx_power_per_band(eCsrBand band, int8_t dB)
{
	cds_msg_t msg;
	tpMaxTxPowerPerBandParams pMaxTxPowerPerBandParams = NULL;

	pMaxTxPowerPerBandParams =
		qdf_mem_malloc(sizeof(tMaxTxPowerPerBandParams));
	if (NULL == pMaxTxPowerPerBandParams) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "%s:Not able to allocate memory for pMaxTxPowerPerBandParams",
			  __func__);
		return QDF_STATUS_E_NOMEM;
	}

	pMaxTxPowerPerBandParams->power = dB;
	pMaxTxPowerPerBandParams->bandInfo = band;

	msg.type = WMA_SET_MAX_TX_POWER_PER_BAND_REQ;
	msg.reserved = 0;
	msg.bodyptr = pMaxTxPowerPerBandParams;
	MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
			 NO_SESSION, msg.type));
	if (QDF_STATUS_SUCCESS != cds_mq_post_message(QDF_MODULE_ID_WMA, &msg)) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "%s:Not able to post WMA_SET_MAX_TX_POWER_PER_BAND_REQ",
			  __func__);
		qdf_mem_free(pMaxTxPowerPerBandParams);
		return QDF_STATUS_E_FAILURE;
	}

	return QDF_STATUS_SUCCESS;
}

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

    \fn sme_set_max_tx_power

    \brief Set the Maximum Transmit Power dynamically. Note: this setting will
    not persist over reboots.

    \param  hHal
    \param pBssid  BSSID to set the power cap for
    \param pBssid  pSelfMacAddress self MAC Address
    \param pBssid  power to set in dB
   \- return QDF_STATUS

   -------------------------------------------------------------------------------*/
QDF_STATUS sme_set_max_tx_power(tHalHandle hHal, struct qdf_mac_addr pBssid,
				struct qdf_mac_addr pSelfMacAddress, int8_t dB)
{
	cds_msg_t msg;
	tpMaxTxPowerParams pMaxTxParams = NULL;

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_SET_MAXTXPOW, NO_SESSION, 0));
	pMaxTxParams = qdf_mem_malloc(sizeof(tMaxTxPowerParams));
	if (NULL == pMaxTxParams) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "%s: Not able to allocate memory for pMaxTxParams",
			  __func__);
		return QDF_STATUS_E_NOMEM;
	}

	qdf_copy_macaddr(&pMaxTxParams->bssId, &pBssid);
	qdf_copy_macaddr(&pMaxTxParams->selfStaMacAddr, &pSelfMacAddress);
	pMaxTxParams->power = dB;

	msg.type = WMA_SET_MAX_TX_POWER_REQ;
	msg.reserved = 0;
	msg.bodyptr = pMaxTxParams;

	if (QDF_STATUS_SUCCESS != cds_mq_post_message(QDF_MODULE_ID_WMA, &msg)) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "%s: Not able to post WMA_SET_MAX_TX_POWER_REQ message to WMA",
			  __func__);
		qdf_mem_free(pMaxTxParams);
		return QDF_STATUS_E_FAILURE;
	}

	return QDF_STATUS_SUCCESS;
}

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

    \fn sme_set_custom_mac_addr

    \brief Set the customer Mac Address.

    \param customMacAddr  customer MAC Address
   \- return QDF_STATUS

   ---------------------------------------------------------------------------*/
QDF_STATUS sme_set_custom_mac_addr(tSirMacAddr customMacAddr)
{
	cds_msg_t msg;
	tSirMacAddr *pBaseMacAddr;

	pBaseMacAddr = qdf_mem_malloc(sizeof(tSirMacAddr));
	if (NULL == pBaseMacAddr) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  FL("Not able to allocate memory for pBaseMacAddr"));
		return QDF_STATUS_E_NOMEM;
	}

	qdf_mem_copy(*pBaseMacAddr, customMacAddr, sizeof(tSirMacAddr));

	msg.type = SIR_HAL_SET_BASE_MACADDR_IND;
	msg.reserved = 0;
	msg.bodyptr = pBaseMacAddr;

	if (QDF_STATUS_SUCCESS != cds_mq_post_message(QDF_MODULE_ID_WMA, &msg)) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  FL
				  ("Not able to post SIR_HAL_SET_BASE_MACADDR_IND message to WMA"));
		qdf_mem_free(pBaseMacAddr);
		return QDF_STATUS_E_FAILURE;
	}

	return QDF_STATUS_SUCCESS;
}

/* ----------------------------------------------------------------------------
   \fn sme_set_tx_power
   \brief Set Transmit Power dynamically.
   \param  hHal
   \param sessionId  Target Session ID
   \pBSSId BSSID
   \dev_mode dev_mode such as station, P2PGO, SAP
   \param dBm  power to set
   \- return QDF_STATUS
   ---------------------------------------------------------------------------*/
QDF_STATUS sme_set_tx_power(tHalHandle hHal, uint8_t sessionId,
			   struct qdf_mac_addr pBSSId,
			   enum tQDF_ADAPTER_MODE dev_mode, int dBm)
{
	cds_msg_t msg;
	tpMaxTxPowerParams pTxParams = NULL;
	int8_t power = (int8_t) dBm;

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_SET_TXPOW, sessionId, 0));

	/* make sure there is no overflow */
	if ((int)power != dBm) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "%s: error, invalid power = %d", __func__, dBm);
		return QDF_STATUS_E_FAILURE;
	}

	pTxParams = qdf_mem_malloc(sizeof(tMaxTxPowerParams));
	if (NULL == pTxParams) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "%s: Not able to allocate memory for pTxParams",
			  __func__);
		return QDF_STATUS_E_NOMEM;
	}

	qdf_copy_macaddr(&pTxParams->bssId, &pBSSId);
	pTxParams->power = power;       /* unit is dBm */
	pTxParams->dev_mode = dev_mode;
	msg.type = WMA_SET_TX_POWER_REQ;
	msg.reserved = 0;
	msg.bodyptr = pTxParams;

	if (QDF_STATUS_SUCCESS != cds_mq_post_message(QDF_MODULE_ID_WMA, &msg)) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "%s: failed to post WMA_SET_TX_POWER_REQ to WMA",
			  __func__);
		qdf_mem_free(pTxParams);
		return QDF_STATUS_E_FAILURE;
	}

	return QDF_STATUS_SUCCESS;
}

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

    \fn sme_hide_ssid

    \brief hide/show SSID dynamically. Note: this setting will
    not persist over reboots.

    \param hHal
    \param sessionId
    \param ssidHidden 0 - Broadcast SSID, 1 - Disable broadcast SSID
   \- return QDF_STATUS

   -------------------------------------------------------------------------------*/
QDF_STATUS sme_hide_ssid(tHalHandle hHal, uint8_t sessionId, uint8_t ssidHidden)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	uint16_t len;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		tpSirUpdateParams pMsg;
		tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);

		if (!pSession) {
			sms_log(pMac, LOGE, FL("  session %d not found "),
				sessionId);
			sme_release_global_lock(&pMac->sme);
			return QDF_STATUS_E_FAILURE;
		}

		if (!pSession->sessionActive)
			QDF_ASSERT(0);

		/* Create the message and send to lim */
		len = sizeof(tSirUpdateParams);
		pMsg = qdf_mem_malloc(len);
		if (NULL == pMsg)
			status = QDF_STATUS_E_NOMEM;
		else {
			qdf_mem_set(pMsg, sizeof(tSirUpdateParams), 0);
			pMsg->messageType = eWNI_SME_HIDE_SSID_REQ;
			pMsg->length = len;
			/* Data starts from here */
			pMsg->sessionId = sessionId;
			pMsg->ssidHidden = ssidHidden;
			status = cds_send_mb_message_to_mac(pMsg);
		}
		sme_release_global_lock(&pMac->sme);
	}
	return status;
}

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

    \fn sme_set_tm_level
    \brief  Set Thermal Mitigation Level to RIVA
    \param  hHal - The handle returned by mac_open.
    \param  newTMLevel - new Thermal Mitigation Level
    \param  tmMode - Thermal Mitigation handle mode, default 0
    \return QDF_STATUS
   ---------------------------------------------------------------------------*/
QDF_STATUS sme_set_tm_level(tHalHandle hHal, uint16_t newTMLevel, uint16_t tmMode)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	cds_msg_t cds_message;
	tAniSetTmLevelReq *setTmLevelReq = NULL;

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_SET_TMLEVEL, NO_SESSION, 0));
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		setTmLevelReq =
			(tAniSetTmLevelReq *)
			qdf_mem_malloc(sizeof(tAniSetTmLevelReq));
		if (NULL == setTmLevelReq) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				  "%s: Not able to allocate memory for sme_set_tm_level",
				  __func__);
			sme_release_global_lock(&pMac->sme);
			return QDF_STATUS_E_NOMEM;
		}

		setTmLevelReq->tmMode = tmMode;
		setTmLevelReq->newTmLevel = newTMLevel;

		/* serialize the req through MC thread */
		cds_message.bodyptr = setTmLevelReq;
		cds_message.type = WMA_SET_TM_LEVEL_REQ;
		MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
				 NO_SESSION, cds_message.type));
		qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				  "%s: Post Set TM Level MSG fail", __func__);
			qdf_mem_free(setTmLevelReq);
			status = QDF_STATUS_E_FAILURE;
		}
		sme_release_global_lock(&pMac->sme);
	}
	return status;
}

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

   \brief sme_feature_caps_exchange() - SME interface to exchange capabilities between
   Host and FW.

   \param  hHal - HAL handle for device

   \return NONE

   ---------------------------------------------------------------------------*/
void sme_feature_caps_exchange(tHalHandle hHal)
{
	MTRACE(qdf_trace
		       (QDF_MODULE_ID_SME, TRACE_CODE_SME_RX_HDD_CAPS_EXCH, NO_SESSION,
		       0));
}

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

   \brief sme_disable_feature_capablity() - SME interface to disable Active mode offload capablity
   in Host.

   \param  hHal - HAL handle for device

   \return NONE

   ---------------------------------------------------------------------------*/
void sme_disable_feature_capablity(uint8_t feature_index)
{
}

/* ---------------------------------------------------------------------------
    \fn     sme_reset_power_values_for5_g
    \brief  Reset the power values for 5G band with default power values.
    \param  hHal - HAL handle for device
   \- return NONE
    -------------------------------------------------------------------------*/
void sme_reset_power_values_for5_g(tHalHandle hHal)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_RESET_PW5G, NO_SESSION, 0));
	csr_save_channel_power_for_band(pMac, true);
	csr_apply_power2_current(pMac);    /* Store the channel+power info in the global place: Cfg */
}

/* ---------------------------------------------------------------------------
    \fn sme_update_roam_prefer5_g_hz
    \brief  enable/disable Roam prefer 5G runtime option
	    This function is called through dynamic setConfig callback function
	    to configure the Roam prefer 5G runtime option
    \param  hHal - HAL handle for device
    \param  nRoamPrefer5GHz Enable/Disable Roam prefer 5G runtime option
   \- return Success or failure
    -------------------------------------------------------------------------*/

QDF_STATUS sme_update_roam_prefer5_g_hz(tHalHandle hHal, bool nRoamPrefer5GHz)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	QDF_STATUS status = QDF_STATUS_SUCCESS;

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_UPDATE_RP5G, NO_SESSION, 0));
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
			  "%s: gRoamPrefer5GHz is changed from %d to %d",
			  __func__, pMac->roam.configParam.nRoamPrefer5GHz,
			  nRoamPrefer5GHz);
		pMac->roam.configParam.nRoamPrefer5GHz = nRoamPrefer5GHz;
		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_set_roam_intra_band
    \brief  enable/disable Intra band roaming
	    This function is called through dynamic setConfig callback function
	    to configure the intra band roaming
    \param  hHal - HAL handle for device
    \param  nRoamIntraBand Enable/Disable Intra band roaming
   \- return Success or failure
    -------------------------------------------------------------------------*/
QDF_STATUS sme_set_roam_intra_band(tHalHandle hHal, const bool nRoamIntraBand)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	QDF_STATUS status = QDF_STATUS_SUCCESS;

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_SET_ROAMIBAND, NO_SESSION, 0));
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
			  "%s: gRoamIntraBand is changed from %d to %d",
			  __func__, pMac->roam.configParam.nRoamIntraBand,
			  nRoamIntraBand);
		pMac->roam.configParam.nRoamIntraBand = nRoamIntraBand;
		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_update_roam_scan_n_probes
    \brief  function to update roam scan N probes
	    This function is called through dynamic setConfig callback function
	    to update roam scan N probes
    \param  hHal - HAL handle for device
    \param  sessionId - Session Identifier
    \param  nProbes number of probe requests to be sent out
   \- return Success or failure
    -------------------------------------------------------------------------*/
QDF_STATUS sme_update_roam_scan_n_probes(tHalHandle hHal, uint8_t sessionId,
					 const uint8_t nProbes)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	QDF_STATUS status = QDF_STATUS_SUCCESS;

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_UPDATE_ROAM_SCAN_N_PROBES,
			 NO_SESSION, 0));
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
			  "%s: gRoamScanNProbes is changed from %d to %d",
			  __func__, pMac->roam.configParam.nProbes, nProbes);
		pMac->roam.configParam.nProbes = nProbes;
		sme_release_global_lock(&pMac->sme);
	}
	if (pMac->roam.configParam.isRoamOffloadScanEnabled) {
		csr_roam_offload_scan(pMac, sessionId,
				      ROAM_SCAN_OFFLOAD_UPDATE_CFG,
				      REASON_NPROBES_CHANGED);
	}
	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_update_roam_scan_home_away_time
    \brief  function to update roam scan Home away time
	    This function is called through dynamic setConfig callback function
	    to update roam scan home away time
    \param  hHal - HAL handle for device
    \param  sessionId - Session Identifier
    \param  nRoamScanAwayTime Scan home away time
    \param  bSendOffloadCmd If true then send offload command to firmware
			    If false then command is not sent to firmware
   \- return Success or failure
    -------------------------------------------------------------------------*/
QDF_STATUS sme_update_roam_scan_home_away_time(tHalHandle hHal,
					       uint8_t sessionId,
					       const uint16_t nRoamScanHomeAwayTime,
					       const bool bSendOffloadCmd)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	QDF_STATUS status = QDF_STATUS_SUCCESS;

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_UPDATE_ROAM_SCAN_HOME_AWAY_TIME,
			 NO_SESSION, 0));
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
			  "%s: gRoamScanHomeAwayTime is changed from %d to %d",
			  __func__,
			  pMac->roam.configParam.nRoamScanHomeAwayTime,
			  nRoamScanHomeAwayTime);
		pMac->roam.configParam.nRoamScanHomeAwayTime =
			nRoamScanHomeAwayTime;
		sme_release_global_lock(&pMac->sme);
	}
	if (pMac->roam.configParam.isRoamOffloadScanEnabled && bSendOffloadCmd) {
		csr_roam_offload_scan(pMac, sessionId,
				      ROAM_SCAN_OFFLOAD_UPDATE_CFG,
				      REASON_HOME_AWAY_TIME_CHANGED);
	}
	return status;
}

/**
 * sme_ext_change_channel()- function to post send ECSA
 * action frame to csr.
 * @hHal: Hal context
 * @channel: new channel to switch
 * @session_id: senssion it should be sent on.
 *
 * This function is called to post ECSA frame to csr.
 *
 * Return: success if msg is sent else return failure
 */
QDF_STATUS sme_ext_change_channel(tHalHandle h_hal, uint32_t channel,
						uint8_t session_id)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal mac_ctx  = PMAC_STRUCT(h_hal);
	uint8_t channel_state;

	sms_log(mac_ctx, LOGE, FL(" Set Channel %d "), channel);
	channel_state =
		cds_get_channel_state(channel);

	if (CHANNEL_STATE_DISABLE == channel_state) {
		sms_log(mac_ctx, LOGE, FL(" Invalid channel %d "), channel);
		return QDF_STATUS_E_INVAL;
	}

	status = sme_acquire_global_lock(&mac_ctx->sme);

	if (QDF_STATUS_SUCCESS == status) {
		/* update the channel list to the firmware */
		status = csr_send_ext_change_channel(mac_ctx,
						channel, session_id);
		sme_release_global_lock(&mac_ctx->sme);
	}

	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_get_roam_intra_band
    \brief  get Intra band roaming
    \param  hHal - HAL handle for device
   \- return Success or failure
    -------------------------------------------------------------------------*/
bool sme_get_roam_intra_band(tHalHandle hHal)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_GET_ROAMIBAND, NO_SESSION, 0));
	return pMac->roam.configParam.nRoamIntraBand;
}

/* ---------------------------------------------------------------------------
    \fn sme_get_roam_scan_n_probes
    \brief  get N Probes
    \param  hHal - HAL handle for device
   \- return Success or failure
    -------------------------------------------------------------------------*/
uint8_t sme_get_roam_scan_n_probes(tHalHandle hHal)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	return pMac->roam.configParam.nProbes;
}

/* ---------------------------------------------------------------------------
    \fn sme_get_roam_scan_home_away_time
    \brief  get Roam scan home away time
    \param  hHal - HAL handle for device
   \- return Success or failure
    -------------------------------------------------------------------------*/
uint16_t sme_get_roam_scan_home_away_time(tHalHandle hHal)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	return pMac->roam.configParam.nRoamScanHomeAwayTime;
}

/* ---------------------------------------------------------------------------
    \fn sme_update_roam_rssi_diff
    \brief  Update RoamRssiDiff
	    This function is called through dynamic setConfig callback function
	    to configure RoamRssiDiff
	    Usage: adb shell iwpriv wlan0 setConfig RoamRssiDiff=[0 .. 125]
    \param  hHal - HAL handle for device
    \param  sessionId - Session Identifier
    \param  RoamRssiDiff - minimum rssi difference between potential
	    candidate and current AP.
   \- return Success or failure
    -------------------------------------------------------------------------*/

QDF_STATUS sme_update_roam_rssi_diff(tHalHandle hHal, uint8_t sessionId,
				     uint8_t RoamRssiDiff)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	QDF_STATUS status = QDF_STATUS_SUCCESS;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
			  "LFR runtime successfully set roam rssi diff to %d - old value is %d - roam state is %s",
			  RoamRssiDiff,
			  pMac->roam.configParam.RoamRssiDiff,
			  mac_trace_get_neighbour_roam_state(pMac->roam.
							     neighborRoamInfo
							     [sessionId].
							     neighborRoamState));
		pMac->roam.configParam.RoamRssiDiff = RoamRssiDiff;
		sme_release_global_lock(&pMac->sme);
	}
	if (pMac->roam.configParam.isRoamOffloadScanEnabled) {
		csr_roam_offload_scan(pMac, sessionId,
				      ROAM_SCAN_OFFLOAD_UPDATE_CFG,
				      REASON_RSSI_DIFF_CHANGED);
	}
	return status;
}

/*--------------------------------------------------------------------------
   \brief sme_update_fast_transition_enabled() - enable/disable Fast Transition
	support at runtime
   It is used at in the REG_DYNAMIC_VARIABLE macro definition of
   isFastTransitionEnabled.
   This is a synchronous call
   \param hHal - The handle returned by mac_open.
   \return QDF_STATUS_SUCCESS - SME update isFastTransitionEnabled config
	successfully.
	Other status means SME is failed to update isFastTransitionEnabled.
   \sa
   --------------------------------------------------------------------------*/
QDF_STATUS sme_update_fast_transition_enabled(tHalHandle hHal,
					      bool isFastTransitionEnabled)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	QDF_STATUS status = QDF_STATUS_SUCCESS;

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_UPDATE_FTENABLED, NO_SESSION,
			 0));
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
			  "%s: FastTransitionEnabled is changed from %d to %d",
			  __func__,
			  pMac->roam.configParam.isFastTransitionEnabled,
			  isFastTransitionEnabled);
		pMac->roam.configParam.isFastTransitionEnabled =
			isFastTransitionEnabled;
		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_update_wes_mode
    \brief  Update WES Mode
	    This function is called through dynamic setConfig callback function
	    to configure isWESModeEnabled
    \param  hHal - HAL handle for device
    \param  isWESModeEnabled - WES mode
    \param  sessionId - Session Identifier
    \return QDF_STATUS_SUCCESS - SME update isWESModeEnabled config successfully.
	    Other status means SME is failed to update isWESModeEnabled.
    -------------------------------------------------------------------------*/

QDF_STATUS sme_update_wes_mode(tHalHandle hHal, bool isWESModeEnabled,
			       uint8_t sessionId)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	QDF_STATUS status = QDF_STATUS_SUCCESS;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
			  "LFR runtime successfully set WES Mode to %d - old value is %d - roam state is %s",
			  isWESModeEnabled,
			  pMac->roam.configParam.isWESModeEnabled,
			  mac_trace_get_neighbour_roam_state(pMac->roam.
							     neighborRoamInfo
							     [sessionId].
							     neighborRoamState));
		pMac->roam.configParam.isWESModeEnabled = isWESModeEnabled;
		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_set_roam_scan_control
    \brief  Set roam scan control
	    This function is called to set roam scan control
	    if roam scan control is set to 0, roaming scan cache is cleared
	    any value other than 0 is treated as invalid value
    \param  hHal - HAL handle for device
    \param  sessionId - Session Identifier
    \return QDF_STATUS_SUCCESS - SME update config successfully.
	    Other status means SME failure to update
    -------------------------------------------------------------------------*/
QDF_STATUS sme_set_roam_scan_control(tHalHandle hHal, uint8_t sessionId,
				     bool roamScanControl)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	QDF_STATUS status = QDF_STATUS_SUCCESS;

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_SET_SCANCTRL, NO_SESSION, 0));
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
			  "LFR runtime successfully set roam scan control to %d - old value is %d - roam state is %s",
			  roamScanControl,
			  pMac->roam.configParam.nRoamScanControl,
			  mac_trace_get_neighbour_roam_state(pMac->roam.
							     neighborRoamInfo
							     [sessionId].
							     neighborRoamState));
		pMac->roam.configParam.nRoamScanControl = roamScanControl;
		if (0 == roamScanControl) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
				  "LFR runtime successfully cleared roam scan cache");
			csr_flush_cfg_bg_scan_roam_channel_list(pMac, sessionId);
			if (pMac->roam.configParam.isRoamOffloadScanEnabled) {
				csr_roam_offload_scan(pMac, sessionId,
						      ROAM_SCAN_OFFLOAD_UPDATE_CFG,
						      REASON_FLUSH_CHANNEL_LIST);
			}
		}
		sme_release_global_lock(&pMac->sme);
	}
	return status;
}

/*--------------------------------------------------------------------------
   \brief sme_update_is_fast_roam_ini_feature_enabled() - enable/disable LFR
	support at runtime
   It is used at in the REG_DYNAMIC_VARIABLE macro definition of
   isFastRoamIniFeatureEnabled.
   This is a synchronous call
   \param hHal - The handle returned by mac_open.
   \param  sessionId - Session Identifier
   \return QDF_STATUS_SUCCESS - SME update isFastRoamIniFeatureEnabled config
	successfully.
	Other status means SME is failed to update isFastRoamIniFeatureEnabled.
   \sa
   --------------------------------------------------------------------------*/
QDF_STATUS sme_update_is_fast_roam_ini_feature_enabled
	(tHalHandle hHal,
	uint8_t sessionId, const bool isFastRoamIniFeatureEnabled) {
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	if (pMac->roam.configParam.isFastRoamIniFeatureEnabled ==
	    isFastRoamIniFeatureEnabled) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
			  "%s: FastRoam is already enabled or disabled, nothing to do (returning) old(%d) new(%d)",
			  __func__,
			  pMac->roam.configParam.isFastRoamIniFeatureEnabled,
			  isFastRoamIniFeatureEnabled);
		return QDF_STATUS_SUCCESS;
	}

	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
		  "%s: FastRoamEnabled is changed from %d to %d", __func__,
		  pMac->roam.configParam.isFastRoamIniFeatureEnabled,
		  isFastRoamIniFeatureEnabled);
	pMac->roam.configParam.isFastRoamIniFeatureEnabled =
		isFastRoamIniFeatureEnabled;
	csr_neighbor_roam_update_fast_roaming_enabled(pMac, sessionId,
						      isFastRoamIniFeatureEnabled);

	return QDF_STATUS_SUCCESS;
}

/*--------------------------------------------------------------------------
   \brief sme_update_is_mawc_ini_feature_enabled() -
   Enable/disable LFR MAWC support at runtime
   It is used at in the REG_DYNAMIC_VARIABLE macro definition of
   isMAWCIniFeatureEnabled.
   This is a synchronous call
   \param hHal - The handle returned by mac_open.
   \return QDF_STATUS_SUCCESS - SME update MAWCEnabled config successfully.
	Other status means SME is failed to update MAWCEnabled.
   \sa
   --------------------------------------------------------------------------*/
QDF_STATUS sme_update_is_mawc_ini_feature_enabled(tHalHandle hHal,
						  const bool MAWCEnabled)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	QDF_STATUS status = QDF_STATUS_SUCCESS;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
			  "%s: MAWCEnabled is changed from %d to %d", __func__,
			  pMac->roam.configParam.MAWCEnabled, MAWCEnabled);
		pMac->roam.configParam.MAWCEnabled = MAWCEnabled;
		sme_release_global_lock(&pMac->sme);
	}

	return status;

}

/*--------------------------------------------------------------------------
   \brief sme_stop_roaming() - Stop roaming for a given sessionId
   This is a synchronous call
   \param hHal      - The handle returned by mac_open
   \param  sessionId - Session Identifier
   \return QDF_STATUS_SUCCESS on success
	   Other status on failure
   \sa
   --------------------------------------------------------------------------*/
QDF_STATUS sme_stop_roaming(tHalHandle hHal, uint8_t sessionId, uint8_t reason)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	QDF_STATUS status = QDF_STATUS_SUCCESS;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		csr_roam_offload_scan(pMac, sessionId, ROAM_SCAN_OFFLOAD_STOP,
				      reason);
		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

/*--------------------------------------------------------------------------
   \brief sme_start_roaming() - Start roaming for a given sessionId
   This is a synchronous call
   \param hHal      - The handle returned by mac_open
   \param  sessionId - Session Identifier
   \return QDF_STATUS_SUCCESS on success
	Other status on failure
   \sa
   --------------------------------------------------------------------------*/
QDF_STATUS sme_start_roaming(tHalHandle hHal, uint8_t sessionId, uint8_t reason)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	QDF_STATUS status = QDF_STATUS_SUCCESS;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		csr_roam_offload_scan(pMac, sessionId, ROAM_SCAN_OFFLOAD_START,
				      reason);
		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

/*--------------------------------------------------------------------------
   \brief sme_update_enable_fast_roam_in_concurrency() - enable/disable LFR if
	Concurrent session exists
   This is a synchronuous call
   \param hHal - The handle returned by mac_open.
   \return QDF_STATUS_SUCCESS
	Other status means SME is failed
   \sa
   --------------------------------------------------------------------------*/

QDF_STATUS sme_update_enable_fast_roam_in_concurrency(tHalHandle hHal,
						      bool
						      bFastRoamInConIniFeatureEnabled)
{

	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	QDF_STATUS status = QDF_STATUS_SUCCESS;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		pMac->roam.configParam.bFastRoamInConIniFeatureEnabled =
			bFastRoamInConIniFeatureEnabled;
		if (0 == pMac->roam.configParam.isRoamOffloadScanEnabled) {
			pMac->roam.configParam.bFastRoamInConIniFeatureEnabled =
				0;
		}
		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

/*--------------------------------------------------------------------------
   \brief sme_update_config_fw_rssi_monitoring() - enable/disable firmware RSSI
	Monitoring at runtime
   It is used at in the REG_DYNAMIC_VARIABLE macro definition of
   fEnableFwRssiMonitoring.
   This is a synchronous call
   \param hHal - The handle returned by mac_open.
   \return QDF_STATUS_SUCCESS - SME update fEnableFwRssiMonitoring.
	config successfully.
	Other status means SME is failed to update fEnableFwRssiMonitoring.
   \sa
   --------------------------------------------------------------------------*/

QDF_STATUS sme_update_config_fw_rssi_monitoring(tHalHandle hHal,
						bool fEnableFwRssiMonitoring)
{
	QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;

	if (sme_cfg_set_int (hHal, WNI_CFG_PS_ENABLE_RSSI_MONITOR,
						fEnableFwRssiMonitoring) == QDF_STATUS_E_FAILURE) {
		qdf_ret_status = QDF_STATUS_E_FAILURE;
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "Could not pass on WNI_CFG_PS_RSSI_MONITOR to CFG");
	}

	return qdf_ret_status;
}

/* ---------------------------------------------------------------------------
    \fn     sme_set_roam_opportunistic_scan_threshold_diff
    \brief  Update Opportunistic Scan threshold diff
	This function is called through dynamic setConfig callback function
	to configure  nOpportunisticThresholdDiff
    \param  hHal - HAL handle for device
    \param  sessionId - Session Identifier
    \param  nOpportunisticThresholdDiff - Opportunistic Scan threshold diff
    \return QDF_STATUS_SUCCESS - SME update nOpportunisticThresholdDiff config
	    successfully.
	    else SME is failed to update nOpportunisticThresholdDiff.
    -------------------------------------------------------------------------*/
QDF_STATUS sme_set_roam_opportunistic_scan_threshold_diff(tHalHandle hHal,
							  uint8_t sessionId,
							  const uint8_t
							  nOpportunisticThresholdDiff)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	QDF_STATUS status = QDF_STATUS_SUCCESS;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		status = csr_neighbor_roam_update_config(pMac, sessionId,
				nOpportunisticThresholdDiff,
				REASON_OPPORTUNISTIC_THRESH_DIFF_CHANGED);
		if (QDF_IS_STATUS_SUCCESS(status)) {
			pMac->roam.configParam.neighborRoamConfig.
			nOpportunisticThresholdDiff =
				nOpportunisticThresholdDiff;
		}
		sme_release_global_lock(&pMac->sme);
	}
	return status;
}

/*--------------------------------------------------------------------------
   \fn    sme_get_roam_opportunistic_scan_threshold_diff()
   \brief gets Opportunistic Scan threshold diff
	This is a synchronous call
   \param hHal - The handle returned by mac_open
   \return uint8_t - nOpportunisticThresholdDiff
   \sa
   --------------------------------------------------------------------------*/
uint8_t sme_get_roam_opportunistic_scan_threshold_diff(tHalHandle hHal)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	return pMac->roam.configParam.neighborRoamConfig.
	       nOpportunisticThresholdDiff;
}

/* ---------------------------------------------------------------------------
    \fn     sme_set_roam_rescan_rssi_diff
    \brief  Update roam rescan rssi diff
	    This function is called through dynamic setConfig callback function
	    to configure  nRoamRescanRssiDiff
    \param  hHal - HAL handle for device
    \param  sessionId - Session Identifier
    \param  nRoamRescanRssiDiff - roam rescan rssi diff
    \return QDF_STATUS_SUCCESS - SME update nRoamRescanRssiDiff config
	    successfully.
	    else SME is failed to update nRoamRescanRssiDiff.
    -------------------------------------------------------------------------*/
QDF_STATUS sme_set_roam_rescan_rssi_diff(tHalHandle hHal,
					 uint8_t sessionId,
					 const uint8_t nRoamRescanRssiDiff)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	QDF_STATUS status = QDF_STATUS_SUCCESS;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		status = csr_neighbor_roam_update_config(pMac, sessionId,
				nRoamRescanRssiDiff,
				REASON_ROAM_RESCAN_RSSI_DIFF_CHANGED);
		if (QDF_IS_STATUS_SUCCESS(status)) {
			pMac->roam.configParam.neighborRoamConfig.
			nRoamRescanRssiDiff = nRoamRescanRssiDiff;
		}
		sme_release_global_lock(&pMac->sme);
	}
	return status;
}

/*--------------------------------------------------------------------------
   \fn    sme_get_roam_rescan_rssi_diff
   \brief gets roam rescan rssi diff
	  This is a synchronous call
   \param hHal - The handle returned by mac_open
   \return int8_t - nRoamRescanRssiDiff
   \sa
   --------------------------------------------------------------------------*/
uint8_t sme_get_roam_rescan_rssi_diff(tHalHandle hHal)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	return pMac->roam.configParam.neighborRoamConfig.nRoamRescanRssiDiff;
}

/* ---------------------------------------------------------------------------
    \fn     sme_set_roam_bmiss_first_bcnt
    \brief  Update Roam count for first beacon miss
	    This function is called through dynamic setConfig callback function
	    to configure nRoamBmissFirstBcnt
    \param  hHal - HAL handle for device
    \param  sessionId - Session Identifier
    \param  nRoamBmissFirstBcnt - Roam first bmiss count
    \return QDF_STATUS_SUCCESS - SME update nRoamBmissFirstBcnt
	    successfully.
	    else SME is failed to update nRoamBmissFirstBcnt
    -------------------------------------------------------------------------*/
QDF_STATUS sme_set_roam_bmiss_first_bcnt(tHalHandle hHal,
					 uint8_t sessionId,
					 const uint8_t nRoamBmissFirstBcnt)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	QDF_STATUS status = QDF_STATUS_SUCCESS;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		status = csr_neighbor_roam_update_config(pMac, sessionId,
				nRoamBmissFirstBcnt,
				REASON_ROAM_BMISS_FIRST_BCNT_CHANGED);
		if (QDF_IS_STATUS_SUCCESS(status)) {
			pMac->roam.configParam.neighborRoamConfig.
			nRoamBmissFirstBcnt = nRoamBmissFirstBcnt;
		}
		sme_release_global_lock(&pMac->sme);
	}
	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_get_roam_bmiss_first_bcnt
    \brief  get neighbor roam beacon miss first count
    \param hHal - The handle returned by mac_open.
    \return uint8_t - neighbor roam beacon miss first count
    -------------------------------------------------------------------------*/
uint8_t sme_get_roam_bmiss_first_bcnt(tHalHandle hHal)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	return pMac->roam.configParam.neighborRoamConfig.nRoamBmissFirstBcnt;
}

/* ---------------------------------------------------------------------------
    \fn     sme_set_roam_bmiss_final_bcnt
    \brief  Update Roam count for final beacon miss
	    This function is called through dynamic setConfig callback function
	    to configure nRoamBmissFinalBcnt
    \param  hHal - HAL handle for device
    \param  sessionId - Session Identifier
    \param  nRoamBmissFinalBcnt - Roam final bmiss count
    \return QDF_STATUS_SUCCESS - SME update nRoamBmissFinalBcnt
	    successfully.
	    else SME is failed to update nRoamBmissFinalBcnt
    -------------------------------------------------------------------------*/
QDF_STATUS sme_set_roam_bmiss_final_bcnt(tHalHandle hHal,
					 uint8_t sessionId,
					 const uint8_t nRoamBmissFinalBcnt)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	QDF_STATUS status = QDF_STATUS_SUCCESS;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		status = csr_neighbor_roam_update_config(pMac, sessionId,
				nRoamBmissFinalBcnt,
				REASON_ROAM_BMISS_FINAL_BCNT_CHANGED);
		if (QDF_IS_STATUS_SUCCESS(status)) {
			pMac->roam.configParam.neighborRoamConfig.
			nRoamBmissFinalBcnt = nRoamBmissFinalBcnt;
		}
		sme_release_global_lock(&pMac->sme);
	}
	return status;
}

/*--------------------------------------------------------------------------
   \fn    sme_get_roam_bmiss_final_bcnt
   \brief gets Roam count for final beacon miss
	  This is a synchronous call
   \param hHal - The handle returned by mac_open
   \return uint8_t - nRoamBmissFinalBcnt
   \sa
   --------------------------------------------------------------------------*/
uint8_t sme_get_roam_bmiss_final_bcnt(tHalHandle hHal)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	return pMac->roam.configParam.neighborRoamConfig.nRoamBmissFinalBcnt;
}

/* ---------------------------------------------------------------------------
    \fn     sme_set_roam_beacon_rssi_weight
    \brief  Update Roam beacon rssi weight
	    This function is called through dynamic setConfig callback function
	    to configure nRoamBeaconRssiWeight
    \param  hHal - HAL handle for device
    \param  sessionId - Session Identifier
    \param  nRoamBeaconRssiWeight - Roam beacon rssi weight
    \return QDF_STATUS_SUCCESS - SME update nRoamBeaconRssiWeight config
	    successfully.
	    else SME is failed to update nRoamBeaconRssiWeight
    -------------------------------------------------------------------------*/
QDF_STATUS sme_set_roam_beacon_rssi_weight(tHalHandle hHal,
					   uint8_t sessionId,
					   const uint8_t nRoamBeaconRssiWeight)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	QDF_STATUS status = QDF_STATUS_SUCCESS;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		status = csr_neighbor_roam_update_config(pMac, sessionId,
				nRoamBeaconRssiWeight,
				REASON_ROAM_BEACON_RSSI_WEIGHT_CHANGED);
		if (QDF_IS_STATUS_SUCCESS(status)) {
			pMac->roam.configParam.neighborRoamConfig.
			nRoamBeaconRssiWeight = nRoamBeaconRssiWeight;
		}
		sme_release_global_lock(&pMac->sme);
	}
	return status;
}

/*--------------------------------------------------------------------------
   \fn    sme_get_roam_beacon_rssi_weight
   \brief gets Roam beacon rssi weight
	  This is a synchronous call
   \param hHal - The handle returned by mac_open
   \return uint8_t - nRoamBeaconRssiWeight
   \sa
   --------------------------------------------------------------------------*/
uint8_t sme_get_roam_beacon_rssi_weight(tHalHandle hHal)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	return pMac->roam.configParam.neighborRoamConfig.nRoamBeaconRssiWeight;
}

/*--------------------------------------------------------------------------
   \brief sme_set_neighbor_lookup_rssi_threshold() - update neighbor lookup
	rssi threshold
   This is a synchronous call
   \param hHal - The handle returned by mac_open.
   \param  sessionId - Session Identifier
   \return QDF_STATUS_SUCCESS - SME update config successful.
	   Other status means SME is failed to update
   \sa
   --------------------------------------------------------------------------*/
QDF_STATUS sme_set_neighbor_lookup_rssi_threshold
	(tHalHandle hHal, uint8_t sessionId, uint8_t neighborLookupRssiThreshold) {
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	QDF_STATUS status = QDF_STATUS_SUCCESS;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		status = csr_neighbor_roam_update_config(pMac,
				sessionId, neighborLookupRssiThreshold,
				REASON_LOOKUP_THRESH_CHANGED);
		if (QDF_IS_STATUS_SUCCESS(status)) {
			pMac->roam.configParam.neighborRoamConfig.
			nNeighborLookupRssiThreshold =
				neighborLookupRssiThreshold;
		}
		sme_release_global_lock(&pMac->sme);
	}
	return status;
}

/*--------------------------------------------------------------------------
  \brief sme_set_delay_before_vdev_stop() - update delay before VDEV_STOP
  This is a synchronous call
  \param  hal - The handle returned by macOpen.
  \param  session_id - Session Identifier
  \param  delay_before_vdev_stop - value to be set
  \return QDF_STATUS_SUCCESS - SME update config successful.
	  Other status means SME is failed to update
  \sa
  --------------------------------------------------------------------------*/
QDF_STATUS sme_set_delay_before_vdev_stop(tHalHandle hal,
					  uint8_t session_id,
					  uint8_t delay_before_vdev_stop)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hal);
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		QDF_TRACE(QDF_MODULE_ID_SME,
			QDF_TRACE_LEVEL_DEBUG,
			FL("LFR param delay_before_vdev_stop changed from %d to %d"),
			pMac->roam.configParam.neighborRoamConfig.
			delay_before_vdev_stop,
			delay_before_vdev_stop);
		pMac->roam.neighborRoamInfo[session_id].cfgParams.
			delay_before_vdev_stop = delay_before_vdev_stop;
		pMac->roam.configParam.neighborRoamConfig.
			delay_before_vdev_stop = delay_before_vdev_stop;
		sme_release_global_lock(&pMac->sme);
	}
	return status;
}

/*--------------------------------------------------------------------------
   \brief sme_get_neighbor_lookup_rssi_threshold() - get neighbor lookup
	rssi threshold
   This is a synchronous call
   \param hHal - The handle returned by mac_open.
   \return QDF_STATUS_SUCCESS - SME update config successful.
	   Other status means SME is failed to update
   \sa
   --------------------------------------------------------------------------*/
uint8_t sme_get_neighbor_lookup_rssi_threshold(tHalHandle hHal)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	return pMac->roam.configParam.neighborRoamConfig.
	       nNeighborLookupRssiThreshold;
}

/*--------------------------------------------------------------------------
   \brief sme_set_neighbor_scan_refresh_period() - set neighbor scan results
	refresh period
   This is a synchronous call
   \param hHal - The handle returned by mac_open.
   \param  sessionId - Session Identifier
   \return QDF_STATUS_SUCCESS - SME update config successful.
	   Other status means SME is failed to update
   \sa
   --------------------------------------------------------------------------*/
QDF_STATUS sme_set_neighbor_scan_refresh_period
	(tHalHandle hHal,
	uint8_t sessionId, uint16_t neighborScanResultsRefreshPeriod) {
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tCsrNeighborRoamConfig *pNeighborRoamConfig = NULL;
	tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		pNeighborRoamConfig =
			&pMac->roam.configParam.neighborRoamConfig;
		pNeighborRoamInfo = &pMac->roam.neighborRoamInfo[sessionId];
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
			  "LFR runtime successfully set roam scan refresh period to %d- old value is %d - roam state is %s",
			  neighborScanResultsRefreshPeriod,
			  pMac->roam.configParam.neighborRoamConfig.
			  nNeighborResultsRefreshPeriod,
			  mac_trace_get_neighbour_roam_state(pMac->roam.
							     neighborRoamInfo
							     [sessionId].
							     neighborRoamState));
		pNeighborRoamConfig->nNeighborResultsRefreshPeriod =
			neighborScanResultsRefreshPeriod;
		pNeighborRoamInfo->cfgParams.neighborResultsRefreshPeriod =
			neighborScanResultsRefreshPeriod;

		sme_release_global_lock(&pMac->sme);
	}
	if (pMac->roam.configParam.isRoamOffloadScanEnabled) {
		csr_roam_offload_scan(pMac, sessionId,
				      ROAM_SCAN_OFFLOAD_UPDATE_CFG,
				      REASON_NEIGHBOR_SCAN_REFRESH_PERIOD_CHANGED);
	}
	return status;
}

/*--------------------------------------------------------------------------
   \brief sme_update_roam_scan_offload_enabled() - enable/disable roam scan
	offload feaure
   It is used at in the REG_DYNAMIC_VARIABLE macro definition of
   gRoamScanOffloadEnabled.
   This is a synchronous call
   \param hHal - The handle returned by mac_open.
   \return QDF_STATUS_SUCCESS - SME update config successfully.
	   Other status means SME is failed to update.
   \sa
   --------------------------------------------------------------------------*/

QDF_STATUS sme_update_roam_scan_offload_enabled(tHalHandle hHal,
						bool nRoamScanOffloadEnabled)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	QDF_STATUS status = QDF_STATUS_SUCCESS;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
			  FL
				  ("gRoamScanOffloadEnabled is changed from %d to %d"),
			  pMac->roam.configParam.isRoamOffloadScanEnabled,
			  nRoamScanOffloadEnabled);
		pMac->roam.configParam.isRoamOffloadScanEnabled =
			nRoamScanOffloadEnabled;
		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

/*--------------------------------------------------------------------------
   \brief sme_get_neighbor_scan_refresh_period() - get neighbor scan results
	refresh period
   This is a synchronous call
   \param hHal - The handle returned by mac_open.
   \return uint16_t - Neighbor scan results refresh period value
   \sa
   --------------------------------------------------------------------------*/
uint16_t sme_get_neighbor_scan_refresh_period(tHalHandle hHal)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	return pMac->roam.configParam.neighborRoamConfig.
	       nNeighborResultsRefreshPeriod;
}

/*--------------------------------------------------------------------------
   \brief sme_get_empty_scan_refresh_period() - get empty scan refresh period
   This is a synchronuous call
   \param hHal - The handle returned by mac_open.
   \return QDF_STATUS_SUCCESS - SME update config successful.
	   Other status means SME is failed to update
   \sa
   --------------------------------------------------------------------------*/
uint16_t sme_get_empty_scan_refresh_period(tHalHandle hHal)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	return pMac->roam.configParam.neighborRoamConfig.
	       nEmptyScanRefreshPeriod;
}

/* ---------------------------------------------------------------------------
    \fn sme_update_empty_scan_refresh_period
    \brief  Update nEmptyScanRefreshPeriod
	    This function is called through dynamic setConfig callback function
	    to configure nEmptyScanRefreshPeriod
	    Usage: adb shell iwpriv wlan0 setConfig
			nEmptyScanRefreshPeriod=[0 .. 60]
    \param  hHal - HAL handle for device
    \param  sessionId - Session Identifier
    \param  nEmptyScanRefreshPeriod - scan period following empty scan results.
   \- return Success or failure
    -------------------------------------------------------------------------*/

QDF_STATUS sme_update_empty_scan_refresh_period(tHalHandle hHal, uint8_t sessionId,
						uint16_t nEmptyScanRefreshPeriod)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tCsrNeighborRoamConfig *pNeighborRoamConfig = NULL;
	tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		pNeighborRoamConfig =
			&pMac->roam.configParam.neighborRoamConfig;
		pNeighborRoamInfo = &pMac->roam.neighborRoamInfo[sessionId];
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
			  "LFR runtime successfully set roam scan period to %d -old value is %d - roam state is %s",
			  nEmptyScanRefreshPeriod,
			  pMac->roam.configParam.neighborRoamConfig.
			  nEmptyScanRefreshPeriod,
			  mac_trace_get_neighbour_roam_state(pMac->roam.
							     neighborRoamInfo
							     [sessionId].
							     neighborRoamState));
		pNeighborRoamConfig->nEmptyScanRefreshPeriod =
			nEmptyScanRefreshPeriod;
		pNeighborRoamInfo->cfgParams.emptyScanRefreshPeriod =
			nEmptyScanRefreshPeriod;
		sme_release_global_lock(&pMac->sme);
	}
	if (pMac->roam.configParam.isRoamOffloadScanEnabled) {
		csr_roam_offload_scan(pMac, sessionId,
				      ROAM_SCAN_OFFLOAD_UPDATE_CFG,
				      REASON_EMPTY_SCAN_REF_PERIOD_CHANGED);
	}
	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_set_neighbor_scan_min_chan_time
    \brief  Update nNeighborScanMinChanTime
	    This function is called through dynamic setConfig callback function
	    to configure gNeighborScanChannelMinTime
	    Usage: adb shell iwpriv wlan0 setConfig
			gNeighborScanChannelMinTime=[0 .. 60]
    \param  hHal - HAL handle for device
    \param  nNeighborScanMinChanTime - Channel minimum dwell time
    \param  sessionId - Session Identifier
   \- return Success or failure
    -------------------------------------------------------------------------*/
QDF_STATUS sme_set_neighbor_scan_min_chan_time(tHalHandle hHal,
					       const uint16_t
					       nNeighborScanMinChanTime,
					       uint8_t sessionId)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	QDF_STATUS status = QDF_STATUS_SUCCESS;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
			  "LFR runtime successfully set channel min dwell time to %d - old value is %d - roam state is %s",
			  nNeighborScanMinChanTime,
			  pMac->roam.configParam.neighborRoamConfig.
			  nNeighborScanMinChanTime,
			  mac_trace_get_neighbour_roam_state(pMac->roam.
							     neighborRoamInfo
							     [sessionId].
							     neighborRoamState));

		pMac->roam.configParam.neighborRoamConfig.
		nNeighborScanMinChanTime = nNeighborScanMinChanTime;
		pMac->roam.neighborRoamInfo[sessionId].cfgParams.
		minChannelScanTime = nNeighborScanMinChanTime;
		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_set_neighbor_scan_max_chan_time
    \brief  Update nNeighborScanMaxChanTime
	    This function is called through dynamic setConfig callback function
	    to configure gNeighborScanChannelMaxTime
	    Usage: adb shell iwpriv wlan0 setConfig
			gNeighborScanChannelMaxTime=[0 .. 60]
    \param  hHal - HAL handle for device
    \param  sessionId - Session Identifier
    \param  nNeighborScanMinChanTime - Channel maximum dwell time
   \- return Success or failure
    -------------------------------------------------------------------------*/
QDF_STATUS sme_set_neighbor_scan_max_chan_time(tHalHandle hHal, uint8_t sessionId,
					       const uint16_t
					       nNeighborScanMaxChanTime)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tCsrNeighborRoamConfig *pNeighborRoamConfig = NULL;
	tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		pNeighborRoamConfig =
			&pMac->roam.configParam.neighborRoamConfig;
		pNeighborRoamInfo = &pMac->roam.neighborRoamInfo[sessionId];
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
			  "LFR runtime successfully set channel max dwell time to %d - old value is %d - roam state is %s",
			  nNeighborScanMaxChanTime,
			  pMac->roam.configParam.neighborRoamConfig.
			  nNeighborScanMaxChanTime,
			  mac_trace_get_neighbour_roam_state(pMac->roam.
							     neighborRoamInfo
							     [sessionId].
							     neighborRoamState));
		pNeighborRoamConfig->nNeighborScanMaxChanTime =
			nNeighborScanMaxChanTime;
		pNeighborRoamInfo->cfgParams.maxChannelScanTime =
			nNeighborScanMaxChanTime;
		sme_release_global_lock(&pMac->sme);
	}
	if (pMac->roam.configParam.isRoamOffloadScanEnabled) {
		csr_roam_offload_scan(pMac, sessionId,
				      ROAM_SCAN_OFFLOAD_UPDATE_CFG,
				      REASON_SCAN_CH_TIME_CHANGED);
	}

	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_get_neighbor_scan_min_chan_time
    \brief  get neighbor scan min channel time
    \param hHal - The handle returned by mac_open.
    \param  sessionId - Session Identifier
    \return uint16_t - channel min time value
    -------------------------------------------------------------------------*/
uint16_t sme_get_neighbor_scan_min_chan_time(tHalHandle hHal, uint8_t sessionId)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	return pMac->roam.neighborRoamInfo[sessionId].cfgParams.
	       minChannelScanTime;
}

/* ---------------------------------------------------------------------------
    \fn sme_get_neighbor_roam_state
    \brief  get neighbor roam state
    \param hHal - The handle returned by mac_open.
    \param  sessionId - Session Identifier
    \return uint32_t - neighbor roam state
    -------------------------------------------------------------------------*/
uint32_t sme_get_neighbor_roam_state(tHalHandle hHal, uint8_t sessionId)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	return pMac->roam.neighborRoamInfo[sessionId].neighborRoamState;
}

/* ---------------------------------------------------------------------------
    \fn sme_get_current_roam_state
    \brief  get current roam state
    \param hHal - The handle returned by mac_open.
    \param  sessionId - Session Identifier
    \return uint32_t - current roam state
    -------------------------------------------------------------------------*/
uint32_t sme_get_current_roam_state(tHalHandle hHal, uint8_t sessionId)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	return pMac->roam.curState[sessionId];
}

/* ---------------------------------------------------------------------------
    \fn sme_get_current_roam_sub_state
    \brief  get neighbor roam sub state
    \param hHal - The handle returned by mac_open.
    \param  sessionId - Session Identifier
    \return uint32_t - current roam sub state
    -------------------------------------------------------------------------*/
uint32_t sme_get_current_roam_sub_state(tHalHandle hHal, uint8_t sessionId)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	return pMac->roam.curSubState[sessionId];
}

/* ---------------------------------------------------------------------------
    \fn sme_get_lim_sme_state
    \brief  get Lim Sme state
    \param hHal - The handle returned by mac_open.
    \return uint32_t - Lim Sme state
    -------------------------------------------------------------------------*/
uint32_t sme_get_lim_sme_state(tHalHandle hHal)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	return pMac->lim.gLimSmeState;
}

/* ---------------------------------------------------------------------------
    \fn sme_get_lim_mlm_state
    \brief  get Lim Mlm state
    \param hHal - The handle returned by mac_open.
    \return uint32_t - Lim Mlm state
    -------------------------------------------------------------------------*/
uint32_t sme_get_lim_mlm_state(tHalHandle hHal)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	return pMac->lim.gLimMlmState;
}

/* ---------------------------------------------------------------------------
    \fn sme_is_lim_session_valid
    \brief  is Lim session valid
    \param hHal - The handle returned by mac_open.
    \param  sessionId - Session Identifier
    \return bool - true or false
    -------------------------------------------------------------------------*/
bool sme_is_lim_session_valid(tHalHandle hHal, uint8_t sessionId)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	if (sessionId > pMac->lim.maxBssId)
		return false;

	return pMac->lim.gpSession[sessionId].valid;
}

/* ---------------------------------------------------------------------------
    \fn sme_get_lim_sme_session_state
    \brief  get Lim Sme session state
    \param hHal - The handle returned by mac_open.
    \param  sessionId - Session Identifier
    \return uint32_t - Lim Sme session state
    -------------------------------------------------------------------------*/
uint32_t sme_get_lim_sme_session_state(tHalHandle hHal, uint8_t sessionId)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	return pMac->lim.gpSession[sessionId].limSmeState;
}

/* ---------------------------------------------------------------------------
    \fn sme_get_lim_mlm_session_state
    \brief  get Lim Mlm session state
    \param hHal - The handle returned by mac_open.
    \param  sessionId - Session Identifier
    \return uint32_t - Lim Mlm session state
    -------------------------------------------------------------------------*/
uint32_t sme_get_lim_mlm_session_state(tHalHandle hHal, uint8_t sessionId)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	return pMac->lim.gpSession[sessionId].limMlmState;
}

/* ---------------------------------------------------------------------------
    \fn sme_get_neighbor_scan_max_chan_time
    \brief  get neighbor scan max channel time
    \param hHal - The handle returned by mac_open.
    \param  sessionId - Session Identifier
    \return uint16_t - channel max time value
    -------------------------------------------------------------------------*/
uint16_t sme_get_neighbor_scan_max_chan_time(tHalHandle hHal, uint8_t sessionId)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	return pMac->roam.neighborRoamInfo[sessionId].cfgParams.
	       maxChannelScanTime;
}

/* ---------------------------------------------------------------------------
    \fn sme_set_neighbor_scan_period
    \brief  Update nNeighborScanPeriod
	    This function is called through dynamic setConfig callback function
	    to configure nNeighborScanPeriod
	    Usage: adb shell iwpriv wlan0 setConfig
			nNeighborScanPeriod=[0 .. 1000]
    \param  hHal - HAL handle for device
    \param  sessionId - Session Identifier
    \param  nNeighborScanPeriod - neighbor scan period
   \- return Success or failure
    -------------------------------------------------------------------------*/
QDF_STATUS sme_set_neighbor_scan_period(tHalHandle hHal, uint8_t sessionId,
					const uint16_t nNeighborScanPeriod)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tCsrNeighborRoamConfig *pNeighborRoamConfig = NULL;
	tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		pNeighborRoamConfig =
			&pMac->roam.configParam.neighborRoamConfig;
		pNeighborRoamInfo = &pMac->roam.neighborRoamInfo[sessionId];
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
			  "LFR runtime successfully set neighbor scan period to %d"
			  " - old value is %d - roam state is %s",
			  nNeighborScanPeriod,
			  pMac->roam.configParam.neighborRoamConfig.
			  nNeighborScanTimerPeriod,
			  mac_trace_get_neighbour_roam_state(pMac->roam.
							     neighborRoamInfo
							     [sessionId].
							     neighborRoamState));
		pNeighborRoamConfig->nNeighborScanTimerPeriod =
			nNeighborScanPeriod;
		pNeighborRoamInfo->cfgParams.neighborScanPeriod =
			nNeighborScanPeriod;
		sme_release_global_lock(&pMac->sme);
	}
	if (pMac->roam.configParam.isRoamOffloadScanEnabled) {
		csr_roam_offload_scan(pMac, sessionId,
				      ROAM_SCAN_OFFLOAD_UPDATE_CFG,
				      REASON_SCAN_HOME_TIME_CHANGED);
	}

	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_get_neighbor_scan_period
    \brief  get neighbor scan period
    \param hHal - The handle returned by mac_open.
    \param  sessionId - Session Identifier
    \return uint16_t - neighbor scan period
    -------------------------------------------------------------------------*/
uint16_t sme_get_neighbor_scan_period(tHalHandle hHal, uint8_t sessionId)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	return pMac->roam.neighborRoamInfo[sessionId].cfgParams.
	       neighborScanPeriod;
}



/*--------------------------------------------------------------------------
   \brief sme_get_roam_rssi_diff() - get Roam rssi diff
   This is a synchronous call
   \param hHal - The handle returned by mac_open.
   \return uint16_t - Rssi diff value
   \sa
   --------------------------------------------------------------------------*/
uint8_t sme_get_roam_rssi_diff(tHalHandle hHal)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	return pMac->roam.configParam.RoamRssiDiff;
}

/**
 * sme_change_roam_scan_channel_list() - to change scan channel list
 * @hHal: pointer HAL handle returned by mac_open
 * @sessionId: sme session id
 * @pChannelList: Output channel list
 * @numChannels: Output number of channels
 *
 * This routine is called to Change roam scan channel list.
 * This is a synchronous call
 *
 * Return: QDF_STATUS
 */
QDF_STATUS sme_change_roam_scan_channel_list(tHalHandle hHal, uint8_t sessionId,
					     uint8_t *pChannelList,
					     uint8_t numChannels)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
		&pMac->roam.neighborRoamInfo[sessionId];
	uint8_t oldChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN * 2] = { 0 };
	uint8_t newChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN * 2] = { 0 };
	uint8_t i = 0, j = 0;
	tCsrChannelInfo *chan_info;


	status = sme_acquire_global_lock(&pMac->sme);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		if (pMac->roam.configParam.isRoamOffloadScanEnabled)
			csr_roam_offload_scan(pMac, sessionId,
					ROAM_SCAN_OFFLOAD_UPDATE_CFG,
					REASON_CHANNEL_LIST_CHANGED);
		return status;
	}
	chan_info = &pNeighborRoamInfo->cfgParams.channelInfo;

	if (NULL != chan_info->ChannelList) {
		for (i = 0; i < chan_info->numOfChannels; i++) {
			if (j < sizeof(oldChannelList))
				j += snprintf(oldChannelList + j,
					sizeof(oldChannelList) -
					j, "%d",
					chan_info->ChannelList[i]);
			else
				break;
		}
	}
	csr_flush_cfg_bg_scan_roam_channel_list(pMac, sessionId);
	csr_create_bg_scan_roam_channel_list(pMac, sessionId, pChannelList,
			numChannels);
	sme_set_roam_scan_control(hHal, sessionId, 1);
	if (NULL != chan_info->ChannelList) {
		j = 0;
		for (i = 0; i < chan_info->numOfChannels; i++) {
			if (j < sizeof(newChannelList))
				j += snprintf(newChannelList + j,
					sizeof(newChannelList) -
					j, " %d",
					chan_info->ChannelList[i]);
			else
				break;
		}
	}
	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
			FL("LFR runtime successfully set roam scan channels to %s - old value is %s - roam state is %d"),
			newChannelList, oldChannelList,
			pMac->roam.neighborRoamInfo[sessionId].neighborRoamState);
	sme_release_global_lock(&pMac->sme);

	if (pMac->roam.configParam.isRoamOffloadScanEnabled)
		csr_roam_offload_scan(pMac, sessionId,
				ROAM_SCAN_OFFLOAD_UPDATE_CFG,
				REASON_CHANNEL_LIST_CHANGED);
	return status;
}

/**
 * sme_get_roam_scan_channel_list() - To get roam scan channel list
 * @hHal: HAL pointer
 * @pChannelList: Output channel list
 * @pNumChannels: Output number of channels
 * @sessionId: Session Identifier
 *
 * To get roam scan channel list This is a synchronous call
 *
 * Return: QDF_STATUS
 */
QDF_STATUS sme_get_roam_scan_channel_list(tHalHandle hHal,
			uint8_t *pChannelList, uint8_t *pNumChannels,
			uint8_t sessionId)
{
	int i = 0;
	uint8_t *pOutPtr = pChannelList;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
		&pMac->roam.neighborRoamInfo[sessionId];
	QDF_STATUS status = QDF_STATUS_SUCCESS;

	status = sme_acquire_global_lock(&pMac->sme);
	if (!QDF_IS_STATUS_SUCCESS(status))
		return status;
	if (NULL == pNeighborRoamInfo->cfgParams.channelInfo.ChannelList) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_WARN,
			FL("Roam Scan channel list is NOT yet initialized"));
		*pNumChannels = 0;
		sme_release_global_lock(&pMac->sme);
		return status;
	}

	*pNumChannels = pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels;
	for (i = 0; i < (*pNumChannels); i++) {
		pOutPtr[i] =
			pNeighborRoamInfo->cfgParams.channelInfo.ChannelList[i];
	}
	pOutPtr[i] = '\0';
	sme_release_global_lock(&pMac->sme);
	return status;
}

/*--------------------------------------------------------------------------
   \brief sme_get_is_ese_feature_enabled() - get ESE feature enabled or not
   This is a synchronuous call
   \param hHal - The handle returned by mac_open.
   \return true (1) - if the ESE feature is enabled
	   false (0) - if feature is disabled (compile or runtime)
   \sa
   --------------------------------------------------------------------------*/
bool sme_get_is_ese_feature_enabled(tHalHandle hHal)
{
#ifdef FEATURE_WLAN_ESE
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	return csr_roam_is_ese_ini_feature_enabled(pMac);
#else
	return false;
#endif
}

/*--------------------------------------------------------------------------
   \brief sme_get_wes_mode() - get WES Mode
   This is a synchronous call
   \param hHal - The handle returned by mac_open
   \return uint8_t - WES Mode Enabled(1)/Disabled(0)
   \sa
   --------------------------------------------------------------------------*/
bool sme_get_wes_mode(tHalHandle hHal)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	return pMac->roam.configParam.isWESModeEnabled;
}

/*--------------------------------------------------------------------------
   \brief sme_get_roam_scan_control() - get scan control
   This is a synchronous call
   \param hHal - The handle returned by mac_open.
   \return bool - Enabled(1)/Disabled(0)
   \sa
   --------------------------------------------------------------------------*/
bool sme_get_roam_scan_control(tHalHandle hHal)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	return pMac->roam.configParam.nRoamScanControl;
}

/*--------------------------------------------------------------------------
   \brief sme_get_is_lfr_feature_enabled() - get LFR feature enabled or not
   This is a synchronuous call
   \param hHal - The handle returned by mac_open.
   \return true (1) - if the feature is enabled
	   false (0) - if feature is disabled (compile or runtime)
   \sa
   --------------------------------------------------------------------------*/
bool sme_get_is_lfr_feature_enabled(tHalHandle hHal)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	return pMac->roam.configParam.isFastRoamIniFeatureEnabled;
}

/*--------------------------------------------------------------------------
   \brief sme_get_is_ft_feature_enabled() - get FT feature enabled or not
   This is a synchronuous call
   \param hHal - The handle returned by mac_open.
   \return true (1) - if the feature is enabled
	   false (0) - if feature is disabled (compile or runtime)
   \sa
   --------------------------------------------------------------------------*/
bool sme_get_is_ft_feature_enabled(tHalHandle hHal)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	return pMac->roam.configParam.isFastTransitionEnabled;
}

/* ---------------------------------------------------------------------------
    \fn sme_is_feature_supported_by_fw
    \brief  Check if an feature is enabled by FW

    \param  feattEnumValue - Enumeration value from placeHolderInCapBitmap
   \- return 1/0 (true/false)
    -------------------------------------------------------------------------*/
uint8_t sme_is_feature_supported_by_fw(uint8_t featEnumValue)
{
	return IS_FEATURE_SUPPORTED_BY_FW(featEnumValue);
}

#ifdef FEATURE_WLAN_TDLS

/* ---------------------------------------------------------------------------
    \fn sme_send_tdls_link_establish_params
    \brief  API to send TDLS Peer Link Establishment Parameters.

    \param  peerMac - peer's Mac Adress.
    \param  tdlsLinkEstablishParams - TDLS Peer Link Establishment Parameters
   \- return QDF_STATUS_SUCCES
    -------------------------------------------------------------------------*/
QDF_STATUS sme_send_tdls_link_establish_params(tHalHandle hHal,
					       uint8_t sessionId,
					       const tSirMacAddr peerMac,
					       tCsrTdlsLinkEstablishParams *
					       tdlsLinkEstablishParams)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_TDLS_LINK_ESTABLISH_PARAM,
			 sessionId,
			 tdlsLinkEstablishParams->isOffChannelSupported));
	status = sme_acquire_global_lock(&pMac->sme);

	if (QDF_IS_STATUS_SUCCESS(status)) {
	    status = csr_tdls_send_link_establish_params(hHal, sessionId,
				peerMac, tdlsLinkEstablishParams);
		sme_release_global_lock(&pMac->sme);
	}
	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_send_tdls_mgmt_frame
    \brief  API to send TDLS management frames.

    \param  peerMac - peer's Mac Adress.
    \param frame_type - Type of TDLS mgmt frame to be sent.
    \param dialog - dialog token used in the frame.
    \param status - status to be incuded in the frame.
    \param peerCapability - peer cpabilities
    \param buf - additional IEs to be included
    \param len - lenght of additional Ies
    \param responder - Tdls request type
   \- return QDF_STATUS_SUCCES
    -------------------------------------------------------------------------*/
QDF_STATUS sme_send_tdls_mgmt_frame(tHalHandle hHal, uint8_t sessionId,
				    const tSirMacAddr peerMac,
				    uint8_t frame_type,
				    uint8_t dialog, uint16_t statusCode,
				    uint32_t peerCapability, uint8_t *buf,
				    uint8_t len, uint8_t responder)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tCsrTdlsSendMgmt sendTdlsReq = { {0} };
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_TDLS_SEND_MGMT_FRAME,
			 sessionId, statusCode));
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		qdf_mem_copy(sendTdlsReq.peerMac, peerMac, sizeof(tSirMacAddr));
		sendTdlsReq.frameType = frame_type;
		sendTdlsReq.buf = buf;
		sendTdlsReq.len = len;
		sendTdlsReq.dialog = dialog;
		sendTdlsReq.statusCode = statusCode;
		sendTdlsReq.responder = responder;
		sendTdlsReq.peerCapability = peerCapability;

		status = csr_tdls_send_mgmt_req(hHal, sessionId, &sendTdlsReq);

		sme_release_global_lock(&pMac->sme);
	}

	return status;

}

/* ---------------------------------------------------------------------------
    \fn sme_change_tdls_peer_sta
    \brief  API to Update TDLS peer sta parameters.

    \param  peerMac - peer's Mac Adress.
    \param  staParams - Peer Station Parameters
   \- return QDF_STATUS_SUCCES
    -------------------------------------------------------------------------*/
QDF_STATUS sme_change_tdls_peer_sta(tHalHandle hHal, uint8_t sessionId,
				    const tSirMacAddr peerMac,
				    tCsrStaParams *pstaParams)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	if (NULL == pstaParams) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "%s :pstaParams is NULL", __func__);
		return QDF_STATUS_E_FAILURE;
	}
	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_TDLS_CHANGE_PEER_STA,
			 sessionId, pstaParams->capability));
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		status = csr_tdls_change_peer_sta(hHal, sessionId, peerMac,
						  pstaParams);

		sme_release_global_lock(&pMac->sme);
	}

	return status;

}

/* ---------------------------------------------------------------------------
    \fn sme_add_tdls_peer_sta
    \brief  API to Add TDLS peer sta entry.

    \param  peerMac - peer's Mac Adress.
   \- return QDF_STATUS_SUCCES
    -------------------------------------------------------------------------*/
QDF_STATUS sme_add_tdls_peer_sta(tHalHandle hHal, uint8_t sessionId,
				 const tSirMacAddr peerMac)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_TDLS_ADD_PEER_STA,
			 sessionId, 0));
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		status = csr_tdls_add_peer_sta(hHal, sessionId, peerMac);

		sme_release_global_lock(&pMac->sme);
	}

	return status;

}

/* ---------------------------------------------------------------------------
    \fn sme_delete_tdls_peer_sta
    \brief  API to Delete TDLS peer sta entry.

    \param  peerMac - peer's Mac Adress.
   \- return QDF_STATUS_SUCCES
    -------------------------------------------------------------------------*/
QDF_STATUS sme_delete_tdls_peer_sta(tHalHandle hHal, uint8_t sessionId,
				    const tSirMacAddr peerMac)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_TDLS_DEL_PEER_STA,
			 sessionId, 0));
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		status = csr_tdls_del_peer_sta(hHal, sessionId, peerMac);

		sme_release_global_lock(&pMac->sme);
	}

	return status;

}

/* ---------------------------------------------------------------------------
    \fn sme_set_tdls_power_save_prohibited
    \API to set/reset the is_tdls_power_save_prohibited.

   \- return void
   -------------------------------------------------------------------------*/
void sme_set_tdls_power_save_prohibited(tHalHandle hHal, uint32_t sessionId,
		bool val)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	struct ps_global_info *ps_global_info = &pMac->sme.ps_global_info;
	struct ps_params *ps_param = &ps_global_info->ps_params[sessionId];
	ps_param->is_tdls_power_save_prohibited = val;
	return;
}

/* ---------------------------------------------------------------------------
   \fn    sme_update_fw_tdls_state

   \brief
    SME will send message to WMA to set TDLS state in f/w

   \param

    hHal - The handle returned by mac_open

    psmeTdlsParams - TDLS state info to update in f/w

    useSmeLock - Need to acquire SME Global Lock before state update or not

   \return QDF_STATUS
   --------------------------------------------------------------------------- */
QDF_STATUS sme_update_fw_tdls_state(tHalHandle hHal, void *psmeTdlsParams,
				    bool useSmeLock)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = NULL;
	cds_msg_t cds_message;

	pMac = PMAC_STRUCT(hHal);
	if (NULL == pMac) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			FL("pMac is Null"));
		return QDF_STATUS_E_FAILURE;
	}

	/* only acquire sme global lock before state update if asked to */
	if (useSmeLock) {
		status = sme_acquire_global_lock(&pMac->sme);
		if (QDF_STATUS_SUCCESS != status)
			return status;
	}

	/* serialize the req through MC thread */
	cds_message.bodyptr = psmeTdlsParams;
	cds_message.type = WMA_UPDATE_FW_TDLS_STATE;
	qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
		status = QDF_STATUS_E_FAILURE;

	/* release the lock if it was acquired */
	if (useSmeLock)
		sme_release_global_lock(&pMac->sme);

	return status;
}

/**
 * sme_update_tdls_peer_state() - to update the state of TDLS peer
 * @hHal: The handle returned by mac_open
 * @peerStateParams: TDLS Peer state info to update in f/w
 *
 * SME will send message to WMA to set TDLS Peer state in f/w
 *
 * Return: QDF_STATUS
 */
QDF_STATUS sme_update_tdls_peer_state(tHalHandle hHal,
				      tSmeTdlsPeerStateParams *peerStateParams)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	tTdlsPeerStateParams *pTdlsPeerStateParams = NULL;
	tTdlsPeerCapParams *peer_cap = NULL;
	cds_msg_t cds_message;
	uint8_t num;
	uint8_t peer_chan_len;
	uint8_t chanId;
	uint8_t i;

	status = sme_acquire_global_lock(&pMac->sme);
	if (!QDF_IS_STATUS_SUCCESS(status))
		return status;
	pTdlsPeerStateParams = qdf_mem_malloc(sizeof(*pTdlsPeerStateParams));
	if (NULL == pTdlsPeerStateParams) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			FL("failed to allocate mem for tdls peer state param"));
		sme_release_global_lock(&pMac->sme);
		return QDF_STATUS_E_NOMEM;
	}

	qdf_mem_zero(pTdlsPeerStateParams, sizeof(*pTdlsPeerStateParams));
	qdf_mem_copy(&pTdlsPeerStateParams->peerMacAddr,
			&peerStateParams->peerMacAddr, sizeof(tSirMacAddr));
	pTdlsPeerStateParams->vdevId = peerStateParams->vdevId;
	pTdlsPeerStateParams->peerState = peerStateParams->peerState;

	switch (peerStateParams->peerState) {
	case eSME_TDLS_PEER_STATE_PEERING:
		pTdlsPeerStateParams->peerState =
			WMA_TDLS_PEER_STATE_PEERING;
		break;

	case eSME_TDLS_PEER_STATE_CONNECTED:
		pTdlsPeerStateParams->peerState =
			WMA_TDLS_PEER_STATE_CONNECTED;
		break;

	case eSME_TDLS_PEER_STATE_TEARDOWN:
		pTdlsPeerStateParams->peerState =
			WMA_TDLS_PEER_STATE_TEARDOWN;
		break;

	case eSME_TDLS_PEER_ADD_MAC_ADDR:
		pTdlsPeerStateParams->peerState = WMA_TDLS_PEER_ADD_MAC_ADDR;
		break;

	case eSME_TDLS_PEER_REMOVE_MAC_ADDR:
		pTdlsPeerStateParams->peerState = WMA_TDLS_PEER_REMOVE_MAC_ADDR;
		break;

	default:
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			FL("invalid peer state param (%d)"),
			peerStateParams->peerState);
		goto error_return;
	}
	peer_cap = &(pTdlsPeerStateParams->peerCap);
	peer_cap->isPeerResponder =
		peerStateParams->peerCap.isPeerResponder;
	peer_cap->peerUapsdQueue =
		peerStateParams->peerCap.peerUapsdQueue;
	peer_cap->peerMaxSp =
		peerStateParams->peerCap.peerMaxSp;
	peer_cap->peerBuffStaSupport =
		peerStateParams->peerCap.peerBuffStaSupport;
	peer_cap->peerOffChanSupport =
		peerStateParams->peerCap.peerOffChanSupport;
	peer_cap->peerCurrOperClass =
		peerStateParams->peerCap.peerCurrOperClass;
	peer_cap->selfCurrOperClass =
		peerStateParams->peerCap.selfCurrOperClass;

	num = 0;
	peer_chan_len = peerStateParams->peerCap.peerChanLen;

	if (peer_chan_len >= 0 &&
	    peer_chan_len <= SME_TDLS_MAX_SUPP_CHANNELS) {
		for (i = 0; i < peerStateParams->peerCap.peerChanLen; i++) {
			chanId = peerStateParams->peerCap.peerChan[i];
			if (csr_roam_is_channel_valid(pMac, chanId) &&
			    !(cds_get_channel_state(chanId) ==
			      CHANNEL_STATE_DFS) &&
			    !cds_is_dsrc_channel(cds_chan_to_freq(chanId))) {
				peer_cap->peerChan[num].chanId = chanId;
				peer_cap->peerChan[num].pwr =
					csr_get_cfg_max_tx_power(pMac, chanId);
				peer_cap->peerChan[num].dfsSet = false;
			num++;
			}
		}
	} else {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			FL("invalid peer channel len (%d)"),
			peer_chan_len);
		goto error_return;
	}

	peer_cap->peerChanLen = num;
	peer_cap->peerOperClassLen =
		peerStateParams->peerCap.peerOperClassLen;
	for (i = 0; i < HAL_TDLS_MAX_SUPP_OPER_CLASSES; i++) {
		peer_cap->peerOperClass[i] =
			peerStateParams->peerCap.peerOperClass[i];
	}

	peer_cap->prefOffChanNum =
		peerStateParams->peerCap.prefOffChanNum;
	peer_cap->prefOffChanBandwidth =
		peerStateParams->peerCap.prefOffChanBandwidth;
	peer_cap->opClassForPrefOffChan =
		peerStateParams->peerCap.opClassForPrefOffChan;

	cds_message.type = WMA_UPDATE_TDLS_PEER_STATE;
	cds_message.reserved = 0;
	cds_message.bodyptr = pTdlsPeerStateParams;

	qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			FL("cds_mq_post_message failed "));
		goto error_return;
	} else {
		goto success_return;
	}

error_return:
	status = QDF_STATUS_E_FAILURE;
	qdf_mem_free(pTdlsPeerStateParams);
success_return:
	sme_release_global_lock(&pMac->sme);
	return status;
}

/**
 * sme_send_tdls_chan_switch_req() - send tdls channel switch request
 * @hal: UMAC handler
 * @ch_switch_params: Pointer to the chan switch parameter structure
 *
 * API to set tdls channel switch parameters.
 *
 * Return: QDF_STATUS_SUCCESS on success; another QDF_STATUS_** code otherwise
 */
QDF_STATUS sme_send_tdls_chan_switch_req(tHalHandle hal,
	sme_tdls_chan_switch_params *ch_switch_params)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal mac = PMAC_STRUCT(hal);
	tdls_chan_switch_params *chan_switch_params = NULL;
	cds_msg_t cds_message;

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_TDLS_CHAN_SWITCH_REQ,
			 NO_SESSION, ch_switch_params->tdls_off_channel));
	status = sme_acquire_global_lock(&mac->sme);
	if (QDF_STATUS_SUCCESS != status)
		return status;
	chan_switch_params = qdf_mem_malloc(sizeof(*chan_switch_params));
	if (NULL == chan_switch_params) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			FL("fail to alloc mem for tdls chan switch param"));
		sme_release_global_lock(&mac->sme);
		return QDF_STATUS_E_FAILURE;
	}
	qdf_mem_zero(chan_switch_params, sizeof(*chan_switch_params));

	switch (ch_switch_params->tdls_off_ch_mode) {
	case ENABLE_CHANSWITCH:
		chan_switch_params->tdls_sw_mode = WMA_TDLS_ENABLE_OFFCHANNEL;
		break;

	case DISABLE_CHANSWITCH:
		chan_switch_params->tdls_sw_mode = WMA_TDLS_DISABLE_OFFCHANNEL;
		break;

	default:
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			FL("invalid off channel command (%d)"),
			ch_switch_params->tdls_off_ch_mode);
		qdf_mem_free(chan_switch_params);
		sme_release_global_lock(&mac->sme);
		return QDF_STATUS_E_FAILURE;
	}

	qdf_mem_copy(&chan_switch_params->peer_mac_addr,
		&ch_switch_params->peer_mac_addr, sizeof(tSirMacAddr));
	chan_switch_params->vdev_id = ch_switch_params->vdev_id;
	chan_switch_params->tdls_off_ch = ch_switch_params->tdls_off_channel;
	chan_switch_params->tdls_off_ch_bw_offset =
		ch_switch_params->tdls_off_ch_bw_offset;
	chan_switch_params->is_responder = ch_switch_params->is_responder;
	chan_switch_params->oper_class = ch_switch_params->opclass;

	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
		FL("Country Code=%s, Req offset=%d, Selected Operate Class=%d"),
		mac->scan.countryCodeCurrent,
		chan_switch_params->tdls_off_ch_bw_offset,
		chan_switch_params->oper_class);

	cds_message.type = WMA_TDLS_SET_OFFCHAN_MODE;
	cds_message.reserved = 0;
	cds_message.bodyptr = chan_switch_params;

	qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			FL("Message Post failed status=%d"),
			qdf_status);
		qdf_mem_free(chan_switch_params);
		status = QDF_STATUS_E_FAILURE;
	}
	sme_release_global_lock(&mac->sme);
	return status;
}
#endif /* FEATURE_WLAN_TDLS */

QDF_STATUS sme_get_link_speed(tHalHandle hHal, tSirLinkSpeedInfo *lsReq,
			      void *plsContext,
			      void (*pCallbackfn)(tSirLinkSpeedInfo *indParam,
						  void *pContext))
{

	QDF_STATUS status = QDF_STATUS_SUCCESS;
	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	cds_msg_t cds_message;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_STATUS_SUCCESS == status) {
		if ((NULL == pCallbackfn) &&
		    (NULL == pMac->sme.pLinkSpeedIndCb)) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				  "%s: Indication Call back did not registered",
				  __func__);
			sme_release_global_lock(&pMac->sme);
			return QDF_STATUS_E_FAILURE;
		} else if (NULL != pCallbackfn) {
			pMac->sme.pLinkSpeedCbContext = plsContext;
			pMac->sme.pLinkSpeedIndCb = pCallbackfn;
		}
		/* serialize the req through MC thread */
		cds_message.bodyptr = lsReq;
		cds_message.type = WMA_GET_LINK_SPEED;
		qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				  "%s: Post Link Speed msg fail", __func__);
			status = QDF_STATUS_E_FAILURE;
		}
		sme_release_global_lock(&pMac->sme);
	}
	return status;
}


/*
 * SME API to enable/disable WLAN driver initiated SSR
 */
void sme_update_enable_ssr(tHalHandle hHal, bool enableSSR)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	QDF_STATUS status = QDF_STATUS_SUCCESS;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
			  "SSR level is changed %d", enableSSR);
		/* not serializing this messsage, as this is only going
		 * to set a variable in WMA/WDI
		 */
		WMA_SetEnableSSR(enableSSR);
		sme_release_global_lock(&pMac->sme);
	}
	return;
}

QDF_STATUS sme_check_ch_in_band(tpAniSirGlobal mac_ctx, uint8_t start_ch,
		uint8_t ch_cnt)
{
	uint8_t i;
	for (i = 0; i < ch_cnt; i++) {
		if (QDF_STATUS_SUCCESS != csr_is_valid_channel(mac_ctx,
					(start_ch + i*4)))
			return QDF_STATUS_E_FAILURE;
	}
	return QDF_STATUS_SUCCESS;
}

/*convert the ini value to the ENUM used in csr and MAC for CB state*/
ePhyChanBondState sme_get_cb_phy_state_from_cb_ini_value(uint32_t cb_ini_value)
{
	return csr_convert_cb_ini_value_to_phy_cb_state(cb_ini_value);
}

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

   \brief sme_set_curr_device_mode() - Sets the current operating device mode.
   \param hHal - The handle returned by mac_open.
   \param currDeviceMode - Current operating device mode.
   --------------------------------------------------------------------------*/

void sme_set_curr_device_mode(tHalHandle hHal,
				enum tQDF_ADAPTER_MODE currDeviceMode)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	pMac->sme.currDeviceMode = currDeviceMode;
	return;
}

/*--------------------------------------------------------------------------
   \brief sme_handoff_request() - a wrapper function to Request a handoff
   from CSR.
   This is a synchronous call
   \param hHal - The handle returned by mac_open
   \param  sessionId - Session Identifier
   \param pHandoffInfo - info provided by HDD with the handoff request (namely:
   BSSID, channel etc.)
   \return QDF_STATUS_SUCCESS - SME passed the request to CSR successfully.
	   Other status means SME is failed to send the request.
   \sa
   --------------------------------------------------------------------------*/

QDF_STATUS sme_handoff_request(tHalHandle hHal,
			       uint8_t sessionId,
			       tCsrHandoffRequest *pHandoffInfo)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	QDF_STATUS status = QDF_STATUS_SUCCESS;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
			  "%s: invoked", __func__);
		status = csr_handoff_request(pMac, sessionId, pHandoffInfo);
		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

#ifdef IPA_OFFLOAD
/* ---------------------------------------------------------------------------
   \fn sme_ipa_offload_enable_disable
   \brief  API to enable/disable IPA offload
   \param  hal - The handle returned by macOpen.
   \param  session_id - Session Identifier
   \param  request -  Pointer to the offload request.
   \return QDF_STATUS
   ---------------------------------------------------------------------------*/
QDF_STATUS sme_ipa_offload_enable_disable(tHalHandle hal, uint8_t session_id,
		struct sir_ipa_offload_enable_disable *request)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hal);
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	struct sir_ipa_offload_enable_disable *request_buf;
	cds_msg_t msg;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_STATUS_SUCCESS == status) {
		request_buf = qdf_mem_malloc(sizeof(*request_buf));
		if (NULL == request_buf) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
					FL("Not able to allocate memory for \
					IPA_OFFLOAD_ENABLE_DISABLE"));
			sme_release_global_lock(&pMac->sme);
			return QDF_STATUS_E_NOMEM;
		}

		request_buf->offload_type = request->offload_type;
		request_buf->vdev_id = request->vdev_id;
		request_buf->enable = request->enable;

		msg.type     = WMA_IPA_OFFLOAD_ENABLE_DISABLE;
		msg.reserved = 0;
		msg.bodyptr  = request_buf;
		if (!QDF_IS_STATUS_SUCCESS(
				cds_mq_post_message(CDS_MQ_ID_WMA, &msg))) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
					FL("Not able to post WMA_IPA_OFFLOAD_\
					ENABLE_DISABLE message to WMA"));
			qdf_mem_free(request_buf);
			sme_release_global_lock(&pMac->sme);
			return QDF_STATUS_E_FAILURE;
		}

		sme_release_global_lock(&pMac->sme);
	}

	return QDF_STATUS_SUCCESS;
}
#endif /* IPA_OFFLOAD */

/*
 * SME API to check if there is any infra station or
 * P2P client is connected
 */
QDF_STATUS sme_is_sta_p2p_client_connected(tHalHandle hHal)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	if (csr_is_infra_connected(pMac)) {
		return QDF_STATUS_SUCCESS;
	}
	return QDF_STATUS_E_FAILURE;
}

#ifdef FEATURE_WLAN_LPHB
/* ---------------------------------------------------------------------------
    \fn sme_lphb_config_req
    \API to make configuration LPHB within FW.
    \param hHal - The handle returned by mac_open
    \param lphdReq - LPHB request argument by client
    \param pCallbackfn - LPHB timeout notification callback function pointer
   \- return Configuration message posting status, SUCCESS or Fail
    -------------------------------------------------------------------------*/
QDF_STATUS sme_lphb_config_req
	(tHalHandle hHal,
	tSirLPHBReq *lphdReq,
	void (*pCallbackfn)(void *pHddCtx, tSirLPHBInd * indParam)
	) {
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	cds_msg_t cds_message;

	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
			 TRACE_CODE_SME_RX_HDD_LPHB_CONFIG_REQ,
			 NO_SESSION, lphdReq->cmd));
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_STATUS_SUCCESS == status) {
		if ((LPHB_SET_EN_PARAMS_INDID == lphdReq->cmd) &&
		    (NULL == pCallbackfn) && (NULL == pMac->sme.pLphbIndCb)) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				  "%s: Indication Call back did not registered",
				  __func__);
			sme_release_global_lock(&pMac->sme);
			return QDF_STATUS_E_FAILURE;
		} else if (NULL != pCallbackfn) {
			pMac->sme.pLphbIndCb = pCallbackfn;
		}

		/* serialize the req through MC thread */
		cds_message.bodyptr = lphdReq;
		cds_message.type = WMA_LPHB_CONF_REQ;
		MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
				 NO_SESSION, cds_message.type));
		qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				  "%s: Post Config LPHB MSG fail", __func__);
			status = QDF_STATUS_E_FAILURE;
		}
		sme_release_global_lock(&pMac->sme);
	}

	return status;
}
#endif /* FEATURE_WLAN_LPHB */
/*--------------------------------------------------------------------------
   \brief sme_enable_disable_split_scan() - a wrapper function to set the split
					    scan parameter.
   This is a synchronous call
   \param hHal - The handle returned by mac_open
   \return NONE.
   \sa
   --------------------------------------------------------------------------*/
void sme_enable_disable_split_scan(tHalHandle hHal, uint8_t nNumStaChan,
				   uint8_t nNumP2PChan)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	pMac->roam.configParam.nNumStaChanCombinedConc = nNumStaChan;
	pMac->roam.configParam.nNumP2PChanCombinedConc = nNumP2PChan;

	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
		  "%s: SCAN nNumStaChanCombinedConc : %d,"
		  "nNumP2PChanCombinedConc : %d ",
		  __func__, nNumStaChan, nNumP2PChan);

	return;

}

/**
 * sme_add_periodic_tx_ptrn() - Add Periodic TX Pattern
 * @hal: global hal handle
 * @addPeriodicTxPtrnParams: request message
 *
 * Return: QDF_STATUS enumeration
 */
QDF_STATUS
sme_add_periodic_tx_ptrn(tHalHandle hal,
			 struct sSirAddPeriodicTxPtrn *addPeriodicTxPtrnParams)
{
	QDF_STATUS status   = QDF_STATUS_SUCCESS;
	tpAniSirGlobal mac  = PMAC_STRUCT(hal);
	struct sSirAddPeriodicTxPtrn *req_msg;
	cds_msg_t msg;

	sms_log(mac, LOG1, FL("enter"));

	req_msg = qdf_mem_malloc(sizeof(*req_msg));
	if (!req_msg) {
		sms_log(mac, LOGE, FL("memory allocation failed"));
		return QDF_STATUS_E_NOMEM;
	}

	*req_msg = *addPeriodicTxPtrnParams;

	status = sme_acquire_global_lock(&mac->sme);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		sms_log(mac, LOGE,
			FL("sme_acquire_global_lock failed!(status=%d)"),
			status);
		qdf_mem_free(req_msg);
		return status;
	}

	/* Serialize the req through MC thread */
	msg.bodyptr = req_msg;
	msg.type    = WMA_ADD_PERIODIC_TX_PTRN_IND;
	MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
			 NO_SESSION, msg.type));
	status = cds_mq_post_message(QDF_MODULE_ID_WMA, &msg);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		sms_log(mac, LOGE,
			FL("cds_mq_post_message failed!(err=%d)"),
			status);
		qdf_mem_free(req_msg);
	}
	sme_release_global_lock(&mac->sme);
	return status;
}

/**
 * sme_del_periodic_tx_ptrn() - Delete Periodic TX Pattern
 * @hal: global hal handle
 * @delPeriodicTxPtrnParams: request message
 *
 * Return: QDF_STATUS enumeration
 */
QDF_STATUS
sme_del_periodic_tx_ptrn(tHalHandle hal,
			 struct sSirDelPeriodicTxPtrn *delPeriodicTxPtrnParams)
{
	QDF_STATUS status    = QDF_STATUS_SUCCESS;
	tpAniSirGlobal mac   = PMAC_STRUCT(hal);
	struct sSirDelPeriodicTxPtrn *req_msg;
	cds_msg_t msg;

	sms_log(mac, LOG1, FL("enter"));

	req_msg = qdf_mem_malloc(sizeof(*req_msg));
	if (!req_msg) {
		sms_log(mac, LOGE, FL("memory allocation failed"));
		return QDF_STATUS_E_NOMEM;
	}

	*req_msg = *delPeriodicTxPtrnParams;

	status = sme_acquire_global_lock(&mac->sme);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		sms_log(mac, LOGE,
			FL("sme_acquire_global_lock failed!(status=%d)"),
			status);
		qdf_mem_free(req_msg);
		return status;
	}

	/* Serialize the req through MC thread */
	msg.bodyptr = req_msg;
	msg.type    = WMA_DEL_PERIODIC_TX_PTRN_IND;
	MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
			 NO_SESSION, msg.type));
	status = cds_mq_post_message(QDF_MODULE_ID_WMA, &msg);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		sms_log(mac, LOGE,
			FL("cds_mq_post_message failed!(err=%d)"),
			status);
		qdf_mem_free(req_msg);
	}
	sme_release_global_lock(&mac->sme);
	return status;
}

/**
  * sme_enable_rmc() - enables RMC
  * @hHal : Pointer to global HAL handle
  * @sessionId : Session ID
  *
  * Return: QDF_STATUS
  */
QDF_STATUS sme_enable_rmc(tHalHandle hHal, uint32_t sessionId)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	cds_msg_t cds_message;
	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;

	sms_log(pMac, LOG1, FL("enable RMC"));
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		cds_message.bodyptr = NULL;
		cds_message.type = WMA_RMC_ENABLE_IND;
		qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				  "%s: failed to post message to WMA",
				  __func__);
			status = QDF_STATUS_E_FAILURE;
		}
		sme_release_global_lock(&pMac->sme);
	}
	return status;
}

/**
  * sme_disable_rmc() - disables RMC
  * @hHal : Pointer to global HAL handle
  * @sessionId : Session ID
  *
  * Return: QDF_STATUS
  */
QDF_STATUS sme_disable_rmc(tHalHandle hHal, uint32_t sessionId)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	cds_msg_t cds_message;
	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;

	sms_log(pMac, LOG1, FL("disable RMC"));
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		cds_message.bodyptr = NULL;
		cds_message.type = WMA_RMC_DISABLE_IND;
		qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				  "%s: failed to post message to WMA",
				  __func__);
			status = QDF_STATUS_E_FAILURE;
		}
		sme_release_global_lock(&pMac->sme);
	}
	return status;
}

/**
  * sme_send_rmc_action_period() - sends RMC action period param to target
  * @hHal : Pointer to global HAL handle
  * @sessionId : Session ID
  *
  * Return: QDF_STATUS
  */
QDF_STATUS sme_send_rmc_action_period(tHalHandle hHal, uint32_t sessionId)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	cds_msg_t cds_message;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_STATUS_SUCCESS == status) {
		cds_message.bodyptr = NULL;
		cds_message.type = WMA_RMC_ACTION_PERIOD_IND;
		qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				  "%s: failed to post message to WMA",
				  __func__);
			status = QDF_STATUS_E_FAILURE;
		}
		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

/**
  * sme_request_ibss_peer_info() -  request ibss peer info
  * @hHal : Pointer to global HAL handle
  * @pUserData : Pointer to user data
  * @peerInfoCbk : Peer info callback
  * @allPeerInfoReqd : All peer info required or not
  * @staIdx : sta index
  *
  * Return:  QDF_STATUS
  */
QDF_STATUS sme_request_ibss_peer_info(tHalHandle hHal, void *pUserData,
				      pIbssPeerInfoCb peerInfoCbk,
				      bool allPeerInfoReqd, uint8_t staIdx)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	cds_msg_t cds_message;
	tSirIbssGetPeerInfoReqParams *pIbssInfoReqParams;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_STATUS_SUCCESS == status) {
		pMac->sme.peerInfoParams.peerInfoCbk = peerInfoCbk;
		pMac->sme.peerInfoParams.pUserData = pUserData;

		pIbssInfoReqParams = (tSirIbssGetPeerInfoReqParams *)
				     qdf_mem_malloc(sizeof(tSirIbssGetPeerInfoReqParams));
		if (NULL == pIbssInfoReqParams) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				  "%s: Not able to allocate memory for dhcp start",
				  __func__);
			sme_release_global_lock(&pMac->sme);
			return QDF_STATUS_E_NOMEM;
		}
		pIbssInfoReqParams->allPeerInfoReqd = allPeerInfoReqd;
		pIbssInfoReqParams->staIdx = staIdx;

		cds_message.type = WMA_GET_IBSS_PEER_INFO_REQ;
		cds_message.bodyptr = pIbssInfoReqParams;
		cds_message.reserved = 0;

		qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
		if (QDF_STATUS_SUCCESS != qdf_status) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				  "%s: Post WMA_GET_IBSS_PEER_INFO_REQ MSG failed",
				  __func__);
			qdf_mem_free(pIbssInfoReqParams);
			qdf_status = QDF_STATUS_E_FAILURE;
		}
		sme_release_global_lock(&pMac->sme);
	}

	return qdf_status;
}

/* ---------------------------------------------------------------------------
    \fn sme_send_cesium_enable_ind
    \brief  Used to send proprietary cesium enable indication to fw
    \param  hHal
    \param  sessionId
   \- return QDF_STATUS
    -------------------------------------------------------------------------*/
QDF_STATUS sme_send_cesium_enable_ind(tHalHandle hHal, uint32_t sessionId)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	cds_msg_t cds_message;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_STATUS_SUCCESS == status) {
		cds_message.bodyptr = NULL;
		cds_message.type = WMA_IBSS_CESIUM_ENABLE_IND;
		qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				  "%s: failed to post message to WMA",
				  __func__);
			status = QDF_STATUS_E_FAILURE;
		}
		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

void sme_get_command_q_status(tHalHandle hHal)
{
	tSmeCmd *pTempCmd = NULL;
	tListElem *pEntry;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	if (NULL == pMac) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "%s: pMac is NULL", __func__);
		return;
	}

	pEntry = csr_ll_peek_head(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK);
	if (pEntry) {
		pTempCmd = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
	}
	sms_log(pMac, LOGE, "Currently smeCmdActiveList has command (0x%X)",
		(pTempCmd) ? pTempCmd->command : eSmeNoCommand);
	if (pTempCmd) {
		if (eSmeCsrCommandMask & pTempCmd->command) {
			/* CSR command is stuck. See what the reason code is for that command */
			dump_csr_command_info(pMac, pTempCmd);
		}
	} /* if(pTempCmd) */

	sms_log(pMac, LOGE, "Currently smeCmdPendingList has %d commands",
		csr_ll_count(&pMac->sme.smeCmdPendingList));

	sms_log(pMac, LOGE, "Currently roamCmdPendingList has %d commands",
		csr_ll_count(&pMac->roam.roamCmdPendingList));

	return;
}

/**
 * sme_set_dot11p_config() - API to set the 802.11p config
 * @hHal:           The handle returned by macOpen
 * @enable_dot11p:  802.11p config param
 */
void sme_set_dot11p_config(tHalHandle hHal, bool enable_dot11p)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	pMac->enable_dot11p = enable_dot11p;
}

/**
 * copy_sir_ocb_config() - Performs deep copy of an OCB configuration
 * @src: the source configuration
 *
 * Return: pointer to the copied OCB configuration
 */
static struct sir_ocb_config *sme_copy_sir_ocb_config(
	struct sir_ocb_config *src)
{
	struct sir_ocb_config *dst;
	uint32_t length;
	void *cursor;

	length = sizeof(*src) +
		src->channel_count * sizeof(*src->channels) +
		src->schedule_size * sizeof(*src->schedule) +
		src->dcc_ndl_chan_list_len +
		src->dcc_ndl_active_state_list_len;

	dst = qdf_mem_malloc(length);
	if (!dst)
		return NULL;

	*dst = *src;

	cursor = dst;
	cursor += sizeof(*dst);
	dst->channels = cursor;
	cursor += src->channel_count * sizeof(*src->channels);
	qdf_mem_copy(dst->channels, src->channels,
		     src->channel_count * sizeof(*src->channels));
	dst->schedule = cursor;
	cursor += src->schedule_size * sizeof(*src->schedule);
	qdf_mem_copy(dst->schedule, src->schedule,
		     src->schedule_size * sizeof(*src->schedule));
	dst->dcc_ndl_chan_list = cursor;
	cursor += src->dcc_ndl_chan_list_len;
	qdf_mem_copy(dst->dcc_ndl_chan_list, src->dcc_ndl_chan_list,
		     src->dcc_ndl_chan_list_len);
	dst->dcc_ndl_active_state_list = cursor;
	cursor += src->dcc_ndl_active_state_list_len;
	qdf_mem_copy(dst->dcc_ndl_active_state_list,
		     src->dcc_ndl_active_state_list,
		     src->dcc_ndl_active_state_list_len);
	return dst;
}

/**
 * sme_ocb_set_config() - Set the OCB configuration
 * @hHal: reference to the HAL
 * @context: the context of the call
 * @callback: the callback to hdd
 * @config: the OCB configuration
 *
 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE on failure
 */
QDF_STATUS sme_ocb_set_config(tHalHandle hHal, void *context,
			      ocb_callback callback,
			      struct sir_ocb_config *config)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	cds_msg_t msg = {0};
	struct sir_ocb_config *msg_body;

	/* Lock the SME structure */
	status = sme_acquire_global_lock(&pMac->sme);
	if (!QDF_IS_STATUS_SUCCESS(status))
		return status;

	/*
	 * Check if there is a pending request and return an error if one
	 * exists
	 */
	if (pMac->sme.ocb_set_config_callback) {
		status = QDF_STATUS_E_BUSY;
		goto end;
	}

	msg_body = sme_copy_sir_ocb_config(config);

	if (!msg_body) {
		status = QDF_STATUS_E_NOMEM;
		goto end;
	}

	msg.type = WMA_OCB_SET_CONFIG_CMD;
	msg.bodyptr = msg_body;

	/* Set the request callback and context */
	pMac->sme.ocb_set_config_callback = callback;
	pMac->sme.ocb_set_config_context = context;

	status = cds_mq_post_message(QDF_MODULE_ID_WMA, &msg);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
		      FL("Error posting message to WDA: %d"), status);
		pMac->sme.ocb_set_config_callback = callback;
		pMac->sme.ocb_set_config_context = context;
		qdf_mem_free(msg_body);
		goto end;
	}

end:
	sme_release_global_lock(&pMac->sme);

	return status;
}

/**
 * sme_ocb_set_utc_time() - Set the OCB UTC time
 * @hHal: reference to the HAL
 * @utc: the UTC time struct
 *
 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE on failure
 */
QDF_STATUS sme_ocb_set_utc_time(tHalHandle hHal, struct sir_ocb_utc *utc)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	cds_msg_t msg = {0};
	struct sir_ocb_utc *sme_utc;

	/* Lock the SME structure */
	status = sme_acquire_global_lock(&pMac->sme);
	if (!QDF_IS_STATUS_SUCCESS(status))
		return status;

	sme_utc = qdf_mem_malloc(sizeof(*sme_utc));
	if (!sme_utc) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  FL("Malloc failed"));
		status = QDF_STATUS_E_NOMEM;
		goto end;
	}
	*sme_utc = *utc;

	msg.type = WMA_OCB_SET_UTC_TIME_CMD;
	msg.reserved = 0;
	msg.bodyptr = sme_utc;
	status = cds_mq_post_message(QDF_MODULE_ID_WMA, &msg);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  FL("Not able to post message to WDA"));
		qdf_mem_free(utc);
		goto end;
	}

end:
	sme_release_global_lock(&pMac->sme);

	return status;
}

/**
 * sme_ocb_start_timing_advert() - Start sending timing advert frames
 * @hHal: reference to the HAL
 * @timing_advert: the timing advertisement struct
 *
 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE on failure
 */
QDF_STATUS sme_ocb_start_timing_advert(tHalHandle hHal,
	struct sir_ocb_timing_advert *timing_advert)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	cds_msg_t msg = {0};
	void *buf;
	struct sir_ocb_timing_advert *sme_timing_advert;

	/* Lock the SME structure */
	status = sme_acquire_global_lock(&pMac->sme);
	if (!QDF_IS_STATUS_SUCCESS(status))
		return status;

	buf = qdf_mem_malloc(sizeof(*sme_timing_advert) +
			     timing_advert->template_length);
	if (!buf) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  FL("Not able to allocate memory for start TA"));
		status = QDF_STATUS_E_NOMEM;
		goto end;
	}

	sme_timing_advert = (struct sir_ocb_timing_advert *)buf;
	*sme_timing_advert = *timing_advert;
	sme_timing_advert->template_value = buf + sizeof(*sme_timing_advert);
	qdf_mem_copy(sme_timing_advert->template_value,
	timing_advert->template_value, timing_advert->template_length);

	msg.type = WMA_OCB_START_TIMING_ADVERT_CMD;
	msg.reserved = 0;
	msg.bodyptr = buf;
	status = cds_mq_post_message(QDF_MODULE_ID_WMA, &msg);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  FL("Not able to post msg to WDA"));
		goto end;
	}

end:
	sme_release_global_lock(&pMac->sme);

	return status;
}

/**
 * sme_ocb_stop_timing_advert() - Stop sending timing advert frames on a channel
 * @hHal: reference to the HAL
 * @timing_advert: the timing advertisement struct
 *
 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE on failure
 */
QDF_STATUS sme_ocb_stop_timing_advert(tHalHandle hHal,
	struct sir_ocb_timing_advert *timing_advert)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	cds_msg_t msg = {0};
	struct sir_ocb_timing_advert *sme_timing_advert;

	/* Lock the SME structure */
	status = sme_acquire_global_lock(&pMac->sme);
	if (!QDF_IS_STATUS_SUCCESS(status))
		return status;

	sme_timing_advert = qdf_mem_malloc(sizeof(*timing_advert));
	if (!sme_timing_advert) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  FL("Not able to allocate memory for stop TA"));
		status = QDF_STATUS_E_NOMEM;
		goto end;
	}
	*sme_timing_advert = *timing_advert;

	msg.type = WMA_OCB_STOP_TIMING_ADVERT_CMD;
	msg.reserved = 0;
	msg.bodyptr = sme_timing_advert;
	status = cds_mq_post_message(QDF_MODULE_ID_WMA, &msg);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  FL("Not able to post msg to WDA"));
		goto end;
	}

end:
	sme_release_global_lock(&pMac->sme);

	return status;
}

/**
 * sme_ocb_gen_timing_advert_frame() - generate TA frame and populate the buffer
 * @hal_handle: reference to the HAL
 * @self_addr: the self MAC address
 * @buf: the buffer that will contain the frame
 * @timestamp_offset: return for the offset of the timestamp field
 * @time_value_offset: return for the time_value field in the TA IE
 *
 * Return: the length of the buffer.
 */
int sme_ocb_gen_timing_advert_frame(tHalHandle hal_handle,
				    tSirMacAddr self_addr, uint8_t **buf,
				    uint32_t *timestamp_offset,
				    uint32_t *time_value_offset)
{
	int template_length;
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_handle);

	template_length = sch_gen_timing_advert_frame(mac_ctx, self_addr, buf,
						  timestamp_offset,
						  time_value_offset);
	return template_length;
}
/**
 * sme_ocb_get_tsf_timer() - Get the TSF timer value
 * @hHal: reference to the HAL
 * @context: the context of the call
 * @callback: the callback to hdd
 * @request: the TSF timer request
 *
 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE on failure
 */
QDF_STATUS sme_ocb_get_tsf_timer(tHalHandle hHal, void *context,
				 ocb_callback callback,
				 struct sir_ocb_get_tsf_timer *request)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	cds_msg_t msg = {0};
	struct sir_ocb_get_tsf_timer *msg_body;

	/* Lock the SME structure */
	status = sme_acquire_global_lock(&pMac->sme);
	if (!QDF_IS_STATUS_SUCCESS(status))
		return status;

	/* Allocate memory for the WMI request, and copy the parameter */
	msg_body = qdf_mem_malloc(sizeof(*msg_body));
	if (!msg_body) {
		status = QDF_STATUS_E_NOMEM;
		goto end;
	}
	*msg_body = *request;

	msg.type = WMA_OCB_GET_TSF_TIMER_CMD;
	msg.bodyptr = msg_body;

	/* Set the request callback and the context */
	pMac->sme.ocb_get_tsf_timer_callback = callback;
	pMac->sme.ocb_get_tsf_timer_context = context;

	/* Post the message to WDA */
	status = cds_mq_post_message(QDF_MODULE_ID_WMA, &msg);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  FL("Error posting message to WDA: %d"), status);
		pMac->sme.ocb_get_tsf_timer_callback = NULL;
		pMac->sme.ocb_get_tsf_timer_context = NULL;
		qdf_mem_free(msg_body);
		goto end;
	}

end:
	sme_release_global_lock(&pMac->sme);

	return status;
}

/**
 * sme_dcc_get_stats() - Get the DCC stats
 * @hHal: reference to the HAL
 * @context: the context of the call
 * @callback: the callback to hdd
 * @request: the get DCC stats request
 *
 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE on failure
 */
QDF_STATUS sme_dcc_get_stats(tHalHandle hHal, void *context,
			     ocb_callback callback,
			     struct sir_dcc_get_stats *request)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	cds_msg_t msg = {0};
	struct sir_dcc_get_stats *msg_body;

	/* Lock the SME structure */
	status = sme_acquire_global_lock(&pMac->sme);
	if (!QDF_IS_STATUS_SUCCESS(status))
		return status;

	/* Allocate memory for the WMI request, and copy the parameter */
	msg_body = qdf_mem_malloc(sizeof(*msg_body) +
				  request->request_array_len);
	if (!msg_body) {
		status = QDF_STATUS_E_NOMEM;
		goto end;
	}
	*msg_body = *request;
	msg_body->request_array = (void *)msg_body + sizeof(*msg_body);
	qdf_mem_copy(msg_body->request_array, request->request_array,
		     request->request_array_len);

	msg.type = WMA_DCC_GET_STATS_CMD;
	msg.bodyptr = msg_body;

	/* Set the request callback and context */
	pMac->sme.dcc_get_stats_callback = callback;
	pMac->sme.dcc_get_stats_context = context;

	status = cds_mq_post_message(QDF_MODULE_ID_WMA, &msg);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  FL("Error posting message to WDA: %d"), status);
		pMac->sme.dcc_get_stats_callback = callback;
		pMac->sme.dcc_get_stats_context = context;
		qdf_mem_free(msg_body);
		goto end;
	}

end:
	sme_release_global_lock(&pMac->sme);

	return status;
}

/**
 * sme_dcc_clear_stats() - Clear the DCC stats
 * @hHal: reference to the HAL
 * @vdev_id: vdev id for OCB interface
 * @dcc_stats_bitmap: the entries in the stats to clear
 *
 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE on failure
 */
QDF_STATUS sme_dcc_clear_stats(tHalHandle hHal, uint32_t vdev_id,
			       uint32_t dcc_stats_bitmap)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	cds_msg_t msg = {0};
	struct sir_dcc_clear_stats *request;

	/* Lock the SME structure */
	status = sme_acquire_global_lock(&pMac->sme);
	if (!QDF_IS_STATUS_SUCCESS(status))
		return status;

	request = qdf_mem_malloc(sizeof(struct sir_dcc_clear_stats));
	if (!request) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  FL("Not able to allocate memory"));
		status = QDF_STATUS_E_NOMEM;
		goto end;
	}

	qdf_mem_zero(request, sizeof(*request));
	request->vdev_id = vdev_id;
	request->dcc_stats_bitmap = dcc_stats_bitmap;

	msg.type = WMA_DCC_CLEAR_STATS_CMD;
	msg.bodyptr = request;

	status = cds_mq_post_message(QDF_MODULE_ID_WMA, &msg);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  FL("Not able to post msg to WDA"));
		qdf_mem_free(request);
		goto end;
	}

end:
	sme_release_global_lock(&pMac->sme);

	return status;
}

/**
 * sme_dcc_update_ndl() - Update the DCC settings
 * @hHal: reference to the HAL
 * @context: the context of the call
 * @callback: the callback to hdd
 * @request: the update DCC request
 *
 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE on failure
 */
QDF_STATUS sme_dcc_update_ndl(tHalHandle hHal, void *context,
			      ocb_callback callback,
			      struct sir_dcc_update_ndl *request)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	cds_msg_t msg = {0};
	struct sir_dcc_update_ndl *msg_body;

	/* Lock the SME structure */
	status = sme_acquire_global_lock(&pMac->sme);
	if (!QDF_IS_STATUS_SUCCESS(status))
		return status;

	/* Allocate memory for the WMI request, and copy the parameter */
	msg_body = qdf_mem_malloc(sizeof(*msg_body) +
				  request->dcc_ndl_chan_list_len +
				  request->dcc_ndl_active_state_list_len);
	if (!msg_body) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  FL("Failed to allocate memory"));
		status = QDF_STATUS_E_NOMEM;
		goto end;
	}

	*msg_body = *request;

	msg_body->dcc_ndl_chan_list = (void *)msg_body + sizeof(*msg_body);
	msg_body->dcc_ndl_active_state_list = msg_body->dcc_ndl_chan_list +
		request->dcc_ndl_chan_list_len;
	qdf_mem_copy(msg_body->dcc_ndl_chan_list, request->dcc_ndl_chan_list,
		     request->dcc_ndl_active_state_list_len);
	qdf_mem_copy(msg_body->dcc_ndl_active_state_list,
		     request->dcc_ndl_active_state_list,
		     request->dcc_ndl_active_state_list_len);

	msg.type = WMA_DCC_UPDATE_NDL_CMD;
	msg.bodyptr = msg_body;

	/* Set the request callback and the context */
	pMac->sme.dcc_update_ndl_callback = callback;
	pMac->sme.dcc_update_ndl_context = context;

	status = cds_mq_post_message(QDF_MODULE_ID_WMA, &msg);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  FL("Error posting message to WDA: %d"), status);
		pMac->sme.dcc_update_ndl_callback = NULL;
		pMac->sme.dcc_update_ndl_context = NULL;
		qdf_mem_free(msg_body);
		goto end;
	}

end:
	sme_release_global_lock(&pMac->sme);

	return status;
}

/**
 * sme_register_for_dcc_stats_event() - Register for the periodic DCC stats
 *                                      event
 * @hHal: reference to the HAL
 * @context: the context of the call
 * @callback: the callback to hdd
 *
 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE on failure
 */
QDF_STATUS sme_register_for_dcc_stats_event(tHalHandle hHal, void *context,
					    ocb_callback callback)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	QDF_STATUS status = QDF_STATUS_E_FAILURE;

	status = sme_acquire_global_lock(&pMac->sme);
	pMac->sme.dcc_stats_event_callback = callback;
	pMac->sme.dcc_stats_event_context = context;
	sme_release_global_lock(&pMac->sme);

	return 0;
}

/**
 * sme_deregister_for_dcc_stats_event() - De-Register for the periodic DCC stats
 *					  event
 * @h_hal: Hal Handle
 *
 * This function de-registers the DCC perioc stats callback
 *
 * Return: QDF_STATUS Enumeration
 */
QDF_STATUS sme_deregister_for_dcc_stats_event(tHalHandle h_hal)
{
	tpAniSirGlobal mac;
	QDF_STATUS status;

	if (!h_hal) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				  FL("h_hal is not valid"));
		return QDF_STATUS_E_INVAL;
	}
	mac = PMAC_STRUCT(h_hal);

	status = sme_acquire_global_lock(&mac->sme);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  FL("Failed to acquire global lock"));
		return status;
	}
	mac->sme.dcc_stats_event_callback = NULL;
	mac->sme.dcc_stats_event_context = NULL;
	sme_release_global_lock(&mac->sme);

	return status;
}

void sme_get_recovery_stats(tHalHandle hHal)
{
	uint8_t i;

	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
		  "Self Recovery Stats");
	for (i = 0; i < MAX_ACTIVE_CMD_STATS; i++) {
		if (eSmeNoCommand !=
		    g_self_recovery_stats.activeCmdStats[i].command) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				  "timestamp %llu: command 0x%0X: reason %d: session %d",
				  g_self_recovery_stats.activeCmdStats[i].
				  timestamp,
				  g_self_recovery_stats.activeCmdStats[i].command,
				  g_self_recovery_stats.activeCmdStats[i].reason,
				  g_self_recovery_stats.activeCmdStats[i].
				  sessionId);
		}
	}
}

/**
 * sme_save_active_cmd_stats() - To save active command stats
 * @hHal: HAL context
 *
 * This routine is to save active command stats
 *
 * Return: None
 */
void sme_save_active_cmd_stats(tHalHandle hHal)
{
	tSmeCmd *pTempCmd = NULL;
	tListElem *pEntry;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	uint8_t statidx = 0;
	tActiveCmdStats *actv_cmd_stat = NULL;

	if (NULL == pMac) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				FL("pMac is NULL"));
		return;
	}

	pEntry = csr_ll_peek_head(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK);
	if (pEntry)
		pTempCmd = GET_BASE_ADDR(pEntry, tSmeCmd, Link);

	if (!pTempCmd)
		return;

	if (eSmeCsrCommandMask & pTempCmd->command) {
		statidx = g_self_recovery_stats.cmdStatsIndx;
		actv_cmd_stat = &g_self_recovery_stats.activeCmdStats[statidx];
		actv_cmd_stat->command = pTempCmd->command;
		actv_cmd_stat->sessionId = pTempCmd->sessionId;
		actv_cmd_stat->timestamp = cds_get_monotonic_boottime();
		if (eSmeCommandRoam == pTempCmd->command)
			actv_cmd_stat->reason = pTempCmd->u.roamCmd.roamReason;
		else if (eSmeCommandScan == pTempCmd->command)
			actv_cmd_stat->reason = pTempCmd->u.scanCmd.reason;
		else
			actv_cmd_stat->reason = 0xFF;

		g_self_recovery_stats.cmdStatsIndx =
			((g_self_recovery_stats.cmdStatsIndx + 1) &
				(MAX_ACTIVE_CMD_STATS - 1));
	}
	return;
}

void active_list_cmd_timeout_handle(void *userData)
{
	tHalHandle hal = (tHalHandle)userData;
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
	tListElem *entry;
	tSmeCmd *temp_cmd = NULL;

	if (NULL == mac_ctx) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			"%s: mac_ctx is null", __func__);
		return;
	}
	/* Return if no cmd pending in active list as
	 * in this case we should not be here.
	 */
	if (0 == csr_ll_count(&mac_ctx->sme.smeCmdActiveList))
		return;
	sms_log(mac_ctx, LOGE,
		FL("Active List command timeout Cmd List Count %d"),
		  csr_ll_count(&mac_ctx->sme.smeCmdActiveList));
	sme_get_command_q_status(hal);

	if (mac_ctx->roam.configParam.enable_fatal_event)
		cds_flush_logs(WLAN_LOG_TYPE_FATAL,
			WLAN_LOG_INDICATOR_HOST_DRIVER,
			WLAN_LOG_REASON_SME_COMMAND_STUCK,
			false,
			mac_ctx->sme.enableSelfRecovery ? true : false);
	else
		qdf_trace_dump_all(mac_ctx, 0, 0, 500, 0);

	entry = csr_ll_peek_head(&mac_ctx->sme.smeCmdActiveList,
				 LL_ACCESS_LOCK);
	if (entry)
		temp_cmd = GET_BASE_ADDR(entry, tSmeCmd, Link);
	/* Ignore if ROC took more than 120 sec */
	if (temp_cmd && (eSmeCommandRemainOnChannel == temp_cmd->command))
		return;

	if (mac_ctx->sme.enableSelfRecovery) {
		sme_save_active_cmd_stats(hal);
		cds_trigger_recovery();
	} else {
		if (!mac_ctx->roam.configParam.enable_fatal_event &&
		   !(cds_is_load_or_unload_in_progress() ||
		    cds_is_driver_recovering()))
			QDF_BUG(0);
	}
}

QDF_STATUS sme_notify_modem_power_state(tHalHandle hHal, uint32_t value)
{
	cds_msg_t msg;
	tpSirModemPowerStateInd request_buf;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	if (NULL == pMac) {
		return QDF_STATUS_E_FAILURE;
	}

	request_buf = qdf_mem_malloc(sizeof(tSirModemPowerStateInd));
	if (NULL == request_buf) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "%s: Not able to allocate memory for MODEM POWER STATE IND",
			  __func__);
		return QDF_STATUS_E_NOMEM;
	}

	request_buf->param = value;

	msg.type = WMA_MODEM_POWER_STATE_IND;
	msg.reserved = 0;
	msg.bodyptr = request_buf;
	if (!QDF_IS_STATUS_SUCCESS
		    (cds_mq_post_message(QDF_MODULE_ID_WMA, &msg))) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "%s: Not able to post WMA_MODEM_POWER_STATE_IND message"
			  " to WMA", __func__);
		qdf_mem_free(request_buf);
		return QDF_STATUS_E_FAILURE;
	}

	return QDF_STATUS_SUCCESS;
}

#ifdef QCA_HT_2040_COEX
QDF_STATUS sme_notify_ht2040_mode(tHalHandle hHal, uint16_t staId,
				  struct qdf_mac_addr macAddrSTA,
				  uint8_t sessionId,
				  uint8_t channel_type)
{
	cds_msg_t msg;
	tUpdateVHTOpMode *pHtOpMode = NULL;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	if (NULL == pMac) {
		return QDF_STATUS_E_FAILURE;
	}

	pHtOpMode = qdf_mem_malloc(sizeof(tUpdateVHTOpMode));
	if (NULL == pHtOpMode) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "%s: Not able to allocate memory for setting OP mode",
			  __func__);
		return QDF_STATUS_E_NOMEM;
	}

	switch (channel_type) {
	case eHT_CHAN_HT20:
		pHtOpMode->opMode = eHT_CHANNEL_WIDTH_20MHZ;
		break;

	case eHT_CHAN_HT40MINUS:
	case eHT_CHAN_HT40PLUS:
		pHtOpMode->opMode = eHT_CHANNEL_WIDTH_40MHZ;
		break;

	default:
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "%s: Invalid OP mode", __func__);
		return QDF_STATUS_E_FAILURE;
	}

	pHtOpMode->staId = staId,
	qdf_mem_copy(pHtOpMode->peer_mac, macAddrSTA.bytes,
		     sizeof(tSirMacAddr));
	pHtOpMode->smesessionId = sessionId;

	msg.type = WMA_UPDATE_OP_MODE;
	msg.reserved = 0;
	msg.bodyptr = pHtOpMode;
	if (!QDF_IS_STATUS_SUCCESS
		    (cds_mq_post_message(QDF_MODULE_ID_WMA, &msg))) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "%s: Not able to post WMA_UPDATE_OP_MODE message"
			  " to WMA", __func__);
		qdf_mem_free(pHtOpMode);
		return QDF_STATUS_E_FAILURE;
	}

	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
		  "%s: Notifed FW about OP mode: %d for staId=%d",
		  __func__, pHtOpMode->opMode, staId);

	return QDF_STATUS_SUCCESS;
}

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

    \fn sme_set_ht2040_mode

    \brief To update HT Operation beacon IE.

    \param

    \return QDF_STATUS  SUCCESS
			FAILURE or RESOURCES
			The API finished and failed.

   -------------------------------------------------------------------------------*/
QDF_STATUS sme_set_ht2040_mode(tHalHandle hHal, uint8_t sessionId,
			       uint8_t channel_type, bool obssEnabled)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	ePhyChanBondState cbMode;

	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
		  "%s: Update HT operation beacon IE, channel_type=%d",
		  __func__, channel_type);

	switch (channel_type) {
	case eHT_CHAN_HT20:
		cbMode = PHY_SINGLE_CHANNEL_CENTERED;
		break;
	case eHT_CHAN_HT40MINUS:
		cbMode = PHY_DOUBLE_CHANNEL_HIGH_PRIMARY;
		break;
	case eHT_CHAN_HT40PLUS:
		cbMode = PHY_DOUBLE_CHANNEL_LOW_PRIMARY;
		break;
	default:
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "%s:Error!!! Invalid HT20/40 mode !", __func__);
		return QDF_STATUS_E_FAILURE;
	}
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		status = csr_set_ht2040_mode(pMac, sessionId,
					     cbMode, obssEnabled);
		sme_release_global_lock(&pMac->sme);
	}
	return status;
}

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

    \fn sme_set_phy_cb_mode24_g

    \brief Changes PHY channel bonding mode

    \param hHal - The handle returned by mac_open.

    \param cbMode new channel bonding mode which is to set

    \return QDF_STATUS  SUCCESS.

   -------------------------------------------------------------------------------*/
QDF_STATUS sme_set_phy_cb_mode24_g(tHalHandle hHal, ePhyChanBondState phyCBMode)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	if (NULL == pMac) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "%s: invalid context", __func__);
		return QDF_STATUS_E_FAILURE;
	}

	pMac->roam.configParam.channelBondingMode24GHz = phyCBMode;

	return QDF_STATUS_SUCCESS;
}
#endif

/*
 * SME API to enable/disable idle mode powersave
 * This should be called only if powersave offload
 * is enabled
 */
QDF_STATUS sme_set_idle_powersave_config(void *cds_context,
				tHalHandle hHal, uint32_t value)
{
	void *wmaContext = cds_get_context(QDF_MODULE_ID_WMA);
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	if (NULL == wmaContext) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "%s: wmaContext is NULL", __func__);
		return QDF_STATUS_E_FAILURE;
	}
	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
		  " Idle Ps Set Value %d", value);

	pMac->imps_enabled = false;
	if (QDF_STATUS_SUCCESS != wma_set_idle_ps_config(wmaContext, value)) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  " Failed to Set Idle Ps Value %d", value);
		return QDF_STATUS_E_FAILURE;
	}
	if (value)
		pMac->imps_enabled = true;
	return QDF_STATUS_SUCCESS;
}

int16_t sme_get_ht_config(tHalHandle hHal, uint8_t session_id, uint16_t ht_capab)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, session_id);

	if (NULL == pSession) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "%s: pSession is NULL", __func__);
		return -EIO;
	}
	switch (ht_capab) {
	case WNI_CFG_HT_CAP_INFO_ADVANCE_CODING:
		return pSession->htConfig.ht_rx_ldpc;
	case WNI_CFG_HT_CAP_INFO_TX_STBC:
		return pSession->htConfig.ht_tx_stbc;
	case WNI_CFG_HT_CAP_INFO_RX_STBC:
		return pSession->htConfig.ht_rx_stbc;
	case WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ:
		return pSession->htConfig.ht_sgi20;
	case WNI_CFG_HT_CAP_INFO_SHORT_GI_40MHZ:
		return pSession->htConfig.ht_sgi40;
	default:
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "invalid ht capability");
		return -EIO;
	}
}

int sme_update_ht_config(tHalHandle hHal, uint8_t sessionId, uint16_t htCapab,
			 int value)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);

	if (NULL == pSession) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "%s: pSession is NULL", __func__);
		return -EIO;
	}

	if (QDF_STATUS_SUCCESS != wma_set_htconfig(sessionId, htCapab, value)) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "Failed to set ht capability in target");
		return -EIO;
	}

	switch (htCapab) {
	case WNI_CFG_HT_CAP_INFO_ADVANCE_CODING:
		pSession->htConfig.ht_rx_ldpc = value;
		break;
	case WNI_CFG_HT_CAP_INFO_TX_STBC:
		pSession->htConfig.ht_tx_stbc = value;
		break;
	case WNI_CFG_HT_CAP_INFO_RX_STBC:
		pSession->htConfig.ht_rx_stbc = value;
		break;
	case WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ:
		pSession->htConfig.ht_sgi20 = value;
		break;
	case WNI_CFG_HT_CAP_INFO_SHORT_GI_40MHZ:
		pSession->htConfig.ht_sgi40 = value;
		break;
	}

	return 0;
}

#define HT20_SHORT_GI_MCS7_RATE 722
/* ---------------------------------------------------------------------------
    \fn sme_send_rate_update_ind
    \brief  API to Update rate
    \param  hHal - The handle returned by mac_open
    \param  rateUpdateParams - Pointer to rate update params
    \return QDF_STATUS
   ---------------------------------------------------------------------------*/
QDF_STATUS sme_send_rate_update_ind(tHalHandle hHal,
				    tSirRateUpdateInd *rateUpdateParams)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	QDF_STATUS status;
	cds_msg_t msg;
	tSirRateUpdateInd *rate_upd = qdf_mem_malloc(sizeof(tSirRateUpdateInd));

	if (rate_upd == NULL) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "Rate update struct alloc failed");
		return QDF_STATUS_E_FAILURE;
	}
	*rate_upd = *rateUpdateParams;

	if (rate_upd->mcastDataRate24GHz == HT20_SHORT_GI_MCS7_RATE)
		rate_upd->mcastDataRate24GHzTxFlag =
			eHAL_TX_RATE_HT20 | eHAL_TX_RATE_SGI;
	else if (rate_upd->reliableMcastDataRate ==
		 HT20_SHORT_GI_MCS7_RATE)
		rate_upd->reliableMcastDataRateTxFlag =
			eHAL_TX_RATE_HT20 | eHAL_TX_RATE_SGI;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_STATUS_SUCCESS == status) {
		msg.type = WMA_RATE_UPDATE_IND;
		msg.bodyptr = rate_upd;
		MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
				 NO_SESSION, msg.type));
		if (!QDF_IS_STATUS_SUCCESS
			    (cds_mq_post_message(QDF_MODULE_ID_WMA, &msg))) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				  "%s: Not able "
				  "to post WMA_SET_RMC_RATE_IND to WMA!",
				  __func__);

			sme_release_global_lock(&pMac->sme);
			qdf_mem_free(rate_upd);
			return QDF_STATUS_E_FAILURE;
		}

		sme_release_global_lock(&pMac->sme);
		return QDF_STATUS_SUCCESS;
	}

	return status;
}

/**
 * sme_update_access_policy_vendor_ie() - update vendor ie and access policy.
 * @hal: Pointer to the mac context
 * @session_id: sme session id
 * @vendor_ie: vendor ie
 * @access_policy: vendor ie access policy
 *
 * This function updates the vendor ie and access policy to lim.
 *
 * Return: success or failure.
 */
QDF_STATUS sme_update_access_policy_vendor_ie(tHalHandle hal,
		uint8_t session_id, uint8_t *vendor_ie, int access_policy)
{
	struct sme_update_access_policy_vendor_ie *msg;
	uint16_t msg_len;
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal mac = PMAC_STRUCT(hal);

	msg_len  = sizeof(*msg);

	msg = qdf_mem_malloc(msg_len);
	if (!msg) {
		sms_log(mac, LOGE,
			"failed to allocate memory for sme_update_access_policy_vendor_ie");
		return QDF_STATUS_E_FAILURE;
	}

	qdf_mem_set(msg, msg_len, 0);
	msg->msg_type = (uint16_t)eWNI_SME_UPDATE_ACCESS_POLICY_VENDOR_IE;
	msg->length = (uint16_t)msg_len;

	qdf_mem_copy(&msg->ie[0], vendor_ie, sizeof(msg->ie));

	msg->sme_session_id = session_id;
	msg->access_policy = access_policy;

	sms_log(mac, LOG1, "sme_session_id %hu, access_policy %d", session_id,
			access_policy);

	status = cds_send_mb_message_to_mac(msg);

	return status;
}

/**
 * sme_get_reg_info() - To get registration info
 * @hHal: HAL context
 * @chanId: channel id
 * @regInfo1: first reg info to fill
 * @regInfo2: second reg info to fill
 *
 * This routine will give you reg info
 *
 * Return: QDF_STATUS
 */
QDF_STATUS sme_get_reg_info(tHalHandle hHal, uint8_t chanId,
			    uint32_t *regInfo1, uint32_t *regInfo2)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	QDF_STATUS status;
	uint8_t i;
	bool found = false;

	status = sme_acquire_global_lock(&pMac->sme);
	*regInfo1 = 0;
	*regInfo2 = 0;
	if (!QDF_IS_STATUS_SUCCESS(status))
		return status;

	for (i = 0; i < WNI_CFG_VALID_CHANNEL_LIST_LEN; i++) {
		if (pMac->scan.defaultPowerTable[i].chan_num == chanId) {
			SME_SET_CHANNEL_REG_POWER(*regInfo1,
				pMac->scan.defaultPowerTable[i].power);

			SME_SET_CHANNEL_MAX_TX_POWER(*regInfo2,
				pMac->scan.defaultPowerTable[i].power);
			found = true;
			break;
		}
	}
	if (!found)
		status = QDF_STATUS_E_FAILURE;

	sme_release_global_lock(&pMac->sme);
	return status;
}

#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
/* ---------------------------------------------------------------------------
    \fn sme_auto_shutdown_cb
    \brief  Used to plug in callback function for receiving auto shutdown evt
    \param  hHal
    \param  pCallbackfn : callback function pointer should be plugged in
   \- return QDF_STATUS
   -------------------------------------------------------------------------*/
QDF_STATUS sme_set_auto_shutdown_cb(tHalHandle hHal, void (*pCallbackfn)(void)
				    ) {
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
		  "%s: Plug in Auto shutdown event callback", __func__);

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_STATUS_SUCCESS == status) {
		if (NULL != pCallbackfn) {
			pMac->sme.pAutoShutdownNotificationCb = pCallbackfn;
		}
		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_set_auto_shutdown_timer
    \API to set auto shutdown timer value in FW.
    \param hHal - The handle returned by mac_open
    \param timer_val - The auto shutdown timer value to be set
   \- return Configuration message posting status, SUCCESS or Fail
    -------------------------------------------------------------------------*/
QDF_STATUS sme_set_auto_shutdown_timer(tHalHandle hHal, uint32_t timer_val)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	tSirAutoShutdownCmdParams *auto_sh_cmd;
	cds_msg_t cds_message;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_STATUS_SUCCESS == status) {
		auto_sh_cmd = (tSirAutoShutdownCmdParams *)
			      qdf_mem_malloc(sizeof(tSirAutoShutdownCmdParams));
		if (auto_sh_cmd == NULL) {
			QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
				  "%s Request Buffer Alloc Fail", __func__);
			sme_release_global_lock(&pMac->sme);
			return QDF_STATUS_E_NOMEM;
		}

		auto_sh_cmd->timer_val = timer_val;

		/* serialize the req through MC thread */
		cds_message.bodyptr = auto_sh_cmd;
		cds_message.type = WMA_SET_AUTO_SHUTDOWN_TIMER_REQ;
		qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				  "%s: Post Auto shutdown MSG fail", __func__);
			qdf_mem_free(auto_sh_cmd);
			sme_release_global_lock(&pMac->sme);
			return QDF_STATUS_E_FAILURE;
		}
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
			  "%s: Posted Auto shutdown MSG", __func__);
		sme_release_global_lock(&pMac->sme);
	}

	return status;
}
#endif

#ifdef FEATURE_WLAN_CH_AVOID
/* ---------------------------------------------------------------------------
    \fn sme_add_ch_avoid_callback
    \brief  Used to plug in callback function
	    Which notify channel may not be used with SAP or P2PGO mode.
	    Notification come from FW.
    \param  hHal
    \param  pCallbackfn : callback function pointer should be plugged in
   \- return QDF_STATUS
    -------------------------------------------------------------------------*/
QDF_STATUS sme_add_ch_avoid_callback
	(tHalHandle hHal, void (*pCallbackfn)(void *pAdapter, void *indParam)
	) {
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
		  "%s: Plug in CH AVOID CB", __func__);

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_STATUS_SUCCESS == status) {
		if (NULL != pCallbackfn) {
			pMac->sme.pChAvoidNotificationCb = pCallbackfn;
		}
		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_ch_avoid_update_req
    \API to request channel avoidance update from FW.
    \param hHal - The handle returned by mac_open
    \param update_type - The udpate_type parameter of this request call
   \- return Configuration message posting status, SUCCESS or Fail
    -------------------------------------------------------------------------*/
QDF_STATUS sme_ch_avoid_update_req(tHalHandle hHal)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	tSirChAvoidUpdateReq *cauReq;
	cds_msg_t cds_message;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_STATUS_SUCCESS == status) {
		cauReq = (tSirChAvoidUpdateReq *)
			 qdf_mem_malloc(sizeof(tSirChAvoidUpdateReq));
		if (NULL == cauReq) {
			QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
				  "%s Request Buffer Alloc Fail", __func__);
			sme_release_global_lock(&pMac->sme);
			return QDF_STATUS_E_NOMEM;
		}

		cauReq->reserved_param = 0;

		/* serialize the req through MC thread */
		cds_message.bodyptr = cauReq;
		cds_message.type = WMA_CH_AVOID_UPDATE_REQ;
		qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				  "%s: Post Ch Avoid Update MSG fail",
				  __func__);
			qdf_mem_free(cauReq);
			sme_release_global_lock(&pMac->sme);
			return QDF_STATUS_E_FAILURE;
		}
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
			  "%s: Posted Ch Avoid Update MSG", __func__);
		sme_release_global_lock(&pMac->sme);
	}

	return status;
}
#endif /* FEATURE_WLAN_CH_AVOID */

/**
 * sme_set_miracast() - Function to set miracast value to UMAC
 * @hal:                Handle returned by macOpen
 * @filter_type:        0-Disabled, 1-Source, 2-sink
 *
 * This function passes down the value of miracast set by
 * framework to UMAC
 *
 * Return: Configuration message posting status, SUCCESS or Fail
 *
 */
QDF_STATUS sme_set_miracast(tHalHandle hal, uint8_t filter_type)
{
	cds_msg_t msg;
	uint32_t *val;
	tpAniSirGlobal mac_ptr = PMAC_STRUCT(hal);

	val = qdf_mem_malloc(sizeof(*val));
	if (NULL == val || NULL == mac_ptr) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				"%s: Invalid pointer", __func__);
		return QDF_STATUS_E_NOMEM;
	}

	*val = filter_type;

	msg.type = SIR_HAL_SET_MIRACAST;
	msg.reserved = 0;
	msg.bodyptr = val;

	if (!QDF_IS_STATUS_SUCCESS(
				cds_mq_post_message(QDF_MODULE_ID_WMA, &msg))) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
		    "%s: Not able to post WDA_SET_MAS_ENABLE_DISABLE to WMA!",
		    __func__);
		qdf_mem_free(val);
		return QDF_STATUS_E_FAILURE;
	}

	mac_ptr->sme.miracast_value = filter_type;
	return QDF_STATUS_SUCCESS;
}

/**
 * sme_set_mas() - Function to set MAS value to UMAC
 * @val:	1-Enable, 0-Disable
 *
 * This function passes down the value of MAS to the UMAC. A
 * value of 1 will enable MAS and a value of 0 will disable MAS
 *
 * Return: Configuration message posting status, SUCCESS or Fail
 *
 */
QDF_STATUS sme_set_mas(uint32_t val)
{
	cds_msg_t msg;
	uint32_t *ptr_val;

	ptr_val = qdf_mem_malloc(sizeof(*ptr_val));
	if (NULL == ptr_val) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				"%s: could not allocate ptr_val", __func__);
		return QDF_STATUS_E_NOMEM;
	}

	*ptr_val = val;

	msg.type = SIR_HAL_SET_MAS;
	msg.reserved = 0;
	msg.bodyptr = ptr_val;

	if (!QDF_IS_STATUS_SUCCESS(
				cds_mq_post_message(QDF_MODULE_ID_WMA, &msg))) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
		    "%s: Not able to post WDA_SET_MAS_ENABLE_DISABLE to WMA!",
		    __func__);
		qdf_mem_free(ptr_val);
		return QDF_STATUS_E_FAILURE;
	}
	return QDF_STATUS_SUCCESS;
}

/**
 * sme_roam_channel_change_req() - Channel change to new target channel
 * @hHal: handle returned by mac_open
 * @bssid: mac address of BSS
 * @ch_params: target channel information
 * @profile: CSR profile
 *
 * API to Indicate Channel change to new target channel
 *
 * Return: QDF_STATUS
 */
QDF_STATUS sme_roam_channel_change_req(tHalHandle hHal,
				       struct qdf_mac_addr bssid,
				       struct ch_params_s *ch_params,
				       tCsrRoamProfile *profile)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {

		status = csr_roam_channel_change_req(pMac, bssid, ch_params,
				profile);
		sme_release_global_lock(&pMac->sme);
	}
	return status;
}

/* -------------------------------------------------------------------------
   \fn sme_process_channel_change_resp
   \brief API to Indicate Channel change response message to SAP.
   \return QDF_STATUS
   ---------------------------------------------------------------------------*/
QDF_STATUS sme_process_channel_change_resp(tpAniSirGlobal pMac,
					   uint16_t msg_type, void *pMsgBuf)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tCsrRoamInfo proam_info = { 0 };
	eCsrRoamResult roamResult;
	tpSwitchChannelParams pChnlParams = (tpSwitchChannelParams) pMsgBuf;
	uint32_t SessionId = pChnlParams->peSessionId;

	proam_info.channelChangeRespEvent =
		(tSirChanChangeResponse *)
		qdf_mem_malloc(sizeof(tSirChanChangeResponse));
	if (NULL == proam_info.channelChangeRespEvent) {
		status = QDF_STATUS_E_NOMEM;
		sms_log(pMac, LOGE,
			"Channel Change Event Allocation Failed: %d\n", status);
		return status;
	}
	if (msg_type == eWNI_SME_CHANNEL_CHANGE_RSP) {
		proam_info.channelChangeRespEvent->sessionId = SessionId;
		proam_info.channelChangeRespEvent->newChannelNumber =
			pChnlParams->channelNumber;
		proam_info.channelChangeRespEvent->secondaryChannelOffset =
			pChnlParams->ch_width;

		if (pChnlParams->status == QDF_STATUS_SUCCESS) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO_MED,
				  "sapdfs: Received success eWNI_SME_CHANNEL_CHANGE_RSP for sessionId[%d]",
				  SessionId);
			proam_info.channelChangeRespEvent->channelChangeStatus =
				1;
			roamResult = eCSR_ROAM_RESULT_CHANNEL_CHANGE_SUCCESS;
		} else {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO_MED,
				  "sapdfs: Received failure eWNI_SME_CHANNEL_CHANGE_RSP for sessionId[%d]",
				  SessionId);
			proam_info.channelChangeRespEvent->channelChangeStatus =
				0;
			roamResult = eCSR_ROAM_RESULT_CHANNEL_CHANGE_FAILURE;
		}

		csr_roam_call_callback(pMac, SessionId, &proam_info, 0,
				       eCSR_ROAM_SET_CHANNEL_RSP, roamResult);

	} else {
		status = QDF_STATUS_E_FAILURE;
		sms_log(pMac, LOGE, "Invalid Channel Change Resp Message: %d\n",
			status);
	}
	qdf_mem_free(proam_info.channelChangeRespEvent);

	return status;
}

/* -------------------------------------------------------------------------
   \fn sme_roam_start_beacon_req
   \brief API to Indicate LIM to start Beacon Tx
   \after SAP CAC Wait is completed.
   \param hHal - The handle returned by mac_open
   \param sessionId - session ID
   \param dfsCacWaitStatus - CAC WAIT status flag
   \return QDF_STATUS
   ---------------------------------------------------------------------------*/
QDF_STATUS sme_roam_start_beacon_req(tHalHandle hHal, struct qdf_mac_addr bssid,
				     uint8_t dfsCacWaitStatus)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	status = sme_acquire_global_lock(&pMac->sme);

	if (QDF_IS_STATUS_SUCCESS(status)) {
		status = csr_roam_start_beacon_req(pMac, bssid, dfsCacWaitStatus);
		sme_release_global_lock(&pMac->sme);
	}
	return status;
}

/**
 * sme_roam_csa_ie_request() - request CSA IE transmission from PE
 * @hHal: handle returned by mac_open
 * @bssid: SAP bssid
 * @targetChannel: target channel information
 * @csaIeReqd: CSA IE Request
 * @ch_params: channel information
 *
 * Return: QDF_STATUS
 */
QDF_STATUS sme_roam_csa_ie_request(tHalHandle hHal, struct qdf_mac_addr bssid,
				uint8_t targetChannel, uint8_t csaIeReqd,
				struct ch_params_s *ch_params)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		status = csr_roam_send_chan_sw_ie_request(pMac, bssid,
				targetChannel, csaIeReqd, ch_params);
		sme_release_global_lock(&pMac->sme);
	}
	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_init_thermal_info
    \brief  SME API to initialize the thermal mitigation parameters
    \param  hHal
    \param  thermalParam : thermal mitigation parameters
   \- return QDF_STATUS
    -------------------------------------------------------------------------*/
QDF_STATUS sme_init_thermal_info(tHalHandle hHal, tSmeThermalParams thermalParam)
{
	t_thermal_mgmt *pWmaParam;
	cds_msg_t msg;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	pWmaParam = (t_thermal_mgmt *) qdf_mem_malloc(sizeof(t_thermal_mgmt));
	if (NULL == pWmaParam) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "%s: could not allocate tThermalMgmt", __func__);
		return QDF_STATUS_E_NOMEM;
	}

	qdf_mem_zero((void *)pWmaParam, sizeof(t_thermal_mgmt));

	pWmaParam->thermalMgmtEnabled = thermalParam.smeThermalMgmtEnabled;
	pWmaParam->throttlePeriod = thermalParam.smeThrottlePeriod;

	pWmaParam->throttle_duty_cycle_tbl[0] =
		thermalParam.sme_throttle_duty_cycle_tbl[0];
	pWmaParam->throttle_duty_cycle_tbl[1] =
		thermalParam.sme_throttle_duty_cycle_tbl[1];
	pWmaParam->throttle_duty_cycle_tbl[2] =
		thermalParam.sme_throttle_duty_cycle_tbl[2];
	pWmaParam->throttle_duty_cycle_tbl[3] =
		thermalParam.sme_throttle_duty_cycle_tbl[3];

	pWmaParam->thermalLevels[0].minTempThreshold =
		thermalParam.smeThermalLevels[0].smeMinTempThreshold;
	pWmaParam->thermalLevels[0].maxTempThreshold =
		thermalParam.smeThermalLevels[0].smeMaxTempThreshold;
	pWmaParam->thermalLevels[1].minTempThreshold =
		thermalParam.smeThermalLevels[1].smeMinTempThreshold;
	pWmaParam->thermalLevels[1].maxTempThreshold =
		thermalParam.smeThermalLevels[1].smeMaxTempThreshold;
	pWmaParam->thermalLevels[2].minTempThreshold =
		thermalParam.smeThermalLevels[2].smeMinTempThreshold;
	pWmaParam->thermalLevels[2].maxTempThreshold =
		thermalParam.smeThermalLevels[2].smeMaxTempThreshold;
	pWmaParam->thermalLevels[3].minTempThreshold =
		thermalParam.smeThermalLevels[3].smeMinTempThreshold;
	pWmaParam->thermalLevels[3].maxTempThreshold =
		thermalParam.smeThermalLevels[3].smeMaxTempThreshold;

	if (QDF_STATUS_SUCCESS == sme_acquire_global_lock(&pMac->sme)) {
		msg.type = WMA_INIT_THERMAL_INFO_CMD;
		msg.bodyptr = pWmaParam;

		if (!QDF_IS_STATUS_SUCCESS
			    (cds_mq_post_message(QDF_MODULE_ID_WMA, &msg))) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				  "%s: Not able to post WMA_SET_THERMAL_INFO_CMD to WMA!",
				  __func__);
			qdf_mem_free(pWmaParam);
			sme_release_global_lock(&pMac->sme);
			return QDF_STATUS_E_FAILURE;
		}
		sme_release_global_lock(&pMac->sme);
		return QDF_STATUS_SUCCESS;
	}
	qdf_mem_free(pWmaParam);
	return QDF_STATUS_E_FAILURE;
}

/**
 * sme_add_set_thermal_level_callback() - Plug in set thermal level callback
 * @hal:	Handle returned by macOpen
 * @callback:	sme_set_thermal_level_callback
 *
 * Plug in set thermal level callback
 *
 * Return: none
 */
void sme_add_set_thermal_level_callback(tHalHandle hal,
		sme_set_thermal_level_callback callback)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hal);

	pMac->sme.set_thermal_level_cb = callback;
}

/**
 * sme_set_thermal_level() - SME API to set the thermal mitigation level
 * @hal:         Handler to HAL
 * @level:       Thermal mitigation level
 *
 * Return: QDF_STATUS
 */
QDF_STATUS sme_set_thermal_level(tHalHandle hal, uint8_t level)
{
	cds_msg_t msg;
	tpAniSirGlobal pMac = PMAC_STRUCT(hal);
	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;

	if (QDF_STATUS_SUCCESS == sme_acquire_global_lock(&pMac->sme)) {
		qdf_mem_set(&msg, sizeof(msg), 0);
		msg.type = WMA_SET_THERMAL_LEVEL;
		msg.bodyval = level;

		qdf_status =  cds_mq_post_message(QDF_MODULE_ID_WMA, &msg);
		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				   "%s: Not able to post WMA_SET_THERMAL_LEVEL to WMA!",
				   __func__);
			sme_release_global_lock(&pMac->sme);
			return QDF_STATUS_E_FAILURE;
		}
		sme_release_global_lock(&pMac->sme);
		return QDF_STATUS_SUCCESS;
	}
	return QDF_STATUS_E_FAILURE;
}

/* ---------------------------------------------------------------------------
   \fn sme_txpower_limit
   \brief SME API to set txpower limits
   \param hHal
   \param psmetx : power limits for 2g/5g
   \- return QDF_STATUS
   -------------------------------------------------------------------------*/
QDF_STATUS sme_txpower_limit(tHalHandle hHal, tSirTxPowerLimit *psmetx)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
	cds_msg_t cds_message;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	tSirTxPowerLimit *tx_power_limit;

	tx_power_limit = qdf_mem_malloc(sizeof(*tx_power_limit));
	if (!tx_power_limit) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "%s: Memory allocation for TxPowerLimit failed!",
			  __func__);
		return QDF_STATUS_E_FAILURE;
	}

	*tx_power_limit = *psmetx;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		cds_message.type = WMA_TX_POWER_LIMIT;
		cds_message.reserved = 0;
		cds_message.bodyptr = tx_power_limit;

		qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				  "%s: not able to post WMA_TX_POWER_LIMIT",
				  __func__);
			status = QDF_STATUS_E_FAILURE;
			qdf_mem_free(tx_power_limit);
		}
		sme_release_global_lock(&pMac->sme);
	}
	return status;
}

QDF_STATUS sme_update_connect_debug(tHalHandle hHal, uint32_t set_value)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	pMac->fEnableDebugLog = set_value;
	return status;
}

/* ---------------------------------------------------------------------------
   \fn    sme_ap_disable_intra_bss_fwd

   \brief
    SME will send message to WMA to set Intra BSS in txrx

   \param

    hHal - The handle returned by mac_open

    sessionId - session id ( vdev id)

    disablefwd - bool value that indicate disable intrabss fwd disable

   \return QDF_STATUS
   --------------------------------------------------------------------------- */
QDF_STATUS sme_ap_disable_intra_bss_fwd(tHalHandle hHal, uint8_t sessionId,
					bool disablefwd)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	int status = QDF_STATUS_SUCCESS;
	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
	cds_msg_t cds_message;
	tpDisableIntraBssFwd pSapDisableIntraFwd = NULL;

	/* Prepare the request to send to SME. */
	pSapDisableIntraFwd = qdf_mem_malloc(sizeof(tDisableIntraBssFwd));
	if (NULL == pSapDisableIntraFwd) {
		sms_log(pMac, LOGP, "Memory Allocation Failure!!! %s", __func__);
		return QDF_STATUS_E_NOMEM;
	}

	qdf_mem_zero(pSapDisableIntraFwd, sizeof(tDisableIntraBssFwd));

	pSapDisableIntraFwd->sessionId = sessionId;
	pSapDisableIntraFwd->disableintrabssfwd = disablefwd;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		/* serialize the req through MC thread */
		cds_message.bodyptr = pSapDisableIntraFwd;
		cds_message.type = WMA_SET_SAP_INTRABSS_DIS;
		qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
			status = QDF_STATUS_E_FAILURE;
			qdf_mem_free(pSapDisableIntraFwd);
		}
		sme_release_global_lock(&pMac->sme);
	}
	return status;
}

#ifdef WLAN_FEATURE_STATS_EXT

/******************************************************************************
   \fn sme_stats_ext_register_callback

   \brief
   a function called to register the callback that send vendor event for stats
   ext

   \param callback - callback to be registered
******************************************************************************/
void sme_stats_ext_register_callback(tHalHandle hHal, StatsExtCallback callback)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	pMac->sme.StatsExtCallback = callback;
}

/**
 * sme_stats_ext_deregister_callback() - De-register ext stats callback
 * @h_hal: Hal Handle
 *
 * This function is called to  de initialize the HDD NAN feature.  Currently
 * the only operation required is to de-register a callback with SME.
 *
 * Return: None
 */
void sme_stats_ext_deregister_callback(tHalHandle h_hal)
{
	tpAniSirGlobal pmac;

	if (!h_hal) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  FL("hHal is not valid"));
		return;
	}

	pmac = PMAC_STRUCT(h_hal);
	pmac->sme.StatsExtCallback = NULL;
}


/******************************************************************************
   \fn sme_stats_ext_request

   \brief
   a function called when HDD receives STATS EXT vendor command from userspace

   \param sessionID - vdevID for the stats ext request

   \param input - Stats Ext Request structure ptr

   \return QDF_STATUS
******************************************************************************/
QDF_STATUS sme_stats_ext_request(uint8_t session_id, tpStatsExtRequestReq input)
{
	cds_msg_t msg;
	tpStatsExtRequest data;
	size_t data_len;

	data_len = sizeof(tStatsExtRequest) + input->request_data_len;
	data = qdf_mem_malloc(data_len);

	if (data == NULL) {
		return QDF_STATUS_E_NOMEM;
	}

	qdf_mem_zero(data, data_len);
	data->vdev_id = session_id;
	data->request_data_len = input->request_data_len;
	if (input->request_data_len) {
		qdf_mem_copy(data->request_data,
			     input->request_data, input->request_data_len);
	}

	msg.type = WMA_STATS_EXT_REQUEST;
	msg.reserved = 0;
	msg.bodyptr = data;

	if (QDF_STATUS_SUCCESS != cds_mq_post_message(QDF_MODULE_ID_WMA, &msg)) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "%s: Not able to post WMA_STATS_EXT_REQUEST message to WMA",
			  __func__);
		qdf_mem_free(data);
		return QDF_STATUS_E_FAILURE;
	}

	return QDF_STATUS_SUCCESS;
}

/******************************************************************************
   \fn sme_stats_ext_event

   \brief
   a callback function called when SME received eWNI_SME_STATS_EXT_EVENT
   response from WMA

   \param hHal - HAL handle for device
   \param pMsg - Message body passed from WMA; includes NAN header
   \return QDF_STATUS
******************************************************************************/
QDF_STATUS sme_stats_ext_event(tHalHandle hHal, void *pMsg)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	QDF_STATUS status = QDF_STATUS_SUCCESS;

	if (NULL == pMsg) {
		sms_log(pMac, LOGE, "in %s msg ptr is NULL", __func__);
		status = QDF_STATUS_E_FAILURE;
	} else {
		sms_log(pMac, LOG2, "SME: entering %s", __func__);

		if (pMac->sme.StatsExtCallback) {
			pMac->sme.StatsExtCallback(pMac->hHdd,
						   (tpStatsExtEvent) pMsg);
		}
	}

	return status;
}

#endif

/* ---------------------------------------------------------------------------
    \fn sme_update_dfs_scan_mode
    \brief  Update DFS roam scan mode
	    This function is called through dynamic setConfig callback function
	    to configure allowDFSChannelRoam.
    \param  hHal - HAL handle for device
    \param  sessionId - Session Identifier
    \param  allowDFSChannelRoam - DFS roaming scan mode 0 (disable),
	    1 (passive), 2 (active)
    \return QDF_STATUS_SUCCESS - SME update DFS roaming scan config
	    successfully.
	    Other status means SME failed to update DFS roaming scan config.
    \sa
    -------------------------------------------------------------------------*/
QDF_STATUS sme_update_dfs_scan_mode(tHalHandle hHal, uint8_t sessionId,
				    uint8_t allowDFSChannelRoam)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	QDF_STATUS status = QDF_STATUS_SUCCESS;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
			  "LFR runtime successfully set AllowDFSChannelRoam Mode to "
			  "%d - old value is %d - roam state is %s",
			  allowDFSChannelRoam,
			  pMac->roam.configParam.allowDFSChannelRoam,
			  mac_trace_get_neighbour_roam_state(pMac->roam.
							     neighborRoamInfo
							     [sessionId].
							     neighborRoamState));
		pMac->roam.configParam.allowDFSChannelRoam =
			allowDFSChannelRoam;
		sme_release_global_lock(&pMac->sme);
	}
	if (pMac->roam.configParam.isRoamOffloadScanEnabled) {
		csr_roam_offload_scan(pMac, sessionId,
				      ROAM_SCAN_OFFLOAD_UPDATE_CFG,
				      REASON_ROAM_DFS_SCAN_MODE_CHANGED);
	}

	return status;
}

/*--------------------------------------------------------------------------
   \brief sme_get_dfs_scan_mode() - get DFS roam scan mode
	  This is a synchronous call
   \param hHal - The handle returned by mac_open.
   \return DFS roaming scan mode 0 (disable), 1 (passive), 2 (active)
   \sa
   --------------------------------------------------------------------------*/
uint8_t sme_get_dfs_scan_mode(tHalHandle hHal)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	return pMac->roam.configParam.allowDFSChannelRoam;
}

/*----------------------------------------------------------------------------
   \fn  sme_modify_add_ie
   \brief  This function sends msg to updates the additional IE buffers in PE
   \param  hHal - global structure
   \param  pModifyIE - pointer to tModifyIE structure
   \param  updateType - type of buffer
   \- return Success or failure
   -----------------------------------------------------------------------------*/
QDF_STATUS sme_modify_add_ie(tHalHandle hHal,
			     tSirModifyIE *pModifyIE, eUpdateIEsType updateType)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	status = sme_acquire_global_lock(&pMac->sme);

	if (QDF_IS_STATUS_SUCCESS(status)) {
		status = csr_roam_modify_add_ies(pMac, pModifyIE, updateType);
		sme_release_global_lock(&pMac->sme);
	}
	return status;
}

/*----------------------------------------------------------------------------
   \fn  sme_update_add_ie
   \brief  This function sends msg to updates the additional IE buffers in PE
   \param  hHal - global structure
   \param  pUpdateIE - pointer to structure tUpdateIE
   \param  updateType - type of buffer
   \- return Success or failure
   -----------------------------------------------------------------------------*/
QDF_STATUS sme_update_add_ie(tHalHandle hHal,
			     tSirUpdateIE *pUpdateIE, eUpdateIEsType updateType)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	status = sme_acquire_global_lock(&pMac->sme);

	if (QDF_IS_STATUS_SUCCESS(status)) {
		status = csr_roam_update_add_ies(pMac, pUpdateIE, updateType);
		sme_release_global_lock(&pMac->sme);
	}
	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_sta_in_middle_of_roaming
    \brief  This function returns true if STA is in the middle of roaming state
    \param  hHal - HAL handle for device
    \param  sessionId - Session Identifier
   \- return true or false
    -------------------------------------------------------------------------*/
bool sme_sta_in_middle_of_roaming(tHalHandle hHal, uint8_t sessionId)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	bool ret = false;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		ret = csr_neighbor_middle_of_roaming(hHal, sessionId);
		sme_release_global_lock(&pMac->sme);
	}
	return ret;
}


/**
 * sme_update_dsc_pto_up_mapping()
 * @hHal: HAL context
 * @dscpmapping: pointer to DSCP mapping structure
 * @sessionId: SME session id
 *
 * This routine is called to update dscp mapping
 *
 * Return: QDF_STATUS
 */
QDF_STATUS sme_update_dsc_pto_up_mapping(tHalHandle hHal,
					 sme_QosWmmUpType *dscpmapping,
					 uint8_t sessionId)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	uint8_t i, j, peSessionId;
	tCsrRoamSession *pCsrSession = NULL;
	tpPESession pSession = NULL;

	status = sme_acquire_global_lock(&pMac->sme);
	if (!QDF_IS_STATUS_SUCCESS(status))
		return status;
	pCsrSession = CSR_GET_SESSION(pMac, sessionId);
	if (pCsrSession == NULL) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				FL("Session lookup fails for CSR session"));
		sme_release_global_lock(&pMac->sme);
		return QDF_STATUS_E_FAILURE;
	}
	if (!CSR_IS_SESSION_VALID(pMac, sessionId)) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				FL("Invalid session Id %u"), sessionId);
		sme_release_global_lock(&pMac->sme);
		return QDF_STATUS_E_FAILURE;
	}

	pSession = pe_find_session_by_bssid(pMac,
				pCsrSession->connectedProfile.bssid.bytes,
				&peSessionId);

	if (pSession == NULL) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				FL(" Session lookup fails for BSSID"));
		sme_release_global_lock(&pMac->sme);
		return QDF_STATUS_E_FAILURE;
	}

	if (!pSession->QosMapSet.present) {
		hdd_notice("QOS Mapping IE not present");
		sme_release_global_lock(&pMac->sme);
		return QDF_STATUS_E_FAILURE;
	}
	for (i = 0; i < SME_QOS_WMM_UP_MAX; i++) {
		for (j = pSession->QosMapSet.dscp_range[i][0];
			j <= pSession->QosMapSet.dscp_range[i][1];
			j++) {
			if ((pSession->QosMapSet.dscp_range[i][0] == 255)
				&& (pSession->QosMapSet.dscp_range[i][1] ==
							255)) {
				dscpmapping[j] = 0;
				QDF_TRACE(QDF_MODULE_ID_SME,
					QDF_TRACE_LEVEL_ERROR,
					FL("User Priority %d isn't used"), i);
				break;
			} else {
				dscpmapping[j] = i;
			}
		}
	}
	for (i = 0; i < pSession->QosMapSet.num_dscp_exceptions; i++)
		if (pSession->QosMapSet.dscp_exceptions[i][0] != 255)
			dscpmapping[pSession->QosMapSet.dscp_exceptions[i][0]] =
				pSession->QosMapSet.dscp_exceptions[i][1];

	sme_release_global_lock(&pMac->sme);
	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_abort_roam_scan
    \brief  API to abort current roam scan cycle by roam scan offload module.
    \param  hHal - The handle returned by mac_open.
    \param  sessionId - Session Identifier
    \return QDF_STATUS
   ---------------------------------------------------------------------------*/

QDF_STATUS sme_abort_roam_scan(tHalHandle hHal, uint8_t sessionId)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	sms_log(pMac, LOGW, "entering function %s", __func__);
	if (pMac->roam.configParam.isRoamOffloadScanEnabled) {
		/* acquire the lock for the sme object */
		status = sme_acquire_global_lock(&pMac->sme);
		if (QDF_IS_STATUS_SUCCESS(status)) {
			csr_roam_offload_scan(pMac, sessionId,
					      ROAM_SCAN_OFFLOAD_ABORT_SCAN,
					      REASON_ROAM_ABORT_ROAM_SCAN);
			/* release the lock for the sme object */
			sme_release_global_lock(&pMac->sme);
		}
	}

	return status;
}

#ifdef FEATURE_WLAN_EXTSCAN
/**
 * sme_get_valid_channels_by_band() - to fetch valid channels filtered by band
 * @hHal: HAL context
 * @wifiBand: RF band information
 * @aValidChannels: output array to store channel info
 * @pNumChannels: output number of channels
 *
 *  SME API to fetch all valid channels filtered by band
 *
 *  Return: QDF_STATUS
 */
QDF_STATUS sme_get_valid_channels_by_band(tHalHandle hHal,
					  uint8_t wifiBand,
					  uint32_t *aValidChannels,
					  uint8_t *pNumChannels)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	uint8_t chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = { 0 };
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	uint8_t numChannels = 0;
	uint8_t i = 0;
	uint32_t totValidChannels = WNI_CFG_VALID_CHANNEL_LIST_LEN;

	if (!aValidChannels || !pNumChannels) {
		sms_log(pMac, QDF_TRACE_LEVEL_ERROR,
			FL("Output channel list/NumChannels is NULL"));
		return QDF_STATUS_E_INVAL;
	}

	if ((wifiBand < WIFI_BAND_UNSPECIFIED) || (wifiBand >= WIFI_BAND_MAX)) {
		sms_log(pMac, QDF_TRACE_LEVEL_ERROR,
			FL("Invalid wifiBand (%d)"), wifiBand);
		return QDF_STATUS_E_INVAL;
	}

	status = sme_get_cfg_valid_channels(hHal, &chanList[0],
			&totValidChannels);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		sms_log(pMac, QDF_TRACE_LEVEL_ERROR,
			FL("Fail to get valid channel list (err=%d)"), status);
		return status;
	}

	switch (wifiBand) {
	case WIFI_BAND_UNSPECIFIED:
		sms_log(pMac, QDF_TRACE_LEVEL_INFO,
			FL("Unspec Band, return all (%d) valid channels"),
			totValidChannels);
		numChannels = totValidChannels;
		for (i = 0; i < totValidChannels; i++) {
			aValidChannels[i] = cds_chan_to_freq(chanList[i]);
		}
		break;

	case WIFI_BAND_BG:
		sms_log(pMac, QDF_TRACE_LEVEL_INFO,
			FL("WIFI_BAND_BG (2.4 GHz)"));
		for (i = 0; i < totValidChannels; i++) {
			if (CDS_IS_CHANNEL_24GHZ(chanList[i])) {
				aValidChannels[numChannels++] =
					cds_chan_to_freq(chanList[i]);
			}
		}
		break;

	case WIFI_BAND_A:
		sms_log(pMac, QDF_TRACE_LEVEL_INFO,
			FL("WIFI_BAND_A (5 GHz without DFS)"));
		for (i = 0; i < totValidChannels; i++) {
			if (CDS_IS_CHANNEL_5GHZ(chanList[i]) &&
			    !CDS_IS_DFS_CH(chanList[i])) {
				aValidChannels[numChannels++] =
					cds_chan_to_freq(chanList[i]);
			}
		}
		break;

	case WIFI_BAND_ABG:
		sms_log(pMac, QDF_TRACE_LEVEL_INFO,
			FL("WIFI_BAND_ABG (2.4 GHz + 5 GHz; no DFS)"));
		for (i = 0; i < totValidChannels; i++) {
			if ((CDS_IS_CHANNEL_24GHZ(chanList[i]) ||
			     CDS_IS_CHANNEL_5GHZ(chanList[i])) &&
			    !CDS_IS_DFS_CH(chanList[i])) {
				aValidChannels[numChannels++] =
					cds_chan_to_freq(chanList[i]);
			}
		}
		break;

	case WIFI_BAND_A_DFS_ONLY:
		sms_log(pMac, QDF_TRACE_LEVEL_INFO,
			FL("WIFI_BAND_A_DFS (5 GHz DFS only)"));
		for (i = 0; i < totValidChannels; i++) {
			if (CDS_IS_CHANNEL_5GHZ(chanList[i]) &&
			    CDS_IS_DFS_CH(chanList[i])) {
				aValidChannels[numChannels++] =
					cds_chan_to_freq(chanList[i]);
			}
		}
		break;

	case WIFI_BAND_A_WITH_DFS:
		sms_log(pMac, QDF_TRACE_LEVEL_INFO,
			FL("WIFI_BAND_A_WITH_DFS (5 GHz with DFS)"));
		for (i = 0; i < totValidChannels; i++) {
			if (CDS_IS_CHANNEL_5GHZ(chanList[i])) {
				aValidChannels[numChannels++] =
					cds_chan_to_freq(chanList[i]);
			}
		}
		break;

	case WIFI_BAND_ABG_WITH_DFS:
		sms_log(pMac, QDF_TRACE_LEVEL_INFO,
			FL("WIFI_BAND_ABG_WITH_DFS (2.4 GHz+5 GHz with DFS)"));
		for (i = 0; i < totValidChannels; i++) {
			if (CDS_IS_CHANNEL_24GHZ(chanList[i]) ||
			    CDS_IS_CHANNEL_5GHZ(chanList[i])) {
				aValidChannels[numChannels++] =
					cds_chan_to_freq(chanList[i]);
			}
		}
		break;

	default:
		sms_log(pMac, QDF_TRACE_LEVEL_ERROR,
			FL("Unknown wifiBand (%d))"), wifiBand);
		return QDF_STATUS_E_INVAL;
		break;
	}
	*pNumChannels = numChannels;

	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_ext_scan_get_capabilities
    \brief  SME API to fetch extscan capabilities
    \param  hHal
    \param  pReq: extscan capabilities structure
   \- return QDF_STATUS
    -------------------------------------------------------------------------*/
QDF_STATUS sme_ext_scan_get_capabilities(tHalHandle hHal,
					 tSirGetExtScanCapabilitiesReqParams *
					 pReq)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	cds_msg_t cds_message;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		/* Serialize the req through MC thread */
		cds_message.bodyptr = pReq;
		cds_message.type = WMA_EXTSCAN_GET_CAPABILITIES_REQ;
		MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
				 NO_SESSION, cds_message.type));
		qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
			status = QDF_STATUS_E_FAILURE;

		sme_release_global_lock(&pMac->sme);
	}
	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_ext_scan_start
    \brief  SME API to issue extscan start
    \param  hHal
    \param  pStartCmd: extscan start structure
   \- return QDF_STATUS
    -------------------------------------------------------------------------*/
QDF_STATUS sme_ext_scan_start(tHalHandle hHal,
			      tSirWifiScanCmdReqParams *pStartCmd)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	cds_msg_t cds_message;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		/* Serialize the req through MC thread */
		cds_message.bodyptr = pStartCmd;
		cds_message.type = WMA_EXTSCAN_START_REQ;
		MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
				 NO_SESSION, cds_message.type));
		qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
			status = QDF_STATUS_E_FAILURE;

		sme_release_global_lock(&pMac->sme);
	}
	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_ext_scan_stop
    \brief  SME API to issue extscan stop
    \param  hHal
    \param  pStopReq: extscan stop structure
   \- return QDF_STATUS
    -------------------------------------------------------------------------*/
QDF_STATUS sme_ext_scan_stop(tHalHandle hHal, tSirExtScanStopReqParams *pStopReq)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	cds_msg_t cds_message;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		/* Serialize the req through MC thread */
		cds_message.bodyptr = pStopReq;
		cds_message.type = WMA_EXTSCAN_STOP_REQ;
		MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
				 NO_SESSION, cds_message.type));
		qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
			status = QDF_STATUS_E_FAILURE;
		sme_release_global_lock(&pMac->sme);
	}
	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_set_bss_hotlist
    \brief  SME API to set BSSID hotlist
    \param  hHal
    \param  pSetHotListReq: extscan set hotlist structure
   \- return QDF_STATUS
    -------------------------------------------------------------------------*/
QDF_STATUS sme_set_bss_hotlist(tHalHandle hHal,
			       tSirExtScanSetBssidHotListReqParams *
			       pSetHotListReq)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	cds_msg_t cds_message;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		/* Serialize the req through MC thread */
		cds_message.bodyptr = pSetHotListReq;
		cds_message.type = WMA_EXTSCAN_SET_BSSID_HOTLIST_REQ;
		MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
				 NO_SESSION, cds_message.type));
		qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
			status = QDF_STATUS_E_FAILURE;

		sme_release_global_lock(&pMac->sme);
	}
	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_reset_bss_hotlist
    \brief  SME API to reset BSSID hotlist
    \param  hHal
    \param  pSetHotListReq: extscan set hotlist structure
   \- return QDF_STATUS
    -------------------------------------------------------------------------*/
QDF_STATUS sme_reset_bss_hotlist(tHalHandle hHal,
				 tSirExtScanResetBssidHotlistReqParams *
				 pResetReq)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	cds_msg_t cds_message;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		/* Serialize the req through MC thread */
		cds_message.bodyptr = pResetReq;
		cds_message.type = WMA_EXTSCAN_RESET_BSSID_HOTLIST_REQ;
		MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
				 NO_SESSION, cds_message.type));
		qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
			status = QDF_STATUS_E_FAILURE;

		sme_release_global_lock(&pMac->sme);
	}
	return status;
}

/**
 * sme_send_wisa_params(): Pass WISA mode to WMA
 * @hal: HAL context
 * @wisa_params: pointer to WISA params struct
 * @sessionId: SME session id
 *
 * Pass WISA params to WMA
 *
 * Return: QDF_STATUS
 */
QDF_STATUS sme_set_wisa_params(tHalHandle hal,
				struct sir_wisa_params *wisa_params)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal mac = PMAC_STRUCT(hal);
	cds_msg_t cds_message;
	struct sir_wisa_params *cds_msg_wisa_params;

	cds_msg_wisa_params = qdf_mem_malloc(sizeof(struct sir_wisa_params));
	if (!cds_msg_wisa_params)
		return QDF_STATUS_E_NOMEM;

	*cds_msg_wisa_params = *wisa_params;
	status = sme_acquire_global_lock(&mac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		cds_message.bodyptr = cds_msg_wisa_params;
		cds_message.type = WMA_SET_WISA_PARAMS;
		status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
		sme_release_global_lock(&mac->sme);
	}
	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_set_significant_change
    \brief  SME API to set significant change
    \param  hHal
    \param  pSetSignificantChangeReq: extscan set significant change structure
   \- return QDF_STATUS
    -------------------------------------------------------------------------*/
QDF_STATUS sme_set_significant_change(tHalHandle hHal,
				      tSirExtScanSetSigChangeReqParams *
				      pSetSignificantChangeReq)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	cds_msg_t cds_message;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		/* Serialize the req through MC thread */
		cds_message.bodyptr = pSetSignificantChangeReq;
		cds_message.type = WMA_EXTSCAN_SET_SIGNF_CHANGE_REQ;
		MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
				 NO_SESSION, cds_message.type));
		qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
			status = QDF_STATUS_E_FAILURE;

		sme_release_global_lock(&pMac->sme);
	}
	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_reset_significant_change
    \brief  SME API to reset significant change
    \param  hHal
    \param  pResetReq: extscan reset significant change structure
   \- return QDF_STATUS
    -------------------------------------------------------------------------*/
QDF_STATUS sme_reset_significant_change(tHalHandle hHal,
					tSirExtScanResetSignificantChangeReqParams
					*pResetReq)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	cds_msg_t cds_message;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		/* Serialize the req through MC thread */
		cds_message.bodyptr = pResetReq;
		cds_message.type = WMA_EXTSCAN_RESET_SIGNF_CHANGE_REQ;
		MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
				 NO_SESSION, cds_message.type));
		qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
			status = QDF_STATUS_E_FAILURE;

		sme_release_global_lock(&pMac->sme);
	}
	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_get_cached_results
    \brief  SME API to get cached results
    \param  hHal
    \param  pCachedResultsReq: extscan get cached results structure
   \- return QDF_STATUS
    -------------------------------------------------------------------------*/
QDF_STATUS sme_get_cached_results(tHalHandle hHal,
				  tSirExtScanGetCachedResultsReqParams *
				  pCachedResultsReq)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	cds_msg_t cds_message;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		/* Serialize the req through MC thread */
		cds_message.bodyptr = pCachedResultsReq;
		cds_message.type = WMA_EXTSCAN_GET_CACHED_RESULTS_REQ;
		MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
				 NO_SESSION, cds_message.type));
		qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
			status = QDF_STATUS_E_FAILURE;

		sme_release_global_lock(&pMac->sme);
	}
	return status;
}

/**
 * sme_set_epno_list() - set epno network list
 * @hal: global hal handle
 * @input: request message
 *
 * This function constructs the cds message and fill in message type,
 * bodyptr with %input and posts it to WDA queue.
 *
 * Return: QDF_STATUS enumeration
 */
QDF_STATUS sme_set_epno_list(tHalHandle hal,
				struct wifi_epno_params *input)
{
	QDF_STATUS status    = QDF_STATUS_SUCCESS;
	tpAniSirGlobal mac   = PMAC_STRUCT(hal);
	cds_msg_t cds_message;
	struct wifi_epno_params *req_msg;
	int len, i;

	sms_log(mac, LOG1, FL("enter"));
	len = sizeof(*req_msg) +
		(input->num_networks * sizeof(struct wifi_epno_network));
	req_msg = qdf_mem_malloc(len);
	if (!req_msg) {
		sms_log(mac, LOGE, FL("qdf_mem_malloc failed"));
		return QDF_STATUS_E_NOMEM;
	}

	qdf_mem_zero(req_msg, len);
	req_msg->num_networks = input->num_networks;
	req_msg->request_id = input->request_id;
	req_msg->session_id = input->session_id;
	for (i = 0; i < req_msg->num_networks; i++) {
		req_msg->networks[i].rssi_threshold =
				input->networks[i].rssi_threshold;
		req_msg->networks[i].flags = input->networks[i].flags;
		req_msg->networks[i].auth_bit_field =
				input->networks[i].auth_bit_field;
		req_msg->networks[i].ssid.length =
				input->networks[i].ssid.length;
		qdf_mem_copy(req_msg->networks[i].ssid.ssId,
				input->networks[i].ssid.ssId,
				req_msg->networks[i].ssid.length);
	}

	status = sme_acquire_global_lock(&mac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		sms_log(mac, LOGE,
			FL("sme_acquire_global_lock failed!(status=%d)"),
			status);
		qdf_mem_free(req_msg);
		return status;
	}

	/* Serialize the req through MC thread */
	cds_message.bodyptr = req_msg;
	cds_message.type    = WMA_SET_EPNO_LIST_REQ;
	status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		sms_log(mac, LOGE,
			FL("cds_mq_post_message failed!(err=%d)"),
			status);
		qdf_mem_free(req_msg);
		status = QDF_STATUS_E_FAILURE;
	}
	sme_release_global_lock(&mac->sme);
	return status;
}

/**
 * sme_set_passpoint_list() - set passpoint network list
 * @hal: global hal handle
 * @input: request message
 *
 * This function constructs the cds message and fill in message type,
 * bodyptr with @input and posts it to WDA queue.
 *
 * Return: QDF_STATUS enumeration
 */
QDF_STATUS sme_set_passpoint_list(tHalHandle hal,
				struct wifi_passpoint_req *input)
{
	QDF_STATUS status  = QDF_STATUS_SUCCESS;
	tpAniSirGlobal mac = PMAC_STRUCT(hal);
	cds_msg_t cds_message;
	struct wifi_passpoint_req *req_msg;
	int len, i;

	sms_log(mac, LOG1, FL("enter"));
	len = sizeof(*req_msg) +
		(input->num_networks * sizeof(struct wifi_passpoint_network));
	req_msg = qdf_mem_malloc(len);
	if (!req_msg) {
		sms_log(mac, LOGE, FL("qdf_mem_malloc failed"));
		return QDF_STATUS_E_NOMEM;
	}

	qdf_mem_zero(req_msg, len);
	req_msg->num_networks = input->num_networks;
	req_msg->request_id = input->request_id;
	req_msg->session_id = input->session_id;
	for (i = 0; i < req_msg->num_networks; i++) {
		req_msg->networks[i].id =
				input->networks[i].id;
		qdf_mem_copy(req_msg->networks[i].realm,
				input->networks[i].realm,
				strlen(input->networks[i].realm) + 1);
		qdf_mem_copy(req_msg->networks[i].plmn,
				input->networks[i].plmn,
				SIR_PASSPOINT_PLMN_LEN);
		qdf_mem_copy(req_msg->networks[i].roaming_consortium_ids,
			     input->networks[i].roaming_consortium_ids,
			sizeof(req_msg->networks[i].roaming_consortium_ids));
	}

	status = sme_acquire_global_lock(&mac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		sms_log(mac, LOGE,
			FL("sme_acquire_global_lock failed!(status=%d)"),
			status);
		qdf_mem_free(req_msg);
		return status;
	}

	/* Serialize the req through MC thread */
	cds_message.bodyptr = req_msg;
	cds_message.type    = WMA_SET_PASSPOINT_LIST_REQ;
	status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		sms_log(mac, LOGE,
			FL("cds_mq_post_message failed!(err=%d)"),
			status);
		qdf_mem_free(req_msg);
		status = QDF_STATUS_E_FAILURE;
	}
	sme_release_global_lock(&mac->sme);
	return status;
}

/**
 * sme_reset_passpoint_list() - reset passpoint network list
 * @hHal: global hal handle
 * @input: request message
 *
 * Return: QDF_STATUS enumeration
 */
QDF_STATUS sme_reset_passpoint_list(tHalHandle hal,
				    struct wifi_passpoint_req *input)
{
	QDF_STATUS status   = QDF_STATUS_SUCCESS;
	tpAniSirGlobal mac  = PMAC_STRUCT(hal);
	cds_msg_t cds_message;
	struct wifi_passpoint_req *req_msg;

	sms_log(mac, LOG1, FL("enter"));
	req_msg = qdf_mem_malloc(sizeof(*req_msg));
	if (!req_msg) {
		sms_log(mac, LOGE, FL("qdf_mem_malloc failed"));
		return QDF_STATUS_E_NOMEM;
	}

	qdf_mem_zero(req_msg, sizeof(*req_msg));
	req_msg->request_id = input->request_id;
	req_msg->session_id = input->session_id;

	status = sme_acquire_global_lock(&mac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		sms_log(mac, LOGE,
			FL("sme_acquire_global_lock failed!(status=%d)"),
			status);
		qdf_mem_free(req_msg);
		return status;
	}

	/* Serialize the req through MC thread */
	cds_message.bodyptr = req_msg;
	cds_message.type    = WMA_RESET_PASSPOINT_LIST_REQ;
	status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		sms_log(mac, LOGE,
			FL("cds_mq_post_message failed!(err=%d)"),
			status);
		qdf_mem_free(req_msg);
		status = QDF_STATUS_E_FAILURE;
	}
	sme_release_global_lock(&mac->sme);
	return status;
}

/**
 * sme_set_ssid_hotlist() - Set the SSID hotlist
 * @hal: SME handle
 * @request: set ssid hotlist request
 *
 * Return: QDF_STATUS
 */
QDF_STATUS
sme_set_ssid_hotlist(tHalHandle hal,
		     struct sir_set_ssid_hotlist_request *request)
{
	QDF_STATUS status   = QDF_STATUS_SUCCESS;
	tpAniSirGlobal mac = PMAC_STRUCT(hal);
	cds_msg_t cds_message;
	struct sir_set_ssid_hotlist_request *set_req;

	set_req = qdf_mem_malloc(sizeof(*set_req));
	if (!set_req) {
		sms_log(mac, LOGE, FL("qdf_mem_malloc failed"));
		return QDF_STATUS_E_FAILURE;
	}

	*set_req = *request;
	status = sme_acquire_global_lock(&mac->sme);
	if (QDF_STATUS_SUCCESS == status) {
		/* Serialize the req through MC thread */
		cds_message.bodyptr = set_req;
		cds_message.type    = WMA_EXTSCAN_SET_SSID_HOTLIST_REQ;
		status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
		sme_release_global_lock(&mac->sme);
		if (!QDF_IS_STATUS_SUCCESS(status)) {
			qdf_mem_free(set_req);
			status = QDF_STATUS_E_FAILURE;
		}
	} else {
		sms_log(mac, LOGE,
			FL("sme_acquire_global_lock failed!(status=%d)"),
			status);
		qdf_mem_free(set_req);
		status = QDF_STATUS_E_FAILURE;
	}
	return status;
}

QDF_STATUS sme_ext_scan_register_callback(tHalHandle hHal,
					  void (*pExtScanIndCb)(void *,
								const uint16_t,
								void *))
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		pMac->sme.pExtScanIndCb = pExtScanIndCb;
		sme_release_global_lock(&pMac->sme);
	}
	return status;
}
#endif /* FEATURE_WLAN_EXTSCAN */

#ifdef WLAN_FEATURE_LINK_LAYER_STATS

/* ---------------------------------------------------------------------------
    \fn sme_ll_stats_clear_req
    \brief  SME API to clear Link Layer Statistics
    \param  hHal
    \param  pclearStatsReq: Link Layer clear stats request params structure
   \- return QDF_STATUS
    -------------------------------------------------------------------------*/
QDF_STATUS sme_ll_stats_clear_req(tHalHandle hHal,
				  tSirLLStatsClearReq *pclearStatsReq)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	cds_msg_t cds_message;
	tSirLLStatsClearReq *clear_stats_req;

	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
		  "staId = %u", pclearStatsReq->staId);
	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
		  "statsClearReqMask = 0x%X",
		  pclearStatsReq->statsClearReqMask);
	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
		  "stopReq = %u", pclearStatsReq->stopReq);

	clear_stats_req = qdf_mem_malloc(sizeof(*clear_stats_req));

	if (!clear_stats_req) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "%s: Not able to allocate memory for WMA_LL_STATS_CLEAR_REQ",
			  __func__);
		return QDF_STATUS_E_NOMEM;
	}

	*clear_stats_req = *pclearStatsReq;

	if (QDF_STATUS_SUCCESS == sme_acquire_global_lock(&pMac->sme)) {
		/* Serialize the req through MC thread */
		cds_message.bodyptr = clear_stats_req;
		cds_message.type = WMA_LINK_LAYER_STATS_CLEAR_REQ;
		MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
				 NO_SESSION, cds_message.type));
		qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				  "%s: not able to post WMA_LL_STATS_CLEAR_REQ",
				  __func__);
			qdf_mem_free(clear_stats_req);
			status = QDF_STATUS_E_FAILURE;
		}
		sme_release_global_lock(&pMac->sme);
	} else {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, "%s: "
			  "sme_acquire_global_lock error", __func__);
		qdf_mem_free(clear_stats_req);
		status = QDF_STATUS_E_FAILURE;
	}

	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_ll_stats_set_req
    \brief  SME API to set the Link Layer Statistics
    \param  hHal
    \param  psetStatsReq: Link Layer set stats request params structure
   \- return QDF_STATUS
    -------------------------------------------------------------------------*/
QDF_STATUS sme_ll_stats_set_req(tHalHandle hHal, tSirLLStatsSetReq *psetStatsReq)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	cds_msg_t cds_message;
	tSirLLStatsSetReq *set_stats_req;

	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
		  "%s:  MPDU Size = %u", __func__,
		  psetStatsReq->mpduSizeThreshold);
	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
		  " Aggressive Stats Collections = %u",
		  psetStatsReq->aggressiveStatisticsGathering);

	set_stats_req = qdf_mem_malloc(sizeof(*set_stats_req));

	if (!set_stats_req) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "%s: Not able to allocate memory for WMA_LL_STATS_SET_REQ",
			  __func__);
		return QDF_STATUS_E_NOMEM;
	}

	*set_stats_req = *psetStatsReq;

	if (QDF_STATUS_SUCCESS == sme_acquire_global_lock(&pMac->sme)) {
		/* Serialize the req through MC thread */
		cds_message.bodyptr = set_stats_req;
		cds_message.type = WMA_LINK_LAYER_STATS_SET_REQ;
		MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
				 NO_SESSION, cds_message.type));
		qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				  "%s: not able to post WMA_LL_STATS_SET_REQ",
				  __func__);
			qdf_mem_free(set_stats_req);
			status = QDF_STATUS_E_FAILURE;
		}
		sme_release_global_lock(&pMac->sme);
	} else {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, "%s: "
			  "sme_acquire_global_lock error", __func__);
		qdf_mem_free(set_stats_req);
		status = QDF_STATUS_E_FAILURE;
	}

	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_ll_stats_get_req
    \brief  SME API to get the Link Layer Statistics
    \param  hHal
    \param  pgetStatsReq: Link Layer get stats request params structure
   \- return QDF_STATUS
    -------------------------------------------------------------------------*/
QDF_STATUS sme_ll_stats_get_req(tHalHandle hHal, tSirLLStatsGetReq *pgetStatsReq)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	cds_msg_t cds_message;
	tSirLLStatsGetReq *get_stats_req;

	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
		  "reqId = %u", pgetStatsReq->reqId);
	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
		  "staId = %u", pgetStatsReq->staId);
	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
		  "Stats Type = %u", pgetStatsReq->paramIdMask);

	get_stats_req = qdf_mem_malloc(sizeof(*get_stats_req));

	if (!get_stats_req) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "%s: Not able to allocate memory for WMA_LL_STATS_GET_REQ",
			  __func__);
		return QDF_STATUS_E_NOMEM;
	}

	*get_stats_req = *pgetStatsReq;

	if (QDF_STATUS_SUCCESS == sme_acquire_global_lock(&pMac->sme)) {
		/* Serialize the req through MC thread */
		cds_message.bodyptr = get_stats_req;
		cds_message.type = WMA_LINK_LAYER_STATS_GET_REQ;
		MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
				 NO_SESSION, cds_message.type));
		qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				  "%s: not able to post WMA_LL_STATS_GET_REQ",
				  __func__);

			qdf_mem_free(get_stats_req);
			status = QDF_STATUS_E_FAILURE;

		}
		sme_release_global_lock(&pMac->sme);
	} else {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, "%s: "
			  "sme_acquire_global_lock error", __func__);
		qdf_mem_free(get_stats_req);
		status = QDF_STATUS_E_FAILURE;
	}

	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_set_link_layer_stats_ind_cb
    \brief  SME API to trigger the stats are available  after get request
    \param  hHal
    \param callback_routine - HDD callback which needs to be invoked after
	   getting status notification from FW
   \- return QDF_STATUS
    -------------------------------------------------------------------------*/
QDF_STATUS sme_set_link_layer_stats_ind_cb
	(tHalHandle hHal,
	void (*callback_routine)(void *callbackCtx, int indType, void *pRsp)
	) {
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		pMac->sme.pLinkLayerStatsIndCallback = callback_routine;
		sme_release_global_lock(&pMac->sme);
	} else {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, "%s: "
			  "sme_acquire_global_lock error", __func__);
	}

	return status;
}

/**
 * sme_reset_link_layer_stats_ind_cb() - SME API to reset link layer stats
 *					 indication
 * @h_hal: Hal Handle
 *
 * This function reset's the link layer stats indication
 *
 * Return: QDF_STATUS Enumeration
 */

QDF_STATUS sme_reset_link_layer_stats_ind_cb(tHalHandle h_hal)
{
	QDF_STATUS status;
	tpAniSirGlobal pmac;

	if (!h_hal) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				  FL("hHal is not valid"));
		return QDF_STATUS_E_INVAL;
	}
	pmac = PMAC_STRUCT(h_hal);

	status = sme_acquire_global_lock(&pmac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		pmac->sme.pLinkLayerStatsIndCallback = NULL;
		sme_release_global_lock(&pmac->sme);
	} else {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, "%s: sme_acquire_global_lock error",
			  __func__);
	}

	return status;
}


#endif /* WLAN_FEATURE_LINK_LAYER_STATS */

/**
 * sme_fw_mem_dump_register_cb() - Register fw memory dump callback
 *
 * @hal - MAC global handle
 * @callback_routine - callback routine from HDD
 *
 * This API is invoked by HDD to register its callback in SME
 *
 * Return: QDF_STATUS
 */
#ifdef WLAN_FEATURE_MEMDUMP
QDF_STATUS sme_fw_mem_dump_register_cb(tHalHandle hal,
		void (*callback_routine)(void *cb_context,
					 struct fw_dump_rsp *rsp))
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pmac = PMAC_STRUCT(hal);

	status = sme_acquire_global_lock(&pmac->sme);
	if (QDF_STATUS_SUCCESS == status) {
		pmac->sme.fw_dump_callback = callback_routine;
		sme_release_global_lock(&pmac->sme);
	} else {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  FL("sme_acquire_global_lock error"));
	}

	return status;
}
#else
QDF_STATUS sme_fw_mem_dump_register_cb(tHalHandle hal,
		void (*callback_routine)(void *cb_context,
					 struct fw_dump_rsp *rsp))
{
	return QDF_STATUS_SUCCESS;
}
#endif /* WLAN_FEATURE_MEMDUMP */

/**
 * sme_fw_mem_dump_unregister_cb() - Unregister fw memory dump callback
 *
 * @hHal - MAC global handle
 *
 * This API is invoked by HDD to unregister its callback in SME
 *
 * Return: QDF_STATUS
 */
#ifdef WLAN_FEATURE_MEMDUMP
QDF_STATUS sme_fw_mem_dump_unregister_cb(tHalHandle hal)
{
	QDF_STATUS status;
	tpAniSirGlobal pmac = PMAC_STRUCT(hal);

	status = sme_acquire_global_lock(&pmac->sme);
	if (QDF_STATUS_SUCCESS == status) {
		pmac->sme.fw_dump_callback = NULL;
		sme_release_global_lock(&pmac->sme);
	} else {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  FL("sme_acquire_global_lock error"));
	}

	return status;
}
#else
QDF_STATUS sme_fw_mem_dump_unregister_cb(tHalHandle hal)
{
	return QDF_STATUS_SUCCESS;
}
#endif /* WLAN_FEATURE_MEMDUMP */

#ifdef WLAN_FEATURE_ROAM_OFFLOAD
/*--------------------------------------------------------------------------
   \brief sme_update_roam_offload_enabled() - enable/disable roam offload feaure
   It is used at in the REG_DYNAMIC_VARIABLE macro definition of
   \param hHal - The handle returned by mac_open.
   \param nRoamOffloadEnabled - The bool to update with
   \return QDF_STATUS_SUCCESS - SME update config successfully.
	   Other status means SME is failed to update.
   \sa
   --------------------------------------------------------------------------*/

QDF_STATUS sme_update_roam_offload_enabled(tHalHandle hHal,
					   bool nRoamOffloadEnabled)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	QDF_STATUS status = QDF_STATUS_SUCCESS;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
			  "%s: LFR3:gRoamOffloadEnabled is changed from %d to %d",
			  __func__, pMac->roam.configParam.isRoamOffloadEnabled,
			  nRoamOffloadEnabled);
		pMac->roam.configParam.isRoamOffloadEnabled =
			nRoamOffloadEnabled;
		sme_release_global_lock(&pMac->sme);
	}

	return status;
}

/**
 * sme_update_roam_key_mgmt_offload_enabled() - enable/disable key mgmt offload
 * This is a synchronous call
 * @hal_ctx: The handle returned by mac_open.
 * @session_id: Session Identifier
 * @key_mgmt_offload_enabled: key mgmt enable/disable flag
 * @okc_enabled: Opportunistic key caching enable/disable flag
 * Return: QDF_STATUS_SUCCESS - SME updated config successfully.
 * Other status means SME is failed to update.
 */

QDF_STATUS sme_update_roam_key_mgmt_offload_enabled(tHalHandle hal_ctx,
						uint8_t session_id,
						bool key_mgmt_offload_enabled,
						bool okc_enabled)
{
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_ctx);
	QDF_STATUS status = QDF_STATUS_SUCCESS;

	status = sme_acquire_global_lock(&mac_ctx->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		if (CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
				"%s: LFR3: key_mgmt_offload_enabled changed to %d",
				  __func__, key_mgmt_offload_enabled);
			status = csr_roam_set_key_mgmt_offload(mac_ctx,
						session_id,
						key_mgmt_offload_enabled,
						okc_enabled);
		} else {
			status = QDF_STATUS_E_INVAL;
		}
		sme_release_global_lock(&mac_ctx->sme);
	}

	return status;
}
#endif

/* ---------------------------------------------------------------------------
   \fn sme_get_temperature
   \brief SME API to get the pdev temperature
   \param hHal
   \param temperature context
   \param pCallbackfn: callback fn with response (temperature)
   \- return QDF_STATUS
   -------------------------------------------------------------------------*/
QDF_STATUS sme_get_temperature(tHalHandle hHal,
			       void *tempContext,
			       void (*pCallbackfn)(int temperature,
						   void *pContext))
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	cds_msg_t cds_message;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_STATUS_SUCCESS == status) {
		if ((NULL == pCallbackfn) &&
		    (NULL == pMac->sme.pGetTemperatureCb)) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				  FL
					  ("Indication Call back did not registered"));
			sme_release_global_lock(&pMac->sme);
			return QDF_STATUS_E_FAILURE;
		} else if (NULL != pCallbackfn) {
			pMac->sme.pTemperatureCbContext = tempContext;
			pMac->sme.pGetTemperatureCb = pCallbackfn;
		}
		/* serialize the req through MC thread */
		cds_message.bodyptr = NULL;
		cds_message.type = WMA_GET_TEMPERATURE_REQ;
		qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				  FL("Post Get Temperature msg fail"));
			status = QDF_STATUS_E_FAILURE;
		}
		sme_release_global_lock(&pMac->sme);
	}
	return status;
}

/* ---------------------------------------------------------------------------
    \fn sme_set_scanning_mac_oui
    \brief  SME API to set scanning mac oui
    \param  hHal
    \param  pScanMacOui: Scanning Mac Oui (input 3 bytes)
   \- return QDF_STATUS
    -------------------------------------------------------------------------*/
QDF_STATUS sme_set_scanning_mac_oui(tHalHandle hHal, tSirScanMacOui *pScanMacOui)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	cds_msg_t cds_message;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_STATUS_SUCCESS == status) {
		/* Serialize the req through MC thread */
		cds_message.bodyptr = pScanMacOui;
		cds_message.type = WMA_SET_SCAN_MAC_OUI_REQ;
		qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				  FL("Msg post Set Scan Mac OUI failed"));
			status = QDF_STATUS_E_FAILURE;
		}
		sme_release_global_lock(&pMac->sme);
	}
	return status;
}

#ifdef DHCP_SERVER_OFFLOAD
/* ---------------------------------------------------------------------------
    \fn sme_set_dhcp_srv_offload
    \brief  SME API to set DHCP server offload info
    \param  hHal
    \param  pDhcpSrvInfo : DHCP server offload info struct
   \- return QDF_STATUS
    -------------------------------------------------------------------------*/
QDF_STATUS sme_set_dhcp_srv_offload(tHalHandle hHal,
				    tSirDhcpSrvOffloadInfo *pDhcpSrvInfo)
{
	cds_msg_t cds_message;
	tSirDhcpSrvOffloadInfo *pSmeDhcpSrvInfo;
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

	pSmeDhcpSrvInfo = qdf_mem_malloc(sizeof(*pSmeDhcpSrvInfo));

	if (!pSmeDhcpSrvInfo) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "%s: Not able to allocate memory for WMA_SET_DHCP_SERVER_OFFLOAD_CMD",
			  __func__);
		return QDF_STATUS_E_NOMEM;
	}

	*pSmeDhcpSrvInfo = *pDhcpSrvInfo;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_STATUS_SUCCESS == status) {
		/* serialize the req through MC thread */
		cds_message.type = WMA_SET_DHCP_SERVER_OFFLOAD_CMD;
		cds_message.bodyptr = pSmeDhcpSrvInfo;

		if (!QDF_IS_STATUS_SUCCESS
			    (cds_mq_post_message(QDF_MODULE_ID_WMA, &cds_message))) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				  "%s: Not able to post WMA_SET_DHCP_SERVER_OFFLOAD_CMD to WMA!",
				  __func__);
			qdf_mem_free(pSmeDhcpSrvInfo);
			status = QDF_STATUS_E_FAILURE;
		}
		sme_release_global_lock(&pMac->sme);
	} else {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "%s: sme_acquire_global_lock error!", __func__);
		qdf_mem_free(pSmeDhcpSrvInfo);
	}

	return status;
}
#endif /* DHCP_SERVER_OFFLOAD */

#ifdef WLAN_FEATURE_GPIO_LED_FLASHING
/* ---------------------------------------------------------------------------
    \fn sme_set_led_flashing
    \brief  API to set the Led flashing parameters.
    \param  hHal - The handle returned by mac_open.
    \param  x0, x1 -  led flashing parameters
    \return QDF_STATUS
   ---------------------------------------------------------------------------*/
QDF_STATUS sme_set_led_flashing(tHalHandle hHal, uint8_t type,
				uint32_t x0, uint32_t x1)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	cds_msg_t cds_message;
	tSirLedFlashingReq *ledflashing;

	ledflashing = qdf_mem_malloc(sizeof(*ledflashing));
	if (!ledflashing) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  FL
				  ("Not able to allocate memory for WMA_LED_TIMING_REQ"));
		return QDF_STATUS_E_NOMEM;
	}

	ledflashing->pattern_id = type;
	ledflashing->led_x0 = x0;
	ledflashing->led_x1 = x1;

	status = sme_acquire_global_lock(&pMac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		/* Serialize the req through MC thread */
		cds_message.bodyptr = ledflashing;
		cds_message.type = WMA_LED_FLASHING_REQ;
		qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
			status = QDF_STATUS_E_FAILURE;
		sme_release_global_lock(&pMac->sme);
	}
	return status;
}
#endif

/**
 *  sme_handle_dfS_chan_scan() - handle DFS channel configuration
 *  @h_hal:         corestack handler
 *  @dfs_flag:      flag indicating dfs channel enable/disable
 *  Return:         QDF_STATUS
 */
QDF_STATUS sme_handle_dfs_chan_scan(tHalHandle h_hal, uint8_t dfs_flag)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal mac  = PMAC_STRUCT(h_hal);

	status = sme_acquire_global_lock(&mac->sme);

	if (QDF_STATUS_SUCCESS == status) {

		mac->scan.fEnableDFSChnlScan = dfs_flag;

		/* update the channel list to the firmware */
		status = csr_update_channel_list(mac);

		sme_release_global_lock(&mac->sme);
	}

	return status;
}

#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
/**
 * sme_validate_sap_channel_switch() - validate target channel switch w.r.t
 *      concurreny rules set to avoid channel interference.
 * @hal - Hal context
 * @sap_ch - channel to switch
 * @sap_phy_mode - phy mode of SAP
 * @cc_switch_mode - concurreny switch mode
 * @session_id - sme session id.
 *
 * Return: true if there is no channel interference else return false
 */
bool sme_validate_sap_channel_switch(tHalHandle hal,
	uint16_t sap_ch, eCsrPhyMode sap_phy_mode, uint8_t cc_switch_mode,
	uint8_t session_id)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal mac = PMAC_STRUCT(hal);
	tCsrRoamSession *session = CSR_GET_SESSION(mac, session_id);
	uint16_t intf_channel = 0;

	if (!session)
		return false;

	session->ch_switch_in_progress = true;
	status = sme_acquire_global_lock(&mac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		intf_channel = csr_check_concurrent_channel_overlap(mac, sap_ch,
						sap_phy_mode,
						cc_switch_mode);
		sme_release_global_lock(&mac->sme);
	} else {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				FL("sme_acquire_global_lock error!"));
		session->ch_switch_in_progress = false;
		return false;
	}

	session->ch_switch_in_progress = false;
	return (intf_channel == 0) ? true : false;
}
#endif

/**
 * sme_configure_stats_avg_factor() - function to config avg. stats factor
 * @hal: hal
 * @session_id: session ID
 * @stats_avg_factor: average stats factor
 *
 * This function configures the stats avg factor in firmware
 *
 * Return: QDF_STATUS
 */
QDF_STATUS sme_configure_stats_avg_factor(tHalHandle hal, uint8_t session_id,
					  uint16_t stats_avg_factor)
{
	cds_msg_t msg;
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal mac  = PMAC_STRUCT(hal);
	struct sir_stats_avg_factor *stats_factor;

	stats_factor = qdf_mem_malloc(sizeof(*stats_factor));

	if (!stats_factor) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "%s: Not able to allocate memory for SIR_HAL_CONFIG_STATS_FACTOR",
			  __func__);
		return QDF_STATUS_E_NOMEM;
	}

	status = sme_acquire_global_lock(&mac->sme);

	if (QDF_STATUS_SUCCESS == status) {

		stats_factor->vdev_id = session_id;
		stats_factor->stats_avg_factor = stats_avg_factor;

		/* serialize the req through MC thread */
		msg.type     = SIR_HAL_CONFIG_STATS_FACTOR;
		msg.bodyptr  = stats_factor;

		if (!QDF_IS_STATUS_SUCCESS(
			    cds_mq_post_message(QDF_MODULE_ID_WMA, &msg))) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				  "%s: Not able to post SIR_HAL_CONFIG_STATS_FACTOR to WMA!",
				  __func__);
			qdf_mem_free(stats_factor);
			status = QDF_STATUS_E_FAILURE;
		}
		sme_release_global_lock(&mac->sme);
	} else {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "%s: sme_acquire_global_lock error!",
			  __func__);
		qdf_mem_free(stats_factor);
	}

	return status;
}

/**
 * sme_configure_guard_time() - function to configure guard time
 * @hal: hal
 * @session_id: session id
 * @guard_time: guard time
 *
 * This function configures the guard time in firmware
 *
 * Return: QDF_STATUS
 */
QDF_STATUS sme_configure_guard_time(tHalHandle hal, uint8_t session_id,
				    uint32_t guard_time)
{
	cds_msg_t msg;
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal mac  = PMAC_STRUCT(hal);
	struct sir_guard_time_request *g_time;

	g_time = qdf_mem_malloc(sizeof(*g_time));

	if (!g_time) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "%s: Not able to allocate memory for SIR_HAL_CONFIG_GUARD_TIME",
			  __func__);
		return QDF_STATUS_E_NOMEM;
	}

	status = sme_acquire_global_lock(&mac->sme);

	if (QDF_STATUS_SUCCESS == status) {

		g_time->vdev_id = session_id;
		g_time->guard_time = guard_time;

		/* serialize the req through MC thread */
		msg.type     = SIR_HAL_CONFIG_GUARD_TIME;
		msg.bodyptr  = g_time;

		if (!QDF_IS_STATUS_SUCCESS(
			    cds_mq_post_message(QDF_MODULE_ID_WMA, &msg))) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				  "%s: Not able to post SIR_HAL_CONFIG_GUARD_TIME to WMA!",
				  __func__);
			qdf_mem_free(g_time);
			status = QDF_STATUS_E_FAILURE;
		}
		sme_release_global_lock(&mac->sme);
	} else {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "%s: sme_acquire_global_lock error!",
			  __func__);
		qdf_mem_free(g_time);
	}

	return status;
}

/**
 * sme_configure_modulated_dtim() - function to configure modulated dtim
 * @h_hal: SME API to enable/disable modulated DTIM instantaneously
 * @session_id: session ID
 * @modulated_dtim: modulated dtim value
 *
 * This function configures the modulated dtim in firmware
 *
 * Return: QDF_STATUS
 */
QDF_STATUS sme_configure_modulated_dtim(tHalHandle h_hal, uint8_t session_id,
					uint32_t modulated_dtim)
{
	cds_msg_t msg;
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal mac  = PMAC_STRUCT(h_hal);
	wma_cli_set_cmd_t *iwcmd;

	iwcmd = qdf_mem_malloc(sizeof(*iwcmd));
	if (NULL == iwcmd) {
		QDF_TRACE(QDF_MODULE_ID_SME,
			  QDF_TRACE_LEVEL_FATAL,
			  "%s: qdf_mem_malloc failed", __func__);
		return QDF_STATUS_E_NOMEM;
	}

	status = sme_acquire_global_lock(&mac->sme);

	if (QDF_STATUS_SUCCESS == status) {

		qdf_mem_zero((void *)iwcmd, sizeof(*iwcmd));
		iwcmd->param_value = modulated_dtim;
		iwcmd->param_vdev_id = session_id;
		iwcmd->param_id = GEN_PARAM_MODULATED_DTIM;
		iwcmd->param_vp_dev = GEN_CMD;
		msg.type = WMA_CLI_SET_CMD;
		msg.reserved = 0;
		msg.bodyptr = (void *)iwcmd;

		if (!QDF_IS_STATUS_SUCCESS(
			    cds_mq_post_message(QDF_MODULE_ID_WMA, &msg))) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				  "%s: Not able to post GEN_PARAM_DYNAMIC_DTIM to WMA!",
				  __func__);
			qdf_mem_free(iwcmd);
			status = QDF_STATUS_E_FAILURE;
		}
		sme_release_global_lock(&mac->sme);
	} else {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "%s: sme_acquire_global_lock error!",
			  __func__);
		qdf_mem_free(iwcmd);
	}

	return status;
}

/*
 * sme_wifi_start_logger() - Send the start/stop logging command to WMA
 * to either start/stop logging
 * @hal: HAL context
 * @start_log: Structure containing the wifi start logger params
 *
 * This function sends the start/stop logging command to WMA
 *
 * Return: QDF_STATUS_SUCCESS on successful posting
 */
QDF_STATUS sme_wifi_start_logger(tHalHandle hal,
		struct sir_wifi_start_log start_log)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal mac   = PMAC_STRUCT(hal);
	cds_msg_t cds_message;
	struct sir_wifi_start_log *req_msg;
	uint32_t len;

	len = sizeof(*req_msg);
	req_msg = qdf_mem_malloc(len);
	if (!req_msg) {
		sms_log(mac, LOGE, FL("qdf_mem_malloc failed"));
		return QDF_STATUS_E_NOMEM;
	}

	qdf_mem_zero(req_msg, len);

	req_msg->verbose_level = start_log.verbose_level;
	req_msg->flag = start_log.flag;
	req_msg->ring_id = start_log.ring_id;
	req_msg->ini_triggered = start_log.ini_triggered;
	req_msg->user_triggered = start_log.user_triggered;

	status = sme_acquire_global_lock(&mac->sme);
	if (status != QDF_STATUS_SUCCESS) {
		sms_log(mac, LOGE,
			FL("sme_acquire_global_lock failed(status=%d)"),
			status);
		qdf_mem_free(req_msg);
		return status;
	}

	/* Serialize the req through MC thread */
	cds_message.bodyptr = req_msg;
	cds_message.type    = SIR_HAL_START_STOP_LOGGING;
	status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		sms_log(mac, LOGE,
			FL("cds_mq_post_message failed!(err=%d)"),
			status);
		qdf_mem_free(req_msg);
		status = QDF_STATUS_E_FAILURE;
	}
	sme_release_global_lock(&mac->sme);

	return status;
}

/**
 * sme_neighbor_middle_of_roaming() - Function to know if
 * STA is in the middle of roaming states
 * @hal:                Handle returned by macOpen
 * @sessionId: sessionId of the STA session
 *
 * This function is a wrapper to call
 * csr_neighbor_middle_of_roaming to know STA is in the
 * middle of roaming states
 *
 * Return: True or False
 *
 */
bool sme_neighbor_middle_of_roaming(tHalHandle hHal, uint8_t sessionId)
{
	return csr_neighbor_middle_of_roaming(PMAC_STRUCT(hHal), sessionId);
}

/*
 * sme_send_flush_logs_cmd_to_fw() - Flush FW logs
 * @mac: MAC handle
 *
 * This function is used to send the command that will
 * be used to flush the logs in the firmware
 *
 * Return: QDF_STATUS
 */
QDF_STATUS sme_send_flush_logs_cmd_to_fw(tpAniSirGlobal mac)
{
	QDF_STATUS status;
	cds_msg_t message;

	status = sme_acquire_global_lock(&mac->sme);
	if (status != QDF_STATUS_SUCCESS) {
		sms_log(mac, LOGE,
			FL("sme_acquire_global_lock failed!(status=%d)"),
			status);
		return status;
	}

	/* Serialize the req through MC thread */
	message.bodyptr = NULL;
	message.type    = SIR_HAL_FLUSH_LOG_TO_FW;
	status = cds_mq_post_message(CDS_MQ_ID_WMA, &message);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		sms_log(mac, LOGE,
			FL("cds_mq_post_message failed!(err=%d)"),
			status);
		status = QDF_STATUS_E_FAILURE;
	}
	sme_release_global_lock(&mac->sme);
	return status;
}

/**
 * sme_enable_uapsd_for_ac() - enable uapsd for access catagory requerst to WMA
 * @cds_ctx: cds context
 * @sta_id: station id
 * @ac: access catagory
 * @tid: tid value
 * @pri: user priority
 * @srvc_int: service interval
 * @sus_int: suspend interval
 * @dir: tspec direction
 * @psb: PSB value
 * @sessionId: session id
 * @delay_interval: delay interval
 *
 * Return: QDF status
 */
QDF_STATUS sme_enable_uapsd_for_ac(void *cds_ctx, uint8_t sta_id,
				   sme_ac_enum_type ac, uint8_t tid,
				   uint8_t pri, uint32_t srvc_int,
				   uint32_t sus_int,
				   sme_tspec_dir_type dir,
				   uint8_t psb, uint32_t sessionId,
				   uint32_t delay_interval)
{
	void *wma_handle;
	t_wma_trigger_uapsd_params uapsd_params;
	enum uapsd_ac access_category;

	if (!psb) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
			"No need to configure auto trigger:psb is 0");
		return QDF_STATUS_SUCCESS;
	}

	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
	if (!wma_handle) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
					"wma_handle is NULL");
		return QDF_STATUS_E_FAILURE;
	}

	switch (ac) {
	case SME_AC_BK:
		access_category = UAPSD_BK;
		break;
	case SME_AC_BE:
		access_category = UAPSD_BE;
		break;
	case SME_AC_VI:
		access_category = UAPSD_VI;
		break;
	case SME_AC_VO:
		access_category = UAPSD_VO;
		break;
	default:
		return QDF_STATUS_E_FAILURE;
	}

	uapsd_params.wmm_ac = access_category;
	uapsd_params.user_priority = pri;
	uapsd_params.service_interval = srvc_int;
	uapsd_params.delay_interval = delay_interval;
	uapsd_params.suspend_interval = sus_int;

	if (QDF_STATUS_SUCCESS !=
	    wma_trigger_uapsd_params(wma_handle, sessionId, &uapsd_params)) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			"Failed to Trigger Uapsd params for sessionId %d",
			    sessionId);
		return QDF_STATUS_E_FAILURE;
	}
	return QDF_STATUS_SUCCESS;
}

/**
 * sme_disable_uapsd_for_ac() - disable uapsed access catagory request to WMA
 * @cds_ctx: cds context
 * @sta_id: station id
 * @ac: access catagory
 * @sessionId: session id
 *
 * Return: QDF status
 */
QDF_STATUS sme_disable_uapsd_for_ac(void *cds_ctx, uint8_t sta_id,
				       sme_ac_enum_type ac,
				       uint32_t sessionId)
{
	void *wma_handle;
	enum uapsd_ac access_category;

	switch (ac) {
	case SME_AC_BK:
		access_category = UAPSD_BK;
		break;
	case SME_AC_BE:
		access_category = UAPSD_BE;
		break;
	case SME_AC_VI:
		access_category = UAPSD_VI;
		break;
	case SME_AC_VO:
		access_category = UAPSD_VO;
		break;
	default:
		return QDF_STATUS_E_FAILURE;
	}

	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
	if (!wma_handle) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				"wma handle is NULL");
		return QDF_STATUS_E_FAILURE;
	}
	if (QDF_STATUS_SUCCESS !=
	    wma_disable_uapsd_per_ac(wma_handle, sessionId, access_category)) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			"Failed to disable uapsd for ac %d for sessionId %d",
			    ac, sessionId);
		return QDF_STATUS_E_FAILURE;
	}
	return QDF_STATUS_SUCCESS;
}

/**
 * sme_update_nss() - SME API to change the number for spatial streams
 * (1 or 2)
 * @hal: Handle returned by mac open
 * @nss: Number of spatial streams
 *
 * This function is used to update the number of spatial streams supported.
 *
 * Return: Success upon successfully changing nss else failure
 *
 */
QDF_STATUS sme_update_nss(tHalHandle h_hal, uint8_t nss)
{
	QDF_STATUS status;
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(h_hal);
	uint32_t i, value = 0;
	union {
		uint16_t cfg_value16;
		tSirMacHTCapabilityInfo ht_cap_info;
	} uHTCapabilityInfo;
	tCsrRoamSession *csr_session;

	status = sme_acquire_global_lock(&mac_ctx->sme);

	if (QDF_STATUS_SUCCESS == status) {
		mac_ctx->roam.configParam.enable2x2 = (nss == 1) ? 0 : 1;

		/* get the HT capability info*/
		sme_cfg_get_int(mac_ctx, WNI_CFG_HT_CAP_INFO, &value);
		uHTCapabilityInfo.cfg_value16 = (0xFFFF & value);

		for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
			if (CSR_IS_SESSION_VALID(mac_ctx, i)) {
				csr_session = &mac_ctx->roam.roamSession[i];
				csr_session->htConfig.ht_tx_stbc =
					uHTCapabilityInfo.ht_cap_info.txSTBC;
			}
		}

		sme_release_global_lock(&mac_ctx->sme);
	}
	return status;
}

/**
 * sme_update_user_configured_nss() - sets the nss based on user request
 * @hal: Pointer to HAL
 * @nss: number of streams
 *
 * Return: None
 */
void sme_update_user_configured_nss(tHalHandle hal, uint8_t nss)
{
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);

	mac_ctx->user_configured_nss = nss;
}

/**
 * sme_set_rssi_threshold_breached_cb() - set rssi threshold breached callback
 * @h_hal: global hal handle
 * @cb: callback function pointer
 *
 * This function stores the rssi threshold breached callback function.
 *
 * Return: QDF_STATUS enumeration.
 */
QDF_STATUS sme_set_rssi_threshold_breached_cb(tHalHandle h_hal,
				void (*cb)(void *, struct rssi_breach_event *))
{
	QDF_STATUS status  = QDF_STATUS_SUCCESS;
	tpAniSirGlobal mac;

	if (!h_hal) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				  FL("hHal is not valid"));
		return QDF_STATUS_E_INVAL;
	}
	mac = PMAC_STRUCT(h_hal);

	status = sme_acquire_global_lock(&mac->sme);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			FL("sme_acquire_global_lock failed!(status=%d)"),
			status);
		return status;
	}

	mac->sme.rssi_threshold_breached_cb = cb;
	sme_release_global_lock(&mac->sme);
	return status;
}

/**
 * sme_set_rssi_threshold_breached_cb() - Reset rssi threshold breached callback
 * @hal: global hal handle
 *
 * This function de-registers the rssi threshold breached callback function.
 *
 * Return: QDF_STATUS enumeration.
 */
QDF_STATUS sme_reset_rssi_threshold_breached_cb(tHalHandle hal)
{
	QDF_STATUS status;
	tpAniSirGlobal mac = PMAC_STRUCT(hal);

	status = sme_acquire_global_lock(&mac->sme);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		sms_log(mac, LOGE,
			FL("sme_acquire_global_lock failed!(status=%d)"),
			status);
		return status;
	}

	mac->sme.rssi_threshold_breached_cb = NULL;
	sme_release_global_lock(&mac->sme);
	return status;
}

/**
 * sme_is_any_session_in_connected_state() - SME wrapper API to
 * check if any session is in connected state or not.
 *
 * @hal: Handle returned by mac open
 *
 * This function is used to check if any valid sme session is in
 * connected state or not.
 *
 * Return: true if any session is connected, else false.
 *
 */
bool sme_is_any_session_in_connected_state(tHalHandle h_hal)
{
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(h_hal);
	QDF_STATUS status;
	bool ret = false;

	status = sme_acquire_global_lock(&mac_ctx->sme);
	if (QDF_STATUS_SUCCESS == status) {
		ret = csr_is_any_session_in_connect_state(mac_ctx);
		sme_release_global_lock(&mac_ctx->sme);
	}
	return ret;
}

/**
 * sme_set_rssi_monitoring() - set rssi monitoring
 * @hal: global hal handle
 * @input: request message
 *
 * This function constructs the vos message and fill in message type,
 * bodyptr with @input and posts it to WDA queue.
 *
 * Return: QDF_STATUS enumeration
 */
QDF_STATUS sme_set_rssi_monitoring(tHalHandle hal,
				struct rssi_monitor_req *input)
{
	QDF_STATUS status     = QDF_STATUS_SUCCESS;
	tpAniSirGlobal mac    = PMAC_STRUCT(hal);
	cds_msg_t cds_message;
	struct rssi_monitor_req *req_msg;

	sms_log(mac, LOG1, FL("enter"));
	req_msg = qdf_mem_malloc(sizeof(*req_msg));
	if (!req_msg) {
		sms_log(mac, LOGE, FL("memory allocation failed"));
		return QDF_STATUS_E_NOMEM;
	}

	*req_msg = *input;

	status = sme_acquire_global_lock(&mac->sme);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		sms_log(mac, LOGE,
			FL("sme_acquire_global_lock failed!(status=%d)"),
			status);
		qdf_mem_free(req_msg);
		return status;
	}

	/* Serialize the req through MC thread */
	cds_message.bodyptr = req_msg;
	cds_message.type    = WMA_SET_RSSI_MONITOR_REQ;
	status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		sms_log(mac, LOGE,
			FL("cds_mq_post_message failed!(err=%d)"),
			status);
		qdf_mem_free(req_msg);
	}
	sme_release_global_lock(&mac->sme);

	return status;
}

/**
 * sme_fw_mem_dump() - Get FW memory dump
 * @hHal: hal handle
 * @recvd_req: received memory dump request.
 *
 * This API is invoked by HDD to indicate FW to start
 * dumping firmware memory.
 *
 * Return: QDF_STATUS
 */
#ifdef WLAN_FEATURE_MEMDUMP
QDF_STATUS sme_fw_mem_dump(tHalHandle hHal, void *recvd_req)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	cds_msg_t msg;
	struct fw_dump_req *send_req;
	struct fw_dump_seg_req seg_req;
	int loop;

	send_req = qdf_mem_malloc(sizeof(*send_req));
	if (!send_req) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			FL("Memory allocation failed for WDA_FW_MEM_DUMP"));
		return QDF_STATUS_E_FAILURE;
	}
	qdf_mem_copy(send_req, recvd_req, sizeof(*send_req));

	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
		  FL("request_id:%d num_seg:%d"),
		  send_req->request_id, send_req->num_seg);
	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
		  FL("Segment Information"));
	for (loop = 0; loop < send_req->num_seg; loop++) {
		seg_req = send_req->segment[loop];
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
			  FL("seg_number:%d"), loop);
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
			  FL("seg_id:%d start_addr_lo:0x%x start_addr_hi:0x%x"),
			  seg_req.seg_id, seg_req.seg_start_addr_lo,
			  seg_req.seg_start_addr_hi);
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
			  FL("seg_length:%d dst_addr_lo:0x%x dst_addr_hi:0x%x"),
			  seg_req.seg_length, seg_req.dst_addr_lo,
			  seg_req.dst_addr_hi);
	}

	if (QDF_STATUS_SUCCESS == sme_acquire_global_lock(&pMac->sme)) {
		msg.bodyptr = send_req;
		msg.type = WMA_FW_MEM_DUMP_REQ;
		msg.reserved = 0;

		qdf_status = cds_mq_post_message(QDF_MODULE_ID_WMA, &msg);
		if (QDF_STATUS_SUCCESS != qdf_status) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				  FL("Not able to post WMA_FW_MEM_DUMP"));
			qdf_mem_free(send_req);
			status = QDF_STATUS_E_FAILURE;
		}
		sme_release_global_lock(&pMac->sme);
	} else {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			FL("Failed to acquire SME Global Lock"));
		qdf_mem_free(send_req);
		status = QDF_STATUS_E_FAILURE;
	}

	return status;
}
#else
QDF_STATUS sme_fw_mem_dump(tHalHandle hHal, void *recvd_req)
{
	return QDF_STATUS_SUCCESS;
}
#endif /* WLAN_FEATURE_MEMDUMP */

/*
 * sme_pdev_set_pcl() - Send WMI_PDEV_SET_PCL_CMDID to the WMA
 * @hal: Handle returned by macOpen
 * @msg: PCL channel list and length structure
 *
 * Sends the command to WMA to send WMI_PDEV_SET_PCL_CMDID to FW
 * Return: QDF_STATUS_SUCCESS on successful posting
 */
QDF_STATUS sme_pdev_set_pcl(tHalHandle hal,
		struct sir_pcl_list msg)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal mac   = PMAC_STRUCT(hal);
	cds_msg_t cds_message;
	struct wmi_pcl_chan_weights *req_msg;
	uint32_t len, i;

	len = sizeof(*req_msg);

	req_msg = qdf_mem_malloc(len);
	if (!req_msg) {
		sms_log(mac, LOGE, FL("qdf_mem_malloc failed"));
		return QDF_STATUS_E_NOMEM;
	}

	qdf_mem_zero(req_msg, len);

	for (i = 0; i < msg.pcl_len; i++) {
		req_msg->pcl_list[i] =  msg.pcl_list[i];
		req_msg->weight_list[i] =  msg.weight_list[i];
	}

	req_msg->pcl_len = msg.pcl_len;

	status = sme_acquire_global_lock(&mac->sme);
	if (status != QDF_STATUS_SUCCESS) {
		sms_log(mac, LOGE,
			FL("sme_acquire_global_lock failed!(status=%d)"),
			status);
		qdf_mem_free(req_msg);
		return status;
	}

	/* Serialize the req through MC thread */
	cds_message.bodyptr = req_msg;
	cds_message.type    = SIR_HAL_PDEV_SET_PCL_TO_FW;
	status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		sms_log(mac, LOGE,
				FL("cds_mq_post_message failed!(err=%d)"),
				status);
		qdf_mem_free(req_msg);
		status = QDF_STATUS_E_FAILURE;
	}
	sme_release_global_lock(&mac->sme);

	return status;
}

/*
 * sme_pdev_set_hw_mode() - Send WMI_PDEV_SET_HW_MODE_CMDID to the WMA
 * @hal: Handle returned by macOpen
 * @msg: HW mode structure containing hw mode and callback details
 *
 * Sends the command to CSR to send WMI_PDEV_SET_HW_MODE_CMDID to FW
 * Return: QDF_STATUS_SUCCESS on successful posting
 */
QDF_STATUS sme_pdev_set_hw_mode(tHalHandle hal,
		struct sir_hw_mode msg)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal mac = PMAC_STRUCT(hal);
	tSmeCmd *cmd = NULL;

	status = sme_acquire_global_lock(&mac->sme);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		sms_log(mac, LOGE, FL("Failed to acquire lock"));
		return QDF_STATUS_E_RESOURCES;
	}

	cmd = sme_get_command_buffer(mac);
	if (!cmd) {
		sms_log(mac, LOGE, FL("Get command buffer failed"));
		sme_release_global_lock(&mac->sme);
		return QDF_STATUS_E_NULL_VALUE;
	}

	cmd->command = e_sme_command_set_hw_mode;
	cmd->u.set_hw_mode_cmd.hw_mode_index = msg.hw_mode_index;
	cmd->u.set_hw_mode_cmd.set_hw_mode_cb = msg.set_hw_mode_cb;
	cmd->u.set_hw_mode_cmd.reason = msg.reason;
	cmd->u.set_hw_mode_cmd.session_id = msg.session_id;

	sms_log(mac, LOG1,
		FL("Queuing set hw mode to CSR, session:%d reason:%d"),
		cmd->u.set_hw_mode_cmd.session_id,
		cmd->u.set_hw_mode_cmd.reason);
	csr_queue_sme_command(mac, cmd, false);

	sme_release_global_lock(&mac->sme);
	return QDF_STATUS_SUCCESS;
}

/**
 * sme_register_hw_mode_trans_cb() - HW mode transition callback registration
 * @hal: Handle returned by macOpen
 * @callback: HDD callback to be registered
 *
 * Registers the HDD callback with SME. This callback will be invoked when
 * HW mode transition event is received from the FW
 *
 * Return: None
 */
void sme_register_hw_mode_trans_cb(tHalHandle hal,
			hw_mode_transition_cb callback)
{
	tpAniSirGlobal mac = PMAC_STRUCT(hal);

	mac->sme.sme_hw_mode_trans_cb = callback;
	sms_log(mac, LOG1, FL("HW mode transition callback registered"));
}

/**
 * sme_nss_update_request() - Send beacon templete update to FW with new
 * nss value
 * @hal: Handle returned by macOpen
 * @vdev_id: the session id
 * @new_nss: the new nss value
 * @cback: hdd callback
 * @next_action: next action to happen at policy mgr after beacon update
 *
 * Sends the command to CSR to send to PE
 * Return: QDF_STATUS_SUCCESS on successful posting
 */
QDF_STATUS sme_nss_update_request(tHalHandle hHal, uint32_t vdev_id,
				uint8_t  new_nss, void *cback, uint8_t next_action,
				void *hdd_context,
				enum sir_conn_update_reason reason)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	tpAniSirGlobal mac = PMAC_STRUCT(hHal);
	tSmeCmd *cmd = NULL;

	status = sme_acquire_global_lock(&mac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		cmd = sme_get_command_buffer(mac);
		if (!cmd) {
			sms_log(mac, LOGE, FL("Get command buffer failed"));
			sme_release_global_lock(&mac->sme);
			return QDF_STATUS_E_NULL_VALUE;
		}
		cmd->command = e_sme_command_nss_update;
		/* Sessionized modules may require this info */
		cmd->sessionId = vdev_id;
		cmd->u.nss_update_cmd.new_nss = new_nss;
		cmd->u.nss_update_cmd.session_id = vdev_id;
		cmd->u.nss_update_cmd.nss_update_cb = cback;
		cmd->u.nss_update_cmd.context = hdd_context;
		cmd->u.nss_update_cmd.next_action = next_action;
		cmd->u.nss_update_cmd.reason = reason;

		sms_log(mac, LOG1, FL("Queuing e_sme_command_nss_update to CSR"));
		csr_queue_sme_command(mac, cmd, false);
		sme_release_global_lock(&mac->sme);
	}
	return status;
}

/**
 * sme_soc_set_dual_mac_config() - Set dual mac configurations
 * @hal: Handle returned by macOpen
 * @msg: Structure containing the dual mac config parameters
 *
 * Queues configuration information to CSR to configure
 * WLAN firmware for the dual MAC features
 *
 * Return: QDF_STATUS
 */
QDF_STATUS sme_soc_set_dual_mac_config(tHalHandle hal,
		struct sir_dual_mac_config msg)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal mac = PMAC_STRUCT(hal);
	tSmeCmd *cmd;

	status = sme_acquire_global_lock(&mac->sme);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		sms_log(mac, LOGE, FL("Failed to acquire lock"));
		return QDF_STATUS_E_RESOURCES;
	}

	cmd = sme_get_command_buffer(mac);
	if (!cmd) {
		sms_log(mac, LOGE, FL("Get command buffer failed"));
		sme_release_global_lock(&mac->sme);
		return QDF_STATUS_E_NULL_VALUE;
	}

	cmd->command = e_sme_command_set_dual_mac_config;
	cmd->u.set_dual_mac_cmd.scan_config = msg.scan_config;
	cmd->u.set_dual_mac_cmd.fw_mode_config = msg.fw_mode_config;
	cmd->u.set_dual_mac_cmd.set_dual_mac_cb = msg.set_dual_mac_cb;

	sms_log(mac, LOG1,
		FL("Queuing e_sme_command_set_dual_mac_config to CSR: %x %x"),
		cmd->u.set_dual_mac_cmd.scan_config,
		cmd->u.set_dual_mac_cmd.fw_mode_config);
	csr_queue_sme_command(mac, cmd, false);

	sme_release_global_lock(&mac->sme);
	return QDF_STATUS_SUCCESS;
}

#ifdef FEATURE_LFR_SUBNET_DETECTION
/**
 * sme_gateway_param_update() - to update gateway parameters with WMA
 * @Hal: hal handle
 * @gw_params: request parameters from HDD
 *
 * Return: QDF_STATUS
 *
 * This routine will update gateway parameters to WMA
 */
QDF_STATUS sme_gateway_param_update(tHalHandle Hal,
			      struct gateway_param_update_req *gw_params)
{
	QDF_STATUS qdf_status;
	cds_msg_t cds_message;
	struct gateway_param_update_req *request_buf;

	request_buf = qdf_mem_malloc(sizeof(*request_buf));
	if (NULL == request_buf) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			FL("Not able to allocate memory for gw param update request"));
		return QDF_STATUS_E_NOMEM;
	}

	*request_buf = *gw_params;

	cds_message.type = WMA_GW_PARAM_UPDATE_REQ;
	cds_message.reserved = 0;
	cds_message.bodyptr = request_buf;
	qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			FL("Not able to post WMA_GW_PARAM_UPDATE_REQ message to HAL"));
		qdf_mem_free(request_buf);
		return QDF_STATUS_E_FAILURE;
	}

	return QDF_STATUS_SUCCESS;
}
#endif /* FEATURE_LFR_SUBNET_DETECTION */

/**
 * sme_soc_set_antenna_mode() - set antenna mode
 * @hal: Handle returned by macOpen
 * @msg: Structure containing the antenna mode parameters
 *
 * Send the command to CSR to send
 * WMI_SOC_SET_ANTENNA_MODE_CMDID to FW
 *
 * Return: QDF_STATUS
 */
QDF_STATUS sme_soc_set_antenna_mode(tHalHandle hal,
				struct sir_antenna_mode_param *msg)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal mac = PMAC_STRUCT(hal);
	tSmeCmd *cmd;

	if (NULL == msg) {
		sms_log(mac, LOGE, FL("antenna mode mesg is NULL"));
		return QDF_STATUS_E_FAILURE;
	}

	status = sme_acquire_global_lock(&mac->sme);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		sms_log(mac, LOGE, FL("Failed to acquire lock"));
		return QDF_STATUS_E_RESOURCES;
	}

	cmd = sme_get_command_buffer(mac);
	if (!cmd) {
		sme_release_global_lock(&mac->sme);
		sms_log(mac, LOGE, FL("Get command buffer failed"));
		return QDF_STATUS_E_NULL_VALUE;
	}

	cmd->command = e_sme_command_set_antenna_mode;
	cmd->u.set_antenna_mode_cmd = *msg;

	sms_log(mac, LOG1,
		FL("Queuing e_sme_command_set_antenna_mode to CSR: %d %d"),
		cmd->u.set_antenna_mode_cmd.num_rx_chains,
		cmd->u.set_antenna_mode_cmd.num_tx_chains);

	csr_queue_sme_command(mac, cmd, false);
	sme_release_global_lock(&mac->sme);

	return QDF_STATUS_SUCCESS;
}

/**
 * sme_set_peer_authorized() - call peer authorized callback
 * @peer_addr: peer mac address
 * @auth_cb: auth callback
 * @vdev_id: vdev id
 *
 * Return: QDF Status
 */
QDF_STATUS sme_set_peer_authorized(uint8_t *peer_addr,
				   sme_peer_authorized_fp auth_cb,
				   uint32_t vdev_id)
{
	void *wma_handle;

	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
	if (!wma_handle) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				"wma handle is NULL");
		return QDF_STATUS_E_FAILURE;
	}

	wma_set_peer_authorized_cb(wma_handle, auth_cb);
	return wma_set_peer_param(wma_handle, peer_addr, WMI_PEER_AUTHORIZE,
				  1, vdev_id);
}

/*
 * sme_handle_set_fcc_channel() - set spec. tx power for non-fcc channel
 * @hal: HAL pointer
 * @fcc_constraint: flag to enable/disable the constraint
 * @scan_pending: whether there is pending scan
 *
 * Return: QDF_STATUS
 */
QDF_STATUS sme_handle_set_fcc_channel(tHalHandle hal, bool fcc_constraint,
				      bool scan_pending)
{
	QDF_STATUS status;
	tpAniSirGlobal mac_ptr  = PMAC_STRUCT(hal);

	status = sme_acquire_global_lock(&mac_ptr->sme);

	if (QDF_STATUS_SUCCESS == status) {

		if (fcc_constraint != mac_ptr->scan.fcc_constraint) {
			mac_ptr->scan.fcc_constraint = fcc_constraint;
			if (scan_pending)
				mac_ptr->scan.defer_update_channel_list = true;
			else
				status = csr_update_channel_list(mac_ptr);
			/* update the channel list in firmware */
			status = csr_update_channel_list(mac_ptr);
		}

		sme_release_global_lock(&mac_ptr->sme);
	}

	return status;
}
/**
 * sme_setdef_dot11mode() - Updates pMac with default dot11mode
 * @hal: Global MAC pointer
 *
 * Return: NULL.
 */
void sme_setdef_dot11mode(tHalHandle hal)
{
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
	csr_set_default_dot11_mode(mac_ctx);
}

/**
 * sme_update_roam_scan_hi_rssi_scan_params() - update high rssi scan
 *         params
 * @hal_handle - The handle returned by macOpen.
 * @session_id - Session Identifier
 * @notify_id - Identifies 1 of the 4 parameters to be modified
 * @val New value of the parameter
 *
 * Return: QDF_STATUS - SME update config successful.
 *         Other status means SME failed to update
 */

QDF_STATUS sme_update_roam_scan_hi_rssi_scan_params(tHalHandle hal_handle,
	uint8_t session_id,
	uint32_t notify_id,
	int32_t val)
{
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_handle);
	QDF_STATUS status  = QDF_STATUS_SUCCESS;
	tCsrNeighborRoamConfig *nr_config = NULL;
	tpCsrNeighborRoamControlInfo nr_info = NULL;
	uint32_t reason = 0;

	status = sme_acquire_global_lock(&mac_ctx->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		nr_config = &mac_ctx->roam.configParam.neighborRoamConfig;
		nr_info   = &mac_ctx->roam.neighborRoamInfo[session_id];
		switch (notify_id) {
		case eCSR_HI_RSSI_SCAN_MAXCOUNT_ID:
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
				"%s: gRoamScanHirssiMaxCount %d => %d",
				__func__, nr_config->nhi_rssi_scan_max_count,
				val);
			nr_config->nhi_rssi_scan_max_count = val;
			nr_info->cfgParams.hi_rssi_scan_max_count = val;
			reason = REASON_ROAM_SCAN_HI_RSSI_MAXCOUNT_CHANGED;
		break;

		case eCSR_HI_RSSI_SCAN_RSSI_DELTA_ID:
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
				FL("gRoamScanHiRssiDelta %d => %d"),
				nr_config->nhi_rssi_scan_rssi_delta,
				val);
			nr_config->nhi_rssi_scan_rssi_delta = val;
			nr_info->cfgParams.hi_rssi_scan_rssi_delta = val;
			reason = REASON_ROAM_SCAN_HI_RSSI_DELTA_CHANGED;
			break;

		case eCSR_HI_RSSI_SCAN_DELAY_ID:
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
				FL("gRoamScanHiRssiDelay %d => %d"),
				nr_config->nhi_rssi_scan_delay,
				val);
			nr_config->nhi_rssi_scan_delay = val;
			nr_info->cfgParams.hi_rssi_scan_delay = val;
			reason = REASON_ROAM_SCAN_HI_RSSI_DELAY_CHANGED;
			break;

		case eCSR_HI_RSSI_SCAN_RSSI_UB_ID:
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
				FL("gRoamScanHiRssiUpperBound %d => %d"),
				nr_config->nhi_rssi_scan_rssi_ub,
				val);
			nr_config->nhi_rssi_scan_rssi_ub = val;
			nr_info->cfgParams.hi_rssi_scan_rssi_ub = val;
			reason = REASON_ROAM_SCAN_HI_RSSI_UB_CHANGED;
			break;

		default:
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
				FL("invalid parameter notify_id %d"),
				notify_id);
			status = QDF_STATUS_E_INVAL;
			break;
		}
		sme_release_global_lock(&mac_ctx->sme);
	}
	if (mac_ctx->roam.configParam.isRoamOffloadScanEnabled &&
		status == QDF_STATUS_SUCCESS) {
		csr_roam_offload_scan(mac_ctx, session_id,
			ROAM_SCAN_OFFLOAD_UPDATE_CFG, reason);
	}

	return status;
}

/**
 * sme_update_tgt_services() - update the target services config.
 * @hal: HAL pointer.
 * @cfg: wma_tgt_services parameters.
 *
 * update the target services config.
 *
 * Return: None.
 */
void sme_update_tgt_services(tHalHandle hal, struct wma_tgt_services *cfg)
{
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);

	mac_ctx->lteCoexAntShare = cfg->lte_coex_ant_share;
	mac_ctx->per_band_chainmask_supp = cfg->per_band_chainmask_supp;
	mac_ctx->beacon_offload = cfg->beacon_offload;
	mac_ctx->pmf_offload = cfg->pmf_offload;
	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
		FL("mac_ctx->pmf_offload: %d"), mac_ctx->pmf_offload);

	return;
}

/**
 * sme_is_session_id_valid() - Check if the session id is valid
 * @hal: Pointer to HAL
 * @session_id: Session id
 *
 * Checks if the session id is valid or not
 *
 * Return: True is the session id is valid, false otherwise
 */
bool sme_is_session_id_valid(tHalHandle hal, uint32_t session_id)
{
	tpAniSirGlobal mac = PMAC_STRUCT(hal);
	if (!mac) {
		/* Using QDF_TRACE since mac is not available for sms_log */
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			"%s: null mac pointer", __func__);
		return false;
	}

	if (CSR_IS_SESSION_VALID(mac, session_id)) {
		return true;
	} else {
		sms_log(mac, LOGE,
			FL("invalid session id:%d"), session_id);
		return false;
	}
}

#ifdef FEATURE_WLAN_TDLS

/**
 * sme_get_opclass() - determine operating class
 * @hal: Pointer to HAL
 * @channel: channel id
 * @bw_offset: bandwidth offset
 * @opclass: pointer to operating class
 *
 * Function will determine operating class from regdm_get_opclass_from_channel
 *
 * Return: none
 */
void sme_get_opclass(tHalHandle hal, uint8_t channel, uint8_t bw_offset,
		uint8_t *opclass)
{
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);

	/* redgm opclass table contains opclass for 40MHz low primary,
	 * 40MHz high primary and 20MHz. No support for 80MHz yet. So
	 * first we will check if bit for 40MHz is set and if so find
	 * matching opclass either with low primary or high primary
	 * (a channel would never be in both) and then search for opclass
	 * matching 20MHz, else for any BW.
	 */
	if (bw_offset & (1 << BW_40_OFFSET_BIT)) {
		*opclass = cds_reg_dmn_get_opclass_from_channel(
				mac_ctx->scan.countryCodeCurrent,
				channel, BW40_LOW_PRIMARY);
		if (!(*opclass)) {
			*opclass = cds_reg_dmn_get_opclass_from_channel(
					mac_ctx->scan.countryCodeCurrent,
					channel, BW40_HIGH_PRIMARY);
		}
	} else if (bw_offset & (1 << BW_20_OFFSET_BIT)) {
		*opclass = cds_reg_dmn_get_opclass_from_channel(
				mac_ctx->scan.countryCodeCurrent,
				channel, BW20);
	} else {
		*opclass = cds_reg_dmn_get_opclass_from_channel(
				mac_ctx->scan.countryCodeCurrent,
				channel, BWALL);
	}
}
#endif

#ifdef FEATURE_GREEN_AP
/**
 * sme_send_egap_conf_params() - set the enhanced green ap configuration params
 * @enable: enable/disable the enhanced green ap feature
 * @inactivity_time: inactivity timeout value
 * @wait_time: wait timeout value
 * @flag: feature flag in bitmasp
 *
 * Return: Return QDF_STATUS, otherwise appropriate failure code
 */
QDF_STATUS sme_send_egap_conf_params(uint32_t enable, uint32_t inactivity_time,
				     uint32_t wait_time, uint32_t flags)
{
	cds_msg_t message;
	QDF_STATUS status;
	struct egap_conf_params *egap_params;

	egap_params = qdf_mem_malloc(sizeof(*egap_params));
	if (NULL == egap_params) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				"%s: fail to alloc egap_params", __func__);
		return QDF_STATUS_E_NOMEM;
	}

	egap_params->enable = enable;
	egap_params->inactivity_time = inactivity_time;
	egap_params->wait_time = wait_time;
	egap_params->flags = flags;

	message.type = WMA_SET_EGAP_CONF_PARAMS;
	message.bodyptr = egap_params;
	status = cds_mq_post_message(QDF_MODULE_ID_WMA, &message);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			"%s: Not able to post msg to WMA!", __func__);

		qdf_mem_free(egap_params);
	}
	return status;
}
#endif

/**
 * sme_set_fw_test() - set fw test
 * @fw_test: fw test param
 *
 * Return: Return QDF_STATUS, otherwise appropriate failure code
 */
QDF_STATUS sme_set_fw_test(struct set_fwtest_params *fw_test)
{
	void *wma_handle;

	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
	if (!wma_handle) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				"wma handle is NULL");
		return QDF_STATUS_E_FAILURE;
	}
	wma_process_fw_test_cmd(wma_handle, fw_test);
	return QDF_STATUS_SUCCESS;
}

/**
 * sme_ht40_stop_obss_scan() - ht40 obss stop scan
 * @hal: mac handel
 * @vdev_id: vdev identifier
 *
 * Return: Return QDF_STATUS, otherwise appropriate failure code
 */
QDF_STATUS sme_ht40_stop_obss_scan(tHalHandle hal, uint32_t vdev_id)
{
	void *wma_handle;

	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
	if (!wma_handle) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				"wma handle is NULL");
		return QDF_STATUS_E_FAILURE;
	}
	wma_ht40_stop_obss_scan(wma_handle, vdev_id);
	return QDF_STATUS_SUCCESS;
}

/**
 * sme_update_mimo_power_save() - Update MIMO power save
 * configuration
 * @hal: The handle returned by macOpen
 * @is_ht_smps_enabled: enable/disable ht smps
 * @ht_smps_mode: smps mode disabled/static/dynamic
 * @send_smps_action: flag to send smps force mode command
 * to FW
 *
 * Return: QDF_STATUS if SME update mimo power save
 * configuration sucsess else failue status
 */
QDF_STATUS sme_update_mimo_power_save(tHalHandle hal,
				      uint8_t is_ht_smps_enabled,
				      uint8_t ht_smps_mode,
				      bool send_smps_action)
{
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);

	sms_log(mac_ctx, LOG1,
		"SMPS enable: %d mode: %d send action: %d",
		is_ht_smps_enabled, ht_smps_mode,
		send_smps_action);
	mac_ctx->roam.configParam.enableHtSmps =
		is_ht_smps_enabled;
	mac_ctx->roam.configParam.htSmps = ht_smps_mode;
	mac_ctx->roam.configParam.send_smps_action =
		send_smps_action;

	return QDF_STATUS_SUCCESS;
}

/**
 * sme_is_sta_smps_allowed() - check if the supported nss for
 * the session is greater than 1x1 to enable sta SMPS
 * @hal: The handle returned by macOpen
 * @session_id: session id
 *
 * Return: bool returns true if supported nss is greater than
 * 1x1 else false
 */
bool sme_is_sta_smps_allowed(tHalHandle hal, uint8_t session_id)
{
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
	tCsrRoamSession *csr_session;

	csr_session = CSR_GET_SESSION(mac_ctx, session_id);
	if (NULL == csr_session) {
		sms_log(mac_ctx, LOGE,
			FL("SME session not valid: %d"), session_id);
		return false;
	}

	if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
		sms_log(mac_ctx, LOGE,
			FL("CSR session not valid: %d"), session_id);
		return false;
	}

	return (csr_session->supported_nss_1x1 == true) ? false : true;
}

/**
 * sme_add_beacon_filter() - set the beacon filter configuration
 * @hal: The handle returned by macOpen
 * @session_id: session id
 * @ie_map: bitwise array of IEs
 *
 * Return: Return QDF_STATUS, otherwise appropriate failure code
 */
QDF_STATUS sme_add_beacon_filter(tHalHandle hal,
				 uint32_t session_id,
				 uint32_t *ie_map)
{
	cds_msg_t message;
	QDF_STATUS qdf_status;
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
	struct beacon_filter_param *filter_param;

	if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
		sms_log(mac_ctx, LOGE,
			"CSR session not valid: %d",
			session_id);
		return QDF_STATUS_E_FAILURE;
	}

	filter_param = qdf_mem_malloc(sizeof(*filter_param));
	if (NULL == filter_param) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				"%s: fail to alloc filter_param", __func__);
		return QDF_STATUS_E_FAILURE;
	}

	filter_param->vdev_id = session_id;

	qdf_mem_copy(filter_param->ie_map, ie_map,
			BCN_FLT_MAX_ELEMS_IE_LIST * sizeof(uint32_t));

	message.type = WMA_ADD_BCN_FILTER_CMDID;
	message.bodyptr = filter_param;
	qdf_status = cds_mq_post_message(QDF_MODULE_ID_WMA,
					&message);
	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			"%s: Not able to post msg to WDA!",
			__func__);

		qdf_mem_free(filter_param);
	}
	return qdf_status;
}

/**
 * sme_remove_beacon_filter() - set the beacon filter configuration
 * @hal: The handle returned by macOpen
 * @session_id: session id
 *
 * Return: Return QDF_STATUS, otherwise appropriate failure code
 */
QDF_STATUS sme_remove_beacon_filter(tHalHandle hal, uint32_t session_id)
{
	cds_msg_t message;
	QDF_STATUS qdf_status;
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
	struct beacon_filter_param *filter_param;

	if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
		sms_log(mac_ctx, LOGE,
			"CSR session not valid: %d",
			session_id);
		return QDF_STATUS_E_FAILURE;
	}

	filter_param = qdf_mem_malloc(sizeof(*filter_param));
	if (NULL == filter_param) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				"%s: fail to alloc filter_param", __func__);
		return QDF_STATUS_E_FAILURE;
	}

	filter_param->vdev_id = session_id;

	message.type = WMA_REMOVE_BCN_FILTER_CMDID;
	message.bodyptr = filter_param;
	qdf_status = cds_mq_post_message(QDF_MODULE_ID_WMA,
					&message);
	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			"%s: Not able to post msg to WDA!",
			__func__);

		qdf_mem_free(filter_param);
	}
	return qdf_status;
}

/**
 * sme_send_disassoc_req_frame - send disassoc req
 * @hal: handler to hal
 * @session_id: session id
 * @peer_mac: peer mac address
 * @reason: reason for disassociation
 * wait_for_ack: wait for acknowledgment
 *
 * function to send disassoc request to lim
 *
 * return: none
 */
void sme_send_disassoc_req_frame(tHalHandle hal, uint8_t session_id,
		uint8_t *peer_mac, uint16_t reason, uint8_t wait_for_ack)
{
	struct sme_send_disassoc_frm_req *msg;
	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
	A_UINT8  *buf;
	A_UINT16 tmp;

	msg = qdf_mem_malloc(sizeof(struct sme_send_disassoc_frm_req));

	if (NULL == msg)
		qdf_status = QDF_STATUS_E_FAILURE;
	else
		qdf_status = QDF_STATUS_SUCCESS;

	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
		return;

	qdf_mem_set(msg, sizeof(struct sme_send_disassoc_frm_req), 0);
	msg->msg_type = (uint16_t) eWNI_SME_SEND_DISASSOC_FRAME;

	msg->length = (uint16_t) sizeof(struct sme_send_disassoc_frm_req);

	buf = &msg->session_id;

	/* session id */
	*buf = (A_UINT8) session_id;
	buf += sizeof(A_UINT8);

	/* transaction id */
	*buf = 0;
	*(buf + 1) = 0;
	buf += sizeof(A_UINT16);

	/* Set the peer MAC address before sending the message to LIM */
	qdf_mem_copy(buf, peer_mac, QDF_MAC_ADDR_SIZE);

	buf += QDF_MAC_ADDR_SIZE;

	/* reasoncode */
	tmp = (uint16_t) reason;
	qdf_mem_copy(buf, &tmp, sizeof(uint16_t));
	buf += sizeof(uint16_t);

	*buf =  wait_for_ack;
	buf += sizeof(uint8_t);

	qdf_status = cds_send_mb_message_to_mac(msg);

	if (qdf_status != QDF_STATUS_SUCCESS)
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			FL("cds_send_mb_message Failed"));
}

/**
 * sme_get_bpf_offload_capabilities() - Get length for BPF offload
 * @hal: Global HAL handle
 * This function constructs the cds message and fill in message type,
 * post the same to WDA.
 * Return: QDF_STATUS enumeration
 */
QDF_STATUS sme_get_bpf_offload_capabilities(tHalHandle hal)
{
	QDF_STATUS          status     = QDF_STATUS_SUCCESS;
	tpAniSirGlobal      mac_ctx      = PMAC_STRUCT(hal);
	cds_msg_t           cds_msg;

	sms_log(mac_ctx, LOG1, FL("enter"));

	status = sme_acquire_global_lock(&mac_ctx->sme);
	if (QDF_STATUS_SUCCESS == status) {
		/* Serialize the req through MC thread */
		cds_msg.bodyptr = NULL;
		cds_msg.type = WDA_BPF_GET_CAPABILITIES_REQ;
		status = cds_mq_post_message(QDF_MODULE_ID_WMA, &cds_msg);
		if (!QDF_IS_STATUS_SUCCESS(status)) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
					FL("Post bpf get offload msg fail"));
			status = QDF_STATUS_E_FAILURE;
		}
		sme_release_global_lock(&mac_ctx->sme);
	} else {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			FL("sme_acquire_global_lock error"));
	}
	sms_log(mac_ctx, LOG1, FL("exit"));
	return status;
}


/**
 * sme_set_bpf_instructions() - Set BPF bpf filter instructions.
 * @hal: HAL handle
 * @bpf_set_offload: struct to set bpf filter instructions.
 *
 * Return: QDF_STATUS enumeration.
 */
QDF_STATUS sme_set_bpf_instructions(tHalHandle hal,
				    struct sir_bpf_set_offload *req)
{
	QDF_STATUS          status     = QDF_STATUS_SUCCESS;
	tpAniSirGlobal      mac_ctx    = PMAC_STRUCT(hal);
	cds_msg_t           cds_msg;
	struct sir_bpf_set_offload *set_offload;

	set_offload = qdf_mem_malloc(sizeof(*set_offload));

	if (NULL == set_offload) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			FL("Failed to alloc set_offload"));
		return QDF_STATUS_E_NOMEM;
	}

	set_offload->session_id = req->session_id;
	set_offload->filter_id = req->filter_id;
	set_offload->current_offset = req->current_offset;
	set_offload->total_length = req->total_length;
	set_offload->current_length = req->current_length;
	if (set_offload->total_length) {
		set_offload->program = qdf_mem_malloc(sizeof(uint8_t) *
						req->current_length);
		if (NULL == set_offload->program) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				FL("Failed to alloc instruction memory"));
			qdf_mem_free(set_offload);
			return QDF_STATUS_E_NOMEM;
		}
		qdf_mem_copy(set_offload->program, req->program,
				set_offload->current_length);
	}
	status = sme_acquire_global_lock(&mac_ctx->sme);
	if (QDF_STATUS_SUCCESS == status) {
		/* Serialize the req through MC thread */
		cds_msg.bodyptr = set_offload;
		cds_msg.type = WDA_BPF_SET_INSTRUCTIONS_REQ;
		status = cds_mq_post_message(QDF_MODULE_ID_WMA, &cds_msg);

		if (!QDF_IS_STATUS_SUCCESS(status)) {
			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				FL("Post BPF set offload msg fail"));
			status = QDF_STATUS_E_FAILURE;
			if (set_offload->total_length)
				qdf_mem_free(set_offload->program);
			qdf_mem_free(set_offload);
		}
		sme_release_global_lock(&mac_ctx->sme);
	} else {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				FL("sme_acquire_global_lock failed"));
		if (set_offload->total_length)
			qdf_mem_free(set_offload->program);
		qdf_mem_free(set_offload);
	}
	return status;
}

/**
 * sme_bpf_offload_register_callback() - Register get bpf offload callbacK
 *
 * @hal - MAC global handle
 * @callback_routine - callback routine from HDD
 *
 * This API is invoked by HDD to register its callback in SME
 *
 * Return: QDF_STATUS
 */
QDF_STATUS sme_bpf_offload_register_callback(tHalHandle hal,
				void (*pbpf_get_offload_cb)(void *context,
					struct sir_bpf_get_offload *))
{
	QDF_STATUS status   = QDF_STATUS_SUCCESS;
	tpAniSirGlobal mac  = PMAC_STRUCT(hal);

	status = sme_acquire_global_lock(&mac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		mac->sme.pbpf_get_offload_cb = pbpf_get_offload_cb;
		sme_release_global_lock(&mac->sme);
	} else {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			FL("sme_acquire_global_lock failed"));
	}
	return status;
}

/**
 * sme_get_wni_dot11_mode() - return configured wni dot11mode
 * @hal: hal pointer
 *
 * Return: wni dot11 mode.
 */
uint32_t sme_get_wni_dot11_mode(tHalHandle hal)
{
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);

	return csr_translate_to_wni_cfg_dot11_mode(mac_ctx,
		mac_ctx->roam.configParam.uCfgDot11Mode);
}

/**
 * sme_bpf_offload_deregister_callback() - Register get bpf offload callbacK
 *
 * @h_hal - MAC global handle
 * @callback_routine - callback routine from HDD
 *
 * This API is invoked by HDD to de-register its callback in SME
 *
 * Return: QDF_STATUS Enumeration
 */
QDF_STATUS sme_bpf_offload_deregister_callback(tHalHandle h_hal)
{
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	tpAniSirGlobal mac;

	if (!h_hal) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				  FL("hHal is not valid"));
		return QDF_STATUS_E_INVAL;
	}

	mac = PMAC_STRUCT(h_hal);

	status = sme_acquire_global_lock(&mac->sme);
	if (QDF_IS_STATUS_SUCCESS(status)) {
		mac->sme.pbpf_get_offload_cb = NULL;
		sme_release_global_lock(&mac->sme);
	} else {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			FL("sme_acquire_global_lock failed"));
	}
	return status;
}


/**
 * sme_create_mon_session() - post message to create PE session for monitormode
 * operation
 * @hal_handle: Handle to the HAL
 * @bssid: pointer to bssid
 *
 * Return: QDF_STATUS_SUCCESS on success, non-zero error code on failure.
 */
QDF_STATUS sme_create_mon_session(tHalHandle hal_handle, tSirMacAddr bss_id)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	struct sir_create_session *msg;

	msg = qdf_mem_malloc(sizeof(*msg));
	if (NULL != msg) {
		msg->type = eWNI_SME_MON_INIT_SESSION;
		msg->msg_len = sizeof(*msg);
		qdf_mem_copy(msg->bss_id.bytes, bss_id, QDF_MAC_ADDR_SIZE);
		status = cds_send_mb_message_to_mac(msg);
	}
	return status;
}

/**
 * sme_set_adaptive_dwelltime_config() - Update Adaptive dwelltime configuration
 * @hal: The handle returned by macOpen
 * @params: adaptive_dwelltime_params config
 *
 * Return: QDF_STATUS if adaptive dwell time update
 * configuration sucsess else failure status
 */
QDF_STATUS sme_set_adaptive_dwelltime_config(tHalHandle hal,
			struct adaptive_dwelltime_params *params)
{
	cds_msg_t message;
	QDF_STATUS status;
	struct adaptive_dwelltime_params *dwelltime_params;

	dwelltime_params = qdf_mem_malloc(sizeof(*dwelltime_params));
	if (NULL == dwelltime_params) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
				"%s: fail to alloc dwelltime_params", __func__);
		return QDF_STATUS_E_NOMEM;
	}

	dwelltime_params->is_enabled = params->is_enabled;
	dwelltime_params->dwelltime_mode = params->dwelltime_mode;
	dwelltime_params->lpf_weight = params->lpf_weight;
	dwelltime_params->passive_mon_intval = params->passive_mon_intval;
	dwelltime_params->wifi_act_threshold = params->wifi_act_threshold;

	message.type = WMA_SET_ADAPT_DWELLTIME_CONF_PARAMS;
	message.bodyptr = dwelltime_params;
	status = cds_mq_post_message(QDF_MODULE_ID_WMA, &message);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			"%s: Not able to post msg to WMA!", __func__);

		qdf_mem_free(dwelltime_params);
	}
	return status;
}
/**
 * sme_set_pdev_ht_vht_ies() - sends the set pdev IE req
 * @hal: Pointer to HAL
 * @enable2x2: 1x1 or 2x2 mode.
 *
 * Sends the set pdev IE req with Nss value.
 *
 * Return: None
 */
void sme_set_pdev_ht_vht_ies(tHalHandle hal, bool enable2x2)
{
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
	struct sir_set_ht_vht_cfg *ht_vht_cfg;
	QDF_STATUS status = QDF_STATUS_E_FAILURE;

	if (!mac_ctx->per_band_chainmask_supp)
		return;

	if (!((mac_ctx->roam.configParam.uCfgDot11Mode ==
					eCSR_CFG_DOT11_MODE_AUTO) ||
				(mac_ctx->roam.configParam.uCfgDot11Mode ==
				 eCSR_CFG_DOT11_MODE_11N) ||
				(mac_ctx->roam.configParam.uCfgDot11Mode ==
				 eCSR_CFG_DOT11_MODE_11N_ONLY) ||
				(mac_ctx->roam.configParam.uCfgDot11Mode ==
				 eCSR_CFG_DOT11_MODE_11AC) ||
				(mac_ctx->roam.configParam.uCfgDot11Mode ==
				 eCSR_CFG_DOT11_MODE_11AC_ONLY)))
		return;

	status = sme_acquire_global_lock(&mac_ctx->sme);
	if (QDF_STATUS_SUCCESS == status) {
		ht_vht_cfg = qdf_mem_malloc(sizeof(*ht_vht_cfg));
		if (NULL == ht_vht_cfg) {
			sms_log(mac_ctx, LOGE,
					"%s: mem alloc failed for ht_vht_cfg",
					__func__);
			sme_release_global_lock(&mac_ctx->sme);
			return;
		}

		ht_vht_cfg->pdev_id = 0;
		if (enable2x2)
			ht_vht_cfg->nss = 2;
		else
			ht_vht_cfg->nss = 1;
		ht_vht_cfg->dot11mode =
			(uint8_t)csr_translate_to_wni_cfg_dot11_mode(mac_ctx,
				mac_ctx->roam.configParam.uCfgDot11Mode);

		ht_vht_cfg->msg_type = eWNI_SME_PDEV_SET_HT_VHT_IE;
		ht_vht_cfg->len = sizeof(*ht_vht_cfg);
		sms_log(mac_ctx, LOG1,
				FL("SET_HT_VHT_IE with nss %d, dot11mode %d"),
				ht_vht_cfg->nss,
				ht_vht_cfg->dot11mode);
		status = cds_send_mb_message_to_mac(ht_vht_cfg);
		if (QDF_STATUS_SUCCESS != status) {
			sms_log(mac_ctx, LOGE, FL(
					"Send SME_PDEV_SET_HT_VHT_IE fail"));
			qdf_mem_free(ht_vht_cfg);
		}
		sme_release_global_lock(&mac_ctx->sme);
	}
	return;
}

/**
 * sme_update_vdev_type_nss() - sets the nss per vdev type
 * @hal: Pointer to HAL
 * @max_supp_nss: max_supported Nss
 * @band: 5G or 2.4G band
 *
 * Sets the per band Nss for each vdev type based on INI and configured
 * chain mask value.
 *
 * Return: None
 */
void sme_update_vdev_type_nss(tHalHandle hal, uint8_t max_supp_nss,
		uint32_t vdev_type_nss, eCsrBand band)
{
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
	struct vdev_type_nss *vdev_nss;

	if (eCSR_BAND_5G == band)
		vdev_nss = &mac_ctx->vdev_type_nss_5g;
	else
		vdev_nss = &mac_ctx->vdev_type_nss_2g;

	vdev_nss->sta = QDF_MIN(max_supp_nss, CFG_STA_NSS(vdev_type_nss));
	vdev_nss->sap = QDF_MIN(max_supp_nss, CFG_SAP_NSS(vdev_type_nss));
	vdev_nss->p2p_go = QDF_MIN(max_supp_nss,
				CFG_P2P_GO_NSS(vdev_type_nss));
	vdev_nss->p2p_cli = QDF_MIN(max_supp_nss,
				CFG_P2P_CLI_NSS(vdev_type_nss));
	vdev_nss->p2p_dev = QDF_MIN(max_supp_nss,
				CFG_P2P_DEV_NSS(vdev_type_nss));
	vdev_nss->ibss = QDF_MIN(max_supp_nss, CFG_IBSS_NSS(vdev_type_nss));
	vdev_nss->tdls = QDF_MIN(max_supp_nss, CFG_TDLS_NSS(vdev_type_nss));
	vdev_nss->ocb = QDF_MIN(max_supp_nss, CFG_OCB_NSS(vdev_type_nss));

	sms_log(mac_ctx, LOG1,
	"band %d NSS:sta %d sap %d cli %d go %d dev %d ibss %d tdls %d ocb %d",
		band, vdev_nss->sta, vdev_nss->sap, vdev_nss->p2p_cli,
		vdev_nss->p2p_go, vdev_nss->p2p_dev, vdev_nss->ibss,
		vdev_nss->tdls, vdev_nss->ocb);
}

/**
 * sme_register_p2p_lo_event() - Register for the p2p lo event
 * @hHal: reference to the HAL
 * @context: the context of the call
 * @callback: the callback to hdd
 *
 * This function registers the callback function for P2P listen
 * offload stop event.
 *
 * Return: none
 */
void sme_register_p2p_lo_event(tHalHandle hHal, void *context,
					p2p_lo_callback callback)
{
	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
	QDF_STATUS status = QDF_STATUS_E_FAILURE;

	status = sme_acquire_global_lock(&pMac->sme);
	pMac->sme.p2p_lo_event_callback = callback;
	pMac->sme.p2p_lo_event_context = context;
	sme_release_global_lock(&pMac->sme);
}

/**
 * sme_process_mac_pwr_dbg_cmd() - enable mac pwr debugging
 * @hal: The handle returned by macOpen
 * @session_id: session id
 * @dbg_args: args for mac pwr debug command
 * Return: Return QDF_STATUS, otherwise appropriate failure code
 */
QDF_STATUS sme_process_mac_pwr_dbg_cmd(tHalHandle hal, uint32_t session_id,
				       struct sir_mac_pwr_dbg_cmd*
				       dbg_args)
{
	cds_msg_t message;
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
	struct sir_mac_pwr_dbg_cmd *req;
	int i;

	if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
		sms_log(mac_ctx, LOGE,
			"CSR session not valid: %d",
			session_id);
		return QDF_STATUS_E_FAILURE;
	}

	req = qdf_mem_malloc(sizeof(*req));
	if (NULL == req) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "%s: fail to alloc mac_pwr_dbg_args", __func__);
		return QDF_STATUS_E_FAILURE;
	}
	req->module_id = dbg_args->module_id;
	req->pdev_id = dbg_args->pdev_id;
	req->num_args = dbg_args->num_args;
	for (i = 0; i < req->num_args; i++)
		req->args[i] = dbg_args->args[i];

	message.type = SIR_HAL_POWER_DBG_CMD;
	message.bodyptr = req;

	if (!QDF_IS_STATUS_SUCCESS(cds_mq_post_message
				(QDF_MODULE_ID_WMA, &message))) {
		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
			  "%s: Not able to post msg to WDA!",
			  __func__);
		qdf_mem_free(req);
	}
	return QDF_STATUS_SUCCESS;
}
/**
 * sme_get_vdev_type_nss() - gets the nss per vdev type
 * @hal: Pointer to HAL
 * @dev_mode: connection type.
 * @nss2g: Pointer to the 2G Nss parameter.
 * @nss5g: Pointer to the 5G Nss parameter.
 *
 * Fills the 2G and 5G Nss values based on connection type.
 *
 * Return: None
 */
void sme_get_vdev_type_nss(tHalHandle hal, enum tQDF_ADAPTER_MODE dev_mode,
		uint8_t *nss_2g, uint8_t *nss_5g)
{
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
	csr_get_vdev_type_nss(mac_ctx, dev_mode, nss_2g, nss_5g);
}
