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

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

#include "cds_api.h"
#include "wni_cfg.h"
#include "ani_global.h"
#include "sir_api.h"
#include "sir_params.h"
#include "cfg_api.h"

#include "sch_api.h"
#include "utils_api.h"
#include "lim_utils.h"
#include "lim_assoc_utils.h"
#include "lim_prop_exts_utils.h"
#include "lim_security_utils.h"
#include "lim_send_messages.h"
#include "lim_send_messages.h"
#include "lim_session_utils.h"
#ifdef WLAN_FEATURE_VOWIFI_11R
#include <lim_ft.h>
#endif
#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
#include "host_diag_core_log.h"
#endif
#include "wma_if.h"

static void lim_process_mlm_start_req(tpAniSirGlobal, uint32_t *);
#ifdef FEATURE_OEM_DATA_SUPPORT
static void lim_process_mlm_oem_data_req(tpAniSirGlobal, uint32_t *);
#endif
static void lim_process_mlm_join_req(tpAniSirGlobal, uint32_t *);
static void lim_process_mlm_auth_req(tpAniSirGlobal, uint32_t *);
static void lim_process_mlm_assoc_req(tpAniSirGlobal, uint32_t *);
static void lim_process_mlm_reassoc_req(tpAniSirGlobal, uint32_t *);
static void lim_process_mlm_disassoc_req(tpAniSirGlobal, uint32_t *);
static void lim_process_mlm_deauth_req(tpAniSirGlobal, uint32_t *);
static void lim_process_mlm_set_keys_req(tpAniSirGlobal, uint32_t *);

/* MLM Timeout event handler templates */
static void lim_process_periodic_probe_req_timer(tpAniSirGlobal mac_ctx);
static void lim_process_join_failure_timeout(tpAniSirGlobal);
static void lim_process_auth_failure_timeout(tpAniSirGlobal);
static void lim_process_auth_rsp_timeout(tpAniSirGlobal, uint32_t);
static void lim_process_assoc_failure_timeout(tpAniSirGlobal, uint32_t);
static void lim_process_periodic_join_probe_req_timer(tpAniSirGlobal);

/**
 * lim_process_mlm_req_messages() - process mlm request messages
 * @mac_ctx: global MAC context
 * @msg: mlm request message
 *
 * This function is called by lim_post_mlm_message(). This
 * function handles MLM primitives invoked by SME.
 * Depending on the message type, corresponding function will be
 * called.
 * ASSUMPTIONS:
 * 1. Upon receiving Beacon in WT_JOIN_STATE, MLM module invokes
 *    APIs exposed by Beacon Processing module for setting parameters
 *    at MAC hardware.
 * 2. If attempt to Reassociate with an AP fails, link with current
 *    AP is restored back.
 *
 * Return: None
 */
void lim_process_mlm_req_messages(tpAniSirGlobal mac_ctx, tpSirMsgQ msg)
{
	MTRACE(mac_trace_msg_rx(mac_ctx, NO_SESSION, msg->type));
	switch (msg->type) {
	case LIM_MLM_START_REQ:
		lim_process_mlm_start_req(mac_ctx, msg->bodyptr);
		break;
#ifdef FEATURE_OEM_DATA_SUPPORT
	case LIM_MLM_OEM_DATA_REQ:
		lim_process_mlm_oem_data_req(mac_ctx, msg->bodyptr);
		break;
#endif
	case LIM_MLM_JOIN_REQ:
		lim_process_mlm_join_req(mac_ctx, msg->bodyptr);
		break;
	case LIM_MLM_AUTH_REQ:
		lim_process_mlm_auth_req(mac_ctx, msg->bodyptr);
		break;
	case LIM_MLM_ASSOC_REQ:
		lim_process_mlm_assoc_req(mac_ctx, msg->bodyptr);
		break;
	case LIM_MLM_REASSOC_REQ:
		lim_process_mlm_reassoc_req(mac_ctx, msg->bodyptr);
		break;
	case LIM_MLM_DISASSOC_REQ:
		lim_process_mlm_disassoc_req(mac_ctx, msg->bodyptr);
		break;
	case LIM_MLM_DEAUTH_REQ:
		lim_process_mlm_deauth_req(mac_ctx, msg->bodyptr);
		break;
	case LIM_MLM_SETKEYS_REQ:
		lim_process_mlm_set_keys_req(mac_ctx, msg->bodyptr);
		break;
	case SIR_LIM_PERIODIC_PROBE_REQ_TIMEOUT:
		lim_process_periodic_probe_req_timer(mac_ctx);
		break;
	case SIR_LIM_JOIN_FAIL_TIMEOUT:
		lim_process_join_failure_timeout(mac_ctx);
		break;
	case SIR_LIM_PERIODIC_JOIN_PROBE_REQ_TIMEOUT:
		lim_process_periodic_join_probe_req_timer(mac_ctx);
		break;
	case SIR_LIM_AUTH_FAIL_TIMEOUT:
		lim_process_auth_failure_timeout(mac_ctx);
		break;
	case SIR_LIM_AUTH_RSP_TIMEOUT:
		lim_process_auth_rsp_timeout(mac_ctx, msg->bodyval);
		break;
	case SIR_LIM_ASSOC_FAIL_TIMEOUT:
		lim_process_assoc_failure_timeout(mac_ctx, msg->bodyval);
		break;
#ifdef WLAN_FEATURE_VOWIFI_11R
	case SIR_LIM_FT_PREAUTH_RSP_TIMEOUT:
		lim_process_ft_preauth_rsp_timeout(mac_ctx);
		break;
#endif
	case SIR_LIM_REMAIN_CHN_TIMEOUT:
		lim_process_remain_on_chn_timeout(mac_ctx);
		break;
	case SIR_LIM_INSERT_SINGLESHOT_NOA_TIMEOUT:
		lim_process_insert_single_shot_noa_timeout(mac_ctx);
		break;
	case SIR_LIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE:
		lim_convert_active_channel_to_passive_channel(mac_ctx);
		break;
	case SIR_LIM_DISASSOC_ACK_TIMEOUT:
		lim_process_disassoc_ack_timeout(mac_ctx);
		break;
	case SIR_LIM_DEAUTH_ACK_TIMEOUT:
		lim_process_deauth_ack_timeout(mac_ctx);
		break;
	case LIM_MLM_TSPEC_REQ:
	default:
		break;
	} /* switch (msg->type) */
}

/* WLAN_SUSPEND_LINK Related */

/**
 * lim_is_link_suspended()- check if link is suspended
 * @mac_ctx: global MAC context
 *
 * This function returns is link is suspended or not.
 * Since Suspend link uses init scan, it just returns
 * gLimSystemInScanLearnMode flag.
 *
 * Return: uint8_t(gLimSystemInScanLearnMode flag)
 */
uint8_t lim_is_link_suspended(tpAniSirGlobal mac_ctx)
{
	return mac_ctx->lim.gLimSystemInScanLearnMode;
}

/**
 * lim_change_channel_with_callback() - change channel and register callback
 * @mac_ctx: global MAC context
 * @new_chan: new channel to switch
 * @callback: Callback function
 * @cbdata: callback data
 * @session_entry: PE session pointer
 *
 * This function is called to change channel and perform off channel operation
 * if required. The caller registers a callback to be called at the end of the
 * channel change.
 *
 * Return: None
 */
void
lim_change_channel_with_callback(tpAniSirGlobal mac_ctx, uint8_t new_chan,
				 CHANGE_CHANNEL_CALLBACK callback,
				 uint32_t *cbdata, tpPESession session_entry)
{
	/* Sanity checks for the current and new channel */
#if defined WLAN_VOWIFI_DEBUG
	lim_log(mac_ctx, LOGE, FL("Switching channel to %d"), new_chan);
#endif
	session_entry->channelChangeReasonCode =
		LIM_SWITCH_CHANNEL_OPERATION;

	mac_ctx->lim.gpchangeChannelCallback = callback;
	mac_ctx->lim.gpchangeChannelData = cbdata;

	lim_send_switch_chnl_params(mac_ctx, new_chan, 0, 0,
		CH_WIDTH_20MHZ, session_entry->maxTxPower,
		session_entry->peSessionId, false);

	return;
}

/**
 * lim_covert_channel_scan_type() - switch between ACTIVE and PASSIVE scan type
 * @mac_ctx: global MAC context
 * @chan_num: channel number to change the scan type
 * @passive_to_active: flag to indicate if switch allowed
 *
 * This function is called to get the list,
 * change the channel type and set again.
 * NOTE: If a channel is ACTIVE, this function will make it as PASSIVE
 *       If a channel is PASSIVE, this fucntion will make it as ACTIVE
 *
 * Return: None
 */

void lim_covert_channel_scan_type(tpAniSirGlobal mac_ctx, uint8_t chan_num,
				  bool passive_to_active)
{

	uint32_t i;
	uint8_t chan_pair[WNI_CFG_SCAN_CONTROL_LIST_LEN];
	uint32_t len = WNI_CFG_SCAN_CONTROL_LIST_LEN;
	tSirRetStatus status;

	status  = wlan_cfg_get_str(mac_ctx, WNI_CFG_SCAN_CONTROL_LIST,
				   chan_pair, &len);
	if (eSIR_SUCCESS != status) {
		lim_log(mac_ctx, LOGE, FL("Unable to get scan control list"));
		return;
	}
	if (len > WNI_CFG_SCAN_CONTROL_LIST_LEN) {
		lim_log(mac_ctx, LOGE,
			FL("Invalid scan control list length:%d"), len);
		return;
	}
	for (i = 0; (i + 1) < len; i += 2) {
		if (chan_pair[i] != chan_num) /* skip this channel */
			continue;
		if ((eSIR_PASSIVE_SCAN == chan_pair[i + 1]) &&
		     true == passive_to_active) {
			lim_log(mac_ctx, LOG1, FL
				("Channel %d changed from Passive to Active"),
				chan_num);
			chan_pair[i + 1] = eSIR_ACTIVE_SCAN;
			break;
		}
		if ((eSIR_ACTIVE_SCAN == chan_pair[i + 1]) &&
		     false == passive_to_active) {
			lim_log(mac_ctx, LOG1, FL
				("Channel %d changed from Active to Passive"),
				chan_num);
			chan_pair[i + 1] = eSIR_PASSIVE_SCAN;
			break;
		}
	}

	cfg_set_str_notify(mac_ctx, WNI_CFG_SCAN_CONTROL_LIST,
			   (uint8_t *) chan_pair, len, false);
	return;
}

/**
 * lim_set_dfs_channel_list() - convert dfs channel list to active channel list
 * @mac_ctx: global MAC context.
 * @chan_num: channel number
 * @dfs_ch_list: list of DFS channels
 *
 * This function is called to convert DFS channel list to active channel list
 * when any beacon is present on that channel. This function store time for
 * passive channels which help to know that for how much time channel has been
 * passive.
 *
 * NOTE: If a channel is ACTIVE, it won't store any time
 *       If a channel is PAssive, it will store time as timestamp
 *
 * Return: None
 */
void lim_set_dfs_channel_list(tpAniSirGlobal mac_ctx, uint8_t chan_num,
			      tSirDFSChannelList *dfs_ch_list)
{
	bool pass_to_active = true;

	if (!((1 <= chan_num) && (165 >= chan_num))) {
		lim_log(mac_ctx, LOGE, FL("Invalid Channel: %d"), chan_num);
		return;
	}

	if (true == lim_isconnected_on_dfs_channel(chan_num)) {
		if (dfs_ch_list->timeStamp[chan_num] == 0) {
			/*
			 * Received first beacon;
			 * Convert DFS channel to Active channel.
			 */
			lim_log(mac_ctx, LOG1,
				FL("Received first beacon on DFS channel: %d"),
				chan_num);
			lim_covert_channel_scan_type(mac_ctx, chan_num,
						     pass_to_active);
		}
		dfs_ch_list->timeStamp[chan_num] =
					cdf_mc_timer_get_system_time();
	} else {
		lim_log(mac_ctx, LOG1, FL("Channel %d is Active"), chan_num);
		return;
	}

	if (!tx_timer_running
		    (&mac_ctx->lim.limTimers.gLimActiveToPassiveChannelTimer)) {
		tx_timer_activate(
		    &mac_ctx->lim.limTimers.gLimActiveToPassiveChannelTimer);
	}

	return;
}

/**
 * lim_restore_pre_scan_state() - restore HW state prior to scan
 *
 * @mac_ctx: global MAC context
 *
 * This function is called by lim_continue_channel_scan()
 * to restore HW state prior to entering 'scan state'
 *
 * Return: None
 */
void lim_restore_pre_scan_state(tpAniSirGlobal mac_ctx)
{
	/* Deactivate MIN/MAX channel timers if running */
	lim_deactivate_and_change_timer(mac_ctx, eLIM_MIN_CHANNEL_TIMER);
	lim_deactivate_and_change_timer(mac_ctx, eLIM_MAX_CHANNEL_TIMER);

	mac_ctx->lim.gLimSystemInScanLearnMode = 0;
	lim_log(mac_ctx, LOG1, FL("Scan ended, took %llu tu"),
		(tx_time_get() - mac_ctx->lim.scanStartTime));
}

#ifdef FEATURE_OEM_DATA_SUPPORT
/**
 * lim_send_hal_oem_data_req() - send oem data request
 * @mac_ctx: global MAC context
 *
 * This function is used to send OEM data request to HAL.
 *
 * Return: None
 */
void lim_send_hal_oem_data_req(tpAniSirGlobal mac_ctx)
{
	tSirMsgQ msg;
	tpStartOemDataReq start_oem_data_req = NULL;
	tSirRetStatus rc = eSIR_SUCCESS;
	tpLimMlmOemDataRsp mlm_oem_data_rsp;
	uint32_t reqlen = 0;

	if (NULL == mac_ctx->lim.gpLimMlmOemDataReq) {
		lim_log(mac_ctx, LOGE, FL("Null pointer"));
		goto error;
	}

	reqlen = sizeof(tStartOemDataReq);

	start_oem_data_req = cdf_mem_malloc(reqlen);
	if (NULL == start_oem_data_req) {
		lim_log(mac_ctx, LOGE, FL
			("Could not allocate memory for start_oem_data_req"));
		goto error;
	}

	cdf_mem_set((uint8_t *) (start_oem_data_req), reqlen, 0);

	/* Now copy over the information to the OEM DATA REQ to HAL */
	cdf_mem_copy(start_oem_data_req->selfMacAddr,
		     mac_ctx->lim.gpLimMlmOemDataReq->selfMacAddr,
		     sizeof(tSirMacAddr));

	cdf_mem_copy(start_oem_data_req->oemDataReq,
		     mac_ctx->lim.gpLimMlmOemDataReq->oemDataReq,
		     OEM_DATA_REQ_SIZE);

	/* Create the message to be passed to HAL */
	msg.type = WMA_START_OEM_DATA_REQ;
	msg.bodyptr = start_oem_data_req;
	msg.bodyval = 0;

	SET_LIM_PROCESS_DEFD_MESGS(mac_ctx, false);
	MTRACE(mac_trace_msg_tx(mac_ctx, NO_SESSION, msg.type));

	rc = wma_post_ctrl_msg(mac_ctx, &msg);
	if (rc == eSIR_SUCCESS)
		return;

	SET_LIM_PROCESS_DEFD_MESGS(mac_ctx, true);
	cdf_mem_free(start_oem_data_req);
	lim_log(mac_ctx, LOGE,
		FL("OEM_DATA: posting WMA_START_OEM_DATA_REQ to HAL failed"));

error:
	mac_ctx->lim.gLimMlmState = mac_ctx->lim.gLimPrevMlmState;
	MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, NO_SESSION,
		       mac_ctx->lim.gLimMlmState));

	mlm_oem_data_rsp = cdf_mem_malloc(sizeof(tLimMlmOemDataRsp));
	if (NULL == mlm_oem_data_rsp) {
		lim_log(mac_ctx->hHdd, LOGP, FL
			("memory allocation for mlm_oem_data_rsp"));
		return;
	}

	if (NULL != mac_ctx->lim.gpLimMlmOemDataReq) {
		cdf_mem_free(mac_ctx->lim.gpLimMlmOemDataReq);
		mac_ctx->lim.gpLimMlmOemDataReq = NULL;
	}

	lim_post_sme_message(mac_ctx, LIM_MLM_OEM_DATA_CNF,
			     (uint32_t *) mlm_oem_data_rsp);

	return;
}
#endif /* FEATURE_OEM_DATA_SUPPORT */

/**
 * mlm_add_sta() - MLM add sta
 * @mac_ctx: global MAC context
 * @sta_param: Add sta params
 * @bssid: BSSID
 * @ht_capable: HT capability
 * @session_entry: PE session entry
 *
 * This function is called to update station parameters
 *
 * Return: None
 */
static void mlm_add_sta(tpAniSirGlobal mac_ctx, tpAddStaParams sta_param,
		uint8_t *bssid, uint8_t ht_capable, tpPESession session_entry)
{
	uint32_t val;
	uint32_t self_dot11mode = 0;

	wlan_cfg_get_int(mac_ctx, WNI_CFG_DOT11_MODE, &self_dot11mode);
	sta_param->staType = STA_ENTRY_SELF; /* Identifying self */

	cdf_mem_copy(sta_param->bssId, bssid, sizeof(tSirMacAddr));
	cdf_mem_copy(sta_param->staMac, session_entry->selfMacAddr,
		     sizeof(tSirMacAddr));

	/* Configuration related parameters to be changed to support BT-AMP */

	if (eSIR_SUCCESS != wlan_cfg_get_int(mac_ctx, WNI_CFG_LISTEN_INTERVAL,
					     &val))
		lim_log(mac_ctx, LOGP, FL("Couldn't get LISTEN_INTERVAL"));
	sta_param->listenInterval = (uint16_t) val;

	if (eSIR_SUCCESS != wlan_cfg_get_int(mac_ctx, WNI_CFG_SHORT_PREAMBLE,
					     &val))
		lim_log(mac_ctx, LOGP, FL("Couldn't get SHORT_PREAMBLE"));
	sta_param->shortPreambleSupported = (uint8_t) val;

	sta_param->assocId = 0;      /* Is SMAC OK with this? */
	sta_param->wmmEnabled = 0;
	sta_param->uAPSD = 0;
	sta_param->maxSPLen = 0;
	sta_param->us32MaxAmpduDuration = 0;
	sta_param->maxAmpduSize = 0; /* 0: 8k, 1: 16k,2: 32k,3: 64k, 4:128k */

	/* For Self STA get the LDPC capability from config.ini */
	sta_param->htLdpcCapable =
		(session_entry->txLdpcIniFeatureEnabled & 0x01);
	sta_param->vhtLdpcCapable =
		((session_entry->txLdpcIniFeatureEnabled >> 1) & 0x01);

	if (IS_DOT11_MODE_HT(session_entry->dot11mode)) {
		sta_param->htCapable = ht_capable;
		sta_param->greenFieldCapable =
			lim_get_ht_capability(mac_ctx, eHT_GREENFIELD,
					      session_entry);
		sta_param->ch_width =
			lim_get_ht_capability(mac_ctx,
				eHT_SUPPORTED_CHANNEL_WIDTH_SET, session_entry);
		sta_param->mimoPS =
			(tSirMacHTMIMOPowerSaveState)lim_get_ht_capability(
				mac_ctx, eHT_MIMO_POWER_SAVE, session_entry);
		sta_param->rifsMode =
			lim_get_ht_capability(mac_ctx, eHT_RIFS_MODE,
					      session_entry);
		sta_param->lsigTxopProtection =
			lim_get_ht_capability(mac_ctx, eHT_LSIG_TXOP_PROTECTION,
					      session_entry);
		sta_param->maxAmpduDensity =
			lim_get_ht_capability(mac_ctx, eHT_MPDU_DENSITY,
					      session_entry);
		sta_param->maxAmsduSize =
			lim_get_ht_capability(mac_ctx, eHT_MAX_AMSDU_LENGTH,
					      session_entry);
		sta_param->fDsssCckMode40Mhz =
			lim_get_ht_capability(mac_ctx, eHT_DSSS_CCK_MODE_40MHZ,
					      session_entry);
		sta_param->fShortGI20Mhz =
			lim_get_ht_capability(mac_ctx, eHT_SHORT_GI_20MHZ,
					      session_entry);
		sta_param->fShortGI40Mhz =
			lim_get_ht_capability(mac_ctx, eHT_SHORT_GI_40MHZ,
					      session_entry);
	}
	if (session_entry->vhtCapability) {
		sta_param->vhtCapable = true;
		sta_param->vhtTxBFCapable =
				session_entry->txBFIniFeatureEnabled;
		sta_param->vhtTxMUBformeeCapable = session_entry->txMuBformee;
		sta_param->enable_su_tx_bformer =
				session_entry->enable_su_tx_bformer;
	}
	/*
	 * Since this is Self-STA, need to populate Self MAX_AMPDU_SIZE
	 * capabilities
	 */
	if (IS_DOT11_MODE_VHT(self_dot11mode)) {
		val = 0;        /* Default 8K AMPDU size */
		if (eSIR_SUCCESS != wlan_cfg_get_int(mac_ctx,
					WNI_CFG_VHT_AMPDU_LEN_EXPONENT, &val))
			lim_log(mac_ctx, LOGE, FL
			    ("Couldn't get WNI_CFG_VHT_AMPDU_LEN_EXPONENT"));
		sta_param->maxAmpduSize = (uint8_t) val;
	}
	sta_param->enableVhtpAid = session_entry->enableVhtpAid;
	sta_param->enableAmpduPs = session_entry->enableAmpduPs;
	sta_param->enableHtSmps = session_entry->enableHtSmps;
	sta_param->htSmpsconfig = session_entry->htSmpsvalue;

#ifdef WLAN_FEATURE_11AC
	lim_populate_own_rate_set(mac_ctx, &sta_param->supportedRates, NULL,
				  false, session_entry, NULL);
#else
	lim_populate_own_rate_set(mac_ctx, &sta_param->supportedRates, NULL,
				  false, session_entry);
#endif
	lim_fill_supported_rates_info(mac_ctx, NULL, &sta_param->supportedRates,
				      session_entry);

	lim_log(mac_ctx, LOGE, FL(
		"GF: %d, ChnlWidth: %d, MimoPS: %d, lsigTXOP: %d, dsssCCK: %d,"
		" SGI20: %d, SGI40%d"), sta_param->greenFieldCapable,
		sta_param->ch_width, sta_param->mimoPS,
		sta_param->lsigTxopProtection, sta_param->fDsssCckMode40Mhz,
		sta_param->fShortGI20Mhz, sta_param->fShortGI40Mhz);

	if (CDF_P2P_GO_MODE == session_entry->pePersona)
		sta_param->p2pCapableSta = 1;
}

/**
 * lim_mlm_add_bss() - HAL interface for WMA_ADD_BSS_REQ
 * @mac_ctx: global MAC context
 * @mlm_start_req: MLM start request
 * @session: PE session entry
 *
 * Package WMA_ADD_BSS_REQ to HAL, in order to start a BSS
 *
 * Return: eSIR_SME_SUCCESS on success, other error codes otherwise
 */
tSirResultCodes
lim_mlm_add_bss(tpAniSirGlobal mac_ctx,
		tLimMlmStartReq *mlm_start_req, tpPESession session)
{
	tSirMsgQ msg_buf;
	tpAddBssParams addbss_param = NULL;
	uint32_t retcode;

	/* Package WMA_ADD_BSS_REQ message parameters */
	addbss_param = cdf_mem_malloc(sizeof(tAddBssParams));
	if (NULL == addbss_param) {
		lim_log(mac_ctx, LOGE,
			FL("Unable to allocate memory during ADD_BSS"));
		/* Respond to SME with LIM_MLM_START_CNF */
		return eSIR_MEM_ALLOC_FAILED;
	}

	cdf_mem_set(addbss_param, sizeof(tAddBssParams), 0);
	/* Fill in tAddBssParams members */
	cdf_mem_copy(addbss_param->bssId, mlm_start_req->bssId,
		     sizeof(tSirMacAddr));

	/* Fill in tAddBssParams selfMacAddr */
	cdf_mem_copy(addbss_param->selfMacAddr,
		     session->selfMacAddr, sizeof(tSirMacAddr));

	addbss_param->bssType = mlm_start_req->bssType;
	if ((mlm_start_req->bssType == eSIR_IBSS_MODE) ||
	    (mlm_start_req->bssType == eSIR_BTAMP_AP_MODE) ||
	    (mlm_start_req->bssType == eSIR_BTAMP_STA_MODE)) {
		addbss_param->operMode = BSS_OPERATIONAL_MODE_STA;
	} else if (mlm_start_req->bssType == eSIR_INFRA_AP_MODE) {
		addbss_param->operMode = BSS_OPERATIONAL_MODE_AP;
	}

	addbss_param->shortSlotTimeSupported = session->shortSlotTimeSupported;
	addbss_param->beaconInterval = mlm_start_req->beaconPeriod;
	addbss_param->dtimPeriod = mlm_start_req->dtimPeriod;
	addbss_param->wps_state = mlm_start_req->wps_state;
	addbss_param->cfParamSet.cfpCount = mlm_start_req->cfParamSet.cfpCount;
	addbss_param->cfParamSet.cfpPeriod =
		mlm_start_req->cfParamSet.cfpPeriod;
	addbss_param->cfParamSet.cfpMaxDuration =
		mlm_start_req->cfParamSet.cfpMaxDuration;
	addbss_param->cfParamSet.cfpDurRemaining =
		mlm_start_req->cfParamSet.cfpDurRemaining;

	addbss_param->rateSet.numRates = mlm_start_req->rateSet.numRates;
	cdf_mem_copy(addbss_param->rateSet.rate, mlm_start_req->rateSet.rate,
		     mlm_start_req->rateSet.numRates);

	addbss_param->nwType = mlm_start_req->nwType;
	addbss_param->htCapable = mlm_start_req->htCapable;
	addbss_param->vhtCapable = session->vhtCapability;
	addbss_param->ch_width = session->ch_width;
	addbss_param->ch_center_freq_seg0 =
		session->ch_center_freq_seg0;
	addbss_param->ch_center_freq_seg1 =
		session->ch_center_freq_seg1;
	addbss_param->htOperMode = mlm_start_req->htOperMode;
	addbss_param->dualCTSProtection = mlm_start_req->dualCTSProtection;
	addbss_param->txChannelWidthSet = mlm_start_req->txChannelWidthSet;

	addbss_param->currentOperChannel = mlm_start_req->channelNumber;
#ifdef WLAN_FEATURE_11W
	addbss_param->rmfEnabled = session->limRmfEnabled;
#endif

	/* Update PE sessionId */
	addbss_param->sessionId = mlm_start_req->sessionId;

	/* Send the SSID to HAL to enable SSID matching for IBSS */
	cdf_mem_copy(&(addbss_param->ssId.ssId),
		     mlm_start_req->ssId.ssId, mlm_start_req->ssId.length);
	addbss_param->ssId.length = mlm_start_req->ssId.length;
	addbss_param->bHiddenSSIDEn = mlm_start_req->ssidHidden;
	lim_log(mac_ctx, LOGE, FL("TRYING TO HIDE SSID %d"),
		addbss_param->bHiddenSSIDEn);
	/* CR309183. Disable Proxy Probe Rsp.  Host handles Probe Requests.  Until FW fixed. */
	addbss_param->bProxyProbeRespEn = 0;
	addbss_param->obssProtEnabled = mlm_start_req->obssProtEnabled;

#if defined WLAN_FEATURE_VOWIFI
	addbss_param->maxTxPower = session->maxTxPower;
#endif
	mlm_add_sta(mac_ctx, &addbss_param->staContext,
		    addbss_param->bssId, addbss_param->htCapable,
		    session);

	addbss_param->status = CDF_STATUS_SUCCESS;
	addbss_param->respReqd = 1;

	/* Set a new state for MLME */
	session->limMlmState = eLIM_MLM_WT_ADD_BSS_RSP_STATE;
	MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, session->peSessionId,
			 session->limMlmState));

	/* pass on the session persona to hal */
	addbss_param->halPersona = session->pePersona;

	addbss_param->bSpectrumMgtEnabled = session->spectrumMgtEnabled ||
		lim_isconnected_on_dfs_channel(mlm_start_req->channelNumber);
#if defined WLAN_FEATURE_VOWIFI_11R
	addbss_param->extSetStaKeyParamValid = 0;
#endif

	addbss_param->dot11_mode = session->dot11mode;
	addbss_param->nss = session->nss;
	lim_log(mac_ctx, LOG2, FL("dot11_mode:%d nss value:%d"),
			addbss_param->dot11_mode, addbss_param->nss);

	msg_buf.type = WMA_ADD_BSS_REQ;
	msg_buf.reserved = 0;
	msg_buf.bodyptr = addbss_param;
	msg_buf.bodyval = 0;
	MTRACE(mac_trace_msg_tx(mac_ctx, session->peSessionId, msg_buf.type));

	lim_log(mac_ctx, LOGW, FL("Sending WMA_ADD_BSS_REQ..."));
	retcode = wma_post_ctrl_msg(mac_ctx, &msg_buf);
	if (eSIR_SUCCESS != retcode) {
		lim_log(mac_ctx, LOGE,
			FL("Posting ADD_BSS_REQ to HAL failed, reason=%X"),
			retcode);
		cdf_mem_free(addbss_param);
		return eSIR_SME_HAL_SEND_MESSAGE_FAIL;
	}

	return eSIR_SME_SUCCESS;
}

/**
 * lim_process_mlm_start_req() - process MLM_START_REQ message
 *
 * @mac_ctx: global MAC context
 * @msg_buf: Pointer to MLM message buffer
 *
 * This function is called to process MLM_START_REQ message
 * from SME
 * 1) MLME receives LIM_MLM_START_REQ from LIM
 * 2) MLME sends WMA_ADD_BSS_REQ to HAL
 * 3) MLME changes state to eLIM_MLM_WT_ADD_BSS_RSP_STATE
 * MLME now waits for HAL to send WMA_ADD_BSS_RSP
 *
 * Return: None
 */
static void lim_process_mlm_start_req(tpAniSirGlobal mac_ctx, uint32_t *msg_buf)
{
	tLimMlmStartReq *mlm_start_req;
	tLimMlmStartCnf mlm_start_cnf;
	tpPESession session = NULL;

	if (msg_buf == NULL) {
		lim_log(mac_ctx, LOGE, FL("Buffer is Pointing to NULL"));
		return;
	}

	mlm_start_req = (tLimMlmStartReq *) msg_buf;
	session = pe_find_session_by_session_id(mac_ctx,
				mlm_start_req->sessionId);
	if (NULL == session) {
		lim_log(mac_ctx, LOGP,
			FL("Session Does not exist for given sessionID"));
		mlm_start_cnf.resultCode = eSIR_SME_REFUSED;
		goto end;
	}

	if (session->limMlmState != eLIM_MLM_IDLE_STATE) {
		/*
		 * Should not have received Start req in states other than idle.
		 * Return Start confirm with failure code.
		 */
		lim_log(mac_ctx, LOGE,
			FL("received unexpected MLM_START_REQ in state %X"),
			session->limMlmState);
		lim_print_mlm_state(mac_ctx, LOGE, session->limMlmState);
		mlm_start_cnf.resultCode =
				eSIR_SME_BSS_ALREADY_STARTED_OR_JOINED;
		goto end;
	}

	mlm_start_cnf.resultCode =
		lim_mlm_add_bss(mac_ctx, mlm_start_req, session);

end:
	/* Update PE session Id */
	mlm_start_cnf.sessionId = mlm_start_req->sessionId;

	/* Free up buffer allocated for LimMlmScanReq */
	cdf_mem_free(msg_buf);

	/*
	 * Respond immediately to LIM, only if MLME has not been
	 * successfully able to send WMA_ADD_BSS_REQ to HAL.
	 * Else, LIM_MLM_START_CNF will be sent after receiving
	 * WMA_ADD_BSS_RSP from HAL
	 */
	if (eSIR_SME_SUCCESS != mlm_start_cnf.resultCode)
		lim_post_sme_message(mac_ctx, LIM_MLM_START_CNF,
				     (uint32_t *) &mlm_start_cnf);
}

#ifdef FEATURE_OEM_DATA_SUPPORT
/**
 * lim_process_mlm_oem_data_req() - process MLM OEM_DATA_REQ message
 * @mac_ctx: global MAC context
 * @msg_buf: MLM message buffer
 *
 * This function process MLM OEM_DATA_REQ message.
 *
 * Return: None
 */
static void lim_process_mlm_oem_data_req(tpAniSirGlobal mac_ctx,
					 uint32_t *msg_buf)
{
	tLimMlmOemDataRsp *mlm_oem_data_rsp;

	if (((mac_ctx->lim.gLimMlmState == eLIM_MLM_IDLE_STATE) ||
	     (mac_ctx->lim.gLimMlmState == eLIM_MLM_JOINED_STATE) ||
	     (mac_ctx->lim.gLimMlmState == eLIM_MLM_AUTHENTICATED_STATE) ||
	     (mac_ctx->lim.gLimMlmState == eLIM_MLM_BSS_STARTED_STATE) ||
	     (mac_ctx->lim.gLimMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE))) {
		/*
		 * Hold onto the oem data request criteria
		 * Free gpLimMlmOemDataReq to avoid memory leak due to
		 * second OEM data request
		 */
		if (mac_ctx->lim.gpLimMlmOemDataReq) {
			cdf_mem_free(mac_ctx->lim.gpLimMlmOemDataReq);
			mac_ctx->lim.gpLimMlmOemDataReq = NULL;
		}

		mac_ctx->lim.gpLimMlmOemDataReq = (tLimMlmOemDataReq *) msg_buf;
		mac_ctx->lim.gLimPrevMlmState = mac_ctx->lim.gLimMlmState;

		lim_log(mac_ctx, LOG2, FL("Calling lim_send_hal_oem_data_req"));
		lim_send_hal_oem_data_req(mac_ctx);
	} else {
		/* Should not have received oem data req in other states */
		lim_log(mac_ctx, LOGW, FL
			("unexpected LIM_MLM_OEM_DATA_REQ in invalid state %X"),
			mac_ctx->lim.gLimMlmState);
		lim_print_mlm_state(mac_ctx, LOGW, mac_ctx->lim.gLimMlmState);

		/* Free up buffer allocated */
		cdf_mem_free(msg_buf);

		/* Return Meas confirm with INVALID_PARAMETERS */
		mlm_oem_data_rsp = cdf_mem_malloc(sizeof(tLimMlmOemDataRsp));
		if (mlm_oem_data_rsp != NULL) {
			lim_post_sme_message(mac_ctx, LIM_MLM_OEM_DATA_CNF,
					     (uint32_t *) mlm_oem_data_rsp);
			cdf_mem_free(mlm_oem_data_rsp);
		} else {
			lim_log(mac_ctx, LOGP, FL
			    ("Could not allocate memory for mlm_oem_data_rsp"));
			return;
		}
	}

	return;
}
#endif /* FEATURE_OEM_DATA_SUPPORT */
/**
 * lim_post_join_set_link_state_callback()- registered callback to perform post
 * peer creation operations
 *
 * @mac: pointer to global mac structure
 * @callback_arg: registered callback argument
 * @status: peer creation status
 *
 * this is registered callback function during association to perform
 * post peer creation operation based on the peer creation status
 *
 * Return: none
 */
void lim_post_join_set_link_state_callback(tpAniSirGlobal mac,
		void *callback_arg, bool status)
{
	uint8_t chan_num, sec_chan_offset;
	tpPESession session_entry = (tpPESession) callback_arg;
	tLimMlmJoinCnf mlm_join_cnf;

	lim_log(mac, LOG1, FL("Sessionid %d set link state(%d) cb status:%d"),
			session_entry->peSessionId, session_entry->limMlmState,
			status);

	if (!status) {
		lim_log(mac, LOGE,
			FL("failed to find pe session for session id:%d"),
			session_entry->peSessionId);
		goto failure;
	}

	chan_num = session_entry->currentOperChannel;
	sec_chan_offset = session_entry->htSecondaryChannelOffset;
	/*
	 * store the channel switch session_entry in the lim
	 * global variable
	 */
	session_entry->channelChangeReasonCode =
			 LIM_SWITCH_CHANNEL_JOIN;
#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || \
	 defined(FEATURE_WLAN_LFR)
	session_entry->pLimMlmReassocRetryReq = NULL;
#endif
	lim_log(mac, LOGE,
		FL("[lim_process_mlm_join_req]: suspend link success(%d) "
		"on sessionid: %d setting channel to: %d with ch_width :%d "
		"and maxtxPower: %d"), status, session_entry->peSessionId,
		session_entry->currentOperChannel,
		session_entry->ch_width,
		session_entry->maxTxPower);
	lim_set_channel(mac, session_entry->currentOperChannel,
		session_entry->ch_center_freq_seg0,
		session_entry->ch_center_freq_seg1,
		session_entry->ch_width,
		session_entry->maxTxPower,
		session_entry->peSessionId);
	return;

failure:
	MTRACE(mac_trace(mac, TRACE_CODE_MLM_STATE, session_entry->peSessionId,
			 session_entry->limMlmState));
	session_entry->limMlmState = eLIM_MLM_IDLE_STATE;
	mlm_join_cnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
	mlm_join_cnf.sessionId = session_entry->peSessionId;
	mlm_join_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
	lim_post_sme_message(mac, LIM_MLM_JOIN_CNF, (uint32_t *) &mlm_join_cnf);
}

/**
 * lim_process_mlm_post_join_suspend_link() - This function is called after the
 * suspend link while joining off channel.
 *
 * @mac_ctx:    Pointer to Global MAC structure
 * @status:  status of suspend link.
 * @ctx:     passed while calling suspend link(session)
 *
 * This function does following:
 *   Check for suspend state.
 *   If success, proceed with setting link state to recieve the
 *   probe response/beacon from intended AP.
 *   Switch to the APs channel.
 *   On an error case, send the MLM_JOIN_CNF with error status.
 *
 * @Return None
 */
static void
lim_process_mlm_post_join_suspend_link(tpAniSirGlobal mac_ctx,
				       CDF_STATUS status,
				       uint32_t *ctx)
{
	tLimMlmJoinCnf mlm_join_cnf;
	tpPESession session = (tpPESession) ctx;
	tSirLinkState lnk_state;

	if (CDF_STATUS_SUCCESS != status) {
		lim_log(mac_ctx, LOGE,
			FL("Sessionid %d Suspend link(NOTIFY_BSS) failed. Still proceeding with join"),
			session->peSessionId);
	}
	lim_deactivate_and_change_timer(mac_ctx, eLIM_JOIN_FAIL_TIMER);

	/* assign appropriate sessionId to the timer object */
	mac_ctx->lim.limTimers.gLimJoinFailureTimer.sessionId =
		session->peSessionId;

	lnk_state = (LIM_IS_BT_AMP_STA_ROLE(session) ?
		eSIR_LINK_BTAMP_PREASSOC_STATE : eSIR_LINK_PREASSOC_STATE);
	lim_log(mac_ctx, LOG1, FL("[lim_process_mlm_join_req]: lnk_state:%d"),
		lnk_state);

	if (lim_set_link_state(mac_ctx, lnk_state,
			session->pLimMlmJoinReq->bssDescription.bssId,
			session->selfMacAddr,
			lim_post_join_set_link_state_callback,
			session) != eSIR_SUCCESS) {
		lim_log(mac_ctx, LOGE,
			FL("SessionId:%d lim_set_link_state to eSIR_LINK_PREASSOC_STATE Failed!!"),
			session->peSessionId);
		lim_print_mac_addr(mac_ctx,
			session->pLimMlmJoinReq->bssDescription.bssId, LOGE);
		mlm_join_cnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
		session->limMlmState = eLIM_MLM_IDLE_STATE;
		MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
				 session->peSessionId, session->limMlmState));
		goto error;
	}

	return;
error:
	mlm_join_cnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
	mlm_join_cnf.sessionId = session->peSessionId;
	mlm_join_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
	lim_post_sme_message(mac_ctx, LIM_MLM_JOIN_CNF,
			     (uint32_t *) &mlm_join_cnf);
}

/**
 * lim_process_mlm_join_req() - process mlm join request.
 *
 * @mac_ctx:    Pointer to Global MAC structure
 * @msg:        Pointer to the MLM message buffer
 *
 * This function is called to process MLM_JOIN_REQ message
 * from SME. It does following:
 * 1) Initialize LIM, HAL, DPH
 * 2) Configure the BSS for which the JOIN REQ was received
 *   a) Send WMA_ADD_BSS_REQ to HAL -
 *   This will identify the BSS that we are interested in
 *   --AND--
 *   Add a STA entry for the AP (in a STA context)
 *   b) Wait for WMA_ADD_BSS_RSP
 *   c) Send WMA_ADD_STA_REQ to HAL
 *   This will add the "local STA" entry to the STA table
 * 3) Continue as before, i.e,
 *   a) Send a PROBE REQ
 *   b) Wait for PROBE RSP/BEACON containing the SSID that
 *   we are interested in
 *   c) Then start an AUTH seq
 *   d) Followed by the ASSOC seq
 *
 * @Return: None
 */
static void lim_process_mlm_join_req(tpAniSirGlobal mac_ctx, uint32_t *msg)
{
	tLimMlmJoinCnf mlmjoin_cnf;
	uint8_t sessionid;
	tpPESession session;

	sessionid = ((tpLimMlmJoinReq) msg)->sessionId;

	session = pe_find_session_by_session_id(mac_ctx, sessionid);
	if (NULL == session) {
		lim_log(mac_ctx, LOGE, FL("SessionId:%d does not exist"),
			sessionid);
		goto error;
	}

	if ((!LIM_IS_AP_ROLE(session) &&
	     !LIM_IS_BT_AMP_AP_ROLE(session)) &&
	     ((session->limMlmState == eLIM_MLM_IDLE_STATE) ||
	     (session->limMlmState == eLIM_MLM_JOINED_STATE)) &&
	     (SIR_MAC_GET_ESS
		(((tpLimMlmJoinReq) msg)->bssDescription.capabilityInfo) !=
		SIR_MAC_GET_IBSS(((tpLimMlmJoinReq) msg)->bssDescription.
			capabilityInfo))) {
		/* Hold onto Join request parameters */

		session->pLimMlmJoinReq = (tpLimMlmJoinReq) msg;
		if (is_lim_session_off_channel(mac_ctx, sessionid)) {
			lim_log(mac_ctx, LOG1,
				"SessionId:%d LimSession is on OffChannel",
				sessionid);
			/* suspend link */
			lim_log(mac_ctx, LOG1,
				FL("Suspend link, sessionid %d is off channel"),
				sessionid);
			if (lim_is_link_suspended(mac_ctx)) {
				lim_log(mac_ctx, LOGE, FL(
					"link is already suspended, session %d"
					), sessionid);
				goto error;
			}
			lim_process_mlm_post_join_suspend_link(mac_ctx,
				CDF_STATUS_SUCCESS, (uint32_t *)session);
		} else {
			lim_log(mac_ctx, LOG1, FL("No need to Suspend link"));
			 /*
			  * No need to Suspend link as LimSession is not
			  * off channel, calling
			  * lim_process_mlm_post_join_suspend_link with
			  * status as SUCCESS.
			  */
			lim_log(mac_ctx, LOG1,
				FL("SessionId:%d Join req on current chan"),
				sessionid);
			lim_process_mlm_post_join_suspend_link(mac_ctx,
				CDF_STATUS_SUCCESS, (uint32_t *)session);
		}
		return;
	} else {
		/**
		 * Should not have received JOIN req in states other than
		 * Idle state or on AP.
		 * Return join confirm with invalid parameters code.
		 */
		lim_log(mac_ctx, LOGE,
			FL("Session:%d Unexpected Join req, role %d state %X"),
			session->peSessionId, GET_LIM_SYSTEM_ROLE(session),
			session->limMlmState);
		lim_print_mlm_state(mac_ctx, LOGE, session->limMlmState);
	}

error:
	cdf_mem_free(msg);
	if (session != NULL)
		session->pLimMlmJoinReq = NULL;
	mlmjoin_cnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
	mlmjoin_cnf.sessionId = sessionid;
	mlmjoin_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
	lim_post_sme_message(mac_ctx, LIM_MLM_JOIN_CNF,
		(uint32_t *)&mlmjoin_cnf);

}

/**
 * lim_is_auth_req_expected() - check if auth request is expected
 *
 * @mac_ctx: global MAC context
 * @session: PE session entry
 *
 * This function is called by lim_process_mlm_auth_req to check
 * if auth request is expected.
 *
 * Return: true if expected and false otherwise
 */
static bool lim_is_auth_req_expected(tpAniSirGlobal mac_ctx,
				     tpPESession session)
{
	bool flag = false;

	/*
	 * Expect Auth request only when:
	 * 1. STA joined/associated with a BSS or
	 * 2. STA is in IBSS mode
	 * and STA is going to authenticate with a unicast
	 * address and requested authentication algorithm is
	 * supported.
	 */

	flag = ((((LIM_IS_STA_ROLE(session) ||
		   LIM_IS_BT_AMP_STA_ROLE(session)) &&
		 ((session->limMlmState == eLIM_MLM_JOINED_STATE) ||
		  (session->limMlmState ==
					eLIM_MLM_LINK_ESTABLISHED_STATE))) ||
		  (LIM_IS_IBSS_ROLE(session) &&
		  (session->limMlmState ==
					eLIM_MLM_BSS_STARTED_STATE))) &&
		(!lim_is_group_addr(mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr))
		 && lim_is_auth_algo_supported(mac_ctx,
			mac_ctx->lim.gpLimMlmAuthReq->authType, session));

	return flag;
}

/**
 * lim_is_preauth_ctx_exisits() - check if preauth context exists
 *
 * @mac_ctx:          global MAC context
 * @session:          PE session entry
 * @preauth_node_ptr: pointer to preauth node pointer
 *
 * This function is called by lim_process_mlm_auth_req to check
 * if preauth context already exists
 *
 * Return: true if exists and false otherwise
 */
static bool lim_is_preauth_ctx_exists(tpAniSirGlobal mac_ctx,
				      tpPESession session,
				      struct tLimPreAuthNode **preauth_node_ptr)
{
	bool fl = false;
	struct tLimPreAuthNode *preauth_node;
	tpDphHashNode stads;
	tSirMacAddr curr_bssid;

	preauth_node = *preauth_node_ptr;
	sir_copy_mac_addr(curr_bssid, session->bssId);
	stads = dph_get_hash_entry(mac_ctx, DPH_STA_HASH_INDEX_PEER,
				   &session->dph.dphHashTable);
	preauth_node = lim_search_pre_auth_list(mac_ctx,
				mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr);

	fl = (((LIM_IS_STA_ROLE(session) || LIM_IS_BT_AMP_STA_ROLE(session)) &&
	       (session->limMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE) &&
	      ((stads != NULL) &&
	       (mac_ctx->lim.gpLimMlmAuthReq->authType ==
			stads->mlmStaContext.authType)) &&
	       (cdf_mem_compare(mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr,
			curr_bssid, sizeof(tSirMacAddr)))) ||
	      ((preauth_node != NULL) &&
	       (preauth_node->authType ==
			mac_ctx->lim.gpLimMlmAuthReq->authType)));

	return fl;
}

/**
 * lim_process_mlm_auth_req() - process lim auth request
 *
 * @mac_ctx:   global MAC context
 * @msg:       MLM auth request message
 *
 * This function is called to process MLM_AUTH_REQ message from SME
 *
 * @Return: None
 */
static void lim_process_mlm_auth_req(tpAniSirGlobal mac_ctx, uint32_t *msg)
{
	uint32_t num_preauth_ctx;
	tSirMacAddr curr_bssid;
	tSirMacAuthFrameBody auth_frame_body;
	tLimMlmAuthCnf mlm_auth_cnf;
	struct tLimPreAuthNode *preauth_node = NULL;
	uint8_t session_id;
	tpPESession session;

	if (msg == NULL) {
		lim_log(mac_ctx, LOGE, FL("Buffer is Pointing to NULL"));
		return;
	}

	mac_ctx->lim.gpLimMlmAuthReq = (tLimMlmAuthReq *) msg;
	session_id = mac_ctx->lim.gpLimMlmAuthReq->sessionId;
	session = pe_find_session_by_session_id(mac_ctx, session_id);
	if (NULL == session) {
		lim_log(mac_ctx, LOGP, FL("SessionId:%d does not exist"),
			session_id);
		return;
	}

	lim_log(mac_ctx, LOG1, FL("Process Auth Req sessionID %d Systemrole %d"
			       "mlmstate %d from: " MAC_ADDRESS_STR
			       " with authtype %d"), session_id,
		GET_LIM_SYSTEM_ROLE(session), session->limMlmState,
		MAC_ADDR_ARRAY(mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr),
		mac_ctx->lim.gpLimMlmAuthReq->authType);

	sir_copy_mac_addr(curr_bssid, session->bssId);

	if (!lim_is_auth_req_expected(mac_ctx, session)) {
		/*
		 * Unexpected auth request.
		 * Return Auth confirm with Invalid parameters code.
		 */
		mlm_auth_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
		goto end;
	}

	/*
	 * This is a request for pre-authentication. Check if there exists
	 * context already for the requested peer OR
	 * if this request is for the AP we're currently associated with.
	 * If yes, return auth confirm immediately when
	 * requested auth type is same as the one used before.
	 */
	if (lim_is_preauth_ctx_exists(mac_ctx, session, &preauth_node)) {
		lim_log(mac_ctx, LOG2,
		    FL("Already have pre-auth context with peer: "
		    MAC_ADDRESS_STR),
		    MAC_ADDR_ARRAY(mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr));
		mlm_auth_cnf.resultCode = (tSirResultCodes)
						eSIR_MAC_SUCCESS_STATUS;
		goto end;
	} else {
		if (wlan_cfg_get_int(mac_ctx, WNI_CFG_MAX_NUM_PRE_AUTH,
			(uint32_t *) &num_preauth_ctx) != eSIR_SUCCESS)
			lim_log(mac_ctx, LOGP,
			    FL("Could not retrieve NumPreAuthLimit from CFG"));

		if (mac_ctx->lim.gLimNumPreAuthContexts == num_preauth_ctx) {
			lim_log(mac_ctx, LOGW,
				FL("Number of pre-auth reached max limit"));
			/* Return Auth confirm with reject code */
			mlm_auth_cnf.resultCode =
				eSIR_SME_MAX_NUM_OF_PRE_AUTH_REACHED;
			goto end;
		}
	}

	/* Delete pre-auth node if exists */
	if (preauth_node)
		lim_delete_pre_auth_node(mac_ctx,
			 mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr);

	session->limPrevMlmState = session->limMlmState;
	session->limMlmState = eLIM_MLM_WT_AUTH_FRAME2_STATE;
	MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, session->peSessionId,
		       session->limMlmState));

	/* Prepare & send Authentication frame */
	auth_frame_body.authAlgoNumber =
		(uint8_t) mac_ctx->lim.gpLimMlmAuthReq->authType;
	auth_frame_body.authTransactionSeqNumber = SIR_MAC_AUTH_FRAME_1;
	auth_frame_body.authStatusCode = 0;
#ifdef FEATURE_WLAN_DIAG_SUPPORT
	lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_AUTH_START_EVENT, session,
			      eSIR_SUCCESS, auth_frame_body.authStatusCode);
#endif

	lim_send_auth_mgmt_frame(mac_ctx,
		&auth_frame_body, mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr,
		LIM_NO_WEP_IN_FC, session);

	/* assign appropriate session_id to the timer object */
	mac_ctx->lim.limTimers.gLimAuthFailureTimer.sessionId = session_id;

	/* Activate Auth failure timer */
	MTRACE(mac_trace(mac_ctx, TRACE_CODE_TIMER_ACTIVATE,
			 session->peSessionId, eLIM_AUTH_FAIL_TIMER));
	if (tx_timer_activate(&mac_ctx->lim.limTimers.gLimAuthFailureTimer)
	    != TX_SUCCESS) {
		/* Could not start Auth failure timer. */
		lim_log(mac_ctx, LOGP,
			FL("could not start Auth failure timer"));
		/* Cleanup as if auth timer expired */
		lim_process_auth_failure_timeout(mac_ctx);
	}
	return;
end:
	cdf_mem_copy((uint8_t *) &mlm_auth_cnf.peerMacAddr,
		     (uint8_t *) &mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr,
		     sizeof(tSirMacAddr));

	mlm_auth_cnf.authType = mac_ctx->lim.gpLimMlmAuthReq->authType;
	mlm_auth_cnf.sessionId = session_id;

	cdf_mem_free(mac_ctx->lim.gpLimMlmAuthReq);
	mac_ctx->lim.gpLimMlmAuthReq = NULL;
	lim_log(mac_ctx, LOG1, "SessionId:%d LimPostSme LIM_MLM_AUTH_CNF ",
		session_id);
	lim_post_sme_message(mac_ctx, LIM_MLM_AUTH_CNF,
			     (uint32_t *) &mlm_auth_cnf);
}

/**
 * lim_process_mlm_assoc_req() - This function is called to process
 * MLM_ASSOC_REQ message from SME
 *
 * @mac_ctx:       Pointer to Global MAC structure
 * @msg_buf:       A pointer to the MLM message buffer
 *
 * This function is called to process MLM_ASSOC_REQ message from SME
 *
 * @Return None
 */

static void lim_process_mlm_assoc_req(tpAniSirGlobal mac_ctx, uint32_t *msg_buf)
{
	tSirMacAddr curr_bssId;
	tLimMlmAssocReq *mlm_assoc_req;
	tLimMlmAssocCnf mlm_assoc_cnf;
	tpPESession session_entry;

	if (msg_buf == NULL) {
		lim_log(mac_ctx, LOGE, FL("Buffer is Pointing to NULL"));
		return;
	}

	mlm_assoc_req = (tLimMlmAssocReq *) msg_buf;
	session_entry = pe_find_session_by_session_id(mac_ctx,
						      mlm_assoc_req->sessionId);
	if (session_entry == NULL) {
		lim_log(mac_ctx, LOGP,
			FL("SessionId:%d Session Does not exist"),
			mlm_assoc_req->sessionId);
		cdf_mem_free(mlm_assoc_req);
		return;
	}

	sir_copy_mac_addr(curr_bssId, session_entry->bssId);

	if (!((!LIM_IS_AP_ROLE(session_entry) &&
	    !LIM_IS_BT_AMP_AP_ROLE(session_entry)) &&
		(session_entry->limMlmState == eLIM_MLM_AUTHENTICATED_STATE ||
		 session_entry->limMlmState == eLIM_MLM_JOINED_STATE) &&
		(cdf_mem_compare(mlm_assoc_req->peerMacAddr,
		 curr_bssId, sizeof(tSirMacAddr))))) {
		/*
		 * Received Association request either in invalid state
		 * or to a peer MAC entity whose address is different
		 * from one that STA is currently joined with or on AP.
		 * Return Assoc confirm with Invalid parameters code.
		 */
		lim_log(mac_ctx, LOGW,
			FL("received unexpected MLM_ASSOC_CNF in state %X for role=%d, MAC addr= "
			   MAC_ADDRESS_STR), session_entry->limMlmState,
			GET_LIM_SYSTEM_ROLE(session_entry),
			MAC_ADDR_ARRAY(mlm_assoc_req->peerMacAddr));
		lim_print_mlm_state(mac_ctx, LOGW, session_entry->limMlmState);
		mlm_assoc_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
		mlm_assoc_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
		goto end;
	}

	/* map the session entry pointer to the AssocFailureTimer */
	mac_ctx->lim.limTimers.gLimAssocFailureTimer.sessionId =
		mlm_assoc_req->sessionId;
#ifdef WLAN_FEATURE_11W
	/*
	 * Store current MLM state in case ASSOC response returns with
	 * TRY_AGAIN_LATER return code.
	 */
	if (session_entry->limRmfEnabled) {
		session_entry->pmfComebackTimerInfo.limPrevMlmState =
			session_entry->limPrevMlmState;
		session_entry->pmfComebackTimerInfo.limMlmState =
			session_entry->limMlmState;
	}
#endif /* WLAN_FEATURE_11W */

	session_entry->limPrevMlmState = session_entry->limMlmState;
	session_entry->limMlmState = eLIM_MLM_WT_ASSOC_RSP_STATE;
	MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
			 session_entry->peSessionId,
			 session_entry->limMlmState));
	lim_log(mac_ctx, LOG1, FL("SessionId:%d Sending Assoc_Req Frame"),
		session_entry->peSessionId);

	/* Prepare and send Association request frame */
	lim_send_assoc_req_mgmt_frame(mac_ctx, mlm_assoc_req, session_entry);

	/*
	 * Set the link state to postAssoc, so HW can start receiving frames
	 * from AP.
	 */
	if ((session_entry->bssType == eSIR_BTAMP_STA_MODE) ||
	    ((session_entry->bssType == eSIR_BTAMP_AP_MODE)
	     && LIM_IS_BT_AMP_STA_ROLE(session_entry))) {
		if (lim_set_link_state(mac_ctx, eSIR_LINK_BTAMP_POSTASSOC_STATE,
					curr_bssId, session_entry->selfMacAddr,
					NULL, NULL) != eSIR_SUCCESS)
			lim_log(mac_ctx, LOGE,
				FL("Failed to set the LinkState"));
	}
	/* Start association failure timer */
	MTRACE(mac_trace(mac_ctx, TRACE_CODE_TIMER_ACTIVATE,
			 session_entry->peSessionId, eLIM_ASSOC_FAIL_TIMER));
	if (tx_timer_activate(&mac_ctx->lim.limTimers.gLimAssocFailureTimer)
	    != TX_SUCCESS) {
		lim_log(mac_ctx, LOGP,
			FL("SessionId:%d couldn't start Assoc failure timer"),
			session_entry->peSessionId);
		/* Cleanup as if assoc timer expired */
		lim_process_assoc_failure_timeout(mac_ctx, LIM_ASSOC);
	}

	return;
end:
	/* Update PE session Id */
	mlm_assoc_cnf.sessionId = mlm_assoc_req->sessionId;
	/* Free up buffer allocated for assocReq */
	cdf_mem_free(mlm_assoc_req);
	lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_CNF,
			     (uint32_t *) &mlm_assoc_cnf);
}

/**
 * lim_process_mlm_reassoc_req() - process mlm reassoc request.
 *
 * @mac_ctx:     pointer to Global MAC structure
 * @msg:  pointer to the MLM message buffer
 *
 * This function is called to process MLM_REASSOC_REQ message
 * from SME
 *
 * Return: None
 */
static void lim_process_mlm_reassoc_req(tpAniSirGlobal mac_ctx, uint32_t *msg)
{
	uint8_t channel, sec_ch_offset;
	struct tLimPreAuthNode *auth_node;
	tLimMlmReassocReq *reassoc_req;
	tLimMlmReassocCnf reassoc_cnf;
	tpPESession session;

	if (msg == NULL) {
		lim_log(mac_ctx, LOGE, FL("Buffer is Pointing to NULL"));
		return;
	}

	reassoc_req = (tLimMlmReassocReq *) msg;
	session = pe_find_session_by_session_id(mac_ctx,
			reassoc_req->sessionId);
	if (NULL == session) {
		lim_log(mac_ctx, LOGE,
			FL("Session Does not exist for given sessionId %d"),
			reassoc_req->sessionId);
		cdf_mem_free(reassoc_req);
		return;
	}

	lim_log(mac_ctx, LOG1,
		FL("Process ReAssoc Req on sessionID %d Systemrole %d mlmstate %d from: " MAC_ADDRESS_STR),
		reassoc_req->sessionId, GET_LIM_SYSTEM_ROLE(session),
		session->limMlmState, MAC_ADDR_ARRAY(reassoc_req->peerMacAddr));

	if ((LIM_IS_AP_ROLE(session) ||
		LIM_IS_BT_AMP_AP_ROLE(session)) ||
		(session->limMlmState !=
		eLIM_MLM_LINK_ESTABLISHED_STATE)) {
		/*
		 * Received Reassoc request in invalid state or
		 * in AP role.Return Reassoc confirm with Invalid
		 * parameters code.
		 */

		lim_log(mac_ctx, LOGW,
			FL("received unexpected MLM_REASSOC_CNF in state %X for role=%d, MAC addr= " MAC_ADDRESS_STR),
			session->limMlmState, GET_LIM_SYSTEM_ROLE(session),
			MAC_ADDR_ARRAY(reassoc_req->peerMacAddr));
		lim_print_mlm_state(mac_ctx, LOGW, session->limMlmState);
		reassoc_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
		reassoc_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
		goto end;
	}

	if (session->pLimMlmReassocReq)
		cdf_mem_free(session->pLimMlmReassocReq);

	/*
	 * Hold Re-Assoc request as part of Session, knock-out mac_ctx
	 * Hold onto Reassoc request parameters
	 */
	session->pLimMlmReassocReq = reassoc_req;

	/* See if we have pre-auth context with new AP */
	auth_node = lim_search_pre_auth_list(mac_ctx, session->limReAssocbssId);

	if (!auth_node && (!cdf_mem_compare(reassoc_req->peerMacAddr,
					    session->bssId,
					    sizeof(tSirMacAddr)))) {
		/*
		 * Either pre-auth context does not exist AND
		 * we are not reassociating with currently
		 * associated AP.
		 * Return Reassoc confirm with not authenticated
		 */
		reassoc_cnf.resultCode = eSIR_SME_STA_NOT_AUTHENTICATED;
		reassoc_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;

		goto end;
	}
	/* assign the sessionId to the timer object */
	mac_ctx->lim.limTimers.gLimReassocFailureTimer.sessionId =
		reassoc_req->sessionId;
	session->limPrevMlmState = session->limMlmState;
	session->limMlmState = eLIM_MLM_WT_REASSOC_RSP_STATE;
	MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, session->peSessionId,
			 session->limMlmState));

	/* Derive channel from BSS description and store it at CFG. */
	channel = session->limReassocChannelId;
	sec_ch_offset = session->reAssocHtSecondaryChannelOffset;

	/* Apply previously set configuration at HW */
	lim_apply_configuration(mac_ctx, session);

	/* store the channel switch sessionEntry in the lim global var */
	session->channelChangeReasonCode =
		LIM_SWITCH_CHANNEL_REASSOC;

	/* Switch channel to the new Operating channel for Reassoc */
	lim_set_channel(mac_ctx, channel,
			session->ch_center_freq_seg0,
			session->ch_center_freq_seg1,
			session->ch_width,
			session->maxTxPower,
			session->peSessionId);

	return;
end:
	reassoc_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
	/* Update PE sessio Id */
	reassoc_cnf.sessionId = reassoc_req->sessionId;
	/* Free up buffer allocated for reassocReq */
	cdf_mem_free(reassoc_req);
	session->pLimReAssocReq = NULL;
	lim_post_sme_message(mac_ctx, LIM_MLM_REASSOC_CNF,
			     (uint32_t *) &reassoc_cnf);
}

/**
 * lim_process_mlm_disassoc_req_ntf() - process disassoc request notification
 *
 * @mac_ctx:        global MAC context
 * @suspend_status: suspend status
 * @msg:            mlm message buffer
 *
 * This function is used to process MLM disassoc notification
 *
 * Return: None
 */
static void
lim_process_mlm_disassoc_req_ntf(tpAniSirGlobal mac_ctx,
				 CDF_STATUS suspend_status, uint32_t *msg)
{
	uint16_t aid;
	tSirMacAddr curr_bssid;
	tpDphHashNode stads;
	tLimMlmDisassocReq *mlm_disassocreq;
	tLimMlmDisassocCnf mlm_disassoccnf;
	tpPESession session;
	extern bool send_disassoc_frame;
	tLimMlmStates mlm_state;

	if (CDF_STATUS_SUCCESS != suspend_status)
		lim_log(mac_ctx, LOGE, FL("Suspend Status is not success %X"),
			suspend_status);

	mlm_disassocreq = (tLimMlmDisassocReq *) msg;

	session = pe_find_session_by_session_id(mac_ctx,
				mlm_disassocreq->sessionId);
	if (NULL == session) {
		lim_log(mac_ctx, LOGE,
			FL("session does not exist for given sessionId %d"),
			mlm_disassocreq->sessionId);
		mlm_disassoccnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
		goto end;
	}

	lim_log(mac_ctx, LOG1,
		FL("Process DisAssoc Req on sessionID %d Systemrole %d"
		   "mlmstate %d from: " MAC_ADDRESS_STR),
		mlm_disassocreq->sessionId, GET_LIM_SYSTEM_ROLE(session),
		session->limMlmState,
		MAC_ADDR_ARRAY(mlm_disassocreq->peerMacAddr));

	sir_copy_mac_addr(curr_bssid, session->bssId);

	switch (GET_LIM_SYSTEM_ROLE(session)) {
	case eLIM_STA_ROLE:
	case eLIM_BT_AMP_STA_ROLE:
		if (!cdf_mem_compare(mlm_disassocreq->peerMacAddr,
				     curr_bssid, sizeof(tSirMacAddr))) {
			lim_log(mac_ctx, LOGW,
			  FL("received MLM_DISASSOC_REQ with invalid BSS id"));
			lim_print_mac_addr(mac_ctx,
				mlm_disassocreq->peerMacAddr, LOGW);

			/* Prepare and Send LIM_MLM_DISASSOC_CNF */
			mlm_disassoccnf.resultCode =
				eSIR_SME_INVALID_PARAMETERS;
			goto end;
		}
		break;
	case eLIM_STA_IN_IBSS_ROLE:
		break;
	case eLIM_AP_ROLE:
	case eLIM_P2P_DEVICE_GO:
		if (true ==
			 mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running) {
			lim_log(mac_ctx, LOGE,
				FL("CAC timer is running, drop disassoc from going out"));
			mlm_disassoccnf.resultCode = eSIR_SME_SUCCESS;
			goto end;
		}
		break;
	default:
		break;
	} /* end switch (GET_LIM_SYSTEM_ROLE(session)) */

	/*
	 * Check if there exists a context for the peer entity
	 * to be disassociated with.
	 */
	stads = dph_lookup_hash_entry(mac_ctx, mlm_disassocreq->peerMacAddr,
				      &aid, &session->dph.dphHashTable);
	if (stads)
		mlm_state = stads->mlmStaContext.mlmState;

	if ((stads == NULL) ||
	    (stads &&
	     ((mlm_state != eLIM_MLM_LINK_ESTABLISHED_STATE) &&
	      (mlm_state != eLIM_MLM_WT_ASSOC_CNF_STATE) &&
	      (mlm_state != eLIM_MLM_ASSOCIATED_STATE)))) {
		/*
		 * Received LIM_MLM_DISASSOC_REQ for STA that does not
		 * have context or in some transit state.
		 */
		lim_log(mac_ctx, LOGW,
			FL("Invalid MLM_DISASSOC_REQ, Addr= " MAC_ADDRESS_STR),
			MAC_ADDR_ARRAY(mlm_disassocreq->peerMacAddr));
		if (stads != NULL)
			lim_log(mac_ctx, LOGE, FL("Sta MlmState : %d"),
				stads->mlmStaContext.mlmState);

		/* Prepare and Send LIM_MLM_DISASSOC_CNF */
		mlm_disassoccnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
		goto end;
	}

	stads->mlmStaContext.disassocReason = (tSirMacReasonCodes)
					       mlm_disassocreq->reasonCode;
	stads->mlmStaContext.cleanupTrigger = mlm_disassocreq->disassocTrigger;

	/*
	 * Set state to mlm State to eLIM_MLM_WT_DEL_STA_RSP_STATE
	 * This is to address the issue of race condition between
	 * disconnect request from the HDD and deauth from AP
	 */

	stads->mlmStaContext.mlmState = eLIM_MLM_WT_DEL_STA_RSP_STATE;

	/* Send Disassociate frame to peer entity */
	if (send_disassoc_frame && (mlm_disassocreq->reasonCode !=
		eSIR_MAC_DISASSOC_DUE_TO_FTHANDOFF_REASON)) {
		mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq =
			mlm_disassocreq;
		/*
		 * Set state to mlm State to eLIM_MLM_WT_DEL_STA_RSP_STATE
		 * This is to address the issue of race condition between
		 * disconnect request from the HDD and deauth from AP
		 */
		stads->mlmStaContext.mlmState = eLIM_MLM_WT_DEL_STA_RSP_STATE;

		/*
		 * If the reason for disassociation is inactivity of STA, then
		 * dont wait for acknowledgement
		 */
		if ((mlm_disassocreq->reasonCode ==
		    eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON) &&
		    LIM_IS_AP_ROLE(session)) {
			lim_send_disassoc_mgmt_frame(mac_ctx,
				mlm_disassocreq->reasonCode,
				mlm_disassocreq->peerMacAddr, session, false);

			/* Send Disassoc CNF and receive path cleanup */
			lim_send_disassoc_cnf(mac_ctx);
		} else {
			lim_send_disassoc_mgmt_frame(mac_ctx,
				mlm_disassocreq->reasonCode,
				mlm_disassocreq->peerMacAddr, session, true);
			/*
			 * Abort Tx so that data frames won't be sent to the AP
			 * after sending Disassoc.
			 */
			if (LIM_IS_STA_ROLE(session))
				wma_tx_abort(session->smeSessionId);
		}
	} else {
		/* Disassoc frame is not sent OTA */
		send_disassoc_frame = 1;
		/* Receive path cleanup with dummy packet */
		if (eSIR_SUCCESS !=
		    lim_cleanup_rx_path(mac_ctx, stads, session)) {
			mlm_disassoccnf.resultCode =
				eSIR_SME_RESOURCES_UNAVAILABLE;
			goto end;
		}
		/* Free up buffer allocated for mlmDisassocReq */
		cdf_mem_free(mlm_disassocreq);
	}

	return;

end:
	cdf_mem_copy((uint8_t *) &mlm_disassoccnf.peerMacAddr,
		     (uint8_t *) mlm_disassocreq->peerMacAddr,
		     sizeof(tSirMacAddr));
	mlm_disassoccnf.aid = mlm_disassocreq->aid;
	mlm_disassoccnf.disassocTrigger = mlm_disassocreq->disassocTrigger;

	/* Update PE session ID */
	mlm_disassoccnf.sessionId = mlm_disassocreq->sessionId;

	/* Free up buffer allocated for mlmDisassocReq */
	cdf_mem_free(mlm_disassocreq);

	lim_post_sme_message(mac_ctx, LIM_MLM_DISASSOC_CNF,
			     (uint32_t *) &mlm_disassoccnf);
}

/**
 * lim_check_disassoc_deauth_ack_pending() - check if deauth is pending
 *
 * @mac_ctx - global MAC context
 * @sta_mac - station MAC
 *
 * This function checks if diassociation or deauthentication is pending for
 * given station MAC address.
 *
 * Return: true if pending and false otherwise.
 */
bool lim_check_disassoc_deauth_ack_pending(tpAniSirGlobal mac_ctx,
					   uint8_t *sta_mac)
{
	tLimMlmDisassocReq *disassoc_req;
	tLimMlmDeauthReq *deauth_req;

	disassoc_req = mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq;
	deauth_req = mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDeauthReq;
	if ((disassoc_req && (cdf_mem_compare((uint8_t *) sta_mac,
			      (uint8_t *) &disassoc_req->peerMacAddr,
			       sizeof(tSirMacAddr)))) ||
	    (deauth_req && (cdf_mem_compare((uint8_t *) sta_mac,
			      (uint8_t *) &deauth_req->peerMacAddr,
			       sizeof(tSirMacAddr))))) {
		PELOG1(lim_log(mac_ctx, LOG1,
			       FL("Disassoc/Deauth ack pending"));)
		return true;
	} else {
		PELOG1(lim_log(mac_ctx, LOG1,
			       FL("Disassoc/Deauth Ack not pending"));)
		return false;
	}
}

/*
 * lim_clean_up_disassoc_deauth_req() - cleans up pending disassoc or deauth req
 *
 * @mac_ctx:        mac_ctx
 * @sta_mac:        sta mac address
 * @clean_rx_path:  flag to indicate whether to cleanup rx path or not
 *
 * This function cleans up pending disassoc or deauth req
 *
 * Return: void
 */
void lim_clean_up_disassoc_deauth_req(tpAniSirGlobal mac_ctx,
				      uint8_t *sta_mac, bool clean_rx_path)
{
	tLimMlmDisassocReq *mlm_disassoc_req;
	tLimMlmDeauthReq *mlm_deauth_req;
	mlm_disassoc_req = mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq;
	if (mlm_disassoc_req &&
	    (cdf_mem_compare((uint8_t *) sta_mac,
			     (uint8_t *) &mlm_disassoc_req->peerMacAddr,
			     sizeof(tSirMacAddr)))) {
		if (clean_rx_path) {
			lim_process_disassoc_ack_timeout(mac_ctx);
		} else {
			if (tx_timer_running(
				&mac_ctx->lim.limTimers.gLimDisassocAckTimer)) {
				lim_deactivate_and_change_timer(mac_ctx,
						eLIM_DISASSOC_ACK_TIMER);
			}
			cdf_mem_free(mlm_disassoc_req);
			mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq =
				NULL;
		}
	}

	mlm_deauth_req = mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDeauthReq;
	if (mlm_deauth_req &&
	    (cdf_mem_compare((uint8_t *) sta_mac,
			     (uint8_t *) &mlm_deauth_req->peerMacAddr,
			     sizeof(tSirMacAddr)))) {
		if (clean_rx_path) {
			lim_process_deauth_ack_timeout(mac_ctx);
		} else {
			if (tx_timer_running(
				&mac_ctx->lim.limTimers.gLimDeauthAckTimer)) {
				lim_deactivate_and_change_timer(mac_ctx,
						eLIM_DEAUTH_ACK_TIMER);
			}
			cdf_mem_free(mlm_deauth_req);
			mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDeauthReq =
				NULL;
		}
	}
}

/*
 * lim_process_disassoc_ack_timeout() - wrapper function around
 * lim_send_disassoc_cnf
 *
 * @mac_ctx:        mac_ctx
 *
 * wrapper function around lim_send_disassoc_cnf
 *
 * Return: void
 */
void lim_process_disassoc_ack_timeout(tpAniSirGlobal mac_ctx)
{
	lim_log(mac_ctx, LOG1, FL(""));
	lim_send_disassoc_cnf(mac_ctx);
}

/**
 * lim_process_mlm_disassoc_req() - This function is called to process
 * MLM_DISASSOC_REQ message from SME
 *
 * @mac_ctx:      Pointer to Global MAC structure
 * @msg_buf:      A pointer to the MLM message buffer
 *
 * This function is called to process MLM_DISASSOC_REQ message from SME
 *
 * @Return: None
 */
static void
lim_process_mlm_disassoc_req(tpAniSirGlobal mac_ctx, uint32_t *msg_buf)
{
	tLimMlmDisassocReq *mlm_disassoc_req;
	tpPESession session;

	if (msg_buf == NULL) {
		lim_log(mac_ctx, LOGE,
			FL("Buffer is Pointing to NULL"));
		return;
	}

	mlm_disassoc_req = (tLimMlmDisassocReq *) msg_buf;
	lim_log(mac_ctx, LOG1,
		FL("Process disassoc req, sessionID %d from: "MAC_ADDRESS_STR),
		mlm_disassoc_req->sessionId,
		MAC_ADDR_ARRAY(mlm_disassoc_req->peerMacAddr));

	session = pe_find_session_by_session_id(mac_ctx,
				mlm_disassoc_req->sessionId);
	if (NULL == session) {
		lim_log(mac_ctx, LOGE,
			FL("session does not exist for given sessionId %d"),
			mlm_disassoc_req->sessionId);
		return;
	}

	lim_process_mlm_disassoc_req_ntf(mac_ctx, CDF_STATUS_SUCCESS,
					 (uint32_t *) msg_buf);
}

/**
 * lim_process_mlm_deauth_req_ntf() - This function is process mlm deauth req
 * notification
 *
 * @mac_ctx:         Pointer to Global MAC structure
 * @suspend_status:  suspend status
 * @msg_buf:         A pointer to the MLM message buffer
 *
 * This function is process mlm deauth req notification
 *
 * @Return: None
 */
static void
lim_process_mlm_deauth_req_ntf(tpAniSirGlobal mac_ctx,
			       CDF_STATUS suspend_status, uint32_t *msg_buf)
{
	uint16_t aid;
	tSirMacAddr curr_bssId;
	tpDphHashNode sta_ds;
	struct tLimPreAuthNode *auth_node;
	tLimMlmDeauthReq *mlm_deauth_req;
	tLimMlmDeauthCnf mlm_deauth_cnf;
	tpPESession session;

	if (CDF_STATUS_SUCCESS != suspend_status)
		lim_log(mac_ctx, LOGE, FL("Suspend Status is not success %X"),
			suspend_status);

	mlm_deauth_req = (tLimMlmDeauthReq *) msg_buf;
	session = pe_find_session_by_session_id(mac_ctx,
				mlm_deauth_req->sessionId);
	if (NULL == session) {
		lim_log(mac_ctx, LOGE,
			FL("session does not exist for given sessionId %d"),
			mlm_deauth_req->sessionId);
		cdf_mem_free(mlm_deauth_req);
		return;
	}
	lim_log(mac_ctx, LOG1, FL("Process Deauth Req on sessionID %d Systemrole %d"
			       "mlmstate %d from: " MAC_ADDRESS_STR),
		mlm_deauth_req->sessionId,
		GET_LIM_SYSTEM_ROLE(session),
		session->limMlmState,
		MAC_ADDR_ARRAY(mlm_deauth_req->peerMacAddr));
	sir_copy_mac_addr(curr_bssId, session->bssId);

	switch (GET_LIM_SYSTEM_ROLE(session)) {
	case eLIM_STA_ROLE:
	case eLIM_BT_AMP_STA_ROLE:
		switch (session->limMlmState) {
		case eLIM_MLM_IDLE_STATE:
			/*
			 * Attempting to Deauthenticate with a pre-authenticated
			 * peer. Deauthetiate with peer if there exists a
			 * pre-auth context below.
			 */
			break;
		case eLIM_MLM_AUTHENTICATED_STATE:
		case eLIM_MLM_WT_ASSOC_RSP_STATE:
		case eLIM_MLM_LINK_ESTABLISHED_STATE:
			if (!cdf_mem_compare(mlm_deauth_req->peerMacAddr,
					curr_bssId, sizeof(tSirMacAddr))) {
				lim_log(mac_ctx, LOGE,
					FL("received MLM_DEAUTH_REQ with invalid BSS id "
					   "Peer MAC: "MAC_ADDRESS_STR
					   " CFG BSSID Addr : "MAC_ADDRESS_STR),
					MAC_ADDR_ARRAY(
						mlm_deauth_req->peerMacAddr),
					MAC_ADDR_ARRAY(curr_bssId));
				/* Prepare and Send LIM_MLM_DEAUTH_CNF */
				mlm_deauth_cnf.resultCode =
					eSIR_SME_INVALID_PARAMETERS;
				goto end;
			}

			if ((session->limMlmState ==
			     eLIM_MLM_AUTHENTICATED_STATE) ||
			    (session->limMlmState ==
			     eLIM_MLM_WT_ASSOC_RSP_STATE)) {
				/* Send deauth frame to peer entity */
				lim_send_deauth_mgmt_frame(mac_ctx,
						mlm_deauth_req->reasonCode,
						mlm_deauth_req->peerMacAddr,
						session, false);
				/* Prepare and Send LIM_MLM_DEAUTH_CNF */
				mlm_deauth_cnf.resultCode = eSIR_SME_SUCCESS;
				session->limMlmState = eLIM_MLM_IDLE_STATE;
				MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
						 session->peSessionId,
						 session->limMlmState));
				goto end;
			}
			break;
		default:
			lim_log(mac_ctx, LOGW,
				FL("received MLM_DEAUTH_REQ with in state %d for peer "
				   MAC_ADDRESS_STR),
				session->limMlmState,
				MAC_ADDR_ARRAY(mlm_deauth_req->peerMacAddr));
			lim_print_mlm_state(mac_ctx, LOGW,
					    session->limMlmState);
			/* Prepare and Send LIM_MLM_DEAUTH_CNF */
			mlm_deauth_cnf.resultCode =
				eSIR_SME_STA_NOT_AUTHENTICATED;

			goto end;
		}
		break;
	case eLIM_STA_IN_IBSS_ROLE:
		lim_log(mac_ctx, LOGE, FL("received MLM_DEAUTH_REQ IBSS Mode"));
		mlm_deauth_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
		goto end;
	case eLIM_AP_ROLE:
	case eLIM_P2P_DEVICE_GO:
		if (true ==
			mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running) {
			lim_log(mac_ctx, LOGE,
				FL("CAC timer is running, drop disassoc from going out"));
			mlm_deauth_cnf.resultCode = eSIR_SME_SUCCESS;
			goto end;
		}
		break;

	default:
		break;
	} /* end switch (GET_LIM_SYSTEM_ROLE(session)) */

	/*
	 * Check if there exists a context for the peer entity
	 * to be deauthenticated with.
	 */
	sta_ds = dph_lookup_hash_entry(mac_ctx, mlm_deauth_req->peerMacAddr,
				       &aid, &session->dph.dphHashTable);

	if (sta_ds == NULL) {
		/* Check if there exists pre-auth context for this STA */
		auth_node = lim_search_pre_auth_list(mac_ctx,
						mlm_deauth_req->peerMacAddr);
		if (auth_node == NULL) {
			/*
			 * Received DEAUTH REQ for a STA that is neither
			 * Associated nor Pre-authenticated. Log error,
			 * Prepare and Send LIM_MLM_DEAUTH_CNF
			 */
			lim_log(mac_ctx, LOGW,
				FL("received MLM_DEAUTH_REQ in mlme state %d for STA that "
				   "does not have context, Addr="
				   MAC_ADDRESS_STR),
				session->limMlmState,
				MAC_ADDR_ARRAY(mlm_deauth_req->peerMacAddr));
			mlm_deauth_cnf.resultCode =
				eSIR_SME_STA_NOT_AUTHENTICATED;
		} else {
			mlm_deauth_cnf.resultCode = eSIR_SME_SUCCESS;
			/* Delete STA from pre-auth STA list */
			lim_delete_pre_auth_node(mac_ctx,
						 mlm_deauth_req->peerMacAddr);
			/* Send Deauthentication frame to peer entity */
			lim_send_deauth_mgmt_frame(mac_ctx,
						   mlm_deauth_req->reasonCode,
						   mlm_deauth_req->peerMacAddr,
						   session, false);
		}
		goto end;
	} else if ((sta_ds->mlmStaContext.mlmState !=
		    eLIM_MLM_LINK_ESTABLISHED_STATE) &&
		   (sta_ds->mlmStaContext.mlmState !=
		    eLIM_MLM_WT_ASSOC_CNF_STATE)) {
		/*
		 * received MLM_DEAUTH_REQ for STA that either has no context or
		 * in some transit state
		 */
		lim_log(mac_ctx, LOGW,
			FL("Invalid MLM_DEAUTH_REQ, Addr="MAC_ADDRESS_STR),
			MAC_ADDR_ARRAY(mlm_deauth_req->peerMacAddr));
		/* Prepare and Send LIM_MLM_DEAUTH_CNF */
		mlm_deauth_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
		goto end;
	}
	/* sta_ds->mlmStaContext.rxPurgeReq     = 1; */
	sta_ds->mlmStaContext.disassocReason = (tSirMacReasonCodes)
					       mlm_deauth_req->reasonCode;
	sta_ds->mlmStaContext.cleanupTrigger = mlm_deauth_req->deauthTrigger;
	mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDeauthReq = mlm_deauth_req;
	/*
	 * Set state to mlm State to eLIM_MLM_WT_DEL_STA_RSP_STATE
	 * This is to address the issue of race condition between
	 * disconnect request from the HDD and disassoc from
	 * inactivity timer. This will make sure that we will not
	 * process disassoc if deauth is in progress for the station
	 * and thus mlmStaContext.cleanupTrigger will not be overwritten.
	 */
	sta_ds->mlmStaContext.mlmState = eLIM_MLM_WT_DEL_STA_RSP_STATE;
	/* Send Deauthentication frame to peer entity */
	lim_send_deauth_mgmt_frame(mac_ctx, mlm_deauth_req->reasonCode,
				   mlm_deauth_req->peerMacAddr, session, true);
	return;
end:
	cdf_mem_copy((uint8_t *) &mlm_deauth_cnf.peerMacAddr,
		     (uint8_t *) mlm_deauth_req->peerMacAddr,
		     sizeof(tSirMacAddr));
	mlm_deauth_cnf.deauthTrigger = mlm_deauth_req->deauthTrigger;
	mlm_deauth_cnf.aid = mlm_deauth_req->aid;
	mlm_deauth_cnf.sessionId = mlm_deauth_req->sessionId;

	/* Free up buffer allocated for mlmDeauthReq */
	cdf_mem_free(mlm_deauth_req);
	lim_post_sme_message(mac_ctx,
			     LIM_MLM_DEAUTH_CNF, (uint32_t *) &mlm_deauth_cnf);
}

/*
 * lim_process_deauth_ack_timeout() - wrapper function around
 * lim_send_deauth_cnf
 *
 * @mac_ctx:        mac_ctx
 *
 * wrapper function around lim_send_deauth_cnf
 *
 * Return: void
 */
void lim_process_deauth_ack_timeout(tpAniSirGlobal mac_ctx)
{
	lim_log(mac_ctx, LOG1, FL(""));
	lim_send_deauth_cnf(mac_ctx);
}

/*
 * lim_process_mlm_deauth_req() - This function is called to process
 * MLM_DEAUTH_REQ message from SME
 *
 * @mac_ctx:      Pointer to Global MAC structure
 * @msg_buf:      A pointer to the MLM message buffer
 *
 * This function is called to process MLM_DEAUTH_REQ message from SME
 *
 * @Return: None
 */
static void
lim_process_mlm_deauth_req(tpAniSirGlobal mac_ctx, uint32_t *msg_buf)
{
	tLimMlmDeauthReq *mlm_deauth_req;
	tpPESession session;

	if (msg_buf == NULL) {
		PELOGE(lim_log(mac_ctx, LOGE, FL("Buffer is Pointing to NULL"));)
		return;
	}

	mlm_deauth_req = (tLimMlmDeauthReq *) msg_buf;
	lim_log(mac_ctx, LOG1,
		FL("Process Deauth Req on sessionID %d from: "
		   MAC_ADDRESS_STR),
		mlm_deauth_req->sessionId,
		MAC_ADDR_ARRAY(mlm_deauth_req->peerMacAddr));

	session = pe_find_session_by_session_id(mac_ctx,
				mlm_deauth_req->sessionId);
	if (NULL == session) {
		lim_log(mac_ctx, LOGE,
			FL("session does not exist for given sessionId %d"),
			mlm_deauth_req->sessionId);
		return;
	}
	lim_process_mlm_deauth_req_ntf(mac_ctx, CDF_STATUS_SUCCESS,
				       (uint32_t *) msg_buf);
}

/**
 * lim_process_mlm_set_keys_req() - This function is called to process
 * MLM_SETKEYS_REQ message from SME
 *
 * @mac_ctx:      Pointer to Global MAC structure
 * @msg_buf:      A pointer to the MLM message buffer
 *
 * This function is called to process MLM_SETKEYS_REQ message from SME
 *
 * @Return: None
 */
static void
lim_process_mlm_set_keys_req(tpAniSirGlobal mac_ctx, uint32_t *msg_buf)
{
	uint16_t aid;
	uint16_t sta_idx = 0;
	uint32_t default_key_id = 0;
	tSirMacAddr curr_bssid;
	tpDphHashNode sta_ds;
	tLimMlmSetKeysReq *mlm_set_keys_req;
	tLimMlmSetKeysCnf mlm_set_keys_cnf;
	tpPESession session;

	if (msg_buf == NULL) {
		lim_log(mac_ctx, LOGE, FL("Buffer is Pointing to NULL"));
		return;
	}

	mlm_set_keys_req = (tLimMlmSetKeysReq *) msg_buf;
	/* Hold onto the SetKeys request parameters */
	mac_ctx->lim.gpLimMlmSetKeysReq = (void *)mlm_set_keys_req;
	session = pe_find_session_by_session_id(mac_ctx,
				mlm_set_keys_req->sessionId);
	if (NULL == session) {
		lim_log(mac_ctx, LOGE,
			FL("session does not exist for given sessionId"));
		return;
	}

	lim_log(mac_ctx, LOGW,
		FL("Received MLM_SETKEYS_REQ with parameters:"
		   "AID [%d], ED Type [%d], # Keys [%d] & Peer MAC Addr - "),
		mlm_set_keys_req->aid, mlm_set_keys_req->edType,
		mlm_set_keys_req->numKeys);
	lim_print_mac_addr(mac_ctx, mlm_set_keys_req->peerMacAddr, LOGW);
	sir_copy_mac_addr(curr_bssid, session->bssId);

	switch (GET_LIM_SYSTEM_ROLE(session)) {
	case eLIM_STA_ROLE:
	case eLIM_BT_AMP_STA_ROLE:
		/*
		 * In case of TDLS, peerMac address need not be BssId. Skip this
		 * check if TDLS is enabled.
		 */
#ifndef FEATURE_WLAN_TDLS
		if ((!lim_is_addr_bc(mlm_set_keys_req->peerMacAddr)) &&
		    (!cdf_mem_compare(mlm_set_keys_req->peerMacAddr,
				      curr_bssid, sizeof(tSirMacAddr)))) {
			lim_log(mac_ctx, LOGW,
				FL("Received MLM_SETKEYS_REQ with invalid BSSID"
				MAC_ADDRESS_STR),
				MAC_ADDR_ARRAY(mlm_set_keys_req->peerMacAddr));
			/*
			 * Prepare and Send LIM_MLM_SETKEYS_CNF with error code
			 */
			mlm_set_keys_cnf.resultCode =
				eSIR_SME_INVALID_PARAMETERS;
			goto end;
		}
#endif
		break;
	case eLIM_STA_IN_IBSS_ROLE:
		/*
		 * update the IBSS PE session encrption type based on the
		 * key type
		 */
		session->encryptType = mlm_set_keys_req->edType;
		break;
	default:
		break;
	}

	/*
	 * Use the "unicast" parameter to determine if the "Group Keys"
	 * are being set.
	 * mlm_set_keys_req->key.unicast = 0 -> Multicast/broadcast
	 * mlm_set_keys_req->key.unicast - 1 -> Unicast keys are being set
	 */
	if (lim_is_addr_bc(mlm_set_keys_req->peerMacAddr)) {
		lim_log(mac_ctx, LOG1, FL("Trying to set Group Keys...%d "),
			mlm_set_keys_req->sessionId);
		/*
		 * When trying to set Group Keys for any security mode other
		 * than WEP, use the STA Index corresponding to the AP...
		 */
		switch (mlm_set_keys_req->edType) {
		case eSIR_ED_CCMP:
#ifdef WLAN_FEATURE_11W
		case eSIR_ED_AES_128_CMAC:
#endif
			sta_idx = session->staId;
			break;
		default:
			break;
		}
	} else {
		lim_log(mac_ctx, LOG1, FL("Trying to set Unicast Keys..."));
		/*
		 * Check if there exists a context for the
		 * peer entity for which keys need to be set.
		 */
		sta_ds = dph_lookup_hash_entry(mac_ctx,
				mlm_set_keys_req->peerMacAddr, &aid,
				&session->dph.dphHashTable);
		if ((sta_ds == NULL) ||
		    ((sta_ds->mlmStaContext.mlmState !=
		    eLIM_MLM_LINK_ESTABLISHED_STATE) &&
		    !LIM_IS_AP_ROLE(session))) {
			/*
			 * Received LIM_MLM_SETKEYS_REQ for STA that does not
			 * have context or in some transit state.
			 */
			lim_log(mac_ctx, LOG1,
				FL("Invalid MLM_SETKEYS_REQ, Addr = "
				   MAC_ADDRESS_STR),
				MAC_ADDR_ARRAY(mlm_set_keys_req->peerMacAddr));
			/* Prepare and Send LIM_MLM_SETKEYS_CNF */
			mlm_set_keys_cnf.resultCode =
				eSIR_SME_INVALID_PARAMETERS;
			goto end;
		} else {
			sta_idx = sta_ds->staIndex;
		}
	}

	if ((mlm_set_keys_req->numKeys == 0)
	    && (mlm_set_keys_req->edType != eSIR_ED_NONE)) {
		/*
		 * Broadcast/Multicast Keys (for WEP!!) are NOT sent
		 * via this interface!! This indicates to HAL that the WEP Keys
		 * need to be extracted from the CFG and applied to hardware
		 */
		default_key_id = 0xff;
	} else if (mlm_set_keys_req->key[0].keyId &&
		   ((mlm_set_keys_req->edType == eSIR_ED_WEP40) ||
		    (mlm_set_keys_req->edType == eSIR_ED_WEP104))) {
		/*
		 * If the Key Id is non zero and encryption mode is WEP,
		 * the key index is coming from the upper layers so that key
		 * only need to be used as the default tx key, This is being
		 * used only in case of WEP mode in HAL
		 */
		default_key_id = mlm_set_keys_req->key[0].keyId;
	} else {
		default_key_id = 0;
	}
	lim_log(mac_ctx, LOG1,
		FL("Trying to set keys for STA Index [%d], using default_key_id [%d]"),
		sta_idx, default_key_id);

	if (lim_is_addr_bc(mlm_set_keys_req->peerMacAddr)) {
		session->limPrevMlmState = session->limMlmState;
		session->limMlmState = eLIM_MLM_WT_SET_BSS_KEY_STATE;
		MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
				 session->peSessionId, session->limMlmState));
		lim_log(mac_ctx, LOG1, FL("Trying to set Group Keys...%d "),
			session->peSessionId);
		/* Package WMA_SET_BSSKEY_REQ message parameters */
		lim_send_set_bss_key_req(mac_ctx, mlm_set_keys_req, session);
		return;
	} else {
		/*
		 * Package WMA_SET_STAKEY_REQ / WMA_SET_STA_BCASTKEY_REQ message
		 * parameters
		 */
		lim_send_set_sta_key_req(mac_ctx, mlm_set_keys_req, sta_idx,
					 (uint8_t) default_key_id, session,
					 true);
		return;
	}
end:
	mlm_set_keys_cnf.sessionId = mlm_set_keys_req->sessionId;
	lim_post_sme_set_keys_cnf(mac_ctx, mlm_set_keys_req, &mlm_set_keys_cnf);
}

/**
 * lim_process_periodic_probe_req_timer() - This function is called to process
 * periodic probe request to send during scan.
 *
 * @mac_ctx:      Pointer to Global MAC structure
 *
 * This function is called to process periodic probe request to send during scan
 *
 * @Return None
 */
static void lim_process_periodic_probe_req_timer(tpAniSirGlobal mac_ctx)
{
	uint8_t channel_num;
	uint8_t i = 0;
	tLimMlmScanReq *mlm_scan_req;
	tSirRetStatus status = eSIR_SUCCESS;
	TX_TIMER *probe_req_timer =
		&mac_ctx->lim.limTimers.gLimPeriodicProbeReqTimer;

	if (cdf_mc_timer_get_current_state(&probe_req_timer->cdf_timer)
					   != CDF_TIMER_STATE_STOPPED) {
		lim_log(mac_ctx, LOG1, FL("Invalid state of timer"));
		return;
	}

	if (!((mac_ctx->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE)
	    && (probe_req_timer->sessionId != 0xff)
	    && (mac_ctx->lim.probeCounter < mac_ctx->lim.maxProbe))) {
		lim_log(mac_ctx, LOG1,
			FL("received unexpected Periodic scan timeout in state %X"),
			mac_ctx->lim.gLimMlmState);
		return;
	}

	mlm_scan_req = mac_ctx->lim.gpLimMlmScanReq;
	lim_log(mac_ctx, LOG1, FL("Scanning : Periodic scanning"));
	mac_ctx->lim.probeCounter++;
	/* Periodic channel timer timed out to send probe request. */
	channel_num = lim_get_current_scan_channel(mac_ctx);
	do {
		/*
		 * Prepare and send Probe Request frame for all the SSIDs
		 * present in the saved MLM
		 */
		status = lim_send_probe_req_mgmt_frame(mac_ctx,
				&mlm_scan_req->ssId[i], mlm_scan_req->bssId,
				channel_num, mac_ctx->lim.gSelfMacAddr,
				mlm_scan_req->dot11mode,
				mlm_scan_req->uIEFieldLen,
				(uint8_t *) (mlm_scan_req) +
					mlm_scan_req->uIEFieldOffset);
		if (status != eSIR_SUCCESS) {
			lim_log(mac_ctx, LOGE,
				FL("send ProbeReq failed for SSID %s on channel: %d"),
				mlm_scan_req->ssId[i].ssId, channel_num);
			return;
		}
		i++;
	} while (i < mlm_scan_req->numSsid);
	/* Activate timer again */
	MTRACE(mac_trace(mac_ctx, TRACE_CODE_TIMER_ACTIVATE,
			 probe_req_timer->sessionId,
			 eLIM_PERIODIC_PROBE_REQ_TIMER));
	if (tx_timer_activate(probe_req_timer) != TX_SUCCESS) {
		lim_log(mac_ctx, LOGP,
			FL("could not start periodic probe req timer"));
		return;
	}
}

/**
 * lim_process_join_failure_timeout() - This function is called to process
 * JoinFailureTimeout
 *
 * @mac_ctx:      Pointer to Global MAC structure
 *
 * This function is called to process JoinFailureTimeout
 *
 * @Return None
 */
static void lim_process_join_failure_timeout(tpAniSirGlobal mac_ctx)
{
	tLimMlmJoinCnf mlm_join_cnf;
	uint32_t len;
#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
	host_log_rssi_pkt_type *rssi_log = NULL;
#endif
	tpPESession session;

	session = pe_find_session_by_session_id(mac_ctx,
			mac_ctx->lim.limTimers.gLimJoinFailureTimer.sessionId);
	if (NULL == session) {
		lim_log(mac_ctx, LOGE,
			FL("Session Does not exist for given sessionID"));
		return;
	}
#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
	WLAN_HOST_DIAG_LOG_ALLOC(rssi_log,
				host_log_rssi_pkt_type, LOG_WLAN_RSSI_UPDATE_C);
	if (rssi_log)
		rssi_log->rssi = session->rssi;
	WLAN_HOST_DIAG_LOG_REPORT(rssi_log);
#endif

	if (session->limMlmState == eLIM_MLM_WT_JOIN_BEACON_STATE) {
		len = sizeof(tSirMacAddr);
		/* Change timer for future activations */
		lim_deactivate_and_change_timer(mac_ctx, eLIM_JOIN_FAIL_TIMER);
		/* Change Periodic probe req timer for future activation */
		lim_deactivate_and_change_timer(mac_ctx,
					eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER);
		/* Issue MLM join confirm with timeout reason code */
		lim_log(mac_ctx, LOGE,
			FL("In state eLIM_MLM_WT_JOIN_BEACON_STATE."));
		lim_log(mac_ctx, LOGE,
			FL("Join Failure Timeout occurred for session %d with BSS "
			   MAC_ADDRESS_STR),
			session->peSessionId, MAC_ADDR_ARRAY(session->bssId));

		mlm_join_cnf.resultCode = eSIR_SME_JOIN_TIMEOUT_RESULT_CODE;
		mlm_join_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
		session->limMlmState = eLIM_MLM_IDLE_STATE;
		MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
				 session->peSessionId, session->limMlmState));
		if (lim_set_link_state(mac_ctx, eSIR_LINK_IDLE_STATE,
				       session->bssId, session->selfMacAddr,
				       NULL, NULL) != eSIR_SUCCESS)
			lim_log(mac_ctx, LOGE,
				("Failed to set the LinkState"));
		/* Update PE session Id */
		mlm_join_cnf.sessionId = session->peSessionId;
		/* Freeup buffer allocated to join request */
		if (session->pLimMlmJoinReq) {
			cdf_mem_free(session->pLimMlmJoinReq);
			session->pLimMlmJoinReq = NULL;
		}
		lim_post_sme_message(mac_ctx, LIM_MLM_JOIN_CNF,
				     (uint32_t *) &mlm_join_cnf);
		return;
	} else {
		lim_log(mac_ctx, LOGW,
			FL("received unexpected JOIN failure timeout in state %X"),
			session->limMlmState);
		lim_print_mlm_state(mac_ctx, LOGW, session->limMlmState);
	}
}

/**
 * lim_process_periodic_join_probe_req_timer() - This function is called to
 * process periodic probe request send during joining process.
 *
 * @mac_ctx:      Pointer to Global MAC structure
 *
 * This function is called to process periodic probe request send during
 * joining process.
 *
 * @Return None
 */
static void lim_process_periodic_join_probe_req_timer(tpAniSirGlobal mac_ctx)
{
	tpPESession session;
	tSirMacSSid ssid;

	session = pe_find_session_by_session_id(mac_ctx,
		mac_ctx->lim.limTimers.gLimPeriodicJoinProbeReqTimer.sessionId);
	if (NULL == session) {
		lim_log(mac_ctx, LOGE,
			FL("session does not exist for given SessionId : %d"),
			mac_ctx->lim.limTimers.gLimPeriodicJoinProbeReqTimer.
			sessionId);
		return;
	}

	if ((true ==
	    tx_timer_running(&mac_ctx->lim.limTimers.gLimJoinFailureTimer))
		&& (session->limMlmState == eLIM_MLM_WT_JOIN_BEACON_STATE)) {
		cdf_mem_copy(ssid.ssId, session->ssId.ssId,
			     session->ssId.length);
		ssid.length = session->ssId.length;
		lim_send_probe_req_mgmt_frame(mac_ctx, &ssid,
			session->pLimMlmJoinReq->bssDescription.bssId,
			session->currentOperChannel /*chanNum */,
			session->selfMacAddr, session->dot11mode,
			session->pLimJoinReq->addIEScan.length,
			session->pLimJoinReq->addIEScan.addIEdata);
		lim_deactivate_and_change_timer(mac_ctx,
				eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER);
		/* Activate Join Periodic Probe Req timer */
		if (tx_timer_activate(
		    &mac_ctx->lim.limTimers.gLimPeriodicJoinProbeReqTimer) !=
		    TX_SUCCESS) {
			lim_log(mac_ctx, LOGP,
				FL("could not activate Periodic Join req failure timer"));
			return;
		}
	}
}

/**
 * lim_process_auth_failure_timeout() - This function is called to process Min
 * Channel Timeout during channel scan.
 *
 * @mac_ctx:      Pointer to Global MAC structure
 *
 * This function is called to process Min Channel Timeout during channel scan.
 *
 * @Return: None
 */
static void lim_process_auth_failure_timeout(tpAniSirGlobal mac_ctx)
{
	/* fetch the sessionEntry based on the sessionId */
	tpPESession session;
#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
	host_log_rssi_pkt_type *rssi_log = NULL;
#endif

	session = pe_find_session_by_session_id(mac_ctx,
			mac_ctx->lim.limTimers.gLimAuthFailureTimer.sessionId);
	if (NULL == session) {
		lim_log(mac_ctx, LOGP,
			FL("Session Does not exist for given sessionID"));
		return;
	}

	lim_log(mac_ctx, LOGE,
		FL("received AUTH failure timeout in sessionid %d "
		   "limMlmstate %X limSmeState %X"),
		session->peSessionId, session->limMlmState,
		session->limSmeState);
#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
	WLAN_HOST_DIAG_LOG_ALLOC(rssi_log, host_log_rssi_pkt_type,
				 LOG_WLAN_RSSI_UPDATE_C);
	if (rssi_log)
		rssi_log->rssi = session->rssi;
	WLAN_HOST_DIAG_LOG_REPORT(rssi_log);
#endif

	switch (session->limMlmState) {
	case eLIM_MLM_WT_AUTH_FRAME2_STATE:
	case eLIM_MLM_WT_AUTH_FRAME4_STATE:
		/*
		 * Requesting STA did not receive next auth frame before Auth
		 * Failure timeout. Issue MLM auth confirm with timeout reason
		 * code. Restore default failure timeout
		 */
		if (CDF_P2P_CLIENT_MODE == session->pePersona
		    && session->defaultAuthFailureTimeout)
			cfg_set_int(mac_ctx,
				    WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT,
				    session->defaultAuthFailureTimeout);
		lim_restore_from_auth_state(mac_ctx,
				eSIR_SME_AUTH_TIMEOUT_RESULT_CODE,
				eSIR_MAC_UNSPEC_FAILURE_REASON, session);
		break;
	default:
		/*
		 * Auth failure timer should not have timed out
		 * in states other than wt_auth_frame2/4
		 */
		lim_log(mac_ctx, LOGE,
			FL("received unexpected AUTH failure timeout in state %X"),
			session->limMlmState);
		lim_print_mlm_state(mac_ctx, LOGE, session->limMlmState);
		break;
	}
}

/**
 * lim_process_auth_rsp_timeout() - This function is called to process Min
 * Channel Timeout during channel scan.
 *
 * @mac_ctx:      Pointer to Global MAC structure
 *
 * This function is called to process Min Channel Timeout during channel scan.
 *
 * @Return: None
 */
static void
lim_process_auth_rsp_timeout(tpAniSirGlobal mac_ctx, uint32_t auth_idx)
{
	struct tLimPreAuthNode *auth_node;
	tpPESession session;
	uint8_t session_id;

	auth_node = lim_get_pre_auth_node_from_index(mac_ctx,
				&mac_ctx->lim.gLimPreAuthTimerTable, auth_idx);
	if (NULL == auth_node) {
		lim_log(mac_ctx, LOGW, FL("Invalid auth node"));
		return;
	}

	session = pe_find_session_by_bssid(mac_ctx, auth_node->peerMacAddr,
					   &session_id);
	if (NULL == session) {
		lim_log(mac_ctx, LOGW,
			FL("session does not exist for given BSSID "));
		return;
	}

	if (LIM_IS_AP_ROLE(session) || LIM_IS_IBSS_ROLE(session)) {
		if (auth_node->mlmState != eLIM_MLM_WT_AUTH_FRAME3_STATE) {
			lim_log(mac_ctx, LOGE,
				FL("received AUTH rsp timeout in unexpected "
				   "state for MAC address: " MAC_ADDRESS_STR),
				MAC_ADDR_ARRAY(auth_node->peerMacAddr));
		} else {
			auth_node->mlmState = eLIM_MLM_AUTH_RSP_TIMEOUT_STATE;
			auth_node->fTimerStarted = 0;
			lim_log(mac_ctx, LOG1,
				FL("AUTH rsp timedout for MAC address "
				   MAC_ADDRESS_STR),
				MAC_ADDR_ARRAY(auth_node->peerMacAddr));
			/* Change timer to reactivate it in future */
			lim_deactivate_and_change_per_sta_id_timer(mac_ctx,
				eLIM_AUTH_RSP_TIMER, auth_node->authNodeIdx);
			lim_delete_pre_auth_node(mac_ctx,
						 auth_node->peerMacAddr);
		}
	}
}

/**
 * lim_process_assoc_failure_timeout() - This function is called to process Min
 * Channel Timeout during channel scan.
 *
 * @mac_ctx      Pointer to Global MAC structure
 *
 * This function is called to process Min Channel Timeout during channel scan.
 *
 * @Return: None
 */
static void
lim_process_assoc_failure_timeout(tpAniSirGlobal mac_ctx, uint32_t msg_type)
{

	tLimMlmAssocCnf mlm_assoc_cnf;
	tpPESession session;
#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
	host_log_rssi_pkt_type *rssi_log = NULL;
#endif
	/*
	 * to fetch the lim/mlm state based on the session_id, use the
	 * below sessionEntry
	 */
	uint8_t session_id;

	if (msg_type == LIM_ASSOC)
		session_id =
		    mac_ctx->lim.limTimers.gLimAssocFailureTimer.sessionId;
	else
		session_id =
		    mac_ctx->lim.limTimers.gLimReassocFailureTimer.sessionId;

	session = pe_find_session_by_session_id(mac_ctx, session_id);
	if (NULL == session) {
		lim_log(mac_ctx, LOGP,
			FL("Session Does not exist for given sessionID"));
		return;
	}
#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
	WLAN_HOST_DIAG_LOG_ALLOC(rssi_log,
				 host_log_rssi_pkt_type,
				 LOG_WLAN_RSSI_UPDATE_C);
	if (rssi_log)
		rssi_log->rssi = session->rssi;
	WLAN_HOST_DIAG_LOG_REPORT(rssi_log);
#endif

	lim_log(mac_ctx, LOG1,
		FL("Re/Association Response not received before timeout "));

	if ((LIM_IS_AP_ROLE(session) || LIM_IS_BT_AMP_AP_ROLE(session)) ||
	    ((session->limMlmState != eLIM_MLM_WT_ASSOC_RSP_STATE) &&
	    (session->limMlmState != eLIM_MLM_WT_REASSOC_RSP_STATE) &&
	    (session->limMlmState != eLIM_MLM_WT_FT_REASSOC_RSP_STATE))) {
		/*
		 * Re/Assoc failure timer should not have timedout on AP
		 * or in a state other than wt_re/assoc_response.
		 */
		lim_log(mac_ctx, LOGW,
			FL("received unexpected REASSOC failure timeout in state %X for role %d"),
			session->limMlmState,
			GET_LIM_SYSTEM_ROLE(session));
		lim_print_mlm_state(mac_ctx, LOGW, session->limMlmState);
		return;
	}

	if ((msg_type == LIM_ASSOC) || ((msg_type == LIM_REASSOC)
	     && (session->limMlmState == eLIM_MLM_WT_FT_REASSOC_RSP_STATE))) {
		lim_log(mac_ctx, LOGE,
			FL("(Re)Assoc Failure Timeout occurred."));
		session->limMlmState = eLIM_MLM_IDLE_STATE;
		MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
			session->peSessionId, session->limMlmState));
		/* Change timer for future activations */
		lim_deactivate_and_change_timer(mac_ctx, eLIM_ASSOC_FAIL_TIMER);
		/*
		 * Free up buffer allocated for JoinReq held by
		 * MLM state machine
		 */
		if (session->pLimMlmJoinReq) {
			cdf_mem_free(session->pLimMlmJoinReq);
			session->pLimMlmJoinReq = NULL;
		}
		/* To remove the preauth node in case of fail to associate */
		if (lim_search_pre_auth_list(mac_ctx, session->bssId)) {
			lim_log(mac_ctx, LOG1,
				FL(" delete pre auth node for "MAC_ADDRESS_STR),
				MAC_ADDR_ARRAY(session->bssId));
			lim_delete_pre_auth_node(mac_ctx,
						 session->bssId);
		}

		mlm_assoc_cnf.resultCode = eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE;
		mlm_assoc_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
		/* Update PE session Id */
		mlm_assoc_cnf.sessionId = session->peSessionId;
		if (msg_type == LIM_ASSOC) {
			lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_CNF,
					     (uint32_t *) &mlm_assoc_cnf);
		} else {
			/*
			 * Will come here only in case of 11r, Ese FT
			 * when reassoc rsp is not received and we
			 * receive a reassoc - timesout
			 */
			mlm_assoc_cnf.resultCode =
				eSIR_SME_FT_REASSOC_TIMEOUT_FAILURE;
			lim_post_sme_message(mac_ctx, LIM_MLM_REASSOC_CNF,
					     (uint32_t *) &mlm_assoc_cnf);
		}
	} else {
		/*
		 * Restore pre-reassoc req state.
		 * Set BSSID to currently associated AP address.
		 */
		session->limMlmState = session->limPrevMlmState;
		MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
				 session->peSessionId, session->limMlmState));
		lim_restore_pre_reassoc_state(mac_ctx,
				eSIR_SME_REASSOC_TIMEOUT_RESULT_CODE,
				eSIR_MAC_UNSPEC_FAILURE_STATUS, session);
	}
}

/**
 * lim_complete_mlm_scan() - This function is called to send MLM_SCAN_CNF
 * message to SME state machine.
 *
 * @mac_ctx:      Pointer to Global MAC structure
 * @ret_code:     Result code to be sent
 *
 * This function is called to send MLM_SCAN_CNF message to SME state machine.
 *
 * @Return: None
 */

void lim_complete_mlm_scan(tpAniSirGlobal mac_ctx, tSirResultCodes ret_code)
{
	tLimMlmScanCnf mlm_scan_cnf;

	/* Restore previous MLM state */
	mac_ctx->lim.gLimMlmState = mac_ctx->lim.gLimPrevMlmState;
	MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, NO_SESSION,
			 mac_ctx->lim.gLimMlmState));
	lim_restore_pre_scan_state(mac_ctx);
	/* Free up mac_ctx->lim.gLimMlmScanReq */
	if (NULL != mac_ctx->lim.gpLimMlmScanReq) {
		cdf_mem_free(mac_ctx->lim.gpLimMlmScanReq);
		mac_ctx->lim.gpLimMlmScanReq = NULL;
	}

	mlm_scan_cnf.resultCode = ret_code;
	lim_post_sme_message(mac_ctx, LIM_MLM_SCAN_CNF,
			     (uint32_t *) &mlm_scan_cnf);
}

/**
 * lim_set_channel() - set channel api for lim
 *
 * @mac_ctx:                Pointer to Global MAC structure
 * @channel:                power save state
 * @ch_center_freq_seg0:    center freq seq 0
 * @ch_center_freq_seg1:    center freq seq 1
 * @ch_width:               channel width
 * @max_tx_power:           max tx power
 * @pe_session_id:          pe session id
 *
 * set channel api for lim
 *
 * @Return: None
 */
void lim_set_channel(tpAniSirGlobal mac_ctx, uint8_t channel,
		     uint8_t ch_center_freq_seg0, uint8_t ch_center_freq_seg1,
		     phy_ch_width ch_width, tPowerdBm max_tx_power,
		     uint8_t pe_session_id)
{
#if !defined WLAN_FEATURE_VOWIFI
	uint32_t localPwrConstraint;
#endif
	tpPESession pe_session;
	pe_session = pe_find_session_by_session_id(mac_ctx, pe_session_id);

	if (NULL == pe_session) {
		lim_log(mac_ctx, LOGP, FL("Invalid PE session = %d"),
			pe_session_id);
		return;
	}
#if defined WLAN_FEATURE_VOWIFI
	lim_send_switch_chnl_params(mac_ctx, channel, ch_center_freq_seg0,
				    ch_center_freq_seg1, ch_width,
				    max_tx_power, pe_session_id, false);
#else
	if (wlan_cfg_get_int(mac_ctx, WNI_CFG_LOCAL_POWER_CONSTRAINT,
			    &localPwrConstraint) != eSIR_SUCCESS) {
		lim_log(mac_ctx, LOGP,
			FL("couldn't read CFG_LOCAL_POWER_CONSTRAINT"));
		return;
	}
	/* Send WMA_CHNL_SWITCH_IND to HAL */
	lim_send_switch_chnl_params(mac_ctx, channel, ch_center_freq_seg0,
				    ch_center_freq_seg1, ch_width,
				    (tPowerdBm) localPwrConstraint,
				    pe_session_id, false);
#endif
}
