Home | History | Annotate | Download | only in AirLink_Managment
      1 /*
      2  * regulatoryDomain.c
      3  *
      4  * Copyright(c) 1998 - 2010 Texas Instruments. All rights reserved.
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  *
     11  *  * Redistributions of source code must retain the above copyright
     12  *    notice, this list of conditions and the following disclaimer.
     13  *  * Redistributions in binary form must reproduce the above copyright
     14  *    notice, this list of conditions and the following disclaimer in
     15  *    the documentation and/or other materials provided with the
     16  *    distribution.
     17  *  * Neither the name Texas Instruments nor the names of its
     18  *    contributors may be used to endorse or promote products derived
     19  *    from this software without specific prior written permission.
     20  *
     21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     24  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     25  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     26  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     27  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     32  */
     33 
     34 /** \file regulatoryDomain.c
     35  *  \brief regulatoryDomain module interface
     36  *
     37  *  \see regulatoryDomain.h
     38  */
     39 
     40 /************************************************************************************************/
     41 /*  												*/
     42 /*		MODULE:		regulatoryDomain.c					        */
     43 /*		PURPOSE:	regulatoryDomain module interface.			        */
     44 /*                  This module calculated the channel that should be scanned and that are      */
     45 /*                   supported. Moreover, he set the transmit power level according to the      */
     46 /*                   regulatory domain requirements and the supported channel.                  */
     47 /*								 			        */
     48 /************************************************************************************************/
     49 #define __FILE_ID__  FILE_ID_3
     50 #include "report.h"
     51 #include "osApi.h"
     52 #include "paramOut.h"
     53 #include "regulatoryDomain.h"
     54 #include "regulatoryDomainApi.h"
     55 #include "TWDriver.h"
     56 #include "siteMgrApi.h"
     57 #include "SwitchChannelApi.h"
     58 #include "DrvMainModules.h"
     59 #include "TWDriver.h"
     60 
     61 
     62 /* Mask for retrieving the TxPower from the Scan Control Table */
     63 #define MASK_TX_POWER					(0x1f) /* bits 0-4 indicates MaxTxPower */
     64 #define MASK_ACTIVE_ALLOWED 			(0x40) /* bit 6 indiactes the channel is allowed for Active scan */
     65 #define MASK_FREQ_ALLOWED 				(0x80) /* bit 7 indicates the cahnnel is allowed*/
     66 
     67 #define CHANNEL_VALIDITY_TS_THRESHOLD   10000 /* 10 sec */
     68 
     69 /*
     70 * Small macro to convert Dbm units into Dbm/10 units. This macro is important
     71 * in order to avoid over-flow of Dbm units bigger than 25
     72 */
     73 #define DBM2DBMDIV10(uTxPower) \
     74 	((uTxPower) > (MAX_TX_POWER / DBM_TO_TX_POWER_FACTOR) ? \
     75 		MAX_TX_POWER : (uTxPower) * DBM_TO_TX_POWER_FACTOR)
     76 
     77 
     78 /********************************************************************************/
     79 /*						Internal functions prototypes.							*/
     80 /********************************************************************************/
     81 static TI_STATUS regulatoryDomain_updateCurrTxPower(regulatoryDomain_t	*pRegulatoryDomain);
     82 
     83 static void regulatoryDomain_setChannelValidity(regulatoryDomain_t *pRegulatoryDomain,
     84 												TI_UINT16 channelNum, TI_BOOL channelValidity);
     85 
     86 static TI_STATUS setSupportedChannelsAccording2CountryIe(regulatoryDomain_t *pRegulatoryDomain, TCountry*	pCountry, TI_BOOL band_2_4);
     87 
     88 static void setSupportedChannelsAccording2ScanControlTable(regulatoryDomain_t  *pRegulatoryDomain);
     89 
     90 static TI_STATUS regulatoryDomain_getChannelCapability(regulatoryDomain_t *pRegulatoryDomain,
     91 													   channelCapabilityReq_t channelCapabilityReq,
     92 													   channelCapabilityRet_t *channelCapabilityRet);
     93 
     94 static void regulatoryDomain_updateChannelsTs(regulatoryDomain_t *pRegulatoryDomain, TI_UINT8 channel);
     95 
     96 static void regulatoryDomain_buildDefaultListOfChannelsPerBand(regulatoryDomain_t *pRegulatoryDomain, ERadioBand band, TI_UINT8 *listSize);
     97 
     98 static void regulatoryDomain_checkCountryCodeExpiry(regulatoryDomain_t *pRegulatoryDomain);
     99 
    100 static TI_BOOL regulatoryDomain_isChannelSupprted(regulatoryDomain_t *pRegulatoryDomain, TI_UINT8 channel);
    101 
    102 static TI_BOOL regulatoryDomain_isCountryFound(regulatoryDomain_t *pRegulatoryDomain, ERadioBand radioBand);
    103 
    104 static void regulatoryDomain_getPowerTableMinMax (regulatoryDomain_t *pRegulatoryDomain,
    105                                                   powerCapability_t  *pPowerCapability);
    106 
    107 static TI_UINT8 regulatoryDomain_getMaxPowerAllowed(regulatoryDomain_t	*pRegulatoryDomain,
    108 												 TI_UINT8				uChannel,
    109 												 ERadioBand		eBand,
    110 												 TI_BOOL				bServingChannel);
    111 
    112 /********************************************************************************/
    113 /*						Interface functions Implementation.						*/
    114 /********************************************************************************/
    115 
    116 
    117 /************************************************************************
    118  *                        regulatoryDomain_create									*
    119  ************************************************************************
    120 DESCRIPTION: regulatoryDomain module creation function, called by the config mgr in creation phase
    121 				performs the following:
    122 				-	Allocate the regulatoryDomain handle
    123 
    124 INPUT:      hOs -			Handle to OS
    125 
    126 
    127 OUTPUT:
    128 
    129 RETURN:     Handle to the regulatoryDomain module on success, NULL otherwise
    130 
    131 ************************************************************************/
    132 TI_HANDLE regulatoryDomain_create(TI_HANDLE hOs)
    133 {
    134 	regulatoryDomain_t			*pRegulatoryDomain = NULL;
    135 
    136 	/* allocating the regulatoryDomain object */
    137 	pRegulatoryDomain = os_memoryAlloc(hOs,sizeof(regulatoryDomain_t));
    138 
    139 	if (pRegulatoryDomain == NULL)
    140 		return NULL;
    141 
    142 	return(pRegulatoryDomain);
    143 }
    144 
    145 
    146 /************************************************************************
    147  *                        regulatoryDomain_init							*
    148  ************************************************************************
    149 DESCRIPTION: Module init function, Called by the DrvMain in init phase
    150 				performs the following:
    151 				-	Reset & initializes local variables
    152 				-	Init the handles to be used by the module
    153 
    154 INPUT:      pStadHandles - List of handles to be used by the module
    155 
    156 OUTPUT:
    157 
    158 RETURN:     void
    159 ************************************************************************/
    160 void regulatoryDomain_init (TStadHandlesList *pStadHandles)
    161 {
    162 	regulatoryDomain_t *pRegulatoryDomain = (regulatoryDomain_t *)(pStadHandles->hRegulatoryDomain);
    163 
    164 	/* init variables */
    165 	pRegulatoryDomain->country_2_4_WasFound		= TI_FALSE;
    166 	pRegulatoryDomain->country_5_WasFound		= TI_FALSE;
    167 	pRegulatoryDomain->uExternTxPowerPreferred	= MAX_TX_POWER;	/* i.e. no restriction */
    168 	pRegulatoryDomain->uPowerConstraint			= MIN_TX_POWER;	/* i.e. no restriction */
    169 
    170 	/* Init handlers */
    171 	pRegulatoryDomain->hSiteMgr       = pStadHandles->hSiteMgr;
    172 	pRegulatoryDomain->hTWD	          = pStadHandles->hTWD;
    173 	pRegulatoryDomain->hReport	      = pStadHandles->hReport;
    174 	pRegulatoryDomain->hOs	          = pStadHandles->hOs;
    175     pRegulatoryDomain->hSwitchChannel = pStadHandles->hSwitchChannel;
    176 }
    177 
    178 
    179 /************************************************************************
    180  *                        regulatoryDomain_SetDefaults						*
    181  ************************************************************************
    182 DESCRIPTION: regulatoryDomain module configuration function, called by the config mgr in configuration phase
    183 				performs the following:
    184 				-	Reset & initializes local variables
    185 				-	Init the handles to be used by the module
    186 
    187 INPUT:      hRegulatoryDomain	-	regulatoryDomain handle
    188 			List of handles to be used by the module
    189 			pRegulatoryDomainInitParams	-	Init table of the module.
    190 
    191 
    192 OUTPUT:
    193 
    194 RETURN:     TI_OK on success, TI_NOK otherwise
    195 
    196 ************************************************************************/
    197 TI_STATUS regulatoryDomain_SetDefaults (TI_HANDLE 	hRegulatoryDomain,
    198                                         regulatoryDomainInitParams_t *pRegulatoryDomainInitParams)
    199 {
    200 	regulatoryDomain_t *pRegulatoryDomain = (regulatoryDomain_t *)hRegulatoryDomain;
    201 
    202 	/* User max Tx power for all channels */
    203 	pRegulatoryDomain->uUserMaxTxPower	  = pRegulatoryDomainInitParams->desiredTxPower;
    204 	/* Temporary Tx Power control to be used */
    205     pRegulatoryDomain->uTemporaryTxPower  = pRegulatoryDomainInitParams->uTemporaryTxPower;
    206     pRegulatoryDomain->uDesiredTemporaryTxPower = pRegulatoryDomainInitParams->uTemporaryTxPower;
    207 
    208     /*
    209 	 * Indicate the time in which the STA didn't receive any country code and was not connected, and therefore
    210      * will delete its current country code
    211 	 */
    212     pRegulatoryDomain->uTimeOutToResetCountryMs = pRegulatoryDomainInitParams->uTimeOutToResetCountryMs;
    213 	pRegulatoryDomain->uLastCountryReceivedTS = 0;
    214 
    215 	pRegulatoryDomain->regulatoryDomainEnabled = pRegulatoryDomainInitParams->multiRegulatoryDomainEnabled;
    216 	pRegulatoryDomain->spectrumManagementEnabled = pRegulatoryDomainInitParams->spectrumManagementEnabled;
    217 	if (pRegulatoryDomain->spectrumManagementEnabled == TI_TRUE)
    218 	{
    219 		pRegulatoryDomain->regulatoryDomainEnabled = TI_TRUE;
    220 	}
    221 
    222 	/* Getting the desired Control Table contents for 2.4 Ghz*/
    223 	os_memoryCopy(pRegulatoryDomain->hOs,
    224 				  (void *)pRegulatoryDomain->scanControlTable.ScanControlTable24.tableString,
    225 				  (void *)pRegulatoryDomainInitParams->desiredScanControlTable.ScanControlTable24.tableString,
    226 					NUM_OF_CHANNELS_24 * sizeof(TI_INT8));
    227 
    228 	/* Getting the desired Control Table contents for 5 Ghz*/
    229 	os_memoryCopy(pRegulatoryDomain->hOs,
    230 				  (void *)pRegulatoryDomain->scanControlTable.ScanControlTable5.tableString,
    231 				  (void *)pRegulatoryDomainInitParams->desiredScanControlTable.ScanControlTable5.tableString,
    232 					A_5G_BAND_NUM_CHANNELS * sizeof(TI_INT8));
    233 
    234 	setSupportedChannelsAccording2ScanControlTable(pRegulatoryDomain);
    235 
    236     pRegulatoryDomain->minDFS_channelNum = A_5G_BAND_MIN_MIDDLE_BAND_DFS_CHANNEL;
    237     pRegulatoryDomain->maxDFS_channelNum = A_5G_BAND_MAX_UPPER_BAND_DFS_CHANNEL;
    238 
    239 TRACE0(pRegulatoryDomain->hReport, REPORT_SEVERITY_INIT, ".....Regulatory domain configured successfully\n");
    240 
    241 	return TI_OK;
    242 }
    243 
    244 TI_STATUS regulatoryDomain_setParam(TI_HANDLE hRegulatoryDomain,
    245 									paramInfo_t	*pParam)
    246 {
    247 	regulatoryDomain_t *pRegulatoryDomain = (regulatoryDomain_t *)hRegulatoryDomain;
    248 
    249 
    250 	switch(pParam->paramType)
    251 	{
    252     case REGULATORY_DOMAIN_COUNTRY_PARAM:
    253         {
    254             TI_BOOL        bBand_2_4;
    255 
    256             /* Sanity check */
    257             if (NULL == pParam->content.pCountry)
    258             {
    259                 TRACE0(pRegulatoryDomain->hReport, REPORT_SEVERITY_ERROR, "regulatoryDomain_setParam, REGULATORY_DOMAIN_COUNTRY_PARAM is set with NULL pointer");
    260 
    261                 return TI_NOK;
    262             }
    263             else /* Update country code and supported channels */
    264             {
    265                 bBand_2_4 = siteMgr_isCurrentBand24(pRegulatoryDomain->hSiteMgr);
    266 
    267 			    /* Setting the CountryIE for every Band */
    268 			    setSupportedChannelsAccording2CountryIe(pRegulatoryDomain, pParam->content.pCountry, bBand_2_4);
    269             }
    270         }
    271 		break;
    272 
    273 	case REGULATORY_DOMAIN_SET_POWER_CONSTRAINT_PARAM:
    274 
    275         /* Update only if 11h enabled */
    276         if (pRegulatoryDomain->spectrumManagementEnabled)
    277 		{
    278             /* Convert to RegDomain units */
    279             TI_UINT8 uNewPowerConstraint = DBM2DBMDIV10(pParam->content.powerConstraint);
    280 
    281 TRACE2(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "SET_POWER_CONSTRAINT Old= %d New = %d (Only if bigger...)\n", 							  pRegulatoryDomain->uPowerConstraint, uNewPowerConstraint);
    282 
    283 			/* Update powerConstraint */
    284 			if ( pRegulatoryDomain->uPowerConstraint != uNewPowerConstraint )
    285 			{
    286 				pRegulatoryDomain->uPowerConstraint = uNewPowerConstraint;
    287 				/* Set new Tx power to TWD - only if needed ! */
    288 				regulatoryDomain_updateCurrTxPower(pRegulatoryDomain);
    289 			}
    290         }
    291 		break;
    292 
    293 	case REGULATORY_DOMAIN_EXTERN_TX_POWER_PREFERRED:
    294 		/* ExternTxPowerPreferred is the TX Power Control (TPC) */
    295 		{
    296 			/* Convert to RegDomain units */
    297 			TI_UINT8 uNewTPC = DBM2DBMDIV10(pParam->content.ExternTxPowerPreferred);
    298 
    299 TRACE2(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "REGULATORY_DOMAIN_EXTERN_TX_POWER_PREFERRED Old= %d New = %d\n", 				pRegulatoryDomain->uExternTxPowerPreferred, uNewTPC);
    300 
    301 			if ( uNewTPC != pRegulatoryDomain->uExternTxPowerPreferred )
    302 			{
    303 				pRegulatoryDomain->uExternTxPowerPreferred = uNewTPC;
    304 				/* Set new Tx power to TWD - only if needed ! */
    305 				regulatoryDomain_updateCurrTxPower(pRegulatoryDomain);
    306 			}
    307 		}
    308 		break;
    309 
    310 	case REGULATORY_DOMAIN_SET_CHANNEL_VALIDITY:
    311 		/* Set channel as Valid or Invalid for Active SCAN only.
    312 			Mainly used by DFS when Switch Channel is active */
    313 		regulatoryDomain_setChannelValidity(pRegulatoryDomain, pParam->content.channelValidity.channelNum,
    314 															   pParam->content.channelValidity.channelValidity);
    315 		break;
    316 
    317 	case REGULATORY_DOMAIN_CURRENT_TX_POWER_IN_DBM_PARAM:
    318 		/* This case is called when the desired Tx Power Level in Dbm is changed by the user */
    319         if(pRegulatoryDomain->uUserMaxTxPower != pParam->content.desiredTxPower)
    320         {
    321             pRegulatoryDomain->uUserMaxTxPower = pParam->content.desiredTxPower;
    322 			/* Set new Tx power to TWD - only if needed ! */
    323 			regulatoryDomain_updateCurrTxPower(pRegulatoryDomain);
    324         }
    325 
    326 		break;
    327 
    328 	case REGULATORY_DOMAIN_TX_POWER_AFTER_SELECTION_PARAM:
    329 		/* Called after joining BSS, set Tx power to TWD */
    330 
    331         TRACE0(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "regulatoryDomain_setParam, REGULATORY_DOMAIN_TX_POWER_AFTER_SELECTION_PARAM \n");
    332 
    333 	   /* setting the Tx Power according to the selected channel */
    334         regulatoryDomain_updateCurrTxPower(pRegulatoryDomain);
    335 
    336 		break;
    337 
    338     case REGULATORY_DOMAIN_DISCONNECT_PARAM:
    339         TRACE0(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "regulatoryDomain_setParam, REGULATORY_DOMAIN_DISCONNECT_PARAM\n");
    340 
    341         pRegulatoryDomain->uExternTxPowerPreferred = MAX_TX_POWER;	/* i.e. no restriction */
    342         pRegulatoryDomain->uPowerConstraint		   = MIN_TX_POWER;	/* i.e. no restriction */
    343 
    344         /* Update the last time a country code was used.
    345         After uTimeOutToResetCountryMs the country code will be deleted     */
    346         if (pRegulatoryDomain->country_2_4_WasFound || pRegulatoryDomain->country_5_WasFound)
    347         {
    348             pRegulatoryDomain->uLastCountryReceivedTS = os_timeStampMs(pRegulatoryDomain->hOs);
    349         }
    350         break;
    351 
    352 	case REGULATORY_DOMAIN_UPDATE_CHANNEL_VALIDITY:
    353 		regulatoryDomain_updateChannelsTs(pRegulatoryDomain, pParam->content.channel);
    354 		break;
    355 
    356     case REGULATORY_DOMAIN_TEMPORARY_TX_ATTENUATION_PARAM:
    357 		/* Temporary Tx Power control */
    358 TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "regulatoryDomain_setParam: temporary fix = %d, \n", pParam->content.bActivateTempPowerFix);
    359 
    360         pRegulatoryDomain->bTemporaryTxPowerEnable = pParam->content.bActivateTempPowerFix;
    361 
    362 			regulatoryDomain_updateCurrTxPower(pRegulatoryDomain);
    363 
    364         break;
    365 
    366     case REGULATORY_DOMAIN_ENABLE_DISABLE_802_11D:
    367         TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "regulatoryDomain_setParam, REGULATORY_DOMAIN_ENABLE_DISABLE_802_11D = %d, \n", pParam->content.enableDisable_802_11d);
    368 
    369         if ((pRegulatoryDomain->regulatoryDomainEnabled != pParam->content.enableDisable_802_11d) &&
    370             !pParam->content.enableDisable_802_11d && pRegulatoryDomain->spectrumManagementEnabled)
    371         {   /* Disable of 802_11d, is not allowed when 802_11h is enabled */
    372             TRACE0(pRegulatoryDomain->hReport, REPORT_SEVERITY_ERROR, "regulatoryDomain_setParam, Disable of 802_11d, is not allowed when 802_11h is enabled  \n");
    373             return TI_NOK;
    374 
    375         }
    376         pRegulatoryDomain->regulatoryDomainEnabled = pParam->content.enableDisable_802_11d;
    377 
    378 		/* Mark that no country was found - applies for both enabling and disabling of 11d */
    379 		pRegulatoryDomain->country_2_4_WasFound = TI_FALSE;
    380 		pRegulatoryDomain->country_5_WasFound = TI_FALSE;
    381 
    382         if (!pRegulatoryDomain->regulatoryDomainEnabled)
    383         {   /* Set regulatory Domain according to scan control table */
    384             setSupportedChannelsAccording2ScanControlTable(pRegulatoryDomain);
    385         }
    386 
    387 		break;
    388 
    389     case REGULATORY_DOMAIN_ENABLE_DISABLE_802_11H:
    390         TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "regulatoryDomain_setParam, REGULATORY_DOMAIN_ENABLE_DISABLE_802_11H = %d, \n", pParam->content.enableDisable_802_11h);
    391 
    392         pRegulatoryDomain->spectrumManagementEnabled = pParam->content.enableDisable_802_11h;
    393         if (pParam->content.enableDisable_802_11h)
    394         {   /* If 802_11h is enabled, enable 802_11d as well */
    395             pRegulatoryDomain->regulatoryDomainEnabled = TI_TRUE;
    396         }
    397         switchChannel_enableDisableSpectrumMngmt(pRegulatoryDomain->hSwitchChannel, pRegulatoryDomain->spectrumManagementEnabled);
    398 		break;
    399 
    400 	case REGULATORY_DOMAIN_COUNTRY_2_4_PARAM:
    401         /* NOTE !!! use this feature carefully. */
    402         TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "regulatoryDomain_setParam, REGULATORY_DOMAIN_COUNTRY_2_4_PARAM Len = %d, \n", pParam->paramLength);
    403 
    404         TRACE_INFO_HEX(pRegulatoryDomain->hReport, (TI_UINT8*)pParam->content.pCountry, sizeof(TCountry));
    405 
    406         return setSupportedChannelsAccording2CountryIe(pRegulatoryDomain, pParam->content.pCountry, TI_TRUE);
    407 
    408 	case REGULATORY_DOMAIN_COUNTRY_5_PARAM:
    409         /* NOTE !!! use this feature carefully */
    410         return setSupportedChannelsAccording2CountryIe(pRegulatoryDomain, pParam->content.pCountry, TI_FALSE);
    411 
    412 
    413     case REGULATORY_DOMAIN_DFS_CHANNELS_RANGE:
    414         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);
    415 
    416         if ((pParam->content.DFS_ChannelRange.minDFS_channelNum<A_5G_BAND_MIN_CHANNEL) ||
    417             (pParam->content.DFS_ChannelRange.maxDFS_channelNum>A_5G_BAND_MAX_CHANNEL) ||
    418             pParam->content.DFS_ChannelRange.minDFS_channelNum > pParam->content.DFS_ChannelRange.maxDFS_channelNum)
    419         {
    420             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);
    421             return TI_NOK;
    422         }
    423         pRegulatoryDomain->minDFS_channelNum = (TI_UINT8)pParam->content.DFS_ChannelRange.minDFS_channelNum;
    424         pRegulatoryDomain->maxDFS_channelNum = (TI_UINT8)pParam->content.DFS_ChannelRange.maxDFS_channelNum;
    425 
    426         break;
    427 
    428 	default:
    429 TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_ERROR, "Set param, Params is not supported, %d\n\n", pParam->paramType);
    430 		return PARAM_NOT_SUPPORTED;
    431 	}
    432 
    433 	return TI_OK;
    434 }
    435 
    436 TI_STATUS regulatoryDomain_getParam(TI_HANDLE hRegulatoryDomain,
    437 									paramInfo_t	*pParam)
    438 {
    439 	regulatoryDomain_t	*pRegulatoryDomain = (regulatoryDomain_t *)hRegulatoryDomain;
    440 
    441     /* Check if country code is still valid */
    442     regulatoryDomain_checkCountryCodeExpiry(pRegulatoryDomain);
    443 
    444 	switch(pParam->paramType)
    445 	{
    446 
    447 	case REGULATORY_DOMAIN_TX_POWER_LEVEL_TABLE_PARAM:
    448         {
    449             TFwInfo *pFwInfo = TWD_GetFWInfo (pRegulatoryDomain->hTWD);
    450             os_memoryCopy(pRegulatoryDomain->hOs,
    451                           (void *)&pParam->content.powerLevelTable,
    452                           (void *)pFwInfo->txPowerTable,
    453                           sizeof(pFwInfo->txPowerTable));
    454         }
    455 		break;
    456 
    457 	case REGULATORY_DOMAIN_MANAGEMENT_CAPABILITY_ENABLED_PARAM:
    458 		pParam->content.spectrumManagementEnabled = pRegulatoryDomain->spectrumManagementEnabled;
    459 		break;
    460 
    461 	case REGULATORY_DOMAIN_ENABLED_PARAM:
    462 		pParam->content.regulatoryDomainEnabled = pRegulatoryDomain->regulatoryDomainEnabled;
    463 		break;
    464 
    465 	case REGULATORY_DOMAIN_GET_SCAN_CAPABILITIES:
    466 		{
    467 			channelCapabilityReq_t	channelCapabilityReq;
    468 
    469 			channelCapabilityReq.band = pParam->content.channelCapabilityReq.band;
    470 			channelCapabilityReq.channelNum = pParam->content.channelCapabilityReq.channelNum;
    471 			channelCapabilityReq.scanOption = pParam->content.channelCapabilityReq.scanOption;
    472 
    473             regulatoryDomain_getChannelCapability(pRegulatoryDomain, channelCapabilityReq, &pParam->content.channelCapabilityRet);
    474 		}
    475 		break;
    476 
    477 	case REGULATORY_DOMAIN_POWER_CAPABILITY_PARAM:
    478 		/* power capability is only applicable when spectrum management is active (802.11h) */
    479 		if(pRegulatoryDomain->spectrumManagementEnabled)
    480 		{
    481             regulatoryDomain_getPowerTableMinMax (pRegulatoryDomain, &pParam->content.powerCapability);
    482 		}
    483 		else
    484 		{
    485 			return TI_NOK;
    486 		}
    487 		break;
    488 
    489 	case REGULATORY_DOMAIN_IS_CHANNEL_SUPPORTED:
    490 		/* checking if the channel is supported */
    491 		pParam->content.bIsChannelSupprted  =
    492 			regulatoryDomain_isChannelSupprted(pRegulatoryDomain, pParam->content.channel);
    493 
    494 		break;
    495 
    496 	case REGULATORY_DOMAIN_ALL_SUPPORTED_CHANNELS:
    497 		{
    498 			ERadioBand	band = pParam->content.siteMgrRadioBand;
    499 			regulatoryDomain_buildDefaultListOfChannelsPerBand(pRegulatoryDomain, band, &pParam->content.supportedChannels.sizeOfList);
    500 		    pParam->content.supportedChannels.listOfChannels = pRegulatoryDomain->pDefaultChannels;
    501 		}
    502 		break;
    503 
    504 	case REGULATORY_DOMAIN_CURRENT_TX_POWER_IN_DBM_PARAM:
    505 
    506             {
    507 			TTwdParamInfo		tparam;
    508 			/* Get last configured Tx power from TWD */
    509 			tparam.paramType = TWD_TX_POWER_PARAM_ID;
    510 			TWD_GetParam(pRegulatoryDomain->hTWD, &tparam);
    511 
    512 			pParam->content.desiredTxPower = tparam.content.halCtrlTxPowerDbm;
    513 
    514 TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "regulatoryDomain_getParam, CURRENT_TX_POWER_IN_DBM  = %d\n", 							   pParam->content.desiredTxPower);
    515             }
    516 
    517         break;
    518 
    519     case REGULATORY_DOMAIN_COUNTRY_PARAM:
    520         {
    521             /* This case is used as an inner function of the driver to retrieve the full IE of the country */
    522             TI_BOOL bBand_2_4 = siteMgr_isCurrentBand24(pRegulatoryDomain->hSiteMgr);
    523 
    524             if (bBand_2_4)
    525             {
    526                 if (pRegulatoryDomain->country_2_4_WasFound)
    527                 {
    528                     pParam->content.pCountry = &pRegulatoryDomain->country24;
    529                 }
    530                 else    /* Do not use the Inforamtion */
    531                 {
    532                     pParam->content.pCountry = NULL;
    533                 }
    534             }   /* band 5.0 */
    535             else
    536             {
    537                 if (pRegulatoryDomain->country_5_WasFound)
    538                 {
    539                    pParam->content.pCountry = &pRegulatoryDomain->country5;
    540                 }
    541                 else    /* Do not use the Inforamtion */
    542                 {
    543                     pParam->content.pCountry = NULL;
    544                 }
    545             }
    546         }
    547         break;
    548 
    549 	case REGULATORY_DOMAIN_COUNTRY_2_4_PARAM:
    550 		/* Getting only country string */
    551 
    552         if (pRegulatoryDomain->country_2_4_WasFound)
    553         {
    554             os_memoryCopy(pRegulatoryDomain->hOs, (void*)pParam->content.pCountryString, (void*)pRegulatoryDomain->country24.countryIE.CountryString, DOT11_COUNTRY_STRING_LEN);
    555         }
    556         else
    557         {
    558             pParam->content.pCountryString[0] = '\0';
    559         }
    560  		break;
    561 
    562 	case REGULATORY_DOMAIN_COUNTRY_5_PARAM:
    563 		/* Getting only country string */
    564 
    565         if (pRegulatoryDomain->country_5_WasFound)
    566         {
    567             os_memoryCopy(pRegulatoryDomain->hOs, (void*)pParam->content.pCountryString, (void*)pRegulatoryDomain->country5.countryIE.CountryString, DOT11_COUNTRY_STRING_LEN);
    568         }
    569         else
    570         {
    571             pParam->content.pCountryString[0] = '\0';
    572         }
    573 		break;
    574 
    575     case REGULATORY_DOMAIN_DFS_CHANNELS_RANGE:
    576         TRACE2(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "regulatoryDomain_getParam, DFS_CHANNELS_RANGE, min = %d, max = %d, \n", pRegulatoryDomain->minDFS_channelNum, pRegulatoryDomain->maxDFS_channelNum);
    577         pParam->content.DFS_ChannelRange.minDFS_channelNum = pRegulatoryDomain->minDFS_channelNum;
    578         pParam->content.DFS_ChannelRange.maxDFS_channelNum = pRegulatoryDomain->maxDFS_channelNum;
    579 
    580         break;
    581 
    582 	case REGULATORY_DOMAIN_IS_COUNTRY_FOUND:
    583 
    584 		pParam->content.bIsCountryFound =
    585 			 regulatoryDomain_isCountryFound(pRegulatoryDomain, pParam->content.eRadioBand);
    586 
    587 		break;
    588 
    589     case REGULATORY_DOMAIN_IS_DFS_CHANNEL:
    590 
    591         if ((pRegulatoryDomain->spectrumManagementEnabled) && /* 802.11h is enabled */
    592             (RADIO_BAND_5_0_GHZ == pParam->content.tDfsChannel.eBand) && /* band is 5 GHz */
    593             (pRegulatoryDomain->minDFS_channelNum <= pParam->content.tDfsChannel.uChannel) && /* channel is within DFS range */
    594             (pRegulatoryDomain->maxDFS_channelNum >= pParam->content.tDfsChannel.uChannel))
    595         {
    596             pParam->content.tDfsChannel.bDfsChannel = TI_TRUE;
    597         }
    598         else
    599         {
    600             pParam->content.tDfsChannel.bDfsChannel = TI_FALSE;
    601         }
    602         break;
    603 
    604     case REGULATORY_DOMAIN_TIME_TO_COUNTRY_EXPIRY:
    605         /* if a country was found for either band */
    606         if ((pRegulatoryDomain->country_2_4_WasFound) || (pRegulatoryDomain->country_5_WasFound))
    607         {
    608             paramInfo_t *pParam2;
    609             TI_STATUS   connStatus;
    610             TI_UINT32   uCurrentTS = os_timeStampMs (pRegulatoryDomain->hOs);
    611 
    612             pParam2 = (paramInfo_t *)os_memoryAlloc(pRegulatoryDomain->hOs, sizeof(paramInfo_t));
    613             if (!pParam2)
    614             {
    615                 return TI_NOK;
    616             }
    617 
    618             /* Get connection status */
    619             pParam2->paramType = SITE_MGR_CURRENT_SSID_PARAM;
    620             connStatus = siteMgr_getParam (pRegulatoryDomain->hSiteMgr, pParam2);
    621             os_memoryFree(pRegulatoryDomain->hOs, pParam2, sizeof(paramInfo_t));
    622 
    623             /* if we are connected, return 0 */
    624             if (connStatus != NO_SITE_SELECTED_YET)
    625             {
    626                 pParam->content.uTimeToCountryExpiryMs = 0;
    627             }
    628             else
    629             {
    630                 /*
    631                  * if country already expired (shouldn't happen as we are checking it at the top of
    632                  * get_param, but just in case...
    633                  */
    634                 if ((uCurrentTS - pRegulatoryDomain->uLastCountryReceivedTS) > pRegulatoryDomain->uTimeOutToResetCountryMs)
    635                 {
    636                     pParam->content.uTimeToCountryExpiryMs = 0;
    637                 }
    638                 else
    639                 {
    640                     pParam->content.uTimeToCountryExpiryMs =
    641                         pRegulatoryDomain->uTimeOutToResetCountryMs - (uCurrentTS - pRegulatoryDomain->uLastCountryReceivedTS);
    642                 }
    643             }
    644         }
    645         else
    646         {
    647             pParam->content.uTimeToCountryExpiryMs = 0;
    648         }
    649         break;
    650 
    651 	default:
    652 		TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_WARNING, "Get param, Params is not supported, %d\n\n", pParam->paramType);
    653 		return PARAM_NOT_SUPPORTED;
    654 	}
    655 
    656 	return TI_OK;
    657 }
    658 
    659 /************************************************************************
    660  *                        regulatoryDomain_destroy						*
    661  ************************************************************************
    662 DESCRIPTION: regulatoryDomain module destroy function, called by the config mgr in the destroy phase
    663 				performs the following:
    664 				-	Free all memory allocated by the module
    665 
    666 INPUT:      hRegulatoryDomain	-	regulatoryDomain handle.
    667 
    668 
    669 OUTPUT:
    670 
    671 RETURN:     TI_OK on success, TI_NOK otherwise
    672 
    673 ************************************************************************/
    674 TI_STATUS regulatoryDomain_destroy(TI_HANDLE hRegulatoryDomain)
    675 {
    676 	regulatoryDomain_t	*pRegulatoryDomain = (regulatoryDomain_t *)hRegulatoryDomain;
    677 
    678 	if (pRegulatoryDomain == NULL)
    679 		return TI_OK;
    680 
    681     os_memoryFree(pRegulatoryDomain->hOs, pRegulatoryDomain, sizeof(regulatoryDomain_t));
    682 
    683 	return TI_OK;
    684 }
    685 
    686 /************************************************************************
    687  *                        regulatoryDomain_isCountryFound						*
    688  ************************************************************************
    689 DESCRIPTION: This function returns the validity of Country according to band
    690 
    691 INPUT:      hRegulatoryDomain	-	regulatoryDomain handle.
    692             radioBand           - the desired band
    693 
    694 
    695 OUTPUT:
    696 
    697 RETURN:     TI_TRUE - if country IE was found according to the band.
    698             TI_FALSE - otherwise.
    699 
    700 ************************************************************************/
    701 TI_BOOL regulatoryDomain_isCountryFound(regulatoryDomain_t  *pRegulatoryDomain, ERadioBand radioBand)
    702 {
    703 
    704     if(radioBand == RADIO_BAND_2_4_GHZ)
    705     {
    706             return pRegulatoryDomain->country_2_4_WasFound;
    707     }
    708     else
    709     {
    710         return pRegulatoryDomain->country_5_WasFound;
    711     }
    712 
    713 }
    714 
    715 /***********************************************************************
    716  *                       setSupportedChannelsAccording2CountryIe
    717  ***********************************************************************
    718 DESCRIPTION:	Called when beacon/Probe Response with Country IE
    719 				is found.
    720 				The function sets the local countryIE per band with the CountryIE
    721 				 that was detected in the last passive scan.
    722 				 It is assumed that only one Country IE per band is allowed.
    723 				 If Country is changed when the TNET is loaded, it should
    724 				 be re-loaded in order to re-config the new Country domain.
    725 
    726 INPUT:      hRegulatoryDomain	-	RegulatoryDomain handle.
    727 			pCountry	-	pointer to the detected country IE.
    728 
    729 OUTPUT:
    730 
    731 RETURN:     TI_OK - New country code was set (or the same one was already configured)
    732             TI_NOK - The new country code could not be set
    733 
    734 ************************************************************************/
    735 static TI_STATUS setSupportedChannelsAccording2CountryIe(regulatoryDomain_t *pRegulatoryDomain, TCountry* pCountry, TI_BOOL band_2_4)
    736 {
    737 	channelCapability_t *pSupportedChannels;
    738 	TI_UINT8				channelIndex;
    739 	TI_UINT8				tripletChannelIndex, tripletChannelCnt;
    740 	TI_UINT8				channelStep, numberOfChannels, minChannelNumber, maxChannelNumber;
    741 
    742 
    743 	if (!pRegulatoryDomain->regulatoryDomainEnabled)
    744 	{  /* Ignore the Country IE if 802.11d is disabled */
    745 		return TI_NOK;
    746 	}
    747 
    748     /* Check if the country code should be reset */
    749     regulatoryDomain_checkCountryCodeExpiry(pRegulatoryDomain);
    750 
    751 	if( band_2_4 == TI_TRUE )
    752 	{
    753 		if (pRegulatoryDomain->country_2_4_WasFound)
    754 		{	/* Do not update new Country IE */
    755 			if (os_memoryCompare(pRegulatoryDomain->hOs, (void *)&pCountry->countryIE, (void *)&pRegulatoryDomain->country24.countryIE, sizeof(dot11_countryIE_t)))
    756 			{
    757 TRACE0(pRegulatoryDomain->hReport, REPORT_SEVERITY_WARNING, "setSupportedChannelsAccording2CountryIe different Country, cur=, new=\n");
    758             	return TI_NOK;
    759             }
    760             else    /* Same IE - just mark the TS and return TI_OK */
    761             {
    762                 /* Mark the time of the received country IE */
    763                 pRegulatoryDomain->uLastCountryReceivedTS = os_timeStampMs(pRegulatoryDomain->hOs);
    764                 return TI_OK;
    765             }
    766 		}
    767 		pRegulatoryDomain->country_2_4_WasFound = TI_TRUE;
    768 		pSupportedChannels = pRegulatoryDomain->supportedChannels_band_2_4;
    769 		channelStep = BG_24G_BAND_CHANNEL_HOPS;
    770 		maxChannelNumber = NUM_OF_CHANNELS_24;
    771 		minChannelNumber = BG_24G_BAND_MIN_CHANNEL;
    772 		numberOfChannels = NUM_OF_CHANNELS_24;
    773 		/* save the country IE */
    774 		os_memoryCopy(pRegulatoryDomain->hOs, (void*)&pRegulatoryDomain->country24, (void *)pCountry, sizeof(TCountry));
    775 
    776         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]);
    777 
    778 	}
    779 	else    /* band 5.0 */
    780 	{
    781 		if (pRegulatoryDomain->country_5_WasFound)
    782 		{	/* Do not update new Country IE if the IE is the same*/
    783 			if (os_memoryCompare(pRegulatoryDomain->hOs, (void *)&pCountry->countryIE, (void *)&pRegulatoryDomain->country5.countryIE, sizeof(dot11_countryIE_t)))
    784 			{
    785 TRACE0(pRegulatoryDomain->hReport, REPORT_SEVERITY_WARNING, "setSupportedChannelsAccording2CountryIe different Country, cur=, new=\n");
    786             	return TI_NOK;
    787             }
    788             else    /* Same IE - just mark the TS and return TI_OK */
    789             {
    790                 /* Mark the time of the received country IE */
    791                 pRegulatoryDomain->uLastCountryReceivedTS = os_timeStampMs(pRegulatoryDomain->hOs);
    792                 return TI_OK;
    793             }
    794 		}
    795 		pRegulatoryDomain->country_5_WasFound = TI_TRUE;
    796 		pSupportedChannels = pRegulatoryDomain->supportedChannels_band_5;
    797 		channelStep = A_5G_BAND_CHANNEL_HOPS;
    798 		maxChannelNumber = A_5G_BAND_MAX_CHANNEL;
    799 		minChannelNumber = A_5G_BAND_MIN_CHANNEL;
    800 		numberOfChannels = A_5G_BAND_NUM_CHANNELS;
    801 		/* save the country IE */
    802 		os_memoryCopy(pRegulatoryDomain->hOs, (void*)&pRegulatoryDomain->country5, (void*)pCountry, sizeof(TCountry));
    803 
    804         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]);
    805 	}
    806 
    807     /*
    808      * New Country IE was saved. Now - update the last received TS and ScanControlTable
    809      */
    810 
    811     /* Mark the time of the received country IE */
    812     pRegulatoryDomain->uLastCountryReceivedTS = os_timeStampMs(pRegulatoryDomain->hOs);
    813 
    814 	/* First clear the validity of all channels
    815 		Overwrite the ScanControlTable */
    816 	for (channelIndex=0; channelIndex<numberOfChannels; channelIndex++)
    817 	{
    818 		pSupportedChannels[channelIndex].channelValidityActive = TI_FALSE;
    819 		pSupportedChannels[channelIndex].channelValidityPassive = TI_FALSE;
    820 		pSupportedChannels[channelIndex].bChanneInCountryIe = TI_FALSE;
    821 		pSupportedChannels[channelIndex].uMaxTxPowerDomain = MIN_TX_POWER;
    822 	}
    823 
    824 	tripletChannelCnt = (pCountry->len - DOT11_COUNTRY_STRING_LEN) / 3;
    825 	/* set validity of the channels according to the band (2.4 or 5) */
    826 	for( tripletChannelIndex = 0; tripletChannelIndex < tripletChannelCnt ; tripletChannelIndex++)
    827 	{
    828 		TI_UINT8	firstChannelNumInTriplet;
    829 
    830 		firstChannelNumInTriplet = pCountry->countryIE.tripletChannels[tripletChannelIndex].firstChannelNumber;
    831 TRACE2(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "firstChannelNumInTriplet=%d,channelStep=%d\n", firstChannelNumInTriplet, channelStep);
    832 		for (channelIndex=0; channelIndex<pCountry->countryIE.tripletChannels[tripletChannelIndex].numberOfChannels; channelIndex++)
    833 		{
    834 			TI_UINT16	channelNumber;
    835 
    836 			channelNumber = firstChannelNumInTriplet+(channelIndex*channelStep);
    837 TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "setSupportedChannelsAccording2CountryIe of channel=%d\n", channelNumber);
    838 
    839 			if (channelNumber <= maxChannelNumber)
    840 			{
    841 				TI_UINT8 	channelIndex4Band;
    842 
    843 				channelIndex4Band = (channelNumber-minChannelNumber);
    844 				pSupportedChannels[channelIndex4Band].bChanneInCountryIe = TI_TRUE;
    845 				pSupportedChannels[channelIndex4Band].channelValidityPassive = TI_TRUE;
    846 				pSupportedChannels[channelIndex4Band].channelValidityActive = TI_TRUE;
    847 
    848 				/* set the TX power in DBM/10 units */
    849 			    pSupportedChannels[channelIndex4Band].uMaxTxPowerDomain =
    850 					DBM2DBMDIV10(pCountry->countryIE.tripletChannels[tripletChannelIndex].maxTxPowerLevel);
    851 
    852 TRACE2(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "channel = %d uMaxTxPowerDomain=%d\n", 										channelNumber, pSupportedChannels[channelIndex4Band].uMaxTxPowerDomain);
    853 			}
    854 		}
    855     }
    856 
    857 	return TI_OK;
    858 }
    859 
    860 
    861 /***********************************************************************
    862  *                        regulatoryDomain_isChannelSupprted
    863  ***********************************************************************
    864 DESCRIPTION:	The function checks if the input channel is supported.
    865 
    866 INPUT:      pRegulatoryDomain	-	RegulatoryDomain pointer.
    867 			channel				-	Channel number.
    868 
    869 
    870 OUTPUT:
    871 
    872 RETURN:     TI_OK if channel is supported, TI_NOK otherwise.
    873 
    874 ************************************************************************/
    875 static TI_BOOL regulatoryDomain_isChannelSupprted(regulatoryDomain_t *pRegulatoryDomain, TI_UINT8 channel)
    876 {
    877 	TI_UINT8				channelIndex;
    878 	channelCapability_t *pSupportedChannels;
    879 
    880 	if (pRegulatoryDomain==NULL)
    881 	{
    882 		return TI_FALSE;
    883 	}
    884 
    885 	if ((channel<BG_24G_BAND_MIN_CHANNEL) || (channel>A_5G_BAND_MAX_CHANNEL))
    886 	{
    887 		return TI_FALSE;
    888 	}
    889 	if (channel>=A_5G_BAND_MIN_CHANNEL)
    890 	{
    891 		channelIndex = (channel-A_5G_BAND_MIN_CHANNEL);
    892 		pSupportedChannels = pRegulatoryDomain->supportedChannels_band_5;
    893 	}
    894 	else
    895 	{
    896 		channelIndex = (channel-BG_24G_BAND_MIN_CHANNEL);
    897 		if (channelIndex >= NUM_OF_CHANNELS_24)
    898 		{
    899 			TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_ERROR,
    900 				   "regulatoryDomain_isChannelSupprted(): 2.4G invalid channel # %u\n", channel );
    901 			return TI_FALSE;
    902 		}
    903 		pSupportedChannels = pRegulatoryDomain->supportedChannels_band_2_4;
    904 	}
    905 	if (pRegulatoryDomain->spectrumManagementEnabled
    906 		&& (channel >= pRegulatoryDomain->minDFS_channelNum)
    907         && (channel <= pRegulatoryDomain->maxDFS_channelNum)
    908 		&& ((os_timeStampMs(pRegulatoryDomain->hOs)-pSupportedChannels[channelIndex].timestamp) >=CHANNEL_VALIDITY_TS_THRESHOLD ))
    909 	{	/* If 802.11h is enabled, a DFS channel is valid only for 10 sec
    910 			from the last Beacon/ProbeResponse */
    911         pSupportedChannels[channelIndex].channelValidityActive = TI_FALSE;
    912         TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "regulatoryDomain_isChannelSupprted(): CHANNEL_VALIDITY_TS_THRESHOLD !! Disable channel no %d, DFS channel\n", channel );
    913 
    914 	}
    915 
    916 	return (pSupportedChannels[channelIndex].channelValidityActive);
    917 
    918 }
    919 
    920 /************************************************************************
    921  *                        regulatoryDomain_setChannelValidity			*
    922  ************************************************************************/
    923 /*
    924 *
    925 *
    926 * \b Description:
    927 *
    928 * This function sets a channel as invalid or valid in the internal Regulatory Domain
    929  * database.
    930 *
    931 * \b ARGS:
    932 *
    933 *  I   - pData - pointer to the regDoamin SM context  \n
    934 *  I   - channelNum - the invalid/valid channel number
    935 *  I   - channelValidity - TI_TRUE if channel is valid, TI_FALSE channel is invalid
    936 *
    937 * \b RETURNS:
    938 *
    939 *  None.
    940 *
    941 *
    942 *************************************************************************/
    943 static void regulatoryDomain_setChannelValidity(regulatoryDomain_t *pRegulatoryDomain,
    944 												TI_UINT16 channelNum, TI_BOOL channelValidity)
    945 {
    946 	channelCapability_t		*pSupportedChannels;
    947 	TI_UINT8					channelIndex;
    948 
    949 
    950 	if (pRegulatoryDomain == NULL)
    951 	{
    952 		return;
    953 	}
    954 	if ((channelNum==0 ) || (channelNum>A_5G_BAND_MAX_CHANNEL))
    955 	{
    956 TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_ERROR, "regulatoryDomain_setChannelValidity, invalid channelNum=%d \n", channelNum);
    957 		return;
    958 	}
    959 
    960 	if (channelNum <= NUM_OF_CHANNELS_24)
    961 	{
    962 		pSupportedChannels = pRegulatoryDomain->supportedChannels_band_2_4;
    963 		channelIndex = (channelNum-BG_24G_BAND_MIN_CHANNEL);
    964 	}
    965 	else
    966 	{
    967 		pSupportedChannels = pRegulatoryDomain->supportedChannels_band_5;
    968 		channelIndex = (channelNum - A_5G_BAND_MIN_CHANNEL);
    969 	}
    970 
    971 	if(channelValidity == TI_TRUE)
    972 		if((pSupportedChannels[channelIndex].bChanneInCountryIe == TI_FALSE) && (pRegulatoryDomain->regulatoryDomainEnabled == TI_TRUE))
    973 		{
    974 TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_WARNING, "regulatoryDomain_setChannelValidity: channelNum = %d isn't supported at the Country. wll not set to active!\n", channelNum);
    975 			return;
    976 		}
    977 
    978     TRACE2(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "regulatoryDomain_setChannelValidity: channelNum=%d, validity=%d \n", channelNum, channelValidity);
    979 
    980 
    981 	pSupportedChannels[channelIndex].channelValidityActive = channelValidity;
    982 }
    983 
    984 
    985 /************************************************************************
    986  *      setSupportedChannelsAccording2ScanControlTable 					*
    987  ************************************************************************/
    988 /**
    989 *
    990 *
    991 * \b Description:
    992 *
    993 * This function is called in config and sets the supported channels according to
    994 * the scan control table read from registry and reg domain read from the chip.
    995 *
    996 * \b ARGS:
    997 *
    998 *  I   - pRegulatoryDomain - pointer to the regDoamin SM context  \n
    999 *
   1000 * \b RETURNS:
   1001 *
   1002 *  None.
   1003 *
   1004 *
   1005 *************************************************************************/
   1006 static void setSupportedChannelsAccording2ScanControlTable(regulatoryDomain_t  *pRegulatoryDomain)
   1007 {
   1008 	TI_UINT8 	channelIndex;
   1009 	TI_UINT8	channelMask;
   1010 
   1011 	if (pRegulatoryDomain==NULL)
   1012 	{
   1013 		return;
   1014 	}
   1015 
   1016     TRACE0(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "setSupportedChannelsAccording2ScanControlTable \n");
   1017 
   1018 	for (channelIndex=0; channelIndex<NUM_OF_CHANNELS_24; channelIndex++)
   1019 	{
   1020 		channelMask = pRegulatoryDomain->scanControlTable.ScanControlTable24.tableString[channelIndex];
   1021 		pRegulatoryDomain->supportedChannels_band_2_4[channelIndex].bChanneInCountryIe = TI_FALSE;
   1022 
   1023 		/* Calculate Domain Tx Power - channelMask units are in Dbm. */
   1024 		pRegulatoryDomain->supportedChannels_band_2_4[channelIndex].uMaxTxPowerDomain =
   1025 						DBM2DBMDIV10(channelMask & MASK_TX_POWER);
   1026 		if (channelMask & (MASK_ACTIVE_ALLOWED | MASK_FREQ_ALLOWED))
   1027 		{	/* The channel is allowed for Active & Passive scans */
   1028 			if (pRegulatoryDomain->regulatoryDomainEnabled)
   1029 			{	/* All channels should be invalid for Active scan */
   1030 				pRegulatoryDomain->supportedChannels_band_2_4[channelIndex].channelValidityActive = TI_FALSE;
   1031                 TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "channelIndex=%d is invalid for Active \n", channelIndex+1);
   1032 			}
   1033 			else
   1034 			{
   1035 				pRegulatoryDomain->supportedChannels_band_2_4[channelIndex].channelValidityActive = TI_TRUE;
   1036                 TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "channelIndex=%d is Active valid \n", channelIndex+1);
   1037 			}
   1038 
   1039 		}
   1040 
   1041 		if (channelMask & MASK_FREQ_ALLOWED)
   1042 		{	/* The channel is allowed for Passive scan */
   1043 			pRegulatoryDomain->supportedChannels_band_2_4[channelIndex].channelValidityPassive = TI_TRUE;
   1044             TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "channelIndex=%d is Passive valid \n", channelIndex+1);
   1045 		}
   1046 		else
   1047 		{	/* The channel is not allowed */
   1048 			pRegulatoryDomain->supportedChannels_band_2_4[channelIndex].channelValidityPassive = TI_FALSE;
   1049 			pRegulatoryDomain->supportedChannels_band_2_4[channelIndex].channelValidityActive = TI_FALSE;
   1050 		}
   1051 	}
   1052 
   1053 	for (channelIndex=A_5G_BAND_MIN_CHANNEL; channelIndex<A_5G_BAND_MAX_CHANNEL; channelIndex++)
   1054 	{
   1055 		TI_UINT8	channelIndexInBand5;
   1056 
   1057 		channelIndexInBand5 = (channelIndex-A_5G_BAND_MIN_CHANNEL);
   1058 		channelMask = pRegulatoryDomain->scanControlTable.ScanControlTable5.tableString[channelIndexInBand5];
   1059         TRACE3(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "channelIndex=%d, channelIndexInBand5=%d channelMask=%d\n", channelIndex, channelIndexInBand5, channelMask);
   1060 
   1061 		/* Calculate Domain Tx Power - channelMask units are in Dbm. */
   1062 		pRegulatoryDomain->supportedChannels_band_5[channelIndexInBand5].uMaxTxPowerDomain =
   1063 			DBM2DBMDIV10(channelMask & MASK_TX_POWER);
   1064 
   1065 		pRegulatoryDomain->supportedChannels_band_5[channelIndexInBand5].bChanneInCountryIe = TI_FALSE;
   1066 		if (channelMask & (MASK_ACTIVE_ALLOWED | MASK_FREQ_ALLOWED))
   1067 		{	 /* The channel is allowed for Active & Passive scans */
   1068 			if (pRegulatoryDomain->regulatoryDomainEnabled)
   1069 			{	/* All channels should be invalid for Active scan */
   1070 				pRegulatoryDomain->supportedChannels_band_5[channelIndexInBand5].channelValidityActive = TI_FALSE;
   1071                 TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "channelIndex=%d is invalid for Active \n", channelIndex);
   1072 			}
   1073 			else
   1074 			{
   1075 				pRegulatoryDomain->supportedChannels_band_5[channelIndexInBand5].channelValidityActive = TI_TRUE;
   1076                 TRACE2(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "channelIndex=%d, channelIndexInBand5=%d, is Active valid \n", channelIndex, channelIndexInBand5);
   1077 			}
   1078 		}
   1079 
   1080 		if (channelMask & MASK_FREQ_ALLOWED)
   1081 		{	/* The channel is allowed for Passive scan */
   1082 			pRegulatoryDomain->supportedChannels_band_5[channelIndexInBand5].channelValidityPassive = TI_TRUE;
   1083             TRACE2(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "channelIndex=%d, channelIndexInBand5=%d, is Passive valid \n", channelIndex, channelIndexInBand5);
   1084 		}
   1085 		else
   1086 		{	/* The channel is not allowed */
   1087 			pRegulatoryDomain->supportedChannels_band_5[channelIndexInBand5].channelValidityPassive = TI_FALSE;
   1088 			pRegulatoryDomain->supportedChannels_band_5[channelIndexInBand5].channelValidityActive = TI_FALSE;
   1089 		}
   1090 
   1091 	}
   1092 }
   1093 
   1094 
   1095 /***********************************************************************
   1096 *                        regulatoryDomain_getChannelCapability
   1097 ***********************************************************************
   1098 DESCRIPTION:	This function returns the channel capability information
   1099 
   1100 INPUT:      pRegulatoryDomain		-	RegulatoryDomain pointer.
   1101 			channelCapabilityReq	-	Channels parameters
   1102 
   1103 
   1104 OUTPUT:		channelCapabilityRet	-   Channel capability information
   1105 
   1106 RETURN:     TI_OK if information was retrieved, TI_NOK otherwise.
   1107 
   1108 ************************************************************************/
   1109 static TI_STATUS regulatoryDomain_getChannelCapability(regulatoryDomain_t *pRegulatoryDomain,
   1110 													   channelCapabilityReq_t channelCapabilityReq,
   1111 													   channelCapabilityRet_t *channelCapabilityRet)
   1112 {
   1113 	channelCapability_t		*pSupportedChannels;
   1114 	TI_UINT8				channelIndex;
   1115 	TI_BOOL					bCountryWasFound, bServingChannel;
   1116 
   1117 	if ((pRegulatoryDomain == NULL) || (channelCapabilityRet == NULL))
   1118 	{
   1119 		return TI_NOK;
   1120 	}
   1121 
   1122 	channelCapabilityRet->channelValidity = TI_FALSE;
   1123 	channelCapabilityRet->maxTxPowerDbm = 0;
   1124 	if ((channelCapabilityReq.channelNum==0 ) || (channelCapabilityReq.channelNum > A_5G_BAND_MAX_CHANNEL))
   1125 	{
   1126         TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_ERROR, "regulatoryDomain_getChannelCapability, invalid channelNum=%d \n", channelCapabilityReq.channelNum);
   1127 		return TI_NOK;
   1128 	}
   1129 
   1130 	if (channelCapabilityReq.band==RADIO_BAND_2_4_GHZ)
   1131 	{
   1132 		pSupportedChannels = pRegulatoryDomain->supportedChannels_band_2_4;
   1133 		channelIndex = (channelCapabilityReq.channelNum-BG_24G_BAND_MIN_CHANNEL);
   1134 		if (channelIndex >= NUM_OF_CHANNELS_24)
   1135 		{
   1136 			TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_ERROR,
   1137 				   "regulatoryDomain_getChannelCapability(): 2.4G invalid channel # %u\n", channelCapabilityReq.channelNum );
   1138 			return TI_NOK;
   1139 		}
   1140 		bCountryWasFound = pRegulatoryDomain->country_2_4_WasFound;
   1141 	}
   1142 	else if (channelCapabilityReq.band==RADIO_BAND_5_0_GHZ)
   1143 	{
   1144 		pSupportedChannels = pRegulatoryDomain->supportedChannels_band_5;
   1145 		channelIndex = (channelCapabilityReq.channelNum - A_5G_BAND_MIN_CHANNEL);
   1146 		if (channelIndex >= A_5G_BAND_NUM_CHANNELS)
   1147 		{
   1148 			TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_ERROR,
   1149 				   "regulatoryDomain_getChannelCapability(): 5G invalid channel # %u\n", channelCapabilityReq.channelNum);
   1150 			return TI_NOK;
   1151 		}
   1152 		bCountryWasFound = pRegulatoryDomain->country_5_WasFound;
   1153 	}
   1154 	else
   1155 	{
   1156 		TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_ERROR, "regulatoryDomain_getChannelCapability, invalid band=%d \n", channelCapabilityReq.band);
   1157 		return TI_NOK;
   1158 	}
   1159 
   1160 
   1161 	/*
   1162 	 * Set channelValidity according to ScanTable and whether 11d is enabled
   1163 	 */
   1164 	if (channelCapabilityReq.scanOption == ACTIVE_SCANNING)
   1165 	{
   1166 		if ( ( pRegulatoryDomain->regulatoryDomainEnabled ) && ( !bCountryWasFound ) )
   1167 		{	/* 11d enabled and no country IE was found - set channel to invalid */
   1168 			channelCapabilityRet->channelValidity = TI_FALSE;
   1169 		}
   1170 		else
   1171 		{
   1172             paramInfo_t *pParam = (paramInfo_t *)os_memoryAlloc(pRegulatoryDomain->hOs, sizeof(paramInfo_t));
   1173             if (!pParam)
   1174             {
   1175                 return TI_NOK;
   1176             }
   1177 
   1178             channelCapabilityRet->channelValidity = pSupportedChannels[channelIndex].channelValidityActive;
   1179 			/*
   1180 			 * Set Maximum Tx power for the channel - only for active scanning
   1181 			 */
   1182 
   1183 			/* Get current channel and check if we are using the same one */
   1184 			pParam->paramType = SITE_MGR_CURRENT_CHANNEL_PARAM;
   1185 			siteMgr_getParam(pRegulatoryDomain->hSiteMgr, pParam);
   1186 
   1187 			bServingChannel = ( pParam->content.siteMgrCurrentChannel == channelCapabilityReq.channelNum ?
   1188 								TI_TRUE : TI_FALSE );
   1189 
   1190 			channelCapabilityRet->maxTxPowerDbm = regulatoryDomain_getMaxPowerAllowed(pRegulatoryDomain,
   1191 				channelCapabilityReq.channelNum,
   1192 				channelCapabilityReq.band,
   1193 				bServingChannel);
   1194             os_memoryFree(pRegulatoryDomain->hOs, pParam, sizeof(paramInfo_t));
   1195 		}
   1196 	}
   1197 	else	/* Passive scanning */
   1198 	{
   1199 		if ( ( pRegulatoryDomain->regulatoryDomainEnabled ) && ( !bCountryWasFound ) )
   1200 		{	/* 11d enabled and no country IE was found - set channel to valid for passive scan */
   1201 			channelCapabilityRet->channelValidity = TI_TRUE;
   1202 		}
   1203 	else
   1204 	{
   1205 		channelCapabilityRet->channelValidity = pSupportedChannels[channelIndex].channelValidityPassive;
   1206 	}
   1207 	}
   1208 
   1209 	if (pRegulatoryDomain->spectrumManagementEnabled
   1210 		&& (channelCapabilityReq.scanOption == ACTIVE_SCANNING)
   1211         && (channelCapabilityReq.channelNum >= pRegulatoryDomain->minDFS_channelNum)
   1212         && (channelCapabilityReq.channelNum <= pRegulatoryDomain->maxDFS_channelNum)
   1213 		&& ((os_timeStampMs(pRegulatoryDomain->hOs)-pSupportedChannels[channelIndex].timestamp) >=CHANNEL_VALIDITY_TS_THRESHOLD ))
   1214 	{	/* If 802.11h is enabled, a DFS channel is valid only for 10 sec
   1215 			from the last Beacon/ProbeResponse */
   1216         pSupportedChannels[channelIndex].channelValidityActive = TI_FALSE;
   1217         channelCapabilityRet->channelValidity = TI_FALSE;
   1218         TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "regulatoryDomain_getChannelCapability(): CHANNEL_VALIDITY_TS_THRESHOLD !!! Disable channel no %d, DFS channel\n", channelCapabilityReq.channelNum  );
   1219     }
   1220 
   1221     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);
   1222 	return TI_OK;
   1223 
   1224 }
   1225 
   1226 
   1227 static void regulatoryDomain_updateChannelsTs(regulatoryDomain_t *pRegulatoryDomain, TI_UINT8 channel)
   1228 {
   1229 	TI_UINT8				channelIndex;
   1230 	channelCapability_t *pSupportedChannels;
   1231 
   1232 	if (pRegulatoryDomain==NULL)
   1233 	{
   1234 		return;
   1235 	}
   1236 
   1237 	if ((channel<BG_24G_BAND_MIN_CHANNEL) || (channel>A_5G_BAND_MAX_CHANNEL))
   1238 	{
   1239 		return;
   1240 	}
   1241 
   1242 	if (channel>=A_5G_BAND_MIN_CHANNEL)
   1243 	{
   1244 		channelIndex = (channel-A_5G_BAND_MIN_CHANNEL);
   1245 		pSupportedChannels = pRegulatoryDomain->supportedChannels_band_5;
   1246 	}
   1247 	else
   1248 	{
   1249 		channelIndex = (channel-BG_24G_BAND_MIN_CHANNEL);
   1250 		if (channelIndex >= NUM_OF_CHANNELS_24)
   1251 		{
   1252 			TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_ERROR,
   1253 				   "regulatoryDomain_updateChannelsTs(): 2.4G invalid channel # %u\n", channel );
   1254 			return;
   1255 		}
   1256 		pSupportedChannels = pRegulatoryDomain->supportedChannels_band_2_4;
   1257 	}
   1258 
   1259 	if((pSupportedChannels[channelIndex].bChanneInCountryIe == TI_FALSE) && (pRegulatoryDomain->regulatoryDomainEnabled == TI_TRUE))
   1260   	{
   1261 		TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_WARNING, "regulatoryDomain_updateChannelsTs: channelNum = %d isn't supported at the Country. wll not set to active!\n", channel);
   1262   		return;
   1263   	}
   1264 
   1265 	pSupportedChannels[channelIndex].timestamp = os_timeStampMs(pRegulatoryDomain->hOs);
   1266 	pSupportedChannels[channelIndex].channelValidityActive = TI_TRUE;
   1267 
   1268 }
   1269 
   1270 /***********************************************************************
   1271  *              regulatoryDomain_updateCurrTxPower
   1272  ***********************************************************************
   1273 DESCRIPTION: Called when new Tx power should be calculated and configured.
   1274 			 Check if we are already joined to BSS/IBSS, calculate
   1275 			 new Tx power and configure it to TWD.
   1276 
   1277 INPUT:		pRegulatoryDomain	- regulatoryDomain pointer.
   1278 
   1279 RETURN:     TI_OK - New value was configured to TWD, TI_NOK - Can't configure value
   1280 			TX_POWER_SET_SAME_VALUE - Same value was already configured.
   1281 
   1282 ************************************************************************/
   1283 static TI_STATUS regulatoryDomain_updateCurrTxPower(regulatoryDomain_t	*pRegulatoryDomain)
   1284 {
   1285     paramInfo_t			*pParam;
   1286 	TI_STATUS			eStatus;
   1287 	TTwdParamInfo		*pTwdParam;
   1288 	TI_UINT8			uCurrChannel, uNewTxPower;
   1289 
   1290     pParam = (paramInfo_t *)os_memoryAlloc(pRegulatoryDomain->hOs, sizeof(paramInfo_t));
   1291     if (!pParam)
   1292     {
   1293         return TI_NOK;
   1294     }
   1295 
   1296     pTwdParam = (TTwdParamInfo *)os_memoryAlloc(pRegulatoryDomain->hOs, sizeof(TTwdParamInfo));
   1297     if (!pTwdParam)
   1298     {
   1299         os_memoryFree(pRegulatoryDomain->hOs, pParam, sizeof(paramInfo_t));
   1300         return TI_NOK;
   1301     }
   1302 
   1303 	/* Get the current channel, and update TWD with the changed */
   1304 	pParam->paramType = SITE_MGR_CURRENT_CHANNEL_PARAM;
   1305 	eStatus = siteMgr_getParam(pRegulatoryDomain->hSiteMgr, pParam);
   1306 
   1307 	if ( eStatus != TI_OK )
   1308 	{
   1309 		/* We are not joined yet - no meaning for new Tx power */
   1310         TRACE0(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "regulatoryDomain_updateCurrTxPower, No site selected yet\n");
   1311         os_memoryFree(pRegulatoryDomain->hOs, pParam, sizeof(paramInfo_t));
   1312         os_memoryFree(pRegulatoryDomain->hOs, pTwdParam, sizeof(TTwdParamInfo));
   1313 		return TI_NOK;
   1314 	}
   1315 	/* Save current channel */
   1316 	uCurrChannel = pParam->content.siteMgrCurrentChannel;
   1317 
   1318 	/* Get the current channel, and update TWD with the changed */
   1319 	pParam->paramType = 	SITE_MGR_RADIO_BAND_PARAM;
   1320 	siteMgr_getParam(pRegulatoryDomain->hSiteMgr, pParam);
   1321 
   1322 	/* Calculate maximum Tx power for the serving channel */
   1323 	uNewTxPower = regulatoryDomain_getMaxPowerAllowed(pRegulatoryDomain, uCurrChannel,
   1324 													  pParam->content.siteMgrRadioBand, TI_TRUE);
   1325     os_memoryFree(pRegulatoryDomain->hOs, pParam, sizeof(paramInfo_t));
   1326 
   1327 	/* Verify that the Temporary TX Power Control doesn't violate the TX Power Constraint */
   1328 	pRegulatoryDomain->uTemporaryTxPower = TI_MIN(pRegulatoryDomain->uDesiredTemporaryTxPower, uNewTxPower);
   1329 
   1330 
   1331     TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "regulatoryDomain_updateCurrTxPower, Write to TWD = %d \n", uNewTxPower);
   1332 
   1333     pTwdParam->paramType = TWD_TX_POWER_PARAM_ID;
   1334 
   1335     /* set TWD according to Temporary Tx Power Enable flag */
   1336     if (TI_TRUE == pRegulatoryDomain->bTemporaryTxPowerEnable)
   1337     {
   1338         pTwdParam->content.halCtrlTxPowerDbm = pRegulatoryDomain->uTemporaryTxPower;
   1339     }
   1340     else
   1341     {
   1342         pTwdParam->content.halCtrlTxPowerDbm = uNewTxPower;
   1343     }
   1344 
   1345     eStatus = TWD_SetParam(pRegulatoryDomain->hTWD, pTwdParam);
   1346     os_memoryFree(pRegulatoryDomain->hOs, pTwdParam, sizeof(TTwdParamInfo));
   1347 	return eStatus;
   1348 }
   1349 
   1350 /***********************************************************************
   1351  *                        regulatoryDomain_checkCountryCodeExpiry
   1352  ***********************************************************************
   1353 DESCRIPTION: Check & Reset the country code that was detected earlier.
   1354                 Reseting country code will be done when the STA was not connected for
   1355                 a certain amount of time, and no country code was received in that period (from the same country).
   1356                 This scenario might indicate that the STA has moved to a different country.
   1357 
   1358 INPUT:      pRegulatoryDomain	-	Regulatory Domain handle.
   1359 
   1360 OUTPUT:		updating country code if necessary.
   1361 
   1362 RETURN:
   1363 
   1364 ************************************************************************/
   1365 void regulatoryDomain_checkCountryCodeExpiry(regulatoryDomain_t *pRegulatoryDomain)
   1366 {
   1367     paramInfo_t *pParam;
   1368     TI_STATUS   connStatus;
   1369     TI_UINT32   uCurrentTS = os_timeStampMs(pRegulatoryDomain->hOs);
   1370 
   1371     if ((pRegulatoryDomain->country_2_4_WasFound) || (pRegulatoryDomain->country_5_WasFound))
   1372     {
   1373         pParam = (paramInfo_t *)os_memoryAlloc(pRegulatoryDomain->hOs, sizeof(paramInfo_t));
   1374         if (!pParam)
   1375         {
   1376             return;
   1377         }
   1378         /* Get connection status */
   1379         pParam->paramType = SITE_MGR_CURRENT_SSID_PARAM;
   1380         connStatus      = siteMgr_getParam(pRegulatoryDomain->hSiteMgr, pParam);
   1381 
   1382          /* If (uTimeOutToResetCountryMs has elapsed && we are not connected)
   1383                  delete the last country code received */
   1384         if (((uCurrentTS - pRegulatoryDomain->uLastCountryReceivedTS) > pRegulatoryDomain->uTimeOutToResetCountryMs) &&
   1385             (connStatus == NO_SITE_SELECTED_YET))
   1386         {
   1387             TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, ", Reset country code after %d Ms\n",(uCurrentTS - pRegulatoryDomain->uLastCountryReceivedTS));
   1388 
   1389             /* Reset country codes */
   1390             pRegulatoryDomain->country_2_4_WasFound = TI_FALSE;
   1391             pRegulatoryDomain->country_5_WasFound = TI_FALSE;
   1392 
   1393             /* Restore default values of the scan control table */
   1394             setSupportedChannelsAccording2ScanControlTable(pRegulatoryDomain);
   1395         }
   1396         os_memoryFree(pRegulatoryDomain->hOs, pParam, sizeof(paramInfo_t));
   1397     }
   1398 }
   1399 
   1400 /***********************************************************************
   1401 *              regulatoryDomain_getMaxPowerAllowed
   1402 ***********************************************************************
   1403 DESCRIPTION: Get the maximum tx power allowed for the given channel.
   1404 				The final value is constructed by:
   1405 				1) User max value
   1406 				2) Domain restriction - 11d country code IE
   1407 				3) 11h power constraint - only on serving channel
   1408 				4) XCC TPC - only on serving channel
   1409 
   1410 RETURN:     Max power in Dbm/10 for the given channel
   1411 
   1412 ************************************************************************/
   1413 static TI_UINT8 regulatoryDomain_getMaxPowerAllowed(regulatoryDomain_t	*pRegulatoryDomain,
   1414 												 TI_UINT8				uChannel,
   1415 												 ERadioBand		eBand,
   1416 												 TI_BOOL				bServingChannel)
   1417 {
   1418 	channelCapability_t	*pSupportedChannels;
   1419 	TI_UINT8				 uChannelIndex, uTxPower;
   1420 
   1421 	if( eBand == RADIO_BAND_2_4_GHZ)
   1422 	{
   1423 		pSupportedChannels = pRegulatoryDomain->supportedChannels_band_2_4;
   1424 		uChannelIndex = uChannel - BG_24G_BAND_MIN_CHANNEL;
   1425 	}
   1426 	else
   1427 	{
   1428 		pSupportedChannels = pRegulatoryDomain->supportedChannels_band_5;
   1429 		uChannelIndex = uChannel - A_5G_BAND_MIN_CHANNEL;
   1430 	}
   1431 
   1432 	/* We'll start with the "Domain restriction - 11d country code IE" */
   1433 	uTxPower = pSupportedChannels[uChannelIndex].uMaxTxPowerDomain;
   1434 
   1435 	if ( bServingChannel)
   1436 	{
   1437 		if (pRegulatoryDomain->uPowerConstraint < uTxPower)
   1438 		{
   1439 			/* When 802.11h is disabled, uPowerConstraint is 0 anyway */
   1440 			uTxPower -= pRegulatoryDomain->uPowerConstraint;
   1441 		}
   1442 
   1443         /* Take XCC limitation too */
   1444         uTxPower = TI_MIN(uTxPower, pRegulatoryDomain->uExternTxPowerPreferred);
   1445 
   1446 	}
   1447 
   1448 	/* Now make sure we are not exceeding the user maximum */
   1449 	uTxPower = TI_MIN(uTxPower, pRegulatoryDomain->uUserMaxTxPower);
   1450 
   1451 TRACE3(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, " uChannel = %d bServingChannel = %d uTxPower = %d \n", uChannel, bServingChannel, uTxPower);
   1452 
   1453 	return uTxPower;
   1454 }
   1455 
   1456 
   1457 static void regulatoryDomain_buildDefaultListOfChannelsPerBand(regulatoryDomain_t *pRegulatoryDomain, ERadioBand band, TI_UINT8 *listSize)
   1458 {
   1459 	TI_UINT8				channelIndex;
   1460 	TI_UINT8				numberOfChannels, minChannelNumber;
   1461 	channelCapability_t	*pSupportedChannels;
   1462 	TI_UINT8				maxSupportedChannels=0;
   1463 
   1464 	if ( (pRegulatoryDomain==NULL) || (listSize==NULL))
   1465 	{
   1466 		return;
   1467 	}
   1468 
   1469 	if( band == RADIO_BAND_2_4_GHZ)
   1470 	{
   1471 		minChannelNumber = BG_24G_BAND_MIN_CHANNEL;
   1472 		numberOfChannels = NUM_OF_CHANNELS_24;
   1473 		pSupportedChannels = pRegulatoryDomain->supportedChannels_band_2_4;
   1474 	}
   1475 	else
   1476 	{
   1477 		minChannelNumber = A_5G_BAND_MIN_CHANNEL;
   1478 		numberOfChannels = A_5G_BAND_NUM_CHANNELS;
   1479 		pSupportedChannels = pRegulatoryDomain->supportedChannels_band_5;
   1480 	}
   1481 
   1482 
   1483 	for (channelIndex=0; channelIndex<numberOfChannels; channelIndex++)
   1484 	{
   1485 		if (pSupportedChannels[channelIndex].channelValidityPassive)
   1486 		{
   1487 			pRegulatoryDomain->pDefaultChannels[maxSupportedChannels] = channelIndex+minChannelNumber;
   1488 TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "Channel num %d is supported \n", pRegulatoryDomain->pDefaultChannels[maxSupportedChannels]);
   1489 			maxSupportedChannels++;
   1490 		}
   1491 	}
   1492 
   1493 	*listSize = maxSupportedChannels;
   1494 
   1495 }
   1496 
   1497 /***********************************************************************
   1498 *              regulatoryDomain_getPowerTableMinMax
   1499 ***********************************************************************
   1500 DESCRIPTION: Find the Tx-power-level table min & max values.
   1501 			 The table is made of 4 power levels and 5 bands/sub-bands.
   1502 
   1503 RETURN:     void
   1504 ************************************************************************/
   1505 static void regulatoryDomain_getPowerTableMinMax (regulatoryDomain_t *pRegulatoryDomain,
   1506                                                   powerCapability_t  *pPowerCapability)
   1507 {
   1508     TFwInfo  *pFwInfo = TWD_GetFWInfo (pRegulatoryDomain->hTWD);
   1509 	TI_UINT8	i;
   1510 
   1511     /* Init the min (max) to the opposite edge so the table values are below (above) this edge */
   1512 	pPowerCapability->minTxPower = MAX_TX_POWER;
   1513 	pPowerCapability->maxTxPower = MIN_TX_POWER;
   1514 
   1515 	/* Find Min and Max values of the table */
   1516 	for (i = 0; i < NUMBER_OF_SUB_BANDS_E; i++)
   1517 	{
   1518 		pPowerCapability->minTxPower = TI_MIN (pPowerCapability->minTxPower,
   1519                                                pFwInfo->txPowerTable[i][NUM_OF_POWER_LEVEL-1]);
   1520 		pPowerCapability->maxTxPower = TI_MAX (pPowerCapability->maxTxPower,
   1521                                                pFwInfo->txPowerTable[i][0]);
   1522 	}
   1523 }
   1524 
   1525 /* for debug */
   1526 void regDomainPrintValidTables(TI_HANDLE hRegulatoryDomain)
   1527 {
   1528 	regulatoryDomain_t  *pRegulatoryDomain = (regulatoryDomain_t *)hRegulatoryDomain;
   1529 	TI_UINT16 channelIndex;
   1530 
   1531 	for (channelIndex=0; channelIndex<NUM_OF_CHANNELS_24; channelIndex++)
   1532 	{
   1533 		if (pRegulatoryDomain->supportedChannels_band_2_4[channelIndex].channelValidityPassive)
   1534 			WLAN_OS_REPORT(("channel num =%d is valid for passive \n", channelIndex+1));
   1535 		if (pRegulatoryDomain->supportedChannels_band_2_4[channelIndex].channelValidityActive)
   1536 		{
   1537 			WLAN_OS_REPORT(("channel =%d is valid for active TX power=%d\n",
   1538 				channelIndex+1, pRegulatoryDomain->supportedChannels_band_2_4[channelIndex].uMaxTxPowerDomain));
   1539 		}
   1540 	}
   1541 
   1542 	for (channelIndex=0; channelIndex<A_5G_BAND_NUM_CHANNELS; channelIndex++)
   1543 	{
   1544 		TI_UINT8	channelNum;
   1545 		channelNum = channelIndex+A_5G_BAND_MIN_CHANNEL;
   1546 		if (pRegulatoryDomain->supportedChannels_band_5[channelIndex].channelValidityPassive)
   1547 			WLAN_OS_REPORT(("channel =%d is valid for passive \n", channelNum));
   1548 		if (pRegulatoryDomain->supportedChannels_band_5[channelIndex].channelValidityActive)
   1549 		{
   1550 			WLAN_OS_REPORT(("channel =%d is valid for active TX power=%d\n",
   1551 				channelNum,pRegulatoryDomain->supportedChannels_band_5[channelIndex].uMaxTxPowerDomain));
   1552 		}
   1553 		}
   1554 
   1555 	WLAN_OS_REPORT(("11h PowerConstraint = %d, XCC TPC = %d, User  = %d\n",
   1556 		pRegulatoryDomain->uPowerConstraint, pRegulatoryDomain->uExternTxPowerPreferred,
   1557 		pRegulatoryDomain->uUserMaxTxPower));
   1558 
   1559 }
   1560