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

/*
 * This file sch_beacon_process.cc contains beacon processing related
 * functions
 *
 * Author:      Sandesh Goel
 * Date:        02/25/02
 * History:-
 * Date            Modified by    Modification Information
 * --------------------------------------------------------------------
 *
 */

#include "cds_api.h"
#include "wni_cfg.h"

#include "cfg_api.h"
#include "lim_api.h"
#include "utils_api.h"
#include "sch_api.h"

#include "lim_utils.h"
#include "lim_send_messages.h"
#include "lim_sta_hash_api.h"

#include "rrm_api.h"

#ifdef FEATURE_WLAN_DIAG_SUPPORT
#include "host_diag_core_log.h"
#endif /* FEATURE_WLAN_DIAG_SUPPORT */

#include "wma.h"
/**
 * Number of bytes of variation in beacon length from the last beacon
 * to trigger reprogramming of rx delay register
 */
#define SCH_BEACON_LEN_DELTA       3

/* calculate 2^cw - 1 */
#define CW_GET(cw) (((cw) == 0) ? 1 : ((1 << (cw)) - 1))

static void
ap_beacon_process_5_ghz(tpAniSirGlobal mac_ctx, uint8_t *rx_pkt_info,
			tpSchBeaconStruct bcn_struct,
			tpUpdateBeaconParams bcn_prm, tpPESession session,
			uint32_t phy_mode)
{
	tpSirMacMgmtHdr mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
	if (!session->htCapability)
		return;

	if (bcn_struct->channelNumber != session->currentOperChannel)
		return;

	/* 11a (non HT) AP  overlaps or */
	/* HT AP with HT op mode as mixed overlaps. */
	/* HT AP with HT op mode as overlap legacy overlaps. */
	if (!bcn_struct->HTInfo.present
	    || (eSIR_HT_OP_MODE_MIXED == bcn_struct->HTInfo.opMode)
	    || (eSIR_HT_OP_MODE_OVERLAP_LEGACY == bcn_struct->HTInfo.opMode)) {
		lim_update_overlap_sta_param(mac_ctx, mac_hdr->bssId,
					&(mac_ctx->lim.gLimOverlap11aParams));

		if (mac_ctx->lim.gLimOverlap11aParams.numSta
		    && !mac_ctx->lim.gLimOverlap11aParams.protectionEnabled) {
			lim_update_11a_protection(mac_ctx, true, true,
						 bcn_prm, session);
		}
		return;
	}
	/* HT AP with HT20 op mode overlaps. */
	if (eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT != bcn_struct->HTInfo.opMode)
		return;

	lim_update_overlap_sta_param(mac_ctx, mac_hdr->bssId,
				     &(mac_ctx->lim.gLimOverlapHt20Params));

	if (mac_ctx->lim.gLimOverlapHt20Params.numSta
	    && !mac_ctx->lim.gLimOverlapHt20Params.protectionEnabled)
		lim_enable_ht20_protection(mac_ctx, true, true,
					   bcn_prm, session);
}

static void
ap_beacon_process_24_ghz(tpAniSirGlobal mac_ctx, uint8_t *rx_pkt_info,
			 tpSchBeaconStruct bcn_struct,
			 tpUpdateBeaconParams bcn_prm, tpPESession session,
			 uint32_t phy_mode)
{
	tpSirMacMgmtHdr mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
	bool tmp_exp = false;
	/* We are 11G AP. */
	if ((phy_mode == WNI_CFG_PHY_MODE_11G) &&
	    (false == session->htCapability)) {
		if (bcn_struct->channelNumber != session->currentOperChannel)
			return;

		tmp_exp = (!bcn_struct->erpPresent
			    && !bcn_struct->HTInfo.present)
			    /* if erp not present then  11B AP overlapping */
			    || (!mac_ctx->roam.configParam.ignore_peer_erp_info &&
					bcn_struct->erpPresent &&
					(bcn_struct->erpIEInfo.useProtection
				    || bcn_struct->erpIEInfo.nonErpPresent));
		if (!tmp_exp)
			return;
#ifdef FEATURE_WLAN_ESE
		if (session->isESEconnection)
			QDF_TRACE(QDF_MODULE_ID_PE,
				  QDF_TRACE_LEVEL_INFO,
				  FL("[INFOLOG]ESE 11g erpPresent=%d useProtection=%d nonErpPresent=%d"),
				  bcn_struct->erpPresent,
				  bcn_struct->erpIEInfo.useProtection,
				  bcn_struct->erpIEInfo.nonErpPresent);
#endif
		lim_enable_overlap11g_protection(mac_ctx, bcn_prm,
						 mac_hdr, session);
		return;
	}
	/* handling the case when HT AP has overlapping legacy BSS. */
	if (!session->htCapability)
		return;

	if (bcn_struct->channelNumber != session->currentOperChannel)
		return;

	tmp_exp = (!bcn_struct->erpPresent && !bcn_struct->HTInfo.present)
		    /* if erp not present then  11B AP overlapping */
		    || (!mac_ctx->roam.configParam.ignore_peer_erp_info &&
				bcn_struct->erpPresent &&
				(bcn_struct->erpIEInfo.useProtection
			    || bcn_struct->erpIEInfo.nonErpPresent));
	if (tmp_exp) {
#ifdef FEATURE_WLAN_ESE
		if (session->isESEconnection) {
			QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_INFO,
				  FL("[INFOLOG]ESE 11g erpPresent=%d useProtection=%d nonErpPresent=%d"),
				  bcn_struct->erpPresent,
				  bcn_struct->erpIEInfo.useProtection,
				  bcn_struct->erpIEInfo.nonErpPresent);
		}
#endif
		lim_enable_overlap11g_protection(mac_ctx, bcn_prm,
						 mac_hdr, session);
	}
	/* 11g device overlaps */
	tmp_exp = bcn_struct->erpPresent
		&& !(bcn_struct->erpIEInfo.useProtection
		     || bcn_struct->erpIEInfo.nonErpPresent)
		&& !(bcn_struct->HTInfo.present);
	if (tmp_exp) {
		lim_update_overlap_sta_param(mac_ctx, mac_hdr->bssId,
					     &(session->gLimOverlap11gParams));

		if (session->gLimOverlap11gParams.numSta
		    && !session->gLimOverlap11gParams.protectionEnabled)
			lim_enable_ht_protection_from11g(mac_ctx, true, true,
							 bcn_prm, session);
	}
	/* ht device overlaps.
	 * here we will check for HT related devices only which might need
	 * protection. check for 11b and 11g is already done in the previous
	 * blocks. so we will not check for HT operating mode as MIXED.
	 */
	if (!bcn_struct->HTInfo.present)
		return;

	/*
	 * if we are not already in mixed mode or legacy mode as HT operating
	 * mode and received beacon has HT operating mode as legacy then we need
	 * to enable protection from 11g station. we don't need protection from
	 * 11b because if that's needed then our operating mode would have
	 * already been set to legacy in the previous blocks.
	 */
	if ((eSIR_HT_OP_MODE_OVERLAP_LEGACY == bcn_struct->HTInfo.opMode) &&
		!mac_ctx->roam.configParam.ignore_peer_ht_opmode) {
		if (eSIR_HT_OP_MODE_OVERLAP_LEGACY == mac_ctx->lim.gHTOperMode
		    || eSIR_HT_OP_MODE_MIXED == mac_ctx->lim.gHTOperMode)
			return;
		lim_update_overlap_sta_param(mac_ctx, mac_hdr->bssId,
					     &(session->gLimOverlap11gParams));
		if (session->gLimOverlap11gParams.numSta
		    && !session->gLimOverlap11gParams.protectionEnabled)
			lim_enable_ht_protection_from11g(mac_ctx, true, true,
							 bcn_prm, session);
		return;
	}

	if (eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT == bcn_struct->HTInfo.opMode) {
		lim_update_overlap_sta_param(mac_ctx, mac_hdr->bssId,
					     &(session->gLimOverlapHt20Params));
		if (session->gLimOverlapHt20Params.numSta
		    && !session->gLimOverlapHt20Params.protectionEnabled)
			lim_enable_ht20_protection(mac_ctx, true, true,
						   bcn_prm, session);
	}
}

/**
 * ap_beacon_process() - processes incoming beacons
 *
 * @mac_ctx:         mac global context
 * @rx_pkt_info:     incoming beacon packet
 * @bcn_struct:      beacon struct
 * @bcn_prm:         beacon params
 * @session:         pe session entry
 *
 * Return: void
 */
static void
ap_beacon_process(tpAniSirGlobal mac_ctx, uint8_t *rx_pkt_info,
		  tpSchBeaconStruct bcn_struct,
		  tpUpdateBeaconParams bcn_prm, tpPESession session)
{
	uint32_t phy_mode;
	tSirRFBand rf_band = SIR_BAND_UNKNOWN;
	/* Get RF band from session */
	rf_band = session->limRFBand;

	lim_get_phy_mode(mac_ctx, &phy_mode, session);

	if (SIR_BAND_5_GHZ == rf_band)
		ap_beacon_process_5_ghz(mac_ctx, rx_pkt_info, bcn_struct,
					bcn_prm, session, phy_mode);
	else if (SIR_BAND_2_4_GHZ == rf_band)
		ap_beacon_process_24_ghz(mac_ctx, rx_pkt_info, bcn_struct,
					 bcn_prm, session, phy_mode);
}

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

/**
 * __sch_beacon_process_no_session
 *
 * FUNCTION:
 * Process the received beacon frame when
 *  -- Station is not scanning
 *  -- No corresponding session is found
 *
 * LOGIC:
 *        Following scenarios exist when Session Does not exist:
 *             * IBSS Beacons, when IBSS session already exists with same SSID,
 *                but from STA which has not yet joined and has a different BSSID.
 *                - invoke lim_handle_ibs_scoalescing with the session context of existing IBSS session.
 *
 *             * IBSS Beacons when IBSS session does not exist, only Infra or BT-AMP session exists,
 *                then save the beacon in the scan results and throw it away.
 *
 *             * Infra Beacons
 *                - beacons received when no session active
 *                    should not come here, it should be handled as part of scanning,
 *                    else they should not be getting received, should update scan results and drop it if that happens.
 *                - beacons received when IBSS session active:
 *                    update scan results and drop it.
 *                - beacons received when Infra session(STA) is active:
 *                    update scan results and drop it
 *                - beacons received when BT-STA session is active:
 *                    update scan results and drop it.
 *                - beacons received when Infra/BT-STA  or Infra/IBSS is active.
 *                    update scan results and drop it.
 *

 */
static void __sch_beacon_process_no_session(tpAniSirGlobal pMac,
					    tpSchBeaconStruct pBeacon,
					    uint8_t *pRxPacketInfo)
{
	tpPESession psessionEntry = NULL;

	psessionEntry = lim_is_ibss_session_active(pMac);
	if (psessionEntry != NULL) {
		lim_handle_ibss_coalescing(pMac, pBeacon, pRxPacketInfo,
					   psessionEntry);
	}
	return;
}

/**
 * get_operating_channel_width() - Get operating channel width
 * @stads - station entry.
 *
 * This function returns the operating channel width based on
 * the supported channel width entry.
 *
 * Return: tSirMacHTChannelWidth on success
 */
static tSirMacHTChannelWidth get_operating_channel_width(tpDphHashNode stads)
{
	tSirMacHTChannelWidth ch_width = eHT_CHANNEL_WIDTH_20MHZ;

	if (stads->vhtSupportedChannelWidthSet ==
			WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)
		ch_width = eHT_CHANNEL_WIDTH_160MHZ;
	else if (stads->vhtSupportedChannelWidthSet ==
			WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ)
		ch_width = eHT_CHANNEL_WIDTH_160MHZ;
	else if (stads->vhtSupportedChannelWidthSet ==
			WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ)
		ch_width = eHT_CHANNEL_WIDTH_80MHZ;
	else if (stads->htSupportedChannelWidthSet)
		ch_width = eHT_CHANNEL_WIDTH_40MHZ;
	else
		ch_width = eHT_CHANNEL_WIDTH_20MHZ;

	return ch_width;
}

/*
 * sch_bcn_process_sta() - Process the received beacon frame for sta,
 * bt_amp_sta
 *
 * @mac_ctx:        mac_ctx
 * @bcn:            beacon struct
 * @rx_pkt_info:    received packet info
 * @session:        pe session pointer
 * @bssIdx:         bss index
 * @beaconParams:   update beacon params
 * @sendProbeReq:   out flag to indicate if probe rsp is to be sent
 * @pMh:            mac header
 *
 * Process the received beacon frame for sta
 *
 * Return: success of failure of operation
 */
static bool
sch_bcn_process_sta(tpAniSirGlobal mac_ctx,
			       tpSchBeaconStruct bcn,
			       uint8_t *rx_pkt_info,
			       tpPESession session, uint8_t *bssIdx,
			       tUpdateBeaconParams *beaconParams,
			       uint8_t *sendProbeReq, tpSirMacMgmtHdr pMh)
{
	uint32_t bi;
	tpDphHashNode pStaDs = NULL;
	/*
	 *  This handles two cases:
	 *  -- Infra STA receving beacons from AP
	 */

	/**
	 * This is the Beacon received from the AP  we're currently associated
	 * with. Check if there are any changes in AP's capabilities
	 */
	if ((uint8_t) bcn->channelNumber != session->currentOperChannel) {
		pe_err("Channel Change from %d --> %d - Ignoring beacon!",
		       session->currentOperChannel,
		       bcn->channelNumber);
		return false;
	}
	lim_detect_change_in_ap_capabilities(mac_ctx, bcn, session);
	if (lim_get_sta_hash_bssidx(mac_ctx, DPH_STA_HASH_INDEX_PEER, bssIdx,
				    session) != eSIR_SUCCESS)
		return false;

	beaconParams->bssIdx = *bssIdx;
	qdf_mem_copy((uint8_t *) &session->lastBeaconTimeStamp,
			(uint8_t *) bcn->timeStamp, sizeof(uint64_t));
	session->lastBeaconDtimCount = bcn->tim.dtimCount;
	session->currentBssBeaconCnt++;
	if (session->lastBeaconDtimPeriod != bcn->tim.dtimPeriod) {
		session->lastBeaconDtimPeriod = bcn->tim.dtimPeriod;
		lim_send_set_dtim_period(mac_ctx, bcn->tim.dtimPeriod,
				session);
	}
	MTRACE(mac_trace(mac_ctx, TRACE_CODE_RX_MGMT_TSF,
	       session->peSessionId, bcn->timeStamp[0]);)
	MTRACE(mac_trace(mac_ctx, TRACE_CODE_RX_MGMT_TSF,
	       session->peSessionId, bcn->timeStamp[1]);)

	/* Read beacon interval session Entry */
	bi = session->beaconParams.beaconInterval;
	if (bi != bcn->beaconInterval) {
		pe_debug("Beacon interval changed from %d to %d",
		       bcn->beaconInterval, bi);

		bi = bcn->beaconInterval;
		session->beaconParams.beaconInterval = (uint16_t) bi;
		beaconParams->paramChangeBitmap |= PARAM_BCN_INTERVAL_CHANGED;
		beaconParams->beaconInterval = (uint16_t) bi;
	}

	if (bcn->cfPresent) {
		cfg_set_int(mac_ctx, WNI_CFG_CFP_PERIOD,
			    bcn->cfParamSet.cfpPeriod);
		lim_send_cf_params(mac_ctx, *bssIdx,
				   bcn->cfParamSet.cfpCount,
				   bcn->cfParamSet.cfpPeriod);
	}

	/* No need to send DTIM Period and Count to HAL/SMAC */
	/* SMAC already parses TIM bit. */
	if (bcn->timPresent)
		cfg_set_int(mac_ctx, WNI_CFG_DTIM_PERIOD, bcn->tim.dtimPeriod);

	if (mac_ctx->lim.gLimProtectionControl !=
			WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE)
		lim_decide_sta_protection(mac_ctx, bcn, beaconParams, session);

	if (bcn->erpPresent) {
		if (bcn->erpIEInfo.barkerPreambleMode)
			lim_enable_short_preamble(mac_ctx, false,
						  beaconParams, session);
		else
			lim_enable_short_preamble(mac_ctx, true,
						  beaconParams, session);
	}
	lim_update_short_slot(mac_ctx, bcn, beaconParams, session);

	pStaDs = dph_get_hash_entry(mac_ctx, DPH_STA_HASH_INDEX_PEER,
				    &session->dph.dphHashTable);
	if ((bcn->wmeEdcaPresent && (session->limWmeEnabled))
	    || (bcn->edcaPresent && (session->limQosEnabled))) {
		if (bcn->edcaParams.qosInfo.count !=
		    session->gLimEdcaParamSetCount) {
			if (sch_beacon_edca_process(mac_ctx, &bcn->edcaParams,
						    session) != eSIR_SUCCESS) {
				pe_err("EDCA parameter processing error");
			} else if (pStaDs != NULL) {
				/* If needed, downgrade the EDCA parameters */
				lim_set_active_edca_params(mac_ctx,
					session->gLimEdcaParams, session);
				lim_send_edca_params(mac_ctx,
					session->gLimEdcaParamsActive,
					pStaDs->bssId);
			} else {
				pe_err("Self Entry missing in Hash Table");
			}
		}
		return true;
	}

	if ((bcn->qosCapabilityPresent && session->limQosEnabled)
	    && (bcn->qosCapability.qosInfo.count !=
		session->gLimEdcaParamSetCount))
		*sendProbeReq = true;

	return true;
}

/**
 * update_nss() - Function to update NSS
 * @mac_ctx: pointer to Global Mac structure
 * @sta_ds: pointer to tpDphHashNode
 * @beacon: pointer to tpSchBeaconStruct
 * @session_entry: pointer to tpPESession
 * @mgmt_hdr: pointer to tpSirMacMgmtHdr
 *
 * function to update NSS
 *
 * Return: none
 */
static void update_nss(tpAniSirGlobal mac_ctx, tpDphHashNode sta_ds,
		       tpSchBeaconStruct beacon, tpPESession session_entry,
		       tpSirMacMgmtHdr mgmt_hdr)
{
	if (sta_ds->vhtSupportedRxNss != (beacon->OperatingMode.rxNSS + 1)) {
		sta_ds->vhtSupportedRxNss =
			beacon->OperatingMode.rxNSS + 1;
		lim_set_nss_change(mac_ctx, session_entry,
			sta_ds->vhtSupportedRxNss, sta_ds->staIndex,
			mgmt_hdr->sa);
	}
}

#ifdef WLAN_FEATURE_11AX_BSS_COLOR
static void
sch_bcn_update_he_ies(tpAniSirGlobal mac_ctx, tpDphHashNode sta_ds,
				tpPESession session, tpSchBeaconStruct bcn,
				tpSirMacMgmtHdr mac_hdr)
{
	uint8_t session_bss_col_disabled_flag;
	bool anything_changed = false;

	if (session->he_op.present && bcn->vendor_he_op.present) {
		if (bcn->vendor_he_bss_color_change.present &&
				(session->he_op.bss_color !=
				 bcn->vendor_he_bss_color_change.new_color)) {
			pe_debug("bss color changed from [%d] to [%d]",
				session->he_op.bss_color,
				bcn->vendor_he_bss_color_change.new_color);
			session->he_op.bss_color =
				bcn->vendor_he_bss_color_change.new_color;
			anything_changed = true;
		}
		session_bss_col_disabled_flag = session->he_op.bss_col_disabled;
		if (session_bss_col_disabled_flag !=
				bcn->vendor_he_op.bss_col_disabled) {
			pe_debug("color disable flag changed from [%d] to [%d]",
				session->he_op.bss_col_disabled,
				bcn->vendor_he_op.bss_col_disabled);
			session->he_op.bss_col_disabled =
				bcn->vendor_he_op.bss_col_disabled;
			anything_changed = true;
		}
	}
	if (anything_changed)
		lim_send_he_ie_update(mac_ctx, session);
}
#else
static void
sch_bcn_update_he_ies(tpAniSirGlobal mac_ctx, tpDphHashNode sta_ds,
				tpPESession session, tpSchBeaconStruct bcn,
				tpSirMacMgmtHdr mac_hdr)
{
	return;
}
#endif

static void
sch_bcn_update_opmode_change(tpAniSirGlobal mac_ctx, tpDphHashNode sta_ds,
				tpPESession session, tpSchBeaconStruct bcn,
				tpSirMacMgmtHdr mac_hdr)
{
	bool skip_opmode_update = false;
	uint8_t oper_mode;
	uint32_t fw_vht_ch_wd = wma_get_vht_ch_width();
	uint8_t ch_width = 0;

	if (session->vhtCapability && bcn->OperatingMode.present) {
		oper_mode = get_operating_channel_width(sta_ds);
		if ((oper_mode == eHT_CHANNEL_WIDTH_80MHZ) &&
		    (bcn->OperatingMode.chanWidth > eHT_CHANNEL_WIDTH_80MHZ))
			skip_opmode_update = true;

		if (!skip_opmode_update &&
			((oper_mode != bcn->OperatingMode.chanWidth) ||
			(sta_ds->vhtSupportedRxNss !=
			(bcn->OperatingMode.rxNSS + 1)))) {
			pe_debug("received OpMode Chanwidth %d, staIdx = %d",
			       bcn->OperatingMode.chanWidth, sta_ds->staIndex);
			pe_debug("MAC - %0x:%0x:%0x:%0x:%0x:%0x",
			       mac_hdr->sa[0], mac_hdr->sa[1],
			       mac_hdr->sa[2], mac_hdr->sa[3],
			       mac_hdr->sa[4], mac_hdr->sa[5]);

			if ((bcn->OperatingMode.chanWidth >=
				eHT_CHANNEL_WIDTH_160MHZ) &&
				(fw_vht_ch_wd > eHT_CHANNEL_WIDTH_80MHZ)) {
				pe_debug("Updating the CH Width to 160MHz");
				sta_ds->vhtSupportedChannelWidthSet =
					WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ;
				sta_ds->htSupportedChannelWidthSet =
					eHT_CHANNEL_WIDTH_40MHZ;
				ch_width = eHT_CHANNEL_WIDTH_160MHZ;
			} else if (bcn->OperatingMode.chanWidth >=
				eHT_CHANNEL_WIDTH_80MHZ) {
				pe_debug("Updating the CH Width to 80MHz");
				sta_ds->vhtSupportedChannelWidthSet =
					WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ;
				sta_ds->htSupportedChannelWidthSet =
					eHT_CHANNEL_WIDTH_40MHZ;
				ch_width = eHT_CHANNEL_WIDTH_80MHZ;
			} else if (bcn->OperatingMode.chanWidth ==
				eHT_CHANNEL_WIDTH_40MHZ) {
				pe_debug("Updating the CH Width to 40MHz");
				sta_ds->vhtSupportedChannelWidthSet =
					WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ;
				sta_ds->htSupportedChannelWidthSet =
					eHT_CHANNEL_WIDTH_40MHZ;
				ch_width = eHT_CHANNEL_WIDTH_40MHZ;
			} else if (bcn->OperatingMode.chanWidth ==
				eHT_CHANNEL_WIDTH_20MHZ) {
				pe_debug("Updating the CH Width to 20MHz");
				sta_ds->vhtSupportedChannelWidthSet =
					WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ;
				sta_ds->htSupportedChannelWidthSet =
					eHT_CHANNEL_WIDTH_20MHZ;
				ch_width = eHT_CHANNEL_WIDTH_20MHZ;
			}
			lim_check_vht_op_mode_change(mac_ctx, session,
				ch_width, sta_ds->staIndex, mac_hdr->sa);
			update_nss(mac_ctx, sta_ds, bcn, session, mac_hdr);
		}
		return;
	}

	if (!(session->vhtCapability && bcn->VHTOperation.present))
		return;

	oper_mode = sta_ds->vhtSupportedChannelWidthSet;
	if ((oper_mode == WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) &&
	    (oper_mode < bcn->VHTOperation.chanWidth))
		skip_opmode_update = true;

	if (!skip_opmode_update &&
	    (oper_mode != bcn->VHTOperation.chanWidth)) {
		pe_debug("received VHTOP CHWidth %d staIdx = %d",
		       bcn->VHTOperation.chanWidth, sta_ds->staIndex);
		pe_debug("MAC - %0x:%0x:%0x:%0x:%0x:%0x",
		       mac_hdr->sa[0], mac_hdr->sa[1],
		       mac_hdr->sa[2], mac_hdr->sa[3],
		       mac_hdr->sa[4], mac_hdr->sa[5]);

		if ((bcn->VHTOperation.chanWidth >=
			WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) &&
			(fw_vht_ch_wd > eHT_CHANNEL_WIDTH_80MHZ)) {
			pe_debug("Updating the CH Width to 160MHz");
			sta_ds->vhtSupportedChannelWidthSet =
				bcn->VHTOperation.chanWidth;
			sta_ds->htSupportedChannelWidthSet =
				eHT_CHANNEL_WIDTH_40MHZ;
			ch_width = eHT_CHANNEL_WIDTH_160MHZ;
		} else if (bcn->VHTOperation.chanWidth >=
			WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) {
			pe_debug("Updating the CH Width to 80MHz");
			sta_ds->vhtSupportedChannelWidthSet =
				WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ;
			sta_ds->htSupportedChannelWidthSet =
				eHT_CHANNEL_WIDTH_40MHZ;
			ch_width = eHT_CHANNEL_WIDTH_80MHZ;
		} else if (bcn->VHTOperation.chanWidth ==
			WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ) {
			sta_ds->vhtSupportedChannelWidthSet =
				WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ;
			if (bcn->HTCaps.supportedChannelWidthSet) {
				pe_debug("Updating the CH Width to 40MHz");
				sta_ds->htSupportedChannelWidthSet =
					eHT_CHANNEL_WIDTH_40MHZ;
				ch_width = eHT_CHANNEL_WIDTH_40MHZ;
			} else {
				pe_debug("Updating the CH Width to 20MHz");
				sta_ds->htSupportedChannelWidthSet =
					eHT_CHANNEL_WIDTH_20MHZ;
				ch_width = eHT_CHANNEL_WIDTH_20MHZ;
			}
		}
		lim_check_vht_op_mode_change(mac_ctx, session, ch_width,
						sta_ds->staIndex, mac_hdr->sa);
	}
}

/*
 * sch_bcn_process_sta_ibss() - Process the received beacon frame
 * for sta, bt_amp_sta and ibss
 *
 * @mac_ctx:        mac_ctx
 * @bcn:            beacon struct
 * @rx_pkt_info:    received packet info
 * @session:        pe session pointer
 * @bssIdx:         bss index
 * @beaconParams:   update beacon params
 * @sendProbeReq:   out flag to indicate if probe rsp is to be sent
 * @pMh:            mac header
 *
 * Process the received beacon frame for sta and ibss
 *
 * Return: void
 */
static void
sch_bcn_process_sta_ibss(tpAniSirGlobal mac_ctx,
				    tpSchBeaconStruct bcn,
				    uint8_t *rx_pkt_info,
				    tpPESession session, uint8_t *bssIdx,
				    tUpdateBeaconParams *beaconParams,
				    uint8_t *sendProbeReq, tpSirMacMgmtHdr pMh)
{
	tpDphHashNode pStaDs = NULL;
	uint16_t aid;
	uint8_t cb_mode;

	if (CHAN_ENUM_14 >= session->currentOperChannel)
		cb_mode = mac_ctx->roam.configParam.channelBondingMode24GHz;
	else
		cb_mode = mac_ctx->roam.configParam.channelBondingMode5GHz;
	/* check for VHT capability */
	pStaDs = dph_lookup_hash_entry(mac_ctx, pMh->sa, &aid,
			&session->dph.dphHashTable);
	if ((NULL == pStaDs) ||
	  (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE == cb_mode) ||
	  ((NULL != pStaDs) &&
	   (STA_INVALID_IDX == pStaDs->staIndex)))
		return;
	sch_bcn_update_opmode_change(mac_ctx, pStaDs, session, bcn, pMh);
	sch_bcn_update_he_ies(mac_ctx, pStaDs, session, bcn, pMh);
	return;
}

/**
 * get_local_power_constraint_beacon() - extracts local constraint
 * from beacon
 * @bcn: beacon structure
 * @local_constraint: local constraint pointer
 *
 * Return: None
 */
#ifdef FEATURE_WLAN_ESE
static void get_local_power_constraint_beacon(
		tpSchBeaconStruct bcn,
		int8_t *local_constraint)
{
	if (bcn->eseTxPwr.present)
		*local_constraint = bcn->eseTxPwr.power_limit;
}
#else
static void get_local_power_constraint_beacon(
		tpSchBeaconStruct bcn,
		int8_t *local_constraint)
{

}
#endif

/*
 * __sch_beacon_process_for_session() - Process the received beacon frame when
 * station is not scanning and corresponding session is found
 *
 *
 * @mac_ctx:        mac_ctx
 * @bcn:            beacon struct
 * @rx_pkt_info:    received packet info
 * @session:        pe session pointer
 *
 * Following scenarios exist when Session exists
 *   IBSS STA receving beacons from IBSS Peers, who are part of IBSS.
 *     - call lim_handle_ibs_scoalescing with that session context.
 *   Infra STA receving beacons from AP to which it is connected
 *     - call sch_beacon_processFromAP with that session's context.
 *     - call sch_beacon_processFromAP with that session's context.
 *     (here need to make sure BTAP creates session entry for BT STA)
 *     - just update the beacon count for heart beat purposes for now,
 *       for now, don't process the beacon.
 *   Infra/IBSS both active and receives IBSS beacon:
 *     - call lim_handle_ibs_scoalescing with that session context.
 *   Infra/IBSS both active and receives Infra beacon:
 *     - call sch_beacon_processFromAP with that session's context.
 *        any updates to EDCA parameters will be effective for IBSS as well,
 *        even though no WMM for IBSS ?? Need to figure out how to handle
 *        this scenario.
 *   Infra/BTSTA both active and receive Infra beacon.
 *     - change in EDCA parameters on Infra affect the BTSTA link.
 *        Update the same parameters on BT link
 *   Infra/BTSTA both active and receive BT-AP beacon.
 *     - update beacon cnt for heartbeat
 *   Infra/BTAP both active and receive Infra beacon.
 *     - BT-AP starts advertising BE parameters from Infra AP, if they get
 *       changed.
 *   Infra/BTAP both active and receive BTSTA beacon.
 *       - update beacon cnt for heartbeat
 *
 * Return: void
 */
static void __sch_beacon_process_for_session(tpAniSirGlobal mac_ctx,
					     tpSchBeaconStruct bcn,
					     uint8_t *rx_pkt_info,
					     tpPESession session)
{
	uint8_t bssIdx = 0;
	tUpdateBeaconParams beaconParams;
	uint8_t sendProbeReq = false;
	tpSirMacMgmtHdr pMh = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
	int8_t regMax = 0, maxTxPower = 0, local_constraint;
	qdf_mem_zero(&beaconParams, sizeof(tUpdateBeaconParams));
	beaconParams.paramChangeBitmap = 0;

	if (LIM_IS_IBSS_ROLE(session)) {
		lim_handle_ibss_coalescing(mac_ctx, bcn, rx_pkt_info, session);
	} else if (LIM_IS_STA_ROLE(session)) {
		if (false == sch_bcn_process_sta(mac_ctx, bcn,
				rx_pkt_info, session, &bssIdx,
				&beaconParams, &sendProbeReq, pMh))
			return;
	}

	/*
	 * For vht session, if opermode ie or vht oper IE is present
	 * bandwidth change will be taken care using these vht IEs.
	 */
	if (!(session->vhtCapability && (bcn->OperatingMode.present ||
	   bcn->VHTOperation.present)) && session->htCapability &&
	   bcn->HTInfo.present && !LIM_IS_IBSS_ROLE(session))
		lim_update_sta_run_time_ht_switch_chnl_params(mac_ctx,
						&bcn->HTInfo, bssIdx, session);

	if ((LIM_IS_STA_ROLE(session) && !wma_is_csa_offload_enabled())
	    || LIM_IS_IBSS_ROLE(session)) {
		/* Channel Switch information element updated */
		if (bcn->channelSwitchPresent) {
			/*
			 * on receiving channel switch announcement from AP,
			 * delete all TDLS peers before leaving BSS and proceed
			 * for channel switch
			 */
			if (LIM_IS_STA_ROLE(session))
				lim_delete_tdls_peers(mac_ctx, session);

			lim_update_channel_switch(mac_ctx, bcn, session);
		} else if (session->gLimSpecMgmt.dot11hChanSwState ==
				eLIM_11H_CHANSW_RUNNING) {
			lim_cancel_dot11h_channel_switch(mac_ctx, session);
		}
	}
	if (LIM_IS_STA_ROLE(session)
	    || LIM_IS_IBSS_ROLE(session))
		sch_bcn_process_sta_ibss(mac_ctx, bcn,
					rx_pkt_info, session, &bssIdx,
					&beaconParams, &sendProbeReq, pMh);
	/* Obtain the Max Tx power for the current regulatory  */
	regMax = cfg_get_regulatory_max_transmit_power(mac_ctx,
					session->currentOperChannel);

	local_constraint = regMax;

	if (mac_ctx->roam.configParam.allow_tpc_from_ap) {
		get_local_power_constraint_beacon(bcn, &local_constraint);
		pe_debug("ESE localPowerConstraint = %d,",
				local_constraint);

		if (mac_ctx->rrm.rrmPEContext.rrmEnable &&
				bcn->powerConstraintPresent) {
			local_constraint = regMax;
			local_constraint -=
				bcn->localPowerConstraint.localPowerConstraints;
			pe_debug("localPowerConstraint = %d,",
				local_constraint);
			}
	}

	maxTxPower = lim_get_max_tx_power(regMax, local_constraint,
					mac_ctx->roam.configParam.nTxPowerCap);

	pe_debug("RegMax = %d, MaxTx pwr = %d",
			regMax, maxTxPower);


	/* If maxTxPower is increased or decreased */
	if (maxTxPower != session->maxTxPower) {
		pe_debug(
			FL("Local power constraint change, Updating new maxTx power %d from old pwr %d"),
			maxTxPower, session->maxTxPower);
		if (lim_send_set_max_tx_power_req(mac_ctx, maxTxPower, session)
		    == eSIR_SUCCESS)
			session->maxTxPower = maxTxPower;
	}

	/* Indicate to LIM that Beacon is received */
	if (bcn->HTInfo.present)
		lim_received_hb_handler(mac_ctx,
				(uint8_t) bcn->HTInfo.primaryChannel, session);
	else
		lim_received_hb_handler(mac_ctx, (uint8_t) bcn->channelNumber,
				session);

	/*
	 * I don't know if any additional IE is required here. Currently, not
	 * include addIE.
	 */
	if (sendProbeReq)
		lim_send_probe_req_mgmt_frame(mac_ctx, &session->ssId,
			session->bssId, session->currentOperChannel,
			session->selfMacAddr, session->dot11mode, 0, NULL);

	if ((false == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running)
	    && beaconParams.paramChangeBitmap) {
		pe_warn("Beacon for session[%d] got changed.",
		       session->peSessionId);
		pe_warn("sending beacon param change bitmap: 0x%x",
		       beaconParams.paramChangeBitmap);
		lim_send_beacon_params(mac_ctx, &beaconParams, session);
	}

	if ((session->pePersona == QDF_P2P_CLIENT_MODE) &&
		session->send_p2p_conf_frame) {
		lim_p2p_oper_chan_change_confirm_action_frame(mac_ctx,
				session->bssId, session);
		session->send_p2p_conf_frame = false;
	}
}

#ifdef WLAN_FEATURE_11AX_BSS_COLOR
static void ap_update_bss_color_info(tpAniSirGlobal mac_ctx,
						tpPESession session,
						uint8_t bss_color)
{
	if (!session)
		return;

	if (bss_color < 1 || bss_color > 63) {
		pe_warn("Invalid BSS color");
		return;
	}

	session->bss_color_info[bss_color - 1].seen_count++;
	session->bss_color_info[bss_color - 1].timestamp =
					qdf_get_system_timestamp();
}

static uint8_t ap_get_new_bss_color(tpAniSirGlobal mac_ctx, tpPESession session)
{
	int i;
	uint8_t new_bss_color;
	struct bss_color_info color_info;
	qdf_time_t cur_timestamp;

	if (!session)
		return 0;

	color_info = session->bss_color_info[0];
	new_bss_color = 0;
	cur_timestamp = qdf_get_system_timestamp();
	for (i = 1; i < MAX_BSS_COLOR_VALUE; i++) {
		if (session->bss_color_info[i].seen_count == 0) {
			new_bss_color = i + 1;
			return new_bss_color;
		}

		if (color_info.seen_count >
				session->bss_color_info[i].seen_count &&
				(cur_timestamp - session->bss_color_info[i].
					timestamp) > TIME_BEACON_NOT_UPDATED) {
			color_info = session->bss_color_info[i];
			new_bss_color = i + 1;
		}
	}
	pe_debug("new bss color: %d", new_bss_color);
	return new_bss_color;
}

static void sch_check_bss_color_ie(tpAniSirGlobal mac_ctx,
					tpPESession ap_session,
					tSchBeaconStruct *bcn,
					tUpdateBeaconParams *bcn_prm)
{
	/* check bss color in the beacon */
	if (ap_session->he_op.present && !ap_session->he_op.bss_color) {
		if (bcn->vendor_he_op.present &&
			(bcn->vendor_he_op.bss_color ==
					ap_session->he_op.bss_color)) {
			ap_session->he_op.bss_col_disabled = 1;
			bcn_prm->paramChangeBitmap |=
						PARAM_BSS_COLOR_CHANGED;
			ap_session->he_bss_color_change.countdown =
						BSS_COLOR_SWITCH_COUNTDOWN;
			ap_session->he_bss_color_change.new_color =
					ap_get_new_bss_color(mac_ctx,
								ap_session);
			ap_session->he_op.bss_color = ap_session->
						he_bss_color_change.new_color;
			WMI_HEOPS_COLOR_SET(bcn_prm->he_ops,
						ap_session->he_op.bss_color);
			WMI_HEOPS_BSSCOLORDISABLE_SET(bcn_prm->he_ops,
					ap_session->he_op.bss_col_disabled);
			ap_session->bss_color_changing = 1;
		} else {
			/* update info for the bss color */
			if (bcn->vendor_he_op.present)
				ap_update_bss_color_info(mac_ctx,
						ap_session,
						bcn->vendor_he_op.bss_color);
		}
	}
}

#else
static void  sch_check_bss_color_ie(tpAniSirGlobal mac_ctx,
					tpPESession ap_session,
					tSchBeaconStruct *bcn,
					tUpdateBeaconParams *bcn_prm)
{
}
#endif

/**
 * sch_beacon_process() - process the beacon frame
 * @mac_ctx:        mac global context
 * @rx_pkt_info:  pointer to buffer descriptor
 *
 * Return: None
 */
void
sch_beacon_process(tpAniSirGlobal mac_ctx, uint8_t *rx_pkt_info,
		   tpPESession session)
{
	static tSchBeaconStruct bcn;
	tUpdateBeaconParams bcn_prm;
	tpPESession ap_session = NULL;
	uint8_t i;

	qdf_mem_zero(&bcn_prm, sizeof(tUpdateBeaconParams));
	bcn_prm.paramChangeBitmap = 0;
	/* Convert the beacon frame into a structure */
	if (sir_convert_beacon_frame2_struct(mac_ctx, (uint8_t *) rx_pkt_info,
		&bcn) != eSIR_SUCCESS) {
		pe_err("beacon parsing failed");
		return;
	}

	if (bcn.ssidPresent)
		bcn.ssId.ssId[bcn.ssId.length] = 0;
	/*
	 * First process the beacon in the context of any existing AP or BTAP
	 * session. This takes cares of following two scenarios:
	 *  - session = NULL:
	 * e.g. beacon received from a neighboring BSS, you want to apply the
	 * protection settings to BTAP/InfraAP beacons
	 *  - session is non NULL:
	 * e.g. beacon received is from the INFRA AP to which you are connected
	 * on another concurrent link. In this case also, we want to apply the
	 * protection settings(as advertised by Infra AP) to BTAP beacons
	 */
	for (i = 0; i < mac_ctx->lim.maxBssId; i++) {
		ap_session = pe_find_session_by_session_id(mac_ctx, i);
		if (!((ap_session != NULL) &&
			(!(WMA_GET_OFFLOADSCANLEARN(rx_pkt_info)))))
			continue;

		if (!LIM_IS_AP_ROLE(ap_session))
			continue;

		bcn_prm.bssIdx = ap_session->bssIdx;

		sch_check_bss_color_ie(mac_ctx, ap_session, &bcn, &bcn_prm);

		if (ap_session->gLimProtectionControl !=
		    WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE)
			ap_beacon_process(mac_ctx, rx_pkt_info,
					  &bcn, &bcn_prm, ap_session);

		if ((false == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running)
		    && bcn_prm.paramChangeBitmap) {
			/* Update the bcn and apply the new settings to HAL */
			sch_set_fixed_beacon_fields(mac_ctx, ap_session);
			pe_debug("Beacon for PE session[%d] got changed",
			       ap_session->peSessionId);
			pe_debug("sending beacon param change bitmap: 0x%x",
			       bcn_prm.paramChangeBitmap);
			lim_send_beacon_params(mac_ctx, &bcn_prm, ap_session);
		}
	}

	/*
	 * Now process the beacon in the context of the BSS which is
	 * transmitting the beacons, if one is found
	 */
	if (session == NULL)
		__sch_beacon_process_no_session(mac_ctx, &bcn, rx_pkt_info);
	else
		__sch_beacon_process_for_session(mac_ctx, &bcn, rx_pkt_info,
						 session);
}

/**
 * sch_beacon_edca_process(): Process the EDCA parameter set in the received
 * beacon frame
 *
 * @mac_ctx:    mac global context
 * @edca:       reference to edca parameters in beacon struct
 * @session :   pesession entry
 *
 * @return status of operation
 */
tSirRetStatus
sch_beacon_edca_process(tpAniSirGlobal pMac, tSirMacEdcaParamSetIE *edca,
			tpPESession session)
{
	uint8_t i;
#ifdef FEATURE_WLAN_DIAG_SUPPORT
	host_log_qos_edca_pkt_type *log_ptr = NULL;
#endif /* FEATURE_WLAN_DIAG_SUPPORT */

	pe_debug("Updating parameter set count: Old %d ---> new %d",
		session->gLimEdcaParamSetCount, edca->qosInfo.count);

	session->gLimEdcaParamSetCount = edca->qosInfo.count;
	session->gLimEdcaParams[EDCA_AC_BE] = edca->acbe;
	session->gLimEdcaParams[EDCA_AC_BK] = edca->acbk;
	session->gLimEdcaParams[EDCA_AC_VI] = edca->acvi;
	session->gLimEdcaParams[EDCA_AC_VO] = edca->acvo;

	if (pMac->roam.configParam.enable_edca_params) {
		session->gLimEdcaParams[EDCA_AC_VO].aci.aifsn =
			pMac->roam.configParam.edca_vo_aifs;
		session->gLimEdcaParams[EDCA_AC_VI].aci.aifsn =
			pMac->roam.configParam.edca_vi_aifs;
		session->gLimEdcaParams[EDCA_AC_BK].aci.aifsn =
			pMac->roam.configParam.edca_bk_aifs;
		session->gLimEdcaParams[EDCA_AC_BE].aci.aifsn =
			pMac->roam.configParam.edca_be_aifs;

		session->gLimEdcaParams[EDCA_AC_VO].cw.min =
			pMac->roam.configParam.edca_vo_cwmin;
		session->gLimEdcaParams[EDCA_AC_VI].cw.min =
			pMac->roam.configParam.edca_vi_cwmin;
		session->gLimEdcaParams[EDCA_AC_BK].cw.min =
			pMac->roam.configParam.edca_bk_cwmin;
		session->gLimEdcaParams[EDCA_AC_BE].cw.min =
			pMac->roam.configParam.edca_be_cwmin;

		session->gLimEdcaParams[EDCA_AC_VO].cw.max =
			pMac->roam.configParam.edca_vo_cwmax;
		session->gLimEdcaParams[EDCA_AC_VI].cw.max =
			pMac->roam.configParam.edca_vi_cwmax;
		session->gLimEdcaParams[EDCA_AC_BK].cw.max =
			pMac->roam.configParam.edca_bk_cwmax;
		session->gLimEdcaParams[EDCA_AC_BE].cw.max =
			pMac->roam.configParam.edca_be_cwmax;
	}
#ifdef FEATURE_WLAN_DIAG_SUPPORT
	WLAN_HOST_DIAG_LOG_ALLOC(log_ptr, host_log_qos_edca_pkt_type,
				 LOG_WLAN_QOS_EDCA_C);
	if (log_ptr) {
		log_ptr->aci_be = session->gLimEdcaParams[EDCA_AC_BE].aci.aci;
		log_ptr->cw_be =
			session->gLimEdcaParams[EDCA_AC_BE].cw.max << 4
				| session->gLimEdcaParams[EDCA_AC_BE].cw.min;
		log_ptr->txoplimit_be =
			session->gLimEdcaParams[EDCA_AC_BE].txoplimit;
		log_ptr->aci_bk =
			session->gLimEdcaParams[EDCA_AC_BK].aci.aci;
		log_ptr->cw_bk =
			session->gLimEdcaParams[EDCA_AC_BK].cw.max << 4
				| session->gLimEdcaParams[EDCA_AC_BK].cw.min;
		log_ptr->txoplimit_bk =
			session->gLimEdcaParams[EDCA_AC_BK].txoplimit;
		log_ptr->aci_vi =
			session->gLimEdcaParams[EDCA_AC_VI].aci.aci;
		log_ptr->cw_vi =
			session->gLimEdcaParams[EDCA_AC_VI].cw.max << 4
				| session->gLimEdcaParams[EDCA_AC_VI].cw.min;
		log_ptr->txoplimit_vi =
			session->gLimEdcaParams[EDCA_AC_VI].txoplimit;
		log_ptr->aci_vo =
			session->gLimEdcaParams[EDCA_AC_VO].aci.aci;
		log_ptr->cw_vo =
			session->gLimEdcaParams[EDCA_AC_VO].cw.max << 4
				| session->gLimEdcaParams[EDCA_AC_VO].cw.min;
		log_ptr->txoplimit_vo =
			session->gLimEdcaParams[EDCA_AC_VO].txoplimit;
	}
	WLAN_HOST_DIAG_LOG_REPORT(log_ptr);
#endif /* FEATURE_WLAN_DIAG_SUPPORT */
	pe_debug("Edsa param enabled in ini %d. Updating Local EDCA Params(gLimEdcaParams) to: ",
		pMac->roam.configParam.enable_edca_params);
	for (i = 0; i < MAX_NUM_AC; i++) {
		pe_debug("AC[%d]:  AIFSN: %d, ACM %d, CWmin %d, CWmax %d, TxOp %d",
		       i, session->gLimEdcaParams[i].aci.aifsn,
		       session->gLimEdcaParams[i].aci.acm,
		       session->gLimEdcaParams[i].cw.min,
		       session->gLimEdcaParams[i].cw.max,
		       session->gLimEdcaParams[i].txoplimit);
	}
	return eSIR_SUCCESS;
}
