• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * regulatoryDomain.c
3  *
4  * Copyright(c) 1998 - 2009 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 *tParam;
609             TI_STATUS   connStatus;
610             TI_UINT32   uCurrentTS = os_timeStampMs (pRegulatoryDomain->hOs);
611 
612             tParam = (paramInfo_t *)os_memoryAlloc(pRegulatoryDomain->hOs, sizeof(paramInfo_t));
613             if (!tParam)
614                 return TI_NOK;
615 
616             /* Get connection status */
617             tParam->paramType = SITE_MGR_CURRENT_SSID_PARAM;
618             connStatus = siteMgr_getParam (pRegulatoryDomain->hSiteMgr, tParam);
619             os_memoryFree(pRegulatoryDomain->hOs, tParam, sizeof(paramInfo_t));
620             /* if we are connected, return 0 */
621             if (connStatus != NO_SITE_SELECTED_YET)
622             {
623                 pParam->content.uTimeToCountryExpiryMs = 0;
624             }
625             else
626             {
627                 /*
628                  * if country already expired (shouldn't happen as we are checking it at the top of
629                  * get_param, but just in case...
630                  */
631                 if ((uCurrentTS - pRegulatoryDomain->uLastCountryReceivedTS) > pRegulatoryDomain->uTimeOutToResetCountryMs)
632                 {
633                     pParam->content.uTimeToCountryExpiryMs = 0;
634                 }
635                 else
636                 {
637                     pParam->content.uTimeToCountryExpiryMs =
638                         pRegulatoryDomain->uTimeOutToResetCountryMs - (uCurrentTS - pRegulatoryDomain->uLastCountryReceivedTS);
639                 }
640             }
641         }
642         else
643         {
644             pParam->content.uTimeToCountryExpiryMs = 0;
645         }
646         break;
647 
648 	default:
649 		TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_WARNING, "Get param, Params is not supported, %d\n\n", pParam->paramType);
650 		return PARAM_NOT_SUPPORTED;
651 	}
652 
653 	return TI_OK;
654 }
655 
656 /************************************************************************
657  *                        regulatoryDomain_destroy						*
658  ************************************************************************
659 DESCRIPTION: regulatoryDomain module destroy function, called by the config mgr in the destroy phase
660 				performs the following:
661 				-	Free all memory allocated by the module
662 
663 INPUT:      hRegulatoryDomain	-	regulatoryDomain handle.
664 
665 
666 OUTPUT:
667 
668 RETURN:     TI_OK on success, TI_NOK otherwise
669 
670 ************************************************************************/
regulatoryDomain_destroy(TI_HANDLE hRegulatoryDomain)671 TI_STATUS regulatoryDomain_destroy(TI_HANDLE hRegulatoryDomain)
672 {
673 	regulatoryDomain_t	*pRegulatoryDomain = (regulatoryDomain_t *)hRegulatoryDomain;
674 
675 	if (pRegulatoryDomain == NULL)
676 		return TI_OK;
677 
678     os_memoryFree(pRegulatoryDomain->hOs, pRegulatoryDomain, sizeof(regulatoryDomain_t));
679 
680 	return TI_OK;
681 }
682 
683 /************************************************************************
684  *                        regulatoryDomain_isCountryFound						*
685  ************************************************************************
686 DESCRIPTION: This function returns the validity of Country according to band
687 
688 INPUT:      hRegulatoryDomain	-	regulatoryDomain handle.
689             radioBand           - the desired band
690 
691 
692 OUTPUT:
693 
694 RETURN:     TI_TRUE - if country IE was found according to the band.
695             TI_FALSE - otherwise.
696 
697 ************************************************************************/
regulatoryDomain_isCountryFound(regulatoryDomain_t * pRegulatoryDomain,ERadioBand radioBand)698 TI_BOOL regulatoryDomain_isCountryFound(regulatoryDomain_t  *pRegulatoryDomain, ERadioBand radioBand)
699 {
700 
701     if(radioBand == RADIO_BAND_2_4_GHZ)
702     {
703             return pRegulatoryDomain->country_2_4_WasFound;
704     }
705     else
706     {
707         return pRegulatoryDomain->country_5_WasFound;
708     }
709 
710 }
711 
712 /***********************************************************************
713  *                       setSupportedChannelsAccording2CountryIe
714  ***********************************************************************
715 DESCRIPTION:	Called when beacon/Probe Response with Country IE
716 				is found.
717 				The function sets the local countryIE per band with the CountryIE
718 				 that was detected in the last passive scan.
719 				 It is assumed that only one Country IE per band is allowed.
720 				 If Country is changed when the TNET is loaded, it should
721 				 be re-loaded in order to re-config the new Country domain.
722 
723 INPUT:      hRegulatoryDomain	-	RegulatoryDomain handle.
724 			pCountry	-	pointer to the detected country IE.
725 
726 OUTPUT:
727 
728 RETURN:     TI_OK - New country code was set (or the same one was already configured)
729             TI_NOK - The new country code could not be set
730 
731 ************************************************************************/
setSupportedChannelsAccording2CountryIe(regulatoryDomain_t * pRegulatoryDomain,TCountry * pCountry,TI_BOOL band_2_4)732 static TI_STATUS setSupportedChannelsAccording2CountryIe(regulatoryDomain_t *pRegulatoryDomain, TCountry* pCountry, TI_BOOL band_2_4)
733 {
734 	channelCapability_t *pSupportedChannels;
735 	TI_UINT8				channelIndex;
736 	TI_UINT8				tripletChannelIndex, tripletChannelCnt;
737 	TI_UINT8				channelStep, numberOfChannels, minChannelNumber, maxChannelNumber;
738 
739 
740 	if (!pRegulatoryDomain->regulatoryDomainEnabled)
741 	{  /* Ignore the Country IE if 802.11d is disabled */
742 		return TI_NOK;
743 	}
744 
745     /* Check if the country code should be reset */
746     regulatoryDomain_checkCountryCodeExpiry(pRegulatoryDomain);
747 
748 	if( band_2_4 == TI_TRUE )
749 	{
750 		if (pRegulatoryDomain->country_2_4_WasFound)
751 		{	/* Do not update new Country IE */
752 			if (os_memoryCompare(pRegulatoryDomain->hOs, (void *)&pCountry->countryIE, (void *)&pRegulatoryDomain->country24.countryIE, sizeof(dot11_countryIE_t)))
753 			{
754 TRACE0(pRegulatoryDomain->hReport, REPORT_SEVERITY_WARNING, "setSupportedChannelsAccording2CountryIe different Country, cur=, new=\n");
755             	return TI_NOK;
756             }
757             else    /* Same IE - just mark the TS and return TI_OK */
758             {
759                 /* Mark the time of the received country IE */
760                 pRegulatoryDomain->uLastCountryReceivedTS = os_timeStampMs(pRegulatoryDomain->hOs);
761                 return TI_OK;
762             }
763 		}
764 		pRegulatoryDomain->country_2_4_WasFound = TI_TRUE;
765 		pSupportedChannels = pRegulatoryDomain->supportedChannels_band_2_4;
766 		channelStep = BG_24G_BAND_CHANNEL_HOPS;
767 		maxChannelNumber = NUM_OF_CHANNELS_24;
768 		minChannelNumber = BG_24G_BAND_MIN_CHANNEL;
769 		numberOfChannels = NUM_OF_CHANNELS_24;
770 		/* save the country IE */
771 		os_memoryCopy(pRegulatoryDomain->hOs, (void*)&pRegulatoryDomain->country24, (void *)pCountry, sizeof(TCountry));
772 
773         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]);
774 
775 	}
776 	else    /* band 5.0 */
777 	{
778 		if (pRegulatoryDomain->country_5_WasFound)
779 		{	/* Do not update new Country IE if the IE is the same*/
780 			if (os_memoryCompare(pRegulatoryDomain->hOs, (void *)&pCountry->countryIE, (void *)&pRegulatoryDomain->country5.countryIE, sizeof(dot11_countryIE_t)))
781 			{
782 TRACE0(pRegulatoryDomain->hReport, REPORT_SEVERITY_WARNING, "setSupportedChannelsAccording2CountryIe different Country, cur=, new=\n");
783             	return TI_NOK;
784             }
785             else    /* Same IE - just mark the TS and return TI_OK */
786             {
787                 /* Mark the time of the received country IE */
788                 pRegulatoryDomain->uLastCountryReceivedTS = os_timeStampMs(pRegulatoryDomain->hOs);
789                 return TI_OK;
790             }
791 		}
792 		pRegulatoryDomain->country_5_WasFound = TI_TRUE;
793 		pSupportedChannels = pRegulatoryDomain->supportedChannels_band_5;
794 		channelStep = A_5G_BAND_CHANNEL_HOPS;
795 		maxChannelNumber = A_5G_BAND_MAX_CHANNEL;
796 		minChannelNumber = A_5G_BAND_MIN_CHANNEL;
797 		numberOfChannels = A_5G_BAND_NUM_CHANNELS;
798 		/* save the country IE */
799 		os_memoryCopy(pRegulatoryDomain->hOs, (void*)&pRegulatoryDomain->country5, (void*)pCountry, sizeof(TCountry));
800 
801         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]);
802 	}
803 
804     /*
805      * New Country IE was saved. Now - update the last received TS and ScanControlTable
806      */
807 
808     /* Mark the time of the received country IE */
809     pRegulatoryDomain->uLastCountryReceivedTS = os_timeStampMs(pRegulatoryDomain->hOs);
810 
811 	/* First clear the validity of all channels
812 		Overwrite the ScanControlTable */
813 	for (channelIndex=0; channelIndex<numberOfChannels; channelIndex++)
814 	{
815 		pSupportedChannels[channelIndex].channelValidityActive = TI_FALSE;
816 		pSupportedChannels[channelIndex].channelValidityPassive = TI_FALSE;
817 		pSupportedChannels[channelIndex].bChanneInCountryIe = TI_FALSE;
818 		pSupportedChannels[channelIndex].uMaxTxPowerDomain = MIN_TX_POWER;
819 	}
820 
821 	tripletChannelCnt = (pCountry->len - DOT11_COUNTRY_STRING_LEN) / 3;
822 	/* set validity of the channels according to the band (2.4 or 5) */
823 	for( tripletChannelIndex = 0; tripletChannelIndex < tripletChannelCnt ; tripletChannelIndex++)
824 	{
825 		TI_UINT8	firstChannelNumInTriplet;
826 
827 		firstChannelNumInTriplet = pCountry->countryIE.tripletChannels[tripletChannelIndex].firstChannelNumber;
828 TRACE2(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "firstChannelNumInTriplet=%d,channelStep=%d\n", firstChannelNumInTriplet, channelStep);
829 		for (channelIndex=0; channelIndex<pCountry->countryIE.tripletChannels[tripletChannelIndex].numberOfChannels; channelIndex++)
830 		{
831 			TI_UINT16	channelNumber;
832 
833 			channelNumber = firstChannelNumInTriplet+(channelIndex*channelStep);
834 TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "setSupportedChannelsAccording2CountryIe of channel=%d\n", channelNumber);
835 
836 			if (channelNumber <= maxChannelNumber)
837 			{
838 				TI_UINT8 	channelIndex4Band;
839 
840 				channelIndex4Band = (channelNumber-minChannelNumber);
841 				pSupportedChannels[channelIndex4Band].bChanneInCountryIe = TI_TRUE;
842 				pSupportedChannels[channelIndex4Band].channelValidityPassive = TI_TRUE;
843 				pSupportedChannels[channelIndex4Band].channelValidityActive = TI_TRUE;
844 
845 				/* set the TX power in DBM/10 units */
846 			    pSupportedChannels[channelIndex4Band].uMaxTxPowerDomain =
847 					DBM2DBMDIV10(pCountry->countryIE.tripletChannels[tripletChannelIndex].maxTxPowerLevel);
848 
849 TRACE2(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "channel = %d uMaxTxPowerDomain=%d\n", 										channelNumber, pSupportedChannels[channelIndex4Band].uMaxTxPowerDomain);
850 			}
851 		}
852     }
853 
854 	return TI_OK;
855 }
856 
857 
858 /***********************************************************************
859  *                        regulatoryDomain_isChannelSupprted
860  ***********************************************************************
861 DESCRIPTION:	The function checks if the input channel is supported.
862 
863 INPUT:      pRegulatoryDomain	-	RegulatoryDomain pointer.
864 			channel				-	Channel number.
865 
866 
867 OUTPUT:
868 
869 RETURN:     TI_OK if channel is supported, TI_NOK otherwise.
870 
871 ************************************************************************/
regulatoryDomain_isChannelSupprted(regulatoryDomain_t * pRegulatoryDomain,TI_UINT8 channel)872 static TI_BOOL regulatoryDomain_isChannelSupprted(regulatoryDomain_t *pRegulatoryDomain, TI_UINT8 channel)
873 {
874 	TI_UINT8				channelIndex;
875 	channelCapability_t *pSupportedChannels;
876 
877 	if (pRegulatoryDomain==NULL)
878 	{
879 		return TI_FALSE;
880 	}
881 
882 	if ((channel<BG_24G_BAND_MIN_CHANNEL) || (channel>A_5G_BAND_MAX_CHANNEL))
883 	{
884 		return TI_FALSE;
885 	}
886 	if (channel>=A_5G_BAND_MIN_CHANNEL)
887 	{
888 		channelIndex = (channel-A_5G_BAND_MIN_CHANNEL);
889 		pSupportedChannels = pRegulatoryDomain->supportedChannels_band_5;
890 	}
891 	else
892 	{
893 		channelIndex = (channel-BG_24G_BAND_MIN_CHANNEL);
894 		if (channelIndex >= NUM_OF_CHANNELS_24)
895 		{
896 			TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_ERROR,
897 				   "regulatoryDomain_isChannelSupprted(): 2.4G invalid channel # %u\n", channel );
898 			return TI_FALSE;
899 		}
900 		pSupportedChannels = pRegulatoryDomain->supportedChannels_band_2_4;
901 	}
902 	if (pRegulatoryDomain->spectrumManagementEnabled
903 		&& (channel >= pRegulatoryDomain->minDFS_channelNum)
904         && (channel <= pRegulatoryDomain->maxDFS_channelNum)
905 		&& ((os_timeStampMs(pRegulatoryDomain->hOs)-pSupportedChannels[channelIndex].timestamp) >=CHANNEL_VALIDITY_TS_THRESHOLD ))
906 	{	/* If 802.11h is enabled, a DFS channel is valid only for 10 sec
907 			from the last Beacon/ProbeResponse */
908         pSupportedChannels[channelIndex].channelValidityActive = TI_FALSE;
909         TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "regulatoryDomain_isChannelSupprted(): CHANNEL_VALIDITY_TS_THRESHOLD !! Disable channel no %d, DFS channel\n", channel );
910 
911 	}
912 
913 	return (pSupportedChannels[channelIndex].channelValidityActive);
914 
915 }
916 
917 /************************************************************************
918  *                        regulatoryDomain_setChannelValidity			*
919  ************************************************************************/
920 /*
921 *
922 *
923 * \b Description:
924 *
925 * This function sets a channel as invalid or valid in the internal Regulatory Domain
926  * database.
927 *
928 * \b ARGS:
929 *
930 *  I   - pData - pointer to the regDoamin SM context  \n
931 *  I   - channelNum - the invalid/valid channel number
932 *  I   - channelValidity - TI_TRUE if channel is valid, TI_FALSE channel is invalid
933 *
934 * \b RETURNS:
935 *
936 *  None.
937 *
938 *
939 *************************************************************************/
regulatoryDomain_setChannelValidity(regulatoryDomain_t * pRegulatoryDomain,TI_UINT16 channelNum,TI_BOOL channelValidity)940 static void regulatoryDomain_setChannelValidity(regulatoryDomain_t *pRegulatoryDomain,
941 												TI_UINT16 channelNum, TI_BOOL channelValidity)
942 {
943 	channelCapability_t		*pSupportedChannels;
944 	TI_UINT8					channelIndex;
945 
946 
947 	if (pRegulatoryDomain == NULL)
948 	{
949 		return;
950 	}
951 	if ((channelNum==0 ) || (channelNum>A_5G_BAND_MAX_CHANNEL))
952 	{
953 TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_ERROR, "regulatoryDomain_setChannelValidity, invalid channelNum=%d \n", channelNum);
954 		return;
955 	}
956 
957 	if (channelNum <= NUM_OF_CHANNELS_24)
958 	{
959 		pSupportedChannels = pRegulatoryDomain->supportedChannels_band_2_4;
960 		channelIndex = (channelNum-BG_24G_BAND_MIN_CHANNEL);
961 	}
962 	else
963 	{
964 		pSupportedChannels = pRegulatoryDomain->supportedChannels_band_5;
965 		channelIndex = (channelNum - A_5G_BAND_MIN_CHANNEL);
966 	}
967 
968 	if(channelValidity == TI_TRUE)
969 		if((pSupportedChannels[channelIndex].bChanneInCountryIe == TI_FALSE) && (pRegulatoryDomain->regulatoryDomainEnabled == TI_TRUE))
970 		{
971 TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_WARNING, "regulatoryDomain_setChannelValidity: channelNum = %d isn't supported at the Country. wll not set to active!\n", channelNum);
972 			return;
973 		}
974 
975     TRACE2(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "regulatoryDomain_setChannelValidity: channelNum=%d, validity=%d \n", channelNum, channelValidity);
976 
977 
978 	pSupportedChannels[channelIndex].channelValidityActive = channelValidity;
979 }
980 
981 
982 /************************************************************************
983  *      setSupportedChannelsAccording2ScanControlTable 					*
984  ************************************************************************/
985 /**
986 *
987 *
988 * \b Description:
989 *
990 * This function is called in config and sets the supported channels according to
991 * the scan control table read from registry and reg domain read from the chip.
992 *
993 * \b ARGS:
994 *
995 *  I   - pRegulatoryDomain - pointer to the regDoamin SM context  \n
996 *
997 * \b RETURNS:
998 *
999 *  None.
1000 *
1001 *
1002 *************************************************************************/
setSupportedChannelsAccording2ScanControlTable(regulatoryDomain_t * pRegulatoryDomain)1003 static void setSupportedChannelsAccording2ScanControlTable(regulatoryDomain_t  *pRegulatoryDomain)
1004 {
1005 	TI_UINT8 	channelIndex;
1006 	TI_UINT8	channelMask;
1007 
1008 	if (pRegulatoryDomain==NULL)
1009 	{
1010 		return;
1011 	}
1012 
1013     TRACE0(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "setSupportedChannelsAccording2ScanControlTable \n");
1014 
1015 	for (channelIndex=0; channelIndex<NUM_OF_CHANNELS_24; channelIndex++)
1016 	{
1017 		channelMask = pRegulatoryDomain->scanControlTable.ScanControlTable24.tableString[channelIndex];
1018 		pRegulatoryDomain->supportedChannels_band_2_4[channelIndex].bChanneInCountryIe = TI_FALSE;
1019 
1020 		/* Calculate Domain Tx Power - channelMask units are in Dbm. */
1021 		pRegulatoryDomain->supportedChannels_band_2_4[channelIndex].uMaxTxPowerDomain =
1022 						DBM2DBMDIV10(channelMask & MASK_TX_POWER);
1023 		if (channelMask & (MASK_ACTIVE_ALLOWED | MASK_FREQ_ALLOWED))
1024 		{	/* The channel is allowed for Active & Passive scans */
1025 			if (pRegulatoryDomain->regulatoryDomainEnabled)
1026 			{	/* All channels should be invalid for Active scan */
1027 				pRegulatoryDomain->supportedChannels_band_2_4[channelIndex].channelValidityActive = TI_FALSE;
1028                 TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "channelIndex=%d is invalid for Active \n", channelIndex+1);
1029 			}
1030 			else
1031 			{
1032 				pRegulatoryDomain->supportedChannels_band_2_4[channelIndex].channelValidityActive = TI_TRUE;
1033                 TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "channelIndex=%d is Active valid \n", channelIndex+1);
1034 			}
1035 
1036 		}
1037 
1038 		if (channelMask & MASK_FREQ_ALLOWED)
1039 		{	/* The channel is allowed for Passive scan */
1040 			pRegulatoryDomain->supportedChannels_band_2_4[channelIndex].channelValidityPassive = TI_TRUE;
1041             TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "channelIndex=%d is Passive valid \n", channelIndex+1);
1042 		}
1043 		else
1044 		{	/* The channel is not allowed */
1045 			pRegulatoryDomain->supportedChannels_band_2_4[channelIndex].channelValidityPassive = TI_FALSE;
1046 			pRegulatoryDomain->supportedChannels_band_2_4[channelIndex].channelValidityActive = TI_FALSE;
1047 		}
1048 	}
1049 
1050 	for (channelIndex=A_5G_BAND_MIN_CHANNEL; channelIndex<A_5G_BAND_MAX_CHANNEL; channelIndex++)
1051 	{
1052 		TI_UINT8	channelIndexInBand5;
1053 
1054 		channelIndexInBand5 = (channelIndex-A_5G_BAND_MIN_CHANNEL);
1055 		channelMask = pRegulatoryDomain->scanControlTable.ScanControlTable5.tableString[channelIndexInBand5];
1056         TRACE3(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "channelIndex=%d, channelIndexInBand5=%d channelMask=%d\n", channelIndex, channelIndexInBand5, channelMask);
1057 
1058 		/* Calculate Domain Tx Power - channelMask units are in Dbm. */
1059 		pRegulatoryDomain->supportedChannels_band_5[channelIndexInBand5].uMaxTxPowerDomain =
1060 			DBM2DBMDIV10(channelMask & MASK_TX_POWER);
1061 
1062 		pRegulatoryDomain->supportedChannels_band_5[channelIndexInBand5].bChanneInCountryIe = TI_FALSE;
1063 		if (channelMask & (MASK_ACTIVE_ALLOWED | MASK_FREQ_ALLOWED))
1064 		{	 /* The channel is allowed for Active & Passive scans */
1065 			if (pRegulatoryDomain->regulatoryDomainEnabled)
1066 			{	/* All channels should be invalid for Active scan */
1067 				pRegulatoryDomain->supportedChannels_band_5[channelIndexInBand5].channelValidityActive = TI_FALSE;
1068                 TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "channelIndex=%d is invalid for Active \n", channelIndex);
1069 			}
1070 			else
1071 			{
1072 				pRegulatoryDomain->supportedChannels_band_5[channelIndexInBand5].channelValidityActive = TI_TRUE;
1073                 TRACE2(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "channelIndex=%d, channelIndexInBand5=%d, is Active valid \n", channelIndex, channelIndexInBand5);
1074 			}
1075 		}
1076 
1077 		if (channelMask & MASK_FREQ_ALLOWED)
1078 		{	/* The channel is allowed for Passive scan */
1079 			pRegulatoryDomain->supportedChannels_band_5[channelIndexInBand5].channelValidityPassive = TI_TRUE;
1080             TRACE2(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "channelIndex=%d, channelIndexInBand5=%d, is Passive valid \n", channelIndex, channelIndexInBand5);
1081 		}
1082 		else
1083 		{	/* The channel is not allowed */
1084 			pRegulatoryDomain->supportedChannels_band_5[channelIndexInBand5].channelValidityPassive = TI_FALSE;
1085 			pRegulatoryDomain->supportedChannels_band_5[channelIndexInBand5].channelValidityActive = TI_FALSE;
1086 		}
1087 
1088 	}
1089 }
1090 
1091 
1092 /***********************************************************************
1093 *                        regulatoryDomain_getChannelCapability
1094 ***********************************************************************
1095 DESCRIPTION:	This function returns the channel capability information
1096 
1097 INPUT:      pRegulatoryDomain		-	RegulatoryDomain pointer.
1098 			channelCapabilityReq	-	Channels parameters
1099 
1100 
1101 OUTPUT:		channelCapabilityRet	-   Channel capability information
1102 
1103 RETURN:     TI_OK if information was retrieved, TI_NOK otherwise.
1104 
1105 ************************************************************************/
regulatoryDomain_getChannelCapability(regulatoryDomain_t * pRegulatoryDomain,channelCapabilityReq_t channelCapabilityReq,channelCapabilityRet_t * channelCapabilityRet)1106 static TI_STATUS regulatoryDomain_getChannelCapability(regulatoryDomain_t *pRegulatoryDomain,
1107 													   channelCapabilityReq_t channelCapabilityReq,
1108 													   channelCapabilityRet_t *channelCapabilityRet)
1109 {
1110 	channelCapability_t		*pSupportedChannels;
1111 	TI_UINT8				channelIndex;
1112 	TI_BOOL					bCountryWasFound, bServingChannel;
1113 	paramInfo_t				*pParam;
1114 
1115 	if ((pRegulatoryDomain == NULL) || (channelCapabilityRet == NULL))
1116 	{
1117 		return TI_NOK;
1118 	}
1119 
1120 	channelCapabilityRet->channelValidity = TI_FALSE;
1121 	channelCapabilityRet->maxTxPowerDbm = 0;
1122 	if ((channelCapabilityReq.channelNum==0 ) || (channelCapabilityReq.channelNum > A_5G_BAND_MAX_CHANNEL))
1123 	{
1124         TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_ERROR, "regulatoryDomain_getChannelCapability, invalid channelNum=%d \n", channelCapabilityReq.channelNum);
1125 		return TI_NOK;
1126 	}
1127 
1128 	if (channelCapabilityReq.band==RADIO_BAND_2_4_GHZ)
1129 	{
1130 		pSupportedChannels = pRegulatoryDomain->supportedChannels_band_2_4;
1131 		channelIndex = (channelCapabilityReq.channelNum-BG_24G_BAND_MIN_CHANNEL);
1132 		if (channelIndex >= NUM_OF_CHANNELS_24)
1133 		{
1134 			TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_ERROR,
1135 				   "regulatoryDomain_getChannelCapability(): 2.4G invalid channel # %u\n", channelCapabilityReq.channelNum );
1136 			return TI_NOK;
1137 		}
1138 		bCountryWasFound = pRegulatoryDomain->country_2_4_WasFound;
1139 	}
1140 	else if (channelCapabilityReq.band==RADIO_BAND_5_0_GHZ)
1141 	{
1142 		pSupportedChannels = pRegulatoryDomain->supportedChannels_band_5;
1143 		channelIndex = (channelCapabilityReq.channelNum - A_5G_BAND_MIN_CHANNEL);
1144 		if (channelIndex >= A_5G_BAND_NUM_CHANNELS)
1145 		{
1146 			TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_ERROR,
1147 				   "regulatoryDomain_getChannelCapability(): 5G invalid channel # %u\n", channelCapabilityReq.channelNum);
1148 			return TI_NOK;
1149 		}
1150 		bCountryWasFound = pRegulatoryDomain->country_5_WasFound;
1151 	}
1152 	else
1153 	{
1154 		TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_ERROR, "regulatoryDomain_getChannelCapability, invalid band=%d \n", channelCapabilityReq.band);
1155 		return TI_NOK;
1156 	}
1157 
1158 
1159 	/*
1160 	 * Set channelValidity according to ScanTable and whether 11d is enabled
1161 	 */
1162 	if (channelCapabilityReq.scanOption == ACTIVE_SCANNING)
1163 	{
1164 		if ( ( pRegulatoryDomain->regulatoryDomainEnabled ) && ( !bCountryWasFound ) )
1165 		{	/* 11d enabled and no country IE was found - set channel to invalid */
1166 			channelCapabilityRet->channelValidity = TI_FALSE;
1167 		}
1168 		else
1169 		{
1170 
1171             pParam = (paramInfo_t *)os_memoryAlloc(pRegulatoryDomain->hOs, sizeof(paramInfo_t));
1172             if (!pParam)
1173                 return TI_NOK;
1174 
1175             channelCapabilityRet->channelValidity = pSupportedChannels[channelIndex].channelValidityActive;
1176 			/*
1177 			 * Set Maximum Tx power for the channel - only for active scanning
1178 			 */
1179 
1180 			/* Get current channel and check if we are using the same one */
1181 			pParam->paramType = SITE_MGR_CURRENT_CHANNEL_PARAM;
1182 			siteMgr_getParam(pRegulatoryDomain->hSiteMgr, pParam);
1183 
1184 			bServingChannel = ( pParam->content.siteMgrCurrentChannel == channelCapabilityReq.channelNum ?
1185 								TI_TRUE : TI_FALSE );
1186 
1187 			channelCapabilityRet->maxTxPowerDbm = regulatoryDomain_getMaxPowerAllowed(pRegulatoryDomain,
1188 				channelCapabilityReq.channelNum,
1189 				channelCapabilityReq.band,
1190 				bServingChannel);
1191             os_memoryFree(pRegulatoryDomain->hOs, pParam, sizeof(paramInfo_t));
1192 		}
1193 	}
1194 	else	/* Passive scanning */
1195 	{
1196 		if ( ( pRegulatoryDomain->regulatoryDomainEnabled ) && ( !bCountryWasFound ) )
1197 		{	/* 11d enabled and no country IE was found - set channel to valid for passive scan */
1198 			channelCapabilityRet->channelValidity = TI_TRUE;
1199 		}
1200 	else
1201 	{
1202 		channelCapabilityRet->channelValidity = pSupportedChannels[channelIndex].channelValidityPassive;
1203 	}
1204 	}
1205 
1206 	if (pRegulatoryDomain->spectrumManagementEnabled
1207 		&& (channelCapabilityReq.scanOption == ACTIVE_SCANNING)
1208         && (channelCapabilityReq.channelNum >= pRegulatoryDomain->minDFS_channelNum)
1209         && (channelCapabilityReq.channelNum <= pRegulatoryDomain->maxDFS_channelNum)
1210 		&& ((os_timeStampMs(pRegulatoryDomain->hOs)-pSupportedChannels[channelIndex].timestamp) >=CHANNEL_VALIDITY_TS_THRESHOLD ))
1211 	{	/* If 802.11h is enabled, a DFS channel is valid only for 10 sec
1212 			from the last Beacon/ProbeResponse */
1213         pSupportedChannels[channelIndex].channelValidityActive = TI_FALSE;
1214         channelCapabilityRet->channelValidity = TI_FALSE;
1215         TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "regulatoryDomain_getChannelCapability(): CHANNEL_VALIDITY_TS_THRESHOLD !!! Disable channel no %d, DFS channel\n", channelCapabilityReq.channelNum  );
1216     }
1217 
1218     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);
1219 	return TI_OK;
1220 
1221 }
1222 
1223 
regulatoryDomain_updateChannelsTs(regulatoryDomain_t * pRegulatoryDomain,TI_UINT8 channel)1224 static void regulatoryDomain_updateChannelsTs(regulatoryDomain_t *pRegulatoryDomain, TI_UINT8 channel)
1225 {
1226 	TI_UINT8				channelIndex;
1227 	channelCapability_t *pSupportedChannels;
1228 
1229 	if (pRegulatoryDomain==NULL)
1230 	{
1231 		return;
1232 	}
1233 
1234 	if ((channel<BG_24G_BAND_MIN_CHANNEL) || (channel>A_5G_BAND_MAX_CHANNEL))
1235 	{
1236 		return;
1237 	}
1238 
1239 	if (channel>=A_5G_BAND_MIN_CHANNEL)
1240 	{
1241 		channelIndex = (channel-A_5G_BAND_MIN_CHANNEL);
1242 		pSupportedChannels = pRegulatoryDomain->supportedChannels_band_5;
1243 	}
1244 	else
1245 	{
1246 		channelIndex = (channel-BG_24G_BAND_MIN_CHANNEL);
1247 		if (channelIndex >= NUM_OF_CHANNELS_24)
1248 		{
1249 			TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_ERROR,
1250 				   "regulatoryDomain_updateChannelsTs(): 2.4G invalid channel # %u\n", channel );
1251 			return;
1252 		}
1253 		pSupportedChannels = pRegulatoryDomain->supportedChannels_band_2_4;
1254 	}
1255 
1256 	if((pSupportedChannels[channelIndex].bChanneInCountryIe == TI_FALSE) && (pRegulatoryDomain->regulatoryDomainEnabled == TI_TRUE))
1257   	{
1258 		TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_WARNING, "regulatoryDomain_updateChannelsTs: channelNum = %d isn't supported at the Country. wll not set to active!\n", channel);
1259   		return;
1260   	}
1261 
1262 	pSupportedChannels[channelIndex].timestamp = os_timeStampMs(pRegulatoryDomain->hOs);
1263 	pSupportedChannels[channelIndex].channelValidityActive = TI_TRUE;
1264 
1265 }
1266 
1267 /***********************************************************************
1268  *              regulatoryDomain_updateCurrTxPower
1269  ***********************************************************************
1270 DESCRIPTION: Called when new Tx power should be calculated and configured.
1271 			 Check if we are already joined to BSS/IBSS, calculate
1272 			 new Tx power and configure it to TWD.
1273 
1274 INPUT:		pRegulatoryDomain	- regulatoryDomain pointer.
1275 
1276 RETURN:     TI_OK - New value was configured to TWD, TI_NOK - Can't configure value
1277 			TX_POWER_SET_SAME_VALUE - Same value was already configured.
1278 
1279 ************************************************************************/
regulatoryDomain_updateCurrTxPower(regulatoryDomain_t * pRegulatoryDomain)1280 static TI_STATUS regulatoryDomain_updateCurrTxPower(regulatoryDomain_t	*pRegulatoryDomain)
1281 {
1282 	paramInfo_t			*pParam;
1283 	TI_STATUS			eStatus;
1284 	TTwdParamInfo		ttparam;
1285 	TI_UINT8    		uCurrChannel, uNewTxPower;
1286 
1287     pParam = (paramInfo_t *)os_memoryAlloc(pRegulatoryDomain->hOs, sizeof(paramInfo_t));
1288     if (!pParam)
1289         return TI_NOK;
1290 
1291 	/* Get the current channel, and update TWD with the changed */
1292 	pParam->paramType = SITE_MGR_CURRENT_CHANNEL_PARAM;
1293 	eStatus = siteMgr_getParam(pRegulatoryDomain->hSiteMgr, pParam);
1294 
1295 	if ( eStatus != TI_OK )
1296 	{
1297 		/* We are not joined yet - no meaning for new Tx power */
1298         TRACE0(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "regulatoryDomain_updateCurrTxPower, No site selected yet\n");
1299         os_memoryFree(pRegulatoryDomain->hOs, pParam, sizeof(paramInfo_t));
1300 		return TI_NOK;
1301 	}
1302 	/* Save current channel */
1303 	uCurrChannel = pParam->content.siteMgrCurrentChannel;
1304 
1305 	/* Get the current channel, and update TWD with the changed */
1306 	pParam->paramType = 	SITE_MGR_RADIO_BAND_PARAM;
1307 	siteMgr_getParam(pRegulatoryDomain->hSiteMgr, pParam);
1308 
1309 	/* Calculate maximum Tx power for the serving channel */
1310 	uNewTxPower = regulatoryDomain_getMaxPowerAllowed(pRegulatoryDomain, uCurrChannel,
1311 													  pParam->content.siteMgrRadioBand, TI_TRUE);
1312     os_memoryFree(pRegulatoryDomain->hOs, pParam, sizeof(paramInfo_t));
1313 	/* Verify that the Temporary TX Power Control doesn't violate the TX Power Constraint */
1314 	pRegulatoryDomain->uTemporaryTxPower = TI_MIN(pRegulatoryDomain->uDesiredTemporaryTxPower, uNewTxPower);
1315 
1316     TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "regulatoryDomain_updateCurrTxPower, Write to TWD = %d \n", uNewTxPower);
1317 
1318     ttparam.paramType = TWD_TX_POWER_PARAM_ID;
1319 
1320     /* set TWD according to Temporary Tx Power Enable flag */
1321     if (TI_TRUE == pRegulatoryDomain->bTemporaryTxPowerEnable)
1322     {
1323         ttparam.content.halCtrlTxPowerDbm = pRegulatoryDomain->uTemporaryTxPower;
1324     }
1325     else
1326     {
1327         ttparam.content.halCtrlTxPowerDbm = uNewTxPower;
1328     }
1329     eStatus = TWD_SetParam(pRegulatoryDomain->hTWD, &ttparam);
1330 	return eStatus;
1331 }
1332 
1333 /***********************************************************************
1334  *                        regulatoryDomain_checkCountryCodeExpiry
1335  ***********************************************************************
1336 DESCRIPTION: Check & Reset the country code that was detected earlier.
1337                 Reseting country code will be done when the STA was not connected for
1338                 a certain amount of time, and no country code was received in that period (from the same country).
1339                 This scenario might indicate that the STA has moved to a different country.
1340 
1341 INPUT:      pRegulatoryDomain	-	Regulatory Domain handle.
1342 
1343 OUTPUT:		updating country code if necessary.
1344 
1345 RETURN:
1346 
1347 ************************************************************************/
regulatoryDomain_checkCountryCodeExpiry(regulatoryDomain_t * pRegulatoryDomain)1348 void regulatoryDomain_checkCountryCodeExpiry(regulatoryDomain_t *pRegulatoryDomain)
1349 {
1350     paramInfo_t *pParam;
1351     TI_STATUS   connStatus;
1352     TI_UINT32   uCurrentTS = os_timeStampMs(pRegulatoryDomain->hOs);
1353 
1354     if ((pRegulatoryDomain->country_2_4_WasFound) || (pRegulatoryDomain->country_5_WasFound))
1355     {
1356         pParam = (paramInfo_t *)os_memoryAlloc(pRegulatoryDomain->hOs, sizeof(paramInfo_t));
1357         if (!pParam)
1358             return;
1359         /* Get connection status */
1360         pParam->paramType = SITE_MGR_CURRENT_SSID_PARAM;
1361         connStatus      = siteMgr_getParam(pRegulatoryDomain->hSiteMgr, pParam);
1362 
1363          /* If (uTimeOutToResetCountryMs has elapsed && we are not connected)
1364                  delete the last country code received */
1365         if (((uCurrentTS - pRegulatoryDomain->uLastCountryReceivedTS) > pRegulatoryDomain->uTimeOutToResetCountryMs) &&
1366             (connStatus == NO_SITE_SELECTED_YET))
1367         {
1368             TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, ", Reset country code after %d Ms\n",(uCurrentTS - pRegulatoryDomain->uLastCountryReceivedTS));
1369 
1370             /* Reset country codes */
1371             pRegulatoryDomain->country_2_4_WasFound = TI_FALSE;
1372             pRegulatoryDomain->country_5_WasFound = TI_FALSE;
1373 
1374             /* Restore default values of the scan control table */
1375             setSupportedChannelsAccording2ScanControlTable(pRegulatoryDomain);
1376         }
1377         os_memoryFree(pRegulatoryDomain->hOs, pParam, sizeof(paramInfo_t));
1378     }
1379 }
1380 
1381 /***********************************************************************
1382 *              regulatoryDomain_getMaxPowerAllowed
1383 ***********************************************************************
1384 DESCRIPTION: Get the maximum tx power allowed for the given channel.
1385 				The final value is constructed by:
1386 				1) User max value
1387 				2) Domain restriction - 11d country code IE
1388 				3) 11h power constraint - only on serving channel
1389 				4) XCC TPC - only on serving channel
1390 
1391 RETURN:     Max power in Dbm/10 for the given channel
1392 
1393 ************************************************************************/
regulatoryDomain_getMaxPowerAllowed(regulatoryDomain_t * pRegulatoryDomain,TI_UINT8 uChannel,ERadioBand eBand,TI_BOOL bServingChannel)1394 static TI_UINT8 regulatoryDomain_getMaxPowerAllowed(regulatoryDomain_t	*pRegulatoryDomain,
1395 												 TI_UINT8				uChannel,
1396 												 ERadioBand		eBand,
1397 												 TI_BOOL				bServingChannel)
1398 {
1399 	channelCapability_t	*pSupportedChannels;
1400 	TI_UINT8				 uChannelIndex, uTxPower;
1401 
1402 	if( eBand == RADIO_BAND_2_4_GHZ)
1403 	{
1404 		pSupportedChannels = pRegulatoryDomain->supportedChannels_band_2_4;
1405 		uChannelIndex = uChannel - BG_24G_BAND_MIN_CHANNEL;
1406 	}
1407 	else
1408 	{
1409 		pSupportedChannels = pRegulatoryDomain->supportedChannels_band_5;
1410 		uChannelIndex = uChannel - A_5G_BAND_MIN_CHANNEL;
1411 	}
1412 
1413 	/* We'll start with the "Domain restriction - 11d country code IE" */
1414 	uTxPower = pSupportedChannels[uChannelIndex].uMaxTxPowerDomain;
1415 
1416 	if ( bServingChannel)
1417 	{
1418 		if (pRegulatoryDomain->uPowerConstraint < uTxPower)
1419 		{
1420 			/* When 802.11h is disabled, uPowerConstraint is 0 anyway */
1421 			uTxPower -= pRegulatoryDomain->uPowerConstraint;
1422 		}
1423 
1424         /* Take XCC limitation too */
1425         uTxPower = TI_MIN(uTxPower, pRegulatoryDomain->uExternTxPowerPreferred);
1426 
1427 	}
1428 
1429 	/* Now make sure we are not exceeding the user maximum */
1430 	uTxPower = TI_MIN(uTxPower, pRegulatoryDomain->uUserMaxTxPower);
1431 
1432 TRACE3(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, " uChannel = %d bServingChannel = %d uTxPower = %d \n", uChannel, bServingChannel, uTxPower);
1433 
1434 	return uTxPower;
1435 }
1436 
1437 
regulatoryDomain_buildDefaultListOfChannelsPerBand(regulatoryDomain_t * pRegulatoryDomain,ERadioBand band,TI_UINT8 * listSize)1438 static void regulatoryDomain_buildDefaultListOfChannelsPerBand(regulatoryDomain_t *pRegulatoryDomain, ERadioBand band, TI_UINT8 *listSize)
1439 {
1440 	TI_UINT8				channelIndex;
1441 	TI_UINT8				numberOfChannels, minChannelNumber;
1442 	channelCapability_t	*pSupportedChannels;
1443 	TI_UINT8				maxSupportedChannels=0;
1444 
1445 	if ( (pRegulatoryDomain==NULL) || (listSize==NULL))
1446 	{
1447 		return;
1448 	}
1449 
1450 	if( band == RADIO_BAND_2_4_GHZ)
1451 	{
1452 		minChannelNumber = BG_24G_BAND_MIN_CHANNEL;
1453 		numberOfChannels = NUM_OF_CHANNELS_24;
1454 		pSupportedChannels = pRegulatoryDomain->supportedChannels_band_2_4;
1455 	}
1456 	else
1457 	{
1458 		minChannelNumber = A_5G_BAND_MIN_CHANNEL;
1459 		numberOfChannels = A_5G_BAND_NUM_CHANNELS;
1460 		pSupportedChannels = pRegulatoryDomain->supportedChannels_band_5;
1461 	}
1462 
1463 
1464 	for (channelIndex=0; channelIndex<numberOfChannels; channelIndex++)
1465 	{
1466 		if (pSupportedChannels[channelIndex].channelValidityPassive)
1467 		{
1468 			pRegulatoryDomain->pDefaultChannels[maxSupportedChannels] = channelIndex+minChannelNumber;
1469 TRACE1(pRegulatoryDomain->hReport, REPORT_SEVERITY_INFORMATION, "Channel num %d is supported \n", pRegulatoryDomain->pDefaultChannels[maxSupportedChannels]);
1470 			maxSupportedChannels++;
1471 		}
1472 	}
1473 
1474 	*listSize = maxSupportedChannels;
1475 
1476 }
1477 
1478 /***********************************************************************
1479 *              regulatoryDomain_getPowerTableMinMax
1480 ***********************************************************************
1481 DESCRIPTION: Find the Tx-power-level table min & max values.
1482 			 The table is made of 4 power levels and 5 bands/sub-bands.
1483 
1484 RETURN:     void
1485 ************************************************************************/
regulatoryDomain_getPowerTableMinMax(regulatoryDomain_t * pRegulatoryDomain,powerCapability_t * pPowerCapability)1486 static void regulatoryDomain_getPowerTableMinMax (regulatoryDomain_t *pRegulatoryDomain,
1487                                                   powerCapability_t  *pPowerCapability)
1488 {
1489     TFwInfo  *pFwInfo = TWD_GetFWInfo (pRegulatoryDomain->hTWD);
1490 	TI_UINT8	i;
1491 
1492     /* Init the min (max) to the opposite edge so the table values are below (above) this edge */
1493 	pPowerCapability->minTxPower = MAX_TX_POWER;
1494 	pPowerCapability->maxTxPower = MIN_TX_POWER;
1495 
1496 	/* Find Min and Max values of the table */
1497 	for (i = 0; i < NUMBER_OF_SUB_BANDS_E; i++)
1498 	{
1499 		pPowerCapability->minTxPower = TI_MIN (pPowerCapability->minTxPower,
1500                                                pFwInfo->txPowerTable[i][NUM_OF_POWER_LEVEL-1]);
1501 		pPowerCapability->maxTxPower = TI_MAX (pPowerCapability->maxTxPower,
1502                                                pFwInfo->txPowerTable[i][0]);
1503 	}
1504 }
1505 
1506 /* for debug */
regDomainPrintValidTables(TI_HANDLE hRegulatoryDomain)1507 void regDomainPrintValidTables(TI_HANDLE hRegulatoryDomain)
1508 {
1509 	regulatoryDomain_t  *pRegulatoryDomain = (regulatoryDomain_t *)hRegulatoryDomain;
1510 	TI_UINT16 channelIndex;
1511 
1512 	for (channelIndex=0; channelIndex<NUM_OF_CHANNELS_24; channelIndex++)
1513 	{
1514 		if (pRegulatoryDomain->supportedChannels_band_2_4[channelIndex].channelValidityPassive)
1515 			WLAN_OS_REPORT(("channel num =%d is valid for passive \n", channelIndex+1));
1516 		if (pRegulatoryDomain->supportedChannels_band_2_4[channelIndex].channelValidityActive)
1517 		{
1518 			WLAN_OS_REPORT(("channel =%d is valid for active TX power=%d\n",
1519 				channelIndex+1, pRegulatoryDomain->supportedChannels_band_2_4[channelIndex].uMaxTxPowerDomain));
1520 		}
1521 	}
1522 
1523 	for (channelIndex=0; channelIndex<A_5G_BAND_NUM_CHANNELS; channelIndex++)
1524 	{
1525 		TI_UINT8	channelNum;
1526 		channelNum = channelIndex+A_5G_BAND_MIN_CHANNEL;
1527 		if (pRegulatoryDomain->supportedChannels_band_5[channelIndex].channelValidityPassive)
1528 			WLAN_OS_REPORT(("channel =%d is valid for passive \n", channelNum));
1529 		if (pRegulatoryDomain->supportedChannels_band_5[channelIndex].channelValidityActive)
1530 		{
1531 			WLAN_OS_REPORT(("channel =%d is valid for active TX power=%d\n",
1532 				channelNum,pRegulatoryDomain->supportedChannels_band_5[channelIndex].uMaxTxPowerDomain));
1533 		}
1534 		}
1535 
1536 	WLAN_OS_REPORT(("11h PowerConstraint = %d, XCC TPC = %d, User  = %d\n",
1537 		pRegulatoryDomain->uPowerConstraint, pRegulatoryDomain->uExternTxPowerPreferred,
1538 		pRegulatoryDomain->uUserMaxTxPower));
1539 
1540 }
1541