/*
 * regulatoryDomain.c
 *
 * Copyright(c) 1998 - 2009 Texas Instruments. All rights reserved.      
 * All rights reserved.                                                  
 *                                                                       
 * Redistribution and use in source and binary forms, with or without    
 * modification, are permitted provided that the following conditions    
 * are met:                                                              
 *                                                                       
 *  * Redistributions of source code must retain the above copyright     
 *    notice, this list of conditions and the following disclaimer.      
 *  * Redistributions in binary form must reproduce the above copyright  
 *    notice, this list of conditions and the following disclaimer in    
 *    the documentation and/or other materials provided with the         
 *    distribution.                                                      
 *  * Neither the name Texas Instruments nor the names of its            
 *    contributors may be used to endorse or promote products derived    
 *    from this software without specific prior written permission.      
 *                                                                       
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS   
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT     
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT  
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT      
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT   
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/** \file regulatoryDomain.c
 *  \brief regulatoryDomain module interface
 *
 *  \see regulatoryDomain.h
 */

/************************************************************************************************/
/*  												*/
/*		MODULE:		regulatoryDomain.c					        */
/*		PURPOSE:	regulatoryDomain module interface.			        */
/*                  This module calculated the channel that should be scanned and that are      */
/*                   supported. Moreover, he set the transmit power level according to the      */
/*                   regulatory domain requirements and the supported channel.                  */
/*								 			        */
/************************************************************************************************/
#define __FILE_ID__  FILE_ID_3
#include "report.h"
#include "osApi.h"
#include "paramOut.h"
#include "regulatoryDomain.h"
#include "regulatoryDomainApi.h"
#include "TWDriver.h"
#include "siteMgrApi.h"
#include "SwitchChannelApi.h"
#include "DrvMainModules.h"
#include "TWDriver.h"


/* Mask for retrieving the TxPower from the Scan Control Table */
#define MASK_TX_POWER					(0x1f) /* bits 0-4 indicates MaxTxPower */ 
#define MASK_ACTIVE_ALLOWED 			(0x40) /* bit 6 indiactes the channel is allowed for Active scan */
#define MASK_FREQ_ALLOWED 				(0x80) /* bit 7 indicates the cahnnel is allowed*/

#define CHANNEL_VALIDITY_TS_THRESHOLD   10000 /* 10 sec */

/* 
* Small macro to convert Dbm units into Dbm/10 units. This macro is important
* in order to avoid over-flow of Dbm units bigger than 25
*/
#define DBM2DBMDIV10(uTxPower) \
	((uTxPower) > (MAX_TX_POWER / DBM_TO_TX_POWER_FACTOR) ? \
		MAX_TX_POWER : (uTxPower) * DBM_TO_TX_POWER_FACTOR)		


/********************************************************************************/
/*						Internal functions prototypes.							*/
/********************************************************************************/
static TI_STATUS regulatoryDomain_updateCurrTxPower(regulatoryDomain_t	*pRegulatoryDomain);

static void regulatoryDomain_setChannelValidity(regulatoryDomain_t *pRegulatoryDomain, 
												TI_UINT16 channelNum, TI_BOOL channelValidity);

static TI_STATUS setSupportedChannelsAccording2CountryIe(regulatoryDomain_t *pRegulatoryDomain, TCountry*	pCountry, TI_BOOL band_2_4);

static void setSupportedChannelsAccording2ScanControlTable(regulatoryDomain_t  *pRegulatoryDomain);

static TI_STATUS regulatoryDomain_getChannelCapability(regulatoryDomain_t *pRegulatoryDomain, 
													   channelCapabilityReq_t channelCapabilityReq, 
													   channelCapabilityRet_t *channelCapabilityRet);

static void regulatoryDomain_updateChannelsTs(regulatoryDomain_t *pRegulatoryDomain, TI_UINT8 channel);

static void regulatoryDomain_buildDefaultListOfChannelsPerBand(regulatoryDomain_t *pRegulatoryDomain, ERadioBand band, TI_UINT8 *listSize);

static void regulatoryDomain_checkCountryCodeExpiry(regulatoryDomain_t *pRegulatoryDomain);

static TI_BOOL regulatoryDomain_isChannelSupprted(regulatoryDomain_t *pRegulatoryDomain, TI_UINT8 channel);

static TI_BOOL regulatoryDomain_isCountryFound(regulatoryDomain_t *pRegulatoryDomain, ERadioBand radioBand);

static void regulatoryDomain_getPowerTableMinMax (regulatoryDomain_t *pRegulatoryDomain,
                                                  powerCapability_t  *pPowerCapability);

static TI_UINT8 regulatoryDomain_getMaxPowerAllowed(regulatoryDomain_t	*pRegulatoryDomain,
												 TI_UINT8				uChannel,
												 ERadioBand		eBand,
												 TI_BOOL				bServingChannel);

/********************************************************************************/
/*						Interface functions Implementation.						*/
/********************************************************************************/


/************************************************************************
 *                        regulatoryDomain_create									*
 ************************************************************************
DESCRIPTION: regulatoryDomain module creation function, called by the config mgr in creation phase 
				performs the following:
				-	Allocate the regulatoryDomain handle
				                                                                                                   
INPUT:      hOs -			Handle to OS		


OUTPUT:		

RETURN:     Handle to the regulatoryDomain module on success, NULL otherwise

************************************************************************/
TI_HANDLE regulatoryDomain_create(TI_HANDLE hOs)
{
	regulatoryDomain_t			*pRegulatoryDomain = NULL;
	
	/* allocating the regulatoryDomain object */
	pRegulatoryDomain = os_memoryAlloc(hOs,sizeof(regulatoryDomain_t));

	if (pRegulatoryDomain == NULL)
		return NULL;

	return(pRegulatoryDomain);
}


/************************************************************************
 *                        regulatoryDomain_init							*
 ************************************************************************
DESCRIPTION: Module init function, Called by the DrvMain in init phase
				performs the following:
				-	Reset & initializes local variables
				-	Init the handles to be used by the module
                                                                                                   
INPUT:      pStadHandles - List of handles to be used by the module

OUTPUT:		

RETURN:     void
************************************************************************/
void regulatoryDomain_init (TStadHandlesList *pStadHandles)
{
	regulatoryDomain_t *pRegulatoryDomain = (regulatoryDomain_t *)(pStadHandles->hRegulatoryDomain);

	/* init variables */
	pRegulatoryDomain->country_2_4_WasFound		= TI_FALSE;
	pRegulatoryDomain->country_5_WasFound		= TI_FALSE;
	pRegulatoryDomain->uExternTxPowerPreferred	= MAX_TX_POWER;	/* i.e. no restriction */
	pRegulatoryDomain->uPowerConstraint			= MIN_TX_POWER;	/* i.e. no restriction */
	 
	/* Init handlers */
	pRegulatoryDomain->hSiteMgr       = pStadHandles->hSiteMgr;
	pRegulatoryDomain->hTWD	          = pStadHandles->hTWD;
	pRegulatoryDomain->hReport	      = pStadHandles->hReport;
	pRegulatoryDomain->hOs	          = pStadHandles->hOs;
    pRegulatoryDomain->hSwitchChannel = pStadHandles->hSwitchChannel;
}


/************************************************************************
 *                        regulatoryDomain_SetDefaults						*
 ************************************************************************
DESCRIPTION: regulatoryDomain module configuration function, called by the config mgr in configuration phase
				performs the following:
				-	Reset & initializes local variables
				-	Init the handles to be used by the module
                                                                                                   
INPUT:      hRegulatoryDomain	-	regulatoryDomain handle
			List of handles to be used by the module
			pRegulatoryDomainInitParams	-	Init table of the module.		


OUTPUT:		

RETURN:     TI_OK on success, TI_NOK otherwise

************************************************************************/
TI_STATUS regulatoryDomain_SetDefaults (TI_HANDLE 	hRegulatoryDomain,
                                        regulatoryDomainInitParams_t *pRegulatoryDomainInitParams)
{
	regulatoryDomain_t *pRegulatoryDomain = (regulatoryDomain_t *)hRegulatoryDomain;

	/* User max Tx power for all channels */
	pRegulatoryDomain->uUserMaxTxPower	  = pRegulatoryDomainInitParams->desiredTxPower; 
	/* Temporary Tx Power control to be used */
    pRegulatoryDomain->uTemporaryTxPower  = pRegulatoryDomainInitParams->uTemporaryTxPower;
    pRegulatoryDomain->uDesiredTemporaryTxPower = pRegulatoryDomainInitParams->uTemporaryTxPower;

    /* 
	 * Indicate the time in which the STA didn't receive any country code and was not connected, and therefore
     * will delete its current country code 
	 */
    pRegulatoryDomain->uTimeOutToResetCountryMs = pRegulatoryDomainInitParams->uTimeOutToResetCountryMs;
	pRegulatoryDomain->uLastCountryReceivedTS = 0;

	pRegulatoryDomain->regulatoryDomainEnabled = pRegulatoryDomainInitParams->multiRegulatoryDomainEnabled;
	pRegulatoryDomain->spectrumManagementEnabled = pRegulatoryDomainInitParams->spectrumManagementEnabled;
	if (pRegulatoryDomain->spectrumManagementEnabled == TI_TRUE)
	{
		pRegulatoryDomain->regulatoryDomainEnabled = TI_TRUE;
	}
		
	/* Getting the desired Control Table contents for 2.4 Ghz*/
	os_memoryCopy(pRegulatoryDomain->hOs,
				  (void *)pRegulatoryDomain->scanControlTable.ScanControlTable24.tableString,
				  (void *)pRegulatoryDomainInitParams->desiredScanControlTable.ScanControlTable24.tableString,
					NUM_OF_CHANNELS_24 * sizeof(TI_INT8));

	/* Getting the desired Control Table contents for 5 Ghz*/
	os_memoryCopy(pRegulatoryDomain->hOs,
				  (void *)pRegulatoryDomain->scanControlTable.ScanControlTable5.tableString,
				  (void *)pRegulatoryDomainInitParams->desiredScanControlTable.ScanControlTable5.tableString,
					A_5G_BAND_NUM_CHANNELS * sizeof(TI_INT8));

	setSupportedChannelsAccording2ScanControlTable(pRegulatoryDomain);

    pRegulatoryDomain->minDFS_channelNum = A_5G_BAND_MIN_MIDDLE_BAND_DFS_CHANNEL;
    pRegulatoryDomain->maxDFS_channelNum = A_5G_BAND_MAX_UPPER_BAND_DFS_CHANNEL;

TRACE0(pRegulatoryDomain->hReport, REPORT_SEVERITY_INIT, ".....Regulatory domain configured successfully\n");

	return TI_OK;
}

TI_STATUS regulatoryDomain_setParam(TI_HANDLE hRegulatoryDomain,
									paramInfo_t	*pParam)
{
	regulatoryDomain_t *pRegulatoryDomain = (regulatoryDomain_t *)hRegulatoryDomain;
    
			
	switch(pParam->paramType)
	{
    case REGULATORY_DOMAIN_COUNTRY_PARAM:
        {
            TI_BOOL        bBand_2_4;

            /* Sanity check */
            if (NULL == pParam->content.pCountry)
            {   
                TRACE0(pRegulatoryDomain->hReport, REPORT_SEVERITY_ERROR, "regulatoryDomain_setParam, REGULATORY_DOMAIN_COUNTRY_PARAM is set with NULL pointer");

                return TI_NOK;
            }
            else /* Update country code and supported channels */
            {         
                bBand_2_4 = siteMgr_isCurrentBand24(pRegulatoryDomain->hSiteMgr);

			    /* Setting the CountryIE for every Band */
			    setSupportedChannelsAccording2CountryIe(pRegulatoryDomain, pParam->content.pCountry, bBand_2_4);
            }
        }
		break;

	case REGULATORY_DOMAIN_SET_POWER_CONSTRAINT_PARAM:

        /* Update only if 11h enabled */
        if (pRegulatoryDomain->spectrumManagementEnabled)
		{	
            /* Convert to RegDomain units */
            TI_UINT8 uNewPowerConstraint = DBM2DBMDIV10(pParam->content.powerConstraint);

TRACE2(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "SET_POWER_CONSTRAINT Old= %d New = %d (Only if bigger...)\n", 							  pRegulatoryDomain->uPowerConstraint, uNewPowerConstraint);

			/* Update powerConstraint */
			if ( pRegulatoryDomain->uPowerConstraint != uNewPowerConstraint )
			{
				pRegulatoryDomain->uPowerConstraint = uNewPowerConstraint;
				/* Set new Tx power to TWD - only if needed ! */
				regulatoryDomain_updateCurrTxPower(pRegulatoryDomain);
			}
        }
		break;	
		
	case REGULATORY_DOMAIN_EXTERN_TX_POWER_PREFERRED:
		/* ExternTxPowerPreferred is the TX Power Control (TPC) */
		{
			/* Convert to RegDomain units */
			TI_UINT8 uNewTPC = DBM2DBMDIV10(pParam->content.ExternTxPowerPreferred);

TRACE2(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "REGULATORY_DOMAIN_EXTERN_TX_POWER_PREFERRED Old= %d New = %d\n", 				pRegulatoryDomain->uExternTxPowerPreferred, uNewTPC);

			if ( uNewTPC != pRegulatoryDomain->uExternTxPowerPreferred )
			{
				pRegulatoryDomain->uExternTxPowerPreferred = uNewTPC;
				/* Set new Tx power to TWD - only if needed ! */
				regulatoryDomain_updateCurrTxPower(pRegulatoryDomain);
			}
		}
		break;	
	
	case REGULATORY_DOMAIN_SET_CHANNEL_VALIDITY:
		/* Set channel as Valid or Invalid for Active SCAN only.
			Mainly used by DFS when Switch Channel is active */
		regulatoryDomain_setChannelValidity(pRegulatoryDomain, pParam->content.channelValidity.channelNum, 
															   pParam->content.channelValidity.channelValidity);
		break;
	
	case REGULATORY_DOMAIN_CURRENT_TX_POWER_IN_DBM_PARAM:
		/* This case is called when the desired Tx Power Level in Dbm is changed by the user */
        if(pRegulatoryDomain->uUserMaxTxPower != pParam->content.desiredTxPower)
        {
            pRegulatoryDomain->uUserMaxTxPower = pParam->content.desiredTxPower;			
			/* Set new Tx power to TWD - only if needed ! */
			regulatoryDomain_updateCurrTxPower(pRegulatoryDomain);
        }

		break;

	case REGULATORY_DOMAIN_TX_POWER_AFTER_SELECTION_PARAM:
		/* Called after joining BSS, set Tx power to TWD */

        TRACE0(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "regulatoryDomain_setParam, REGULATORY_DOMAIN_TX_POWER_AFTER_SELECTION_PARAM \n");

	   /* setting the Tx Power according to the selected channel */
        regulatoryDomain_updateCurrTxPower(pRegulatoryDomain);
        
		break;

    case REGULATORY_DOMAIN_DISCONNECT_PARAM:
        TRACE0(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "regulatoryDomain_setParam, REGULATORY_DOMAIN_DISCONNECT_PARAM\n");

        pRegulatoryDomain->uExternTxPowerPreferred = MAX_TX_POWER;	/* i.e. no restriction */
        pRegulatoryDomain->uPowerConstraint		   = MIN_TX_POWER;	/* i.e. no restriction */

        /* Update the last time a country code was used. 
        After uTimeOutToResetCountryMs the country code will be deleted     */
        if (pRegulatoryDomain->country_2_4_WasFound || pRegulatoryDomain->country_5_WasFound)
        {
            pRegulatoryDomain->uLastCountryReceivedTS = os_timeStampMs(pRegulatoryDomain->hOs);
        }
        break;

	case REGULATORY_DOMAIN_UPDATE_CHANNEL_VALIDITY:
		regulatoryDomain_updateChannelsTs(pRegulatoryDomain, pParam->content.channel);
		break;

    case REGULATORY_DOMAIN_TEMPORARY_TX_ATTENUATION_PARAM:
		/* Temporary Tx Power control */
TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "regulatoryDomain_setParam: temporary fix = %d, \n", pParam->content.bActivateTempPowerFix);

        pRegulatoryDomain->bTemporaryTxPowerEnable = pParam->content.bActivateTempPowerFix;

			regulatoryDomain_updateCurrTxPower(pRegulatoryDomain);

        break;

    case REGULATORY_DOMAIN_ENABLE_DISABLE_802_11D:
        TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "regulatoryDomain_setParam, REGULATORY_DOMAIN_ENABLE_DISABLE_802_11D = %d, \n", pParam->content.enableDisable_802_11d);

        if ((pRegulatoryDomain->regulatoryDomainEnabled != pParam->content.enableDisable_802_11d) &&
            !pParam->content.enableDisable_802_11d && pRegulatoryDomain->spectrumManagementEnabled)
        {   /* Disable of 802_11d, is not allowed when 802_11h is enabled */
            TRACE0(pRegulatoryDomain->hReport, REPORT_SEVERITY_ERROR, "regulatoryDomain_setParam, Disable of 802_11d, is not allowed when 802_11h is enabled  \n");
            return TI_NOK;
            
        }
        pRegulatoryDomain->regulatoryDomainEnabled = pParam->content.enableDisable_802_11d;

		/* Mark that no country was found - applies for both enabling and disabling of 11d */
		pRegulatoryDomain->country_2_4_WasFound = TI_FALSE;
		pRegulatoryDomain->country_5_WasFound = TI_FALSE;

        if (!pRegulatoryDomain->regulatoryDomainEnabled)
        {   /* Set regulatory Domain according to scan control table */
            setSupportedChannelsAccording2ScanControlTable(pRegulatoryDomain);
        }

		break;

    case REGULATORY_DOMAIN_ENABLE_DISABLE_802_11H:
        TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "regulatoryDomain_setParam, REGULATORY_DOMAIN_ENABLE_DISABLE_802_11H = %d, \n", pParam->content.enableDisable_802_11h);

        pRegulatoryDomain->spectrumManagementEnabled = pParam->content.enableDisable_802_11h;
        if (pParam->content.enableDisable_802_11h)
        {   /* If 802_11h is enabled, enable 802_11d as well */
            pRegulatoryDomain->regulatoryDomainEnabled = TI_TRUE;
        }
        switchChannel_enableDisableSpectrumMngmt(pRegulatoryDomain->hSwitchChannel, pRegulatoryDomain->spectrumManagementEnabled);
		break;

	case REGULATORY_DOMAIN_COUNTRY_2_4_PARAM:
        /* NOTE !!! use this feature carefully. */
        TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "regulatoryDomain_setParam, REGULATORY_DOMAIN_COUNTRY_2_4_PARAM Len = %d, \n", pParam->paramLength);

        TRACE_INFO_HEX(pRegulatoryDomain->hReport, (TI_UINT8*)pParam->content.pCountry, sizeof(TCountry));

        return setSupportedChannelsAccording2CountryIe(pRegulatoryDomain, pParam->content.pCountry, TI_TRUE);

	case REGULATORY_DOMAIN_COUNTRY_5_PARAM:
        /* NOTE !!! use this feature carefully */
        return setSupportedChannelsAccording2CountryIe(pRegulatoryDomain, pParam->content.pCountry, TI_FALSE);


    case REGULATORY_DOMAIN_DFS_CHANNELS_RANGE:
        TRACE2(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "regulatoryDomain_setParam, DFS_CHANNELS_RANGE, min = %d, max = %d, \n", pParam->content.DFS_ChannelRange.minDFS_channelNum, pParam->content.DFS_ChannelRange.maxDFS_channelNum);

        if ((pParam->content.DFS_ChannelRange.minDFS_channelNum<A_5G_BAND_MIN_CHANNEL) ||
            (pParam->content.DFS_ChannelRange.maxDFS_channelNum>A_5G_BAND_MAX_CHANNEL) ||
            pParam->content.DFS_ChannelRange.minDFS_channelNum > pParam->content.DFS_ChannelRange.maxDFS_channelNum)
        {
            TRACE2(pRegulatoryDomain->hReport, REPORT_SEVERITY_ERROR, "regulatoryDomain_setParam, Bad DFS_CHANNELS_RANGE, min = %d, max = %d, \n", pParam->content.DFS_ChannelRange.minDFS_channelNum, pParam->content.DFS_ChannelRange.maxDFS_channelNum);
            return TI_NOK;
        }
        pRegulatoryDomain->minDFS_channelNum = (TI_UINT8)pParam->content.DFS_ChannelRange.minDFS_channelNum;
        pRegulatoryDomain->maxDFS_channelNum = (TI_UINT8)pParam->content.DFS_ChannelRange.maxDFS_channelNum;

        break;

	default:
TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_ERROR, "Set param, Params is not supported, %d\n\n", pParam->paramType);
		return PARAM_NOT_SUPPORTED;
	}

	return TI_OK;
}

TI_STATUS regulatoryDomain_getParam(TI_HANDLE hRegulatoryDomain,
									paramInfo_t	*pParam)
{
	regulatoryDomain_t	*pRegulatoryDomain = (regulatoryDomain_t *)hRegulatoryDomain;

    /* Check if country code is still valid */
    regulatoryDomain_checkCountryCodeExpiry(pRegulatoryDomain);

	switch(pParam->paramType)
	{

	case REGULATORY_DOMAIN_TX_POWER_LEVEL_TABLE_PARAM:
        {
            TFwInfo *pFwInfo = TWD_GetFWInfo (pRegulatoryDomain->hTWD);
            os_memoryCopy(pRegulatoryDomain->hOs, 
                          (void *)&pParam->content.powerLevelTable,
                          (void *)pFwInfo->txPowerTable,
                          sizeof(pFwInfo->txPowerTable));
        }
		break;

	case REGULATORY_DOMAIN_MANAGEMENT_CAPABILITY_ENABLED_PARAM:
		pParam->content.spectrumManagementEnabled = pRegulatoryDomain->spectrumManagementEnabled;
		break;
		
	case REGULATORY_DOMAIN_ENABLED_PARAM:
		pParam->content.regulatoryDomainEnabled = pRegulatoryDomain->regulatoryDomainEnabled;
		break;

	case REGULATORY_DOMAIN_GET_SCAN_CAPABILITIES:
		{
			channelCapabilityReq_t	channelCapabilityReq;

			channelCapabilityReq.band = pParam->content.channelCapabilityReq.band;
			channelCapabilityReq.channelNum = pParam->content.channelCapabilityReq.channelNum;
			channelCapabilityReq.scanOption = pParam->content.channelCapabilityReq.scanOption;

            regulatoryDomain_getChannelCapability(pRegulatoryDomain, channelCapabilityReq, &pParam->content.channelCapabilityRet);
		}
		break;

	case REGULATORY_DOMAIN_POWER_CAPABILITY_PARAM:
		/* power capability is only applicable when spectrum management is active (802.11h) */ 
		if(pRegulatoryDomain->spectrumManagementEnabled)
		{
            regulatoryDomain_getPowerTableMinMax (pRegulatoryDomain, &pParam->content.powerCapability);
		}
		else
		{
			return TI_NOK;
		}
		break;

	case REGULATORY_DOMAIN_IS_CHANNEL_SUPPORTED:
		/* checking if the channel is supported */
		pParam->content.bIsChannelSupprted  = 
			regulatoryDomain_isChannelSupprted(pRegulatoryDomain, pParam->content.channel);
			
		break;

	case REGULATORY_DOMAIN_ALL_SUPPORTED_CHANNELS:
		{
			ERadioBand	band = pParam->content.siteMgrRadioBand;
			regulatoryDomain_buildDefaultListOfChannelsPerBand(pRegulatoryDomain, band, &pParam->content.supportedChannels.sizeOfList);
		    pParam->content.supportedChannels.listOfChannels = pRegulatoryDomain->pDefaultChannels;
		}
		break;

	case REGULATORY_DOMAIN_CURRENT_TX_POWER_IN_DBM_PARAM:

            {
			TTwdParamInfo		tparam;
			/* Get last configured Tx power from TWD */
			tparam.paramType = TWD_TX_POWER_PARAM_ID;
			TWD_GetParam(pRegulatoryDomain->hTWD, &tparam);

			pParam->content.desiredTxPower = tparam.content.halCtrlTxPowerDbm;

TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "regulatoryDomain_getParam, CURRENT_TX_POWER_IN_DBM  = %d\n", 							   pParam->content.desiredTxPower);
            }

        break;

    case REGULATORY_DOMAIN_COUNTRY_PARAM:
        {   
            /* This case is used as an inner function of the driver to retrieve the full IE of the country */
            TI_BOOL bBand_2_4 = siteMgr_isCurrentBand24(pRegulatoryDomain->hSiteMgr);

            if (bBand_2_4)
            {
                if (pRegulatoryDomain->country_2_4_WasFound)
                {
                    pParam->content.pCountry = &pRegulatoryDomain->country24;
                }
                else    /* Do not use the Inforamtion */
                {
                    pParam->content.pCountry = NULL;
                }
            }   /* band 5.0 */
            else
            { 
                if (pRegulatoryDomain->country_5_WasFound)
                {
                   pParam->content.pCountry = &pRegulatoryDomain->country5;
                }
                else    /* Do not use the Inforamtion */
                {
                    pParam->content.pCountry = NULL;
                }
            }
        }
        break;
        
	case REGULATORY_DOMAIN_COUNTRY_2_4_PARAM:
		/* Getting only country string */

        if (pRegulatoryDomain->country_2_4_WasFound)
        {
            os_memoryCopy(pRegulatoryDomain->hOs, (void*)pParam->content.pCountryString, (void*)pRegulatoryDomain->country24.countryIE.CountryString, DOT11_COUNTRY_STRING_LEN);
        }
        else
        {
            pParam->content.pCountryString[0] = '\0';
        }
 		break;

	case REGULATORY_DOMAIN_COUNTRY_5_PARAM:
		/* Getting only country string */

        if (pRegulatoryDomain->country_5_WasFound)
        {
            os_memoryCopy(pRegulatoryDomain->hOs, (void*)pParam->content.pCountryString, (void*)pRegulatoryDomain->country5.countryIE.CountryString, DOT11_COUNTRY_STRING_LEN);
        }
        else
        {
            pParam->content.pCountryString[0] = '\0';
        }
		break;

    case REGULATORY_DOMAIN_DFS_CHANNELS_RANGE:
        TRACE2(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "regulatoryDomain_getParam, DFS_CHANNELS_RANGE, min = %d, max = %d, \n", pRegulatoryDomain->minDFS_channelNum, pRegulatoryDomain->maxDFS_channelNum);
        pParam->content.DFS_ChannelRange.minDFS_channelNum = pRegulatoryDomain->minDFS_channelNum;
        pParam->content.DFS_ChannelRange.maxDFS_channelNum = pRegulatoryDomain->maxDFS_channelNum;

        break;

	case REGULATORY_DOMAIN_IS_COUNTRY_FOUND:

		pParam->content.bIsCountryFound = 
			 regulatoryDomain_isCountryFound(pRegulatoryDomain, pParam->content.eRadioBand);
		
		break;

    case REGULATORY_DOMAIN_IS_DFS_CHANNEL:

        if ((pRegulatoryDomain->spectrumManagementEnabled) && /* 802.11h is enabled */
            (RADIO_BAND_5_0_GHZ == pParam->content.tDfsChannel.eBand) && /* band is 5 GHz */
            (pRegulatoryDomain->minDFS_channelNum <= pParam->content.tDfsChannel.uChannel) && /* channel is within DFS range */
            (pRegulatoryDomain->maxDFS_channelNum >= pParam->content.tDfsChannel.uChannel))
        {
            pParam->content.tDfsChannel.bDfsChannel = TI_TRUE;
        }
        else
        {
            pParam->content.tDfsChannel.bDfsChannel = TI_FALSE;
        }
        break;

    case REGULATORY_DOMAIN_TIME_TO_COUNTRY_EXPIRY:
        /* if a country was found for either band */
        if ((pRegulatoryDomain->country_2_4_WasFound) || (pRegulatoryDomain->country_5_WasFound))
        {
            paramInfo_t *tParam;
            TI_STATUS   connStatus;
            TI_UINT32   uCurrentTS = os_timeStampMs (pRegulatoryDomain->hOs);

            tParam = (paramInfo_t *)os_memoryAlloc(pRegulatoryDomain->hOs, sizeof(paramInfo_t));
            if (!tParam)
                return TI_NOK;

            /* Get connection status */
            tParam->paramType = SITE_MGR_CURRENT_SSID_PARAM;
            connStatus = siteMgr_getParam (pRegulatoryDomain->hSiteMgr, tParam);
            os_memoryFree(pRegulatoryDomain->hOs, tParam, sizeof(paramInfo_t));
            /* if we are connected, return 0 */
            if (connStatus != NO_SITE_SELECTED_YET)
            {
                pParam->content.uTimeToCountryExpiryMs = 0;
            }
            else
            {
                /* 
                 * if country already expired (shouldn't happen as we are checking it at the top of
                 * get_param, but just in case...
                 */
                if ((uCurrentTS - pRegulatoryDomain->uLastCountryReceivedTS) > pRegulatoryDomain->uTimeOutToResetCountryMs)
                {
                    pParam->content.uTimeToCountryExpiryMs = 0;
                }
                else
                {
                    pParam->content.uTimeToCountryExpiryMs = 
                        pRegulatoryDomain->uTimeOutToResetCountryMs - (uCurrentTS - pRegulatoryDomain->uLastCountryReceivedTS);
                }
            }
        }
        else
        {
            pParam->content.uTimeToCountryExpiryMs = 0;
        }
        break;

	default:
		TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_WARNING, "Get param, Params is not supported, %d\n\n", pParam->paramType);
		return PARAM_NOT_SUPPORTED;
	}

	return TI_OK;
}

/************************************************************************
 *                        regulatoryDomain_destroy						*
 ************************************************************************
DESCRIPTION: regulatoryDomain module destroy function, called by the config mgr in the destroy phase 
				performs the following:
				-	Free all memory allocated by the module
                                                                                                   
INPUT:      hRegulatoryDomain	-	regulatoryDomain handle.		


OUTPUT:		

RETURN:     TI_OK on success, TI_NOK otherwise

************************************************************************/
TI_STATUS regulatoryDomain_destroy(TI_HANDLE hRegulatoryDomain)
{
	regulatoryDomain_t	*pRegulatoryDomain = (regulatoryDomain_t *)hRegulatoryDomain;

	if (pRegulatoryDomain == NULL)
		return TI_OK;

    os_memoryFree(pRegulatoryDomain->hOs, pRegulatoryDomain, sizeof(regulatoryDomain_t));

	return TI_OK;
}

/************************************************************************
 *                        regulatoryDomain_isCountryFound						*
 ************************************************************************
DESCRIPTION: This function returns the validity of Country according to band
                                                                                                   
INPUT:      hRegulatoryDomain	-	regulatoryDomain handle.   
            radioBand           - the desired band 	


OUTPUT:		

RETURN:     TI_TRUE - if country IE was found according to the band.
            TI_FALSE - otherwise.

************************************************************************/
TI_BOOL regulatoryDomain_isCountryFound(regulatoryDomain_t  *pRegulatoryDomain, ERadioBand radioBand)
{

    if(radioBand == RADIO_BAND_2_4_GHZ)
    {
            return pRegulatoryDomain->country_2_4_WasFound;
    }
    else
    {
        return pRegulatoryDomain->country_5_WasFound;
    }

}

/***********************************************************************
 *                       setSupportedChannelsAccording2CountryIe									
 ***********************************************************************
DESCRIPTION:	Called when beacon/Probe Response with Country IE
				is found.
				The function sets the local countryIE per band with the CountryIE
				 that was detected in the last passive scan.
				 It is assumed that only one Country IE per band is allowed.
				 If Country is changed when the TNET is loaded, it should
				 be re-loaded in order to re-config the new Country domain.
                                                                                                   
INPUT:      hRegulatoryDomain	-	RegulatoryDomain handle.
			pCountry	-	pointer to the detected country IE.

OUTPUT:		

RETURN:     TI_OK - New country code was set (or the same one was already configured)
            TI_NOK - The new country code could not be set

************************************************************************/
static TI_STATUS setSupportedChannelsAccording2CountryIe(regulatoryDomain_t *pRegulatoryDomain, TCountry* pCountry, TI_BOOL band_2_4)
{
	channelCapability_t *pSupportedChannels;
	TI_UINT8				channelIndex;
	TI_UINT8				tripletChannelIndex, tripletChannelCnt;
	TI_UINT8				channelStep, numberOfChannels, minChannelNumber, maxChannelNumber;

	
	if (!pRegulatoryDomain->regulatoryDomainEnabled)
	{  /* Ignore the Country IE if 802.11d is disabled */
		return TI_NOK;
	}

    /* Check if the country code should be reset */
    regulatoryDomain_checkCountryCodeExpiry(pRegulatoryDomain);

	if( band_2_4 == TI_TRUE )
	{
		if (pRegulatoryDomain->country_2_4_WasFound)
		{	/* Do not update new Country IE */
			if (os_memoryCompare(pRegulatoryDomain->hOs, (void *)&pCountry->countryIE, (void *)&pRegulatoryDomain->country24.countryIE, sizeof(dot11_countryIE_t)))
			{
TRACE0(pRegulatoryDomain->hReport, REPORT_SEVERITY_WARNING, "setSupportedChannelsAccording2CountryIe different Country, cur=, new=\n");
            	return TI_NOK;
            }
            else    /* Same IE - just mark the TS and return TI_OK */
            {
                /* Mark the time of the received country IE */                
                pRegulatoryDomain->uLastCountryReceivedTS = os_timeStampMs(pRegulatoryDomain->hOs);
                return TI_OK;
            }
		}
		pRegulatoryDomain->country_2_4_WasFound = TI_TRUE;
		pSupportedChannels = pRegulatoryDomain->supportedChannels_band_2_4;
		channelStep = BG_24G_BAND_CHANNEL_HOPS;
		maxChannelNumber = NUM_OF_CHANNELS_24;
		minChannelNumber = BG_24G_BAND_MIN_CHANNEL;
		numberOfChannels = NUM_OF_CHANNELS_24;
		/* save the country IE */
		os_memoryCopy(pRegulatoryDomain->hOs, (void*)&pRegulatoryDomain->country24, (void *)pCountry, sizeof(TCountry));

        TRACE3(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "Country 2.4 =%c%c%c\n",pRegulatoryDomain->country24.countryIE.CountryString[0], pRegulatoryDomain->country24.countryIE.CountryString[1], pRegulatoryDomain->country24.countryIE.CountryString[2]);

	}
	else    /* band 5.0 */
	{
		if (pRegulatoryDomain->country_5_WasFound)
		{	/* Do not update new Country IE if the IE is the same*/
			if (os_memoryCompare(pRegulatoryDomain->hOs, (void *)&pCountry->countryIE, (void *)&pRegulatoryDomain->country5.countryIE, sizeof(dot11_countryIE_t)))
			{
TRACE0(pRegulatoryDomain->hReport, REPORT_SEVERITY_WARNING, "setSupportedChannelsAccording2CountryIe different Country, cur=, new=\n");
            	return TI_NOK;
            }
            else    /* Same IE - just mark the TS and return TI_OK */
            {
                /* Mark the time of the received country IE */                
                pRegulatoryDomain->uLastCountryReceivedTS = os_timeStampMs(pRegulatoryDomain->hOs);
                return TI_OK;
            }
		}
		pRegulatoryDomain->country_5_WasFound = TI_TRUE;
		pSupportedChannels = pRegulatoryDomain->supportedChannels_band_5;
		channelStep = A_5G_BAND_CHANNEL_HOPS;
		maxChannelNumber = A_5G_BAND_MAX_CHANNEL;
		minChannelNumber = A_5G_BAND_MIN_CHANNEL;
		numberOfChannels = A_5G_BAND_NUM_CHANNELS;
		/* save the country IE */
		os_memoryCopy(pRegulatoryDomain->hOs, (void*)&pRegulatoryDomain->country5, (void*)pCountry, sizeof(TCountry));

        TRACE3(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "Country 5 =%c%c%c\n",pRegulatoryDomain->country5.countryIE.CountryString[0], pRegulatoryDomain->country5.countryIE.CountryString[1], pRegulatoryDomain->country5.countryIE.CountryString[2]);
	}

    /*
     * New Country IE was saved. Now - update the last received TS and ScanControlTable
     */

    /* Mark the time of the received country IE */                
    pRegulatoryDomain->uLastCountryReceivedTS = os_timeStampMs(pRegulatoryDomain->hOs);

	/* First clear the validity of all channels 
		Overwrite the ScanControlTable */
	for (channelIndex=0; channelIndex<numberOfChannels; channelIndex++)
	{
		pSupportedChannels[channelIndex].channelValidityActive = TI_FALSE;
		pSupportedChannels[channelIndex].channelValidityPassive = TI_FALSE;
		pSupportedChannels[channelIndex].bChanneInCountryIe = TI_FALSE;
		pSupportedChannels[channelIndex].uMaxTxPowerDomain = MIN_TX_POWER; 	
	}
    
	tripletChannelCnt = (pCountry->len - DOT11_COUNTRY_STRING_LEN) / 3;
	/* set validity of the channels according to the band (2.4 or 5) */
	for( tripletChannelIndex = 0; tripletChannelIndex < tripletChannelCnt ; tripletChannelIndex++)
	{
		TI_UINT8	firstChannelNumInTriplet;
		
		firstChannelNumInTriplet = pCountry->countryIE.tripletChannels[tripletChannelIndex].firstChannelNumber;
TRACE2(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "firstChannelNumInTriplet=%d,channelStep=%d\n", firstChannelNumInTriplet, channelStep);
		for (channelIndex=0; channelIndex<pCountry->countryIE.tripletChannels[tripletChannelIndex].numberOfChannels; channelIndex++)
		{
			TI_UINT16	channelNumber;

			channelNumber = firstChannelNumInTriplet+(channelIndex*channelStep);
TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "setSupportedChannelsAccording2CountryIe of channel=%d\n", channelNumber);
			
			if (channelNumber <= maxChannelNumber)
			{
				TI_UINT8 	channelIndex4Band;

				channelIndex4Band = (channelNumber-minChannelNumber);
				pSupportedChannels[channelIndex4Band].bChanneInCountryIe = TI_TRUE;
				pSupportedChannels[channelIndex4Band].channelValidityPassive = TI_TRUE;
				pSupportedChannels[channelIndex4Band].channelValidityActive = TI_TRUE;

				/* set the TX power in DBM/10 units */
			    pSupportedChannels[channelIndex4Band].uMaxTxPowerDomain = 
					DBM2DBMDIV10(pCountry->countryIE.tripletChannels[tripletChannelIndex].maxTxPowerLevel);

TRACE2(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "channel = %d uMaxTxPowerDomain=%d\n", 										channelNumber, pSupportedChannels[channelIndex4Band].uMaxTxPowerDomain);
			}
		}
    }

	return TI_OK;
}


/***********************************************************************
 *                        regulatoryDomain_isChannelSupprted									
 ***********************************************************************
DESCRIPTION:	The function checks if the input channel is supported.
                                                                                                   
INPUT:      pRegulatoryDomain	-	RegulatoryDomain pointer.
			channel				-	Channel number.
			

OUTPUT:		

RETURN:     TI_OK if channel is supported, TI_NOK otherwise.

************************************************************************/
static TI_BOOL regulatoryDomain_isChannelSupprted(regulatoryDomain_t *pRegulatoryDomain, TI_UINT8 channel)
{
	TI_UINT8				channelIndex;
	channelCapability_t *pSupportedChannels;

	if (pRegulatoryDomain==NULL)
	{
		return TI_FALSE;
	}

	if ((channel<BG_24G_BAND_MIN_CHANNEL) || (channel>A_5G_BAND_MAX_CHANNEL))
	{
		return TI_FALSE;
	}
	if (channel>=A_5G_BAND_MIN_CHANNEL)
	{
		channelIndex = (channel-A_5G_BAND_MIN_CHANNEL);
		pSupportedChannels = pRegulatoryDomain->supportedChannels_band_5;
	}
	else
	{
		channelIndex = (channel-BG_24G_BAND_MIN_CHANNEL);
		if (channelIndex >= NUM_OF_CHANNELS_24)
		{
			TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_ERROR,
				   "regulatoryDomain_isChannelSupprted(): 2.4G invalid channel # %u\n", channel );
			return TI_FALSE;
		}
		pSupportedChannels = pRegulatoryDomain->supportedChannels_band_2_4;
	}
	if (pRegulatoryDomain->spectrumManagementEnabled 
		&& (channel >= pRegulatoryDomain->minDFS_channelNum) 
        && (channel <= pRegulatoryDomain->maxDFS_channelNum)
		&& ((os_timeStampMs(pRegulatoryDomain->hOs)-pSupportedChannels[channelIndex].timestamp) >=CHANNEL_VALIDITY_TS_THRESHOLD ))
	{	/* If 802.11h is enabled, a DFS channel is valid only for 10 sec
			from the last Beacon/ProbeResponse */
        pSupportedChannels[channelIndex].channelValidityActive = TI_FALSE;
        TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "regulatoryDomain_isChannelSupprted(): CHANNEL_VALIDITY_TS_THRESHOLD !! Disable channel no %d, DFS channel\n", channel );

	}

	return (pSupportedChannels[channelIndex].channelValidityActive);

}

/************************************************************************
 *                        regulatoryDomain_setChannelValidity			*
 ************************************************************************/
/*
*
*
* \b Description: 
*
* This function sets a channel as invalid or valid in the internal Regulatory Domain
 * database. 
*
* \b ARGS:
*
*  I   - pData - pointer to the regDoamin SM context  \n
*  I   - channelNum - the invalid/valid channel number
*  I   - channelValidity - TI_TRUE if channel is valid, TI_FALSE channel is invalid
*
* \b RETURNS:
*
*  None.
*
* 
*************************************************************************/
static void regulatoryDomain_setChannelValidity(regulatoryDomain_t *pRegulatoryDomain, 
												TI_UINT16 channelNum, TI_BOOL channelValidity)
{
	channelCapability_t		*pSupportedChannels;
	TI_UINT8					channelIndex;


	if (pRegulatoryDomain == NULL)
	{
		return;
	}
	if ((channelNum==0 ) || (channelNum>A_5G_BAND_MAX_CHANNEL))
	{
TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_ERROR, "regulatoryDomain_setChannelValidity, invalid channelNum=%d \n", channelNum);
		return;
	}
	
	if (channelNum <= NUM_OF_CHANNELS_24)
	{
		pSupportedChannels = pRegulatoryDomain->supportedChannels_band_2_4;
		channelIndex = (channelNum-BG_24G_BAND_MIN_CHANNEL);
	}
	else 
	{
		pSupportedChannels = pRegulatoryDomain->supportedChannels_band_5;
		channelIndex = (channelNum - A_5G_BAND_MIN_CHANNEL);
	}
	
	if(channelValidity == TI_TRUE)
		if((pSupportedChannels[channelIndex].bChanneInCountryIe == TI_FALSE) && (pRegulatoryDomain->regulatoryDomainEnabled == TI_TRUE))
		{
TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_WARNING, "regulatoryDomain_setChannelValidity: channelNum = %d isn't supported at the Country. wll not set to active!\n", channelNum);
			return;
		}

    TRACE2(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "regulatoryDomain_setChannelValidity: channelNum=%d, validity=%d \n", channelNum, channelValidity);


	pSupportedChannels[channelIndex].channelValidityActive = channelValidity;
}


/************************************************************************
 *      setSupportedChannelsAccording2ScanControlTable 					*
 ************************************************************************/
/**
*
*
* \b Description: 
*
* This function is called in config and sets the supported channels according to
* the scan control table read from registry and reg domain read from the chip.
*
* \b ARGS:
*
*  I   - pRegulatoryDomain - pointer to the regDoamin SM context  \n
*
* \b RETURNS:
*
*  None.
*
* 
*************************************************************************/
static void setSupportedChannelsAccording2ScanControlTable(regulatoryDomain_t  *pRegulatoryDomain)
{
	TI_UINT8 	channelIndex;
	TI_UINT8	channelMask;

	if (pRegulatoryDomain==NULL)
	{
		return;
	}

    TRACE0(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "setSupportedChannelsAccording2ScanControlTable \n");

	for (channelIndex=0; channelIndex<NUM_OF_CHANNELS_24; channelIndex++)
	{
		channelMask = pRegulatoryDomain->scanControlTable.ScanControlTable24.tableString[channelIndex];
		pRegulatoryDomain->supportedChannels_band_2_4[channelIndex].bChanneInCountryIe = TI_FALSE;

		/* Calculate Domain Tx Power - channelMask units are in Dbm. */
		pRegulatoryDomain->supportedChannels_band_2_4[channelIndex].uMaxTxPowerDomain = 
						DBM2DBMDIV10(channelMask & MASK_TX_POWER);
		if (channelMask & (MASK_ACTIVE_ALLOWED | MASK_FREQ_ALLOWED))
		{	/* The channel is allowed for Active & Passive scans */
			if (pRegulatoryDomain->regulatoryDomainEnabled)
			{	/* All channels should be invalid for Active scan */
				pRegulatoryDomain->supportedChannels_band_2_4[channelIndex].channelValidityActive = TI_FALSE;
                TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "channelIndex=%d is invalid for Active \n", channelIndex+1);
			}
			else
			{
				pRegulatoryDomain->supportedChannels_band_2_4[channelIndex].channelValidityActive = TI_TRUE;
                TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "channelIndex=%d is Active valid \n", channelIndex+1);
			}
			
		}
		
		if (channelMask & MASK_FREQ_ALLOWED)
		{	/* The channel is allowed for Passive scan */
			pRegulatoryDomain->supportedChannels_band_2_4[channelIndex].channelValidityPassive = TI_TRUE;
            TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "channelIndex=%d is Passive valid \n", channelIndex+1);
		}
		else
		{	/* The channel is not allowed */
			pRegulatoryDomain->supportedChannels_band_2_4[channelIndex].channelValidityPassive = TI_FALSE;
			pRegulatoryDomain->supportedChannels_band_2_4[channelIndex].channelValidityActive = TI_FALSE;
		}
	}

	for (channelIndex=A_5G_BAND_MIN_CHANNEL; channelIndex<A_5G_BAND_MAX_CHANNEL; channelIndex++)
	{	
		TI_UINT8	channelIndexInBand5;

		channelIndexInBand5 = (channelIndex-A_5G_BAND_MIN_CHANNEL);
		channelMask = pRegulatoryDomain->scanControlTable.ScanControlTable5.tableString[channelIndexInBand5];
        TRACE3(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "channelIndex=%d, channelIndexInBand5=%d channelMask=%d\n", channelIndex, channelIndexInBand5, channelMask);

		/* Calculate Domain Tx Power - channelMask units are in Dbm. */
		pRegulatoryDomain->supportedChannels_band_5[channelIndexInBand5].uMaxTxPowerDomain = 
			DBM2DBMDIV10(channelMask & MASK_TX_POWER);

		pRegulatoryDomain->supportedChannels_band_5[channelIndexInBand5].bChanneInCountryIe = TI_FALSE;
		if (channelMask & (MASK_ACTIVE_ALLOWED | MASK_FREQ_ALLOWED))
		{	 /* The channel is allowed for Active & Passive scans */
			if (pRegulatoryDomain->regulatoryDomainEnabled)
			{	/* All channels should be invalid for Active scan */
				pRegulatoryDomain->supportedChannels_band_5[channelIndexInBand5].channelValidityActive = TI_FALSE;
                TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "channelIndex=%d is invalid for Active \n", channelIndex);
			}
			else
			{
				pRegulatoryDomain->supportedChannels_band_5[channelIndexInBand5].channelValidityActive = TI_TRUE;
                TRACE2(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "channelIndex=%d, channelIndexInBand5=%d, is Active valid \n", channelIndex, channelIndexInBand5);
			}   		
		}
		
		if (channelMask & MASK_FREQ_ALLOWED)
		{	/* The channel is allowed for Passive scan */
			pRegulatoryDomain->supportedChannels_band_5[channelIndexInBand5].channelValidityPassive = TI_TRUE;
            TRACE2(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "channelIndex=%d, channelIndexInBand5=%d, is Passive valid \n", channelIndex, channelIndexInBand5);
		}
		else
		{	/* The channel is not allowed */
			pRegulatoryDomain->supportedChannels_band_5[channelIndexInBand5].channelValidityPassive = TI_FALSE;
			pRegulatoryDomain->supportedChannels_band_5[channelIndexInBand5].channelValidityActive = TI_FALSE;
		}

	}
}


/***********************************************************************
*                        regulatoryDomain_getChannelCapability									
***********************************************************************
DESCRIPTION:	This function returns the channel capability information

INPUT:      pRegulatoryDomain		-	RegulatoryDomain pointer.
			channelCapabilityReq	-	Channels parameters


OUTPUT:		channelCapabilityRet	-   Channel capability information

RETURN:     TI_OK if information was retrieved, TI_NOK otherwise.

************************************************************************/
static TI_STATUS regulatoryDomain_getChannelCapability(regulatoryDomain_t *pRegulatoryDomain, 
													   channelCapabilityReq_t channelCapabilityReq, 
													   channelCapabilityRet_t *channelCapabilityRet)
{
	channelCapability_t		*pSupportedChannels;
	TI_UINT8				channelIndex;
	TI_BOOL					bCountryWasFound, bServingChannel;
	paramInfo_t				*pParam;

	if ((pRegulatoryDomain == NULL) || (channelCapabilityRet == NULL))
	{
		return TI_NOK;
	}

	channelCapabilityRet->channelValidity = TI_FALSE;
	channelCapabilityRet->maxTxPowerDbm = 0;
	if ((channelCapabilityReq.channelNum==0 ) || (channelCapabilityReq.channelNum > A_5G_BAND_MAX_CHANNEL))
	{
        TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_ERROR, "regulatoryDomain_getChannelCapability, invalid channelNum=%d \n", channelCapabilityReq.channelNum);
		return TI_NOK;
	}
	
	if (channelCapabilityReq.band==RADIO_BAND_2_4_GHZ)
	{
		pSupportedChannels = pRegulatoryDomain->supportedChannels_band_2_4;
		channelIndex = (channelCapabilityReq.channelNum-BG_24G_BAND_MIN_CHANNEL);
		if (channelIndex >= NUM_OF_CHANNELS_24)
		{
			TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_ERROR,
				   "regulatoryDomain_getChannelCapability(): 2.4G invalid channel # %u\n", channelCapabilityReq.channelNum );
			return TI_NOK;
		}
		bCountryWasFound = pRegulatoryDomain->country_2_4_WasFound;
	}
	else if (channelCapabilityReq.band==RADIO_BAND_5_0_GHZ)
	{
		pSupportedChannels = pRegulatoryDomain->supportedChannels_band_5;
		channelIndex = (channelCapabilityReq.channelNum - A_5G_BAND_MIN_CHANNEL);
		if (channelIndex >= A_5G_BAND_NUM_CHANNELS)
		{
			TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_ERROR,
				   "regulatoryDomain_getChannelCapability(): 5G invalid channel # %u\n", channelCapabilityReq.channelNum);
			return TI_NOK;
		}
		bCountryWasFound = pRegulatoryDomain->country_5_WasFound;
	}
	else
	{
		TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_ERROR, "regulatoryDomain_getChannelCapability, invalid band=%d \n", channelCapabilityReq.band);
		return TI_NOK;
	}


	/* 
	 * Set channelValidity according to ScanTable and whether 11d is enabled 
	 */
	if (channelCapabilityReq.scanOption == ACTIVE_SCANNING)
	{
		if ( ( pRegulatoryDomain->regulatoryDomainEnabled ) && ( !bCountryWasFound ) )
		{	/* 11d enabled and no country IE was found - set channel to invalid */
			channelCapabilityRet->channelValidity = TI_FALSE;
		}
		else
		{

            pParam = (paramInfo_t *)os_memoryAlloc(pRegulatoryDomain->hOs, sizeof(paramInfo_t));
            if (!pParam)
                return TI_NOK;

            channelCapabilityRet->channelValidity = pSupportedChannels[channelIndex].channelValidityActive;
			/*
			 * Set Maximum Tx power for the channel - only for active scanning
			 */ 

			/* Get current channel and check if we are using the same one */
			pParam->paramType = SITE_MGR_CURRENT_CHANNEL_PARAM;
			siteMgr_getParam(pRegulatoryDomain->hSiteMgr, pParam);

			bServingChannel = ( pParam->content.siteMgrCurrentChannel == channelCapabilityReq.channelNum ?
								TI_TRUE : TI_FALSE );

			channelCapabilityRet->maxTxPowerDbm = regulatoryDomain_getMaxPowerAllowed(pRegulatoryDomain, 
				channelCapabilityReq.channelNum, 
				channelCapabilityReq.band, 
				bServingChannel);
            os_memoryFree(pRegulatoryDomain->hOs, pParam, sizeof(paramInfo_t));
		}
	}
	else	/* Passive scanning */
	{
		if ( ( pRegulatoryDomain->regulatoryDomainEnabled ) && ( !bCountryWasFound ) )
		{	/* 11d enabled and no country IE was found - set channel to valid for passive scan */
			channelCapabilityRet->channelValidity = TI_TRUE;
		}
	else
	{
		channelCapabilityRet->channelValidity = pSupportedChannels[channelIndex].channelValidityPassive;
	}
	}
	
	if (pRegulatoryDomain->spectrumManagementEnabled 
		&& (channelCapabilityReq.scanOption == ACTIVE_SCANNING)
        && (channelCapabilityReq.channelNum >= pRegulatoryDomain->minDFS_channelNum) 
        && (channelCapabilityReq.channelNum <= pRegulatoryDomain->maxDFS_channelNum)
		&& ((os_timeStampMs(pRegulatoryDomain->hOs)-pSupportedChannels[channelIndex].timestamp) >=CHANNEL_VALIDITY_TS_THRESHOLD ))
	{	/* If 802.11h is enabled, a DFS channel is valid only for 10 sec
			from the last Beacon/ProbeResponse */
        pSupportedChannels[channelIndex].channelValidityActive = TI_FALSE;
        channelCapabilityRet->channelValidity = TI_FALSE;
        TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "regulatoryDomain_getChannelCapability(): CHANNEL_VALIDITY_TS_THRESHOLD !!! Disable channel no %d, DFS channel\n", channelCapabilityReq.channelNum  );
    }

    TRACE4(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, " Channel num= %d, scan option=%d validity = %d, TX power = %d \n", 					channelCapabilityReq.channelNum, 					channelCapabilityReq.scanOption,					channelCapabilityRet->channelValidity,					channelCapabilityRet->maxTxPowerDbm);
	return TI_OK;

}


static void regulatoryDomain_updateChannelsTs(regulatoryDomain_t *pRegulatoryDomain, TI_UINT8 channel)
{
	TI_UINT8				channelIndex;
	channelCapability_t *pSupportedChannels;

	if (pRegulatoryDomain==NULL)
	{
		return;
	}

	if ((channel<BG_24G_BAND_MIN_CHANNEL) || (channel>A_5G_BAND_MAX_CHANNEL))
	{
		return;
	}

	if (channel>=A_5G_BAND_MIN_CHANNEL)
	{
		channelIndex = (channel-A_5G_BAND_MIN_CHANNEL);
		pSupportedChannels = pRegulatoryDomain->supportedChannels_band_5;
	}
	else
	{
		channelIndex = (channel-BG_24G_BAND_MIN_CHANNEL);
		if (channelIndex >= NUM_OF_CHANNELS_24)
		{
			TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_ERROR,
				   "regulatoryDomain_updateChannelsTs(): 2.4G invalid channel # %u\n", channel );
			return;
		}
		pSupportedChannels = pRegulatoryDomain->supportedChannels_band_2_4;
	}
	
	if((pSupportedChannels[channelIndex].bChanneInCountryIe == TI_FALSE) && (pRegulatoryDomain->regulatoryDomainEnabled == TI_TRUE))
  	{
		TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_WARNING, "regulatoryDomain_updateChannelsTs: channelNum = %d isn't supported at the Country. wll not set to active!\n", channel);
  		return;
  	}

	pSupportedChannels[channelIndex].timestamp = os_timeStampMs(pRegulatoryDomain->hOs);
	pSupportedChannels[channelIndex].channelValidityActive = TI_TRUE;

}

/***********************************************************************
 *              regulatoryDomain_updateCurrTxPower								
 ***********************************************************************
DESCRIPTION: Called when new Tx power should be calculated and configured.
			 Check if we are already joined to BSS/IBSS, calculate 
			 new Tx power and configure it to TWD.
				
INPUT:		pRegulatoryDomain	- regulatoryDomain pointer.
			
RETURN:     TI_OK - New value was configured to TWD, TI_NOK - Can't configure value
			TX_POWER_SET_SAME_VALUE - Same value was already configured.

************************************************************************/
static TI_STATUS regulatoryDomain_updateCurrTxPower(regulatoryDomain_t	*pRegulatoryDomain)
{
	paramInfo_t			*pParam;
	TI_STATUS			eStatus;
	TTwdParamInfo		ttparam;
	TI_UINT8    		uCurrChannel, uNewTxPower;

    pParam = (paramInfo_t *)os_memoryAlloc(pRegulatoryDomain->hOs, sizeof(paramInfo_t));
    if (!pParam)
        return TI_NOK;

	/* Get the current channel, and update TWD with the changed */
	pParam->paramType = SITE_MGR_CURRENT_CHANNEL_PARAM;
	eStatus = siteMgr_getParam(pRegulatoryDomain->hSiteMgr, pParam);

	if ( eStatus != TI_OK )
	{
		/* We are not joined yet - no meaning for new Tx power */
        TRACE0(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "regulatoryDomain_updateCurrTxPower, No site selected yet\n");
        os_memoryFree(pRegulatoryDomain->hOs, pParam, sizeof(paramInfo_t));
		return TI_NOK;
	}
	/* Save current channel */
	uCurrChannel = pParam->content.siteMgrCurrentChannel;

	/* Get the current channel, and update TWD with the changed */
	pParam->paramType = 	SITE_MGR_RADIO_BAND_PARAM;
	siteMgr_getParam(pRegulatoryDomain->hSiteMgr, pParam);

	/* Calculate maximum Tx power for the serving channel */
	uNewTxPower = regulatoryDomain_getMaxPowerAllowed(pRegulatoryDomain, uCurrChannel, 
													  pParam->content.siteMgrRadioBand, TI_TRUE);
    os_memoryFree(pRegulatoryDomain->hOs, pParam, sizeof(paramInfo_t));	
	/* Verify that the Temporary TX Power Control doesn't violate the TX Power Constraint */
	pRegulatoryDomain->uTemporaryTxPower = TI_MIN(pRegulatoryDomain->uDesiredTemporaryTxPower, uNewTxPower);

    TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "regulatoryDomain_updateCurrTxPower, Write to TWD = %d \n", uNewTxPower);

    ttparam.paramType = TWD_TX_POWER_PARAM_ID;

    /* set TWD according to Temporary Tx Power Enable flag */
    if (TI_TRUE == pRegulatoryDomain->bTemporaryTxPowerEnable)
    {
        ttparam.content.halCtrlTxPowerDbm = pRegulatoryDomain->uTemporaryTxPower;
    }
    else
    {
        ttparam.content.halCtrlTxPowerDbm = uNewTxPower;
    }
    eStatus = TWD_SetParam(pRegulatoryDomain->hTWD, &ttparam);
	return eStatus;
}

/***********************************************************************
 *                        regulatoryDomain_checkCountryCodeExpiry									
 ***********************************************************************
DESCRIPTION: Check & Reset the country code that was detected earlier.
                Reseting country code will be done when the STA was not connected for 
                a certain amount of time, and no country code was received in that period (from the same country).
                This scenario might indicate that the STA has moved to a different country.
                                                                                                   
INPUT:      pRegulatoryDomain	-	Regulatory Domain handle.

OUTPUT:		updating country code if necessary.

RETURN:     

************************************************************************/
void regulatoryDomain_checkCountryCodeExpiry(regulatoryDomain_t *pRegulatoryDomain)
{
    paramInfo_t *pParam;
    TI_STATUS   connStatus;
    TI_UINT32   uCurrentTS = os_timeStampMs(pRegulatoryDomain->hOs);

    if ((pRegulatoryDomain->country_2_4_WasFound) || (pRegulatoryDomain->country_5_WasFound))
    {
        pParam = (paramInfo_t *)os_memoryAlloc(pRegulatoryDomain->hOs, sizeof(paramInfo_t));
        if (!pParam)
            return;
        /* Get connection status */
        pParam->paramType = SITE_MGR_CURRENT_SSID_PARAM;
        connStatus      = siteMgr_getParam(pRegulatoryDomain->hSiteMgr, pParam);

         /* If (uTimeOutToResetCountryMs has elapsed && we are not connected)
                 delete the last country code received */
        if (((uCurrentTS - pRegulatoryDomain->uLastCountryReceivedTS) > pRegulatoryDomain->uTimeOutToResetCountryMs) &&
            (connStatus == NO_SITE_SELECTED_YET))
        {
            TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, ", Reset country code after %d Ms\n",(uCurrentTS - pRegulatoryDomain->uLastCountryReceivedTS));

            /* Reset country codes */
            pRegulatoryDomain->country_2_4_WasFound = TI_FALSE;
            pRegulatoryDomain->country_5_WasFound = TI_FALSE;
            
            /* Restore default values of the scan control table */
            setSupportedChannelsAccording2ScanControlTable(pRegulatoryDomain); 
        }
        os_memoryFree(pRegulatoryDomain->hOs, pParam, sizeof(paramInfo_t));
    }
}

/***********************************************************************
*              regulatoryDomain_getMaxPowerAllowed								
***********************************************************************
DESCRIPTION: Get the maximum tx power allowed for the given channel.
				The final value is constructed by:
				1) User max value
				2) Domain restriction - 11d country code IE
				3) 11h power constraint - only on serving channel
				4) XCC TPC - only on serving channel

RETURN:     Max power in Dbm/10 for the given channel

************************************************************************/
static TI_UINT8 regulatoryDomain_getMaxPowerAllowed(regulatoryDomain_t	*pRegulatoryDomain,
												 TI_UINT8				uChannel,
												 ERadioBand		eBand,
												 TI_BOOL				bServingChannel)
{
	channelCapability_t	*pSupportedChannels;
	TI_UINT8				 uChannelIndex, uTxPower;

	if( eBand == RADIO_BAND_2_4_GHZ)
	{
		pSupportedChannels = pRegulatoryDomain->supportedChannels_band_2_4;
		uChannelIndex = uChannel - BG_24G_BAND_MIN_CHANNEL;
	}
	else
	{
		pSupportedChannels = pRegulatoryDomain->supportedChannels_band_5;
		uChannelIndex = uChannel - A_5G_BAND_MIN_CHANNEL;
	}

	/* We'll start with the "Domain restriction - 11d country code IE" */
	uTxPower = pSupportedChannels[uChannelIndex].uMaxTxPowerDomain;

	if ( bServingChannel)
	{
		if (pRegulatoryDomain->uPowerConstraint < uTxPower)
		{
			/* When 802.11h is disabled, uPowerConstraint is 0 anyway */
			uTxPower -= pRegulatoryDomain->uPowerConstraint;
		}
        
        /* Take XCC limitation too */
        uTxPower = TI_MIN(uTxPower, pRegulatoryDomain->uExternTxPowerPreferred);

	}

	/* Now make sure we are not exceeding the user maximum */
	uTxPower = TI_MIN(uTxPower, pRegulatoryDomain->uUserMaxTxPower);

TRACE3(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, " uChannel = %d bServingChannel = %d uTxPower = %d \n", uChannel, bServingChannel, uTxPower);

	return uTxPower;
}


static void regulatoryDomain_buildDefaultListOfChannelsPerBand(regulatoryDomain_t *pRegulatoryDomain, ERadioBand band, TI_UINT8 *listSize)
{
	TI_UINT8				channelIndex;
	TI_UINT8				numberOfChannels, minChannelNumber;
	channelCapability_t	*pSupportedChannels;
	TI_UINT8				maxSupportedChannels=0;

	if ( (pRegulatoryDomain==NULL) || (listSize==NULL))
	{
		return;
	}

	if( band == RADIO_BAND_2_4_GHZ)
	{
		minChannelNumber = BG_24G_BAND_MIN_CHANNEL;
		numberOfChannels = NUM_OF_CHANNELS_24;
		pSupportedChannels = pRegulatoryDomain->supportedChannels_band_2_4;
	}
	else
	{
		minChannelNumber = A_5G_BAND_MIN_CHANNEL;
		numberOfChannels = A_5G_BAND_NUM_CHANNELS;
		pSupportedChannels = pRegulatoryDomain->supportedChannels_band_5;
	}


	for (channelIndex=0; channelIndex<numberOfChannels; channelIndex++)
	{
		if (pSupportedChannels[channelIndex].channelValidityPassive)
		{
			pRegulatoryDomain->pDefaultChannels[maxSupportedChannels] = channelIndex+minChannelNumber;
TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "Channel num %d is supported \n", pRegulatoryDomain->pDefaultChannels[maxSupportedChannels]);
			maxSupportedChannels++;
		}
	}
 
	*listSize = maxSupportedChannels;
    
}

/***********************************************************************
*              regulatoryDomain_getPowerTableMinMax								
***********************************************************************
DESCRIPTION: Find the Tx-power-level table min & max values.
			 The table is made of 4 power levels and 5 bands/sub-bands. 

RETURN:     void
************************************************************************/
static void regulatoryDomain_getPowerTableMinMax (regulatoryDomain_t *pRegulatoryDomain,
                                                  powerCapability_t  *pPowerCapability)
{
    TFwInfo  *pFwInfo = TWD_GetFWInfo (pRegulatoryDomain->hTWD);
	TI_UINT8	i;

    /* Init the min (max) to the opposite edge so the table values are below (above) this edge */ 
	pPowerCapability->minTxPower = MAX_TX_POWER;
	pPowerCapability->maxTxPower = MIN_TX_POWER;

	/* Find Min and Max values of the table */
	for (i = 0; i < NUMBER_OF_SUB_BANDS_E; i++)
	{
		pPowerCapability->minTxPower = TI_MIN (pPowerCapability->minTxPower, 
                                               pFwInfo->txPowerTable[i][NUM_OF_POWER_LEVEL-1]);
		pPowerCapability->maxTxPower = TI_MAX (pPowerCapability->maxTxPower, 
                                               pFwInfo->txPowerTable[i][0]);
	}
}

/* for debug */
void regDomainPrintValidTables(TI_HANDLE hRegulatoryDomain)
{
	regulatoryDomain_t  *pRegulatoryDomain = (regulatoryDomain_t *)hRegulatoryDomain;
	TI_UINT16 channelIndex;

	for (channelIndex=0; channelIndex<NUM_OF_CHANNELS_24; channelIndex++)
	{
		if (pRegulatoryDomain->supportedChannels_band_2_4[channelIndex].channelValidityPassive)
			WLAN_OS_REPORT(("channel num =%d is valid for passive \n", channelIndex+1));
		if (pRegulatoryDomain->supportedChannels_band_2_4[channelIndex].channelValidityActive)
		{
			WLAN_OS_REPORT(("channel =%d is valid for active TX power=%d\n", 
				channelIndex+1, pRegulatoryDomain->supportedChannels_band_2_4[channelIndex].uMaxTxPowerDomain));
		}
	}

	for (channelIndex=0; channelIndex<A_5G_BAND_NUM_CHANNELS; channelIndex++)
	{
		TI_UINT8	channelNum;
		channelNum = channelIndex+A_5G_BAND_MIN_CHANNEL;
		if (pRegulatoryDomain->supportedChannels_band_5[channelIndex].channelValidityPassive)
			WLAN_OS_REPORT(("channel =%d is valid for passive \n", channelNum));
		if (pRegulatoryDomain->supportedChannels_band_5[channelIndex].channelValidityActive)
		{
			WLAN_OS_REPORT(("channel =%d is valid for active TX power=%d\n", 
				channelNum,pRegulatoryDomain->supportedChannels_band_5[channelIndex].uMaxTxPowerDomain));
		}
		}

	WLAN_OS_REPORT(("11h PowerConstraint = %d, XCC TPC = %d, User  = %d\n", 
		pRegulatoryDomain->uPowerConstraint, pRegulatoryDomain->uExternTxPowerPreferred,
		pRegulatoryDomain->uUserMaxTxPower));

}
