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