/*
 * 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.
 */

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

   \file  lim_session_utils.c
   \brief implementation for lim Session Utility  APIs
   \author Sunit Bhatia
   ========================================================================*/

/*--------------------------------------------------------------------------
   Include Files
   ------------------------------------------------------------------------*/
#include "ani_global.h"
#include "lim_debug.h"
#ifdef WLAN_FEATURE_VOWIFI_11R
#include "lim_ft_defs.h"
#endif
#include "lim_session.h"
#include "lim_session_utils.h"
#include "lim_utils.h"

/**
 * is_lim_session_off_channel() - checks if any other off channel session exists
 * @mac_ctx: Global MAC context.
 * @sessionId: PE session ID.
 *
 * Return: This function returns true if the session Id passed needs to be on
 *         a different channel than atleast one session already active.
 **/
uint8_t is_lim_session_off_channel(tpAniSirGlobal mac_ctx, uint8_t session_id)
{
	uint8_t i;

	if (session_id >= mac_ctx->lim.maxBssId) {
		lim_log(mac_ctx, LOGE, FL("Invalid session_id:%d"), session_id);
		return false;
	}

	for (i = 0; i < mac_ctx->lim.maxBssId; i++) {
		/* Skip the session_id that is to be joined. */
		if (i == session_id)
			continue;
		/*
		 * if another session is valid and it is on different channel
		 * then it is an off channel operation.
		 */
		if ((mac_ctx->lim.gpSession[i].valid) &&
		    (mac_ctx->lim.gpSession[i].currentOperChannel !=
		     mac_ctx->lim.gpSession[session_id].currentOperChannel))
			return true;
	}
	return false;

}

/**
 * lim_is_chan_switch_running() - check if channel switch is happening
 * @mac_ctx: Global MAC context.
 *
 * Return: 1 - if channel switch is happening on any session.
 *         0 - if channel switch is not happening.
 **/
uint8_t lim_is_chan_switch_running(tpAniSirGlobal mac_ctx)
{
	uint8_t i;

	for (i = 0; i < mac_ctx->lim.maxBssId; i++)
		if (mac_ctx->lim.gpSession[i].valid &&
			mac_ctx->lim.gpSession[i].gLimSpecMgmt.dot11hChanSwState
			== eLIM_11H_CHANSW_RUNNING)
			return 1;
	return 0;
}

/**
 * lim_is_in_mcc() - check if device is in MCC
 * @mac_ctx: Global MAC context.
 *
 * Return: true - if in MCC.
 *         false - Not in MCC
 **/
uint8_t lim_is_in_mcc(tpAniSirGlobal mac_ctx)
{
	uint8_t i;
	uint8_t chan = 0;
	uint8_t curr_oper_channel = 0;

	for (i = 0; i < mac_ctx->lim.maxBssId; i++) {
		/*
		 * if another session is valid and it is on different channel
		 * it is an off channel operation.
		 */
		if ((mac_ctx->lim.gpSession[i].valid)) {
			curr_oper_channel =
				mac_ctx->lim.gpSession[i].currentOperChannel;
			if (chan == 0)
				chan = curr_oper_channel;
			else if (chan != curr_oper_channel)
				return true;
		}
	}
	return false;
}

/**
 * pe_get_current_stas_count() - Total stations associated on all sessions.
 * @mac_ctx: Global MAC context.
 *
 * Return: true - Number of stations active on all sessions.
 **/
uint8_t pe_get_current_stas_count(tpAniSirGlobal mac_ctx)
{
	uint8_t i;
	uint8_t stacount = 0;
	for (i = 0; i < mac_ctx->lim.maxBssId; i++)
		if (mac_ctx->lim.gpSession[i].valid == true)
			stacount +=
				mac_ctx->lim.gpSession[i].gLimNumOfCurrentSTAs;
	return stacount;
}
