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