• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 ************************************************************************/
regulatoryDomain_create(TI_HANDLE hOs)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 ************************************************************************/
regulatoryDomain_init(TStadHandlesList * pStadHandles)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 ************************************************************************/
regulatoryDomain_SetDefaults(TI_HANDLE hRegulatoryDomain,regulatoryDomainInitParams_t * pRegulatoryDomainInitParams)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 
regulatoryDomain_setParam(TI_HANDLE hRegulatoryDomain,paramInfo_t * pParam)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 
regulatoryDomain_getParam(TI_HANDLE hRegulatoryDomain,paramInfo_t * pParam)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 ************************************************************************/
regulatoryDomain_destroy(TI_HANDLE hRegulatoryDomain)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 ************************************************************************/
regulatoryDomain_isCountryFound(regulatoryDomain_t * pRegulatoryDomain,ERadioBand radioBand)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 ************************************************************************/
setSupportedChannelsAccording2CountryIe(regulatoryDomain_t * pRegulatoryDomain,TCountry * pCountry,TI_BOOL band_2_4)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 ************************************************************************/
regulatoryDomain_isChannelSupprted(regulatoryDomain_t * pRegulatoryDomain,TI_UINT8 channel)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 *************************************************************************/
regulatoryDomain_setChannelValidity(regulatoryDomain_t * pRegulatoryDomain,TI_UINT16 channelNum,TI_BOOL channelValidity)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 *************************************************************************/
setSupportedChannelsAccording2ScanControlTable(regulatoryDomain_t * pRegulatoryDomain)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 ************************************************************************/
regulatoryDomain_getChannelCapability(regulatoryDomain_t * pRegulatoryDomain,channelCapabilityReq_t channelCapabilityReq,channelCapabilityRet_t * channelCapabilityRet)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 
regulatoryDomain_updateChannelsTs(regulatoryDomain_t * pRegulatoryDomain,TI_UINT8 channel)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 ************************************************************************/
regulatoryDomain_updateCurrTxPower(regulatoryDomain_t * pRegulatoryDomain)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 ************************************************************************/
regulatoryDomain_checkCountryCodeExpiry(regulatoryDomain_t * pRegulatoryDomain)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 ************************************************************************/
regulatoryDomain_getMaxPowerAllowed(regulatoryDomain_t * pRegulatoryDomain,TI_UINT8 uChannel,ERadioBand eBand,TI_BOOL bServingChannel)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 
regulatoryDomain_buildDefaultListOfChannelsPerBand(regulatoryDomain_t * pRegulatoryDomain,ERadioBand band,TI_UINT8 * listSize)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 ************************************************************************/
regulatoryDomain_getPowerTableMinMax(regulatoryDomain_t * pRegulatoryDomain,powerCapability_t * pPowerCapability)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 */
regDomainPrintValidTables(TI_HANDLE hRegulatoryDomain)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