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