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