Home | History | Annotate | Download | only in SwitchChannel
      1 /** \file SwitchChannel.c
      2  *  \brief SwitchChannel module interface
      3  *
      4  *  \see SwitchChannelApi.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:		SwitchChannel.c																			*/
     44 /*		PURPOSE:	SwitchChannel module interface.															*/
     45 /*                  This module perform SwitchChannel (Dynamic Frequency Selection)							*/
     46 /*						according to AP command. The object responsibles for switching channel after*/
     47 /*						the requires time and quieting the channel for the required duration		*/
     48 /*						time.														 				*/
     49 /****************************************************************************************************/
     50 #include "report.h"
     51 #include "osApi.h"
     52 #include "paramOut.h"
     53 #include "paramIn.h"
     54 #include "utils.h"
     55 #include "SwitchChannelApi.h"
     56 #include "DataCtrl_Api.h"
     57 #include "regulatoryDomainApi.h"
     58 #include "apConn.h"
     59 #include "siteMgrApi.h"
     60 #include "PowerMgr_API.h"
     61 #include "whalCtrl_api.h"
     62 #include "healthMonitor.h"
     63 #include "fsm.h"
     64 
     65 /* allocation vector */
     66 #define SC_INIT_BIT						(1)
     67 #define SC_SM_INIT_BIT					(2)
     68 
     69 #define SC_SWITCH_CHANNEL_CMD_LEN				3
     70 #define SC_SWITCH_CHANNEL_MODE_NOT_TX_SUS		0
     71 #define SC_SWITCH_CHANNEL_MODE_TX_SUS			1
     72 
     73 
     74 #define SC_CHANNEL_INVALID			FALSE
     75 #define SC_CHANNEL_VALID			TRUE
     76 
     77 /* Enumerations */
     78 
     79 /** state machine states */
     80 typedef enum
     81 {
     82 	SC_STATE_IDLE           = 0,
     83 	SC_STATE_WAIT_4_CMD     = 1,
     84 	SC_STATE_WAIT_4_SCR     = 2,
     85 	SC_STATE_SC_IN_PROG     = 3,
     86 	SC_STATE_LAST           = 4
     87 } switchChannel_smStates;
     88 
     89 /** State machine events */
     90 typedef enum
     91 {
     92 	SC_EVENT_START          = 0,
     93 	SC_EVENT_STOP           = 1,
     94 	SC_EVENT_SC_CMD         = 2,
     95 	SC_EVENT_SCR_RUN        = 3,
     96 	SC_EVENT_SCR_FAIL       = 4,
     97 	SC_EVENT_SC_CMPLT       = 5,
     98 	SC_EVENT_FW_RESET       = 6,
     99 	SC_EVENT_LAST           = 7
    100 } switchChannel_smEvents;
    101 
    102 
    103 #define SC_NUM_STATES	   	SC_STATE_LAST
    104 #define SC_NUM_EVENTS		SC_EVENT_LAST
    105 
    106 
    107 /* Structures */
    108 typedef struct
    109 {
    110 
    111 	/* SwitchChannel parameters that can be configured externally */
    112 	BOOL            dot11SpectrumManagementRequired;
    113 
    114 	/* Internal SwitchChannel parameters */
    115 	switchChannel_smStates  currentState;
    116 	dot11_CHANNEL_SWITCH_t  curChannelSwitchCmdParams;
    117 	UINT32					SCRRequestTimestamp;
    118 	UINT8					currentChannel;
    119 	BOOL					switchChannelStarted;
    120 
    121 #ifdef TI_DBG
    122 	/* switchChannelCmd for debug */
    123 	dot11_CHANNEL_SWITCH_t  debugChannelSwitchCmdParams;
    124 	UINT8					ignoreCancelSwitchChannelCmd;
    125 #endif
    126 
    127 	/* SwitchChannel SM */
    128 	fsm_stateMachine_t          *pSwitchChannelSm;
    129 
    130 	/* SwitchChannel handles to other objects */
    131 	TI_HANDLE       hHalCtrl;
    132 	TI_HANDLE       hSiteMgr;
    133 	TI_HANDLE		hSCR;
    134 	TI_HANDLE 		hRegulatoryDomain;
    135 	TI_HANDLE		hPowerMngr;
    136 	TI_HANDLE		hApConn;
    137 	TI_HANDLE       hReport;
    138 	TI_HANDLE       hOs;
    139     TI_HANDLE       hHealthMonitor;
    140 
    141 } switchChannel_t;
    142 
    143 
    144 
    145 
    146 /* External data definitions */
    147 
    148 /* Local functions definitions */
    149 
    150 /* Global variables */
    151 
    152 #ifdef REPORT_LOG
    153 
    154 static char *switchChannel_stateDesc[SC_NUM_STATES] = {
    155 	"STATE_IDLE",
    156 	"STATE_WAIT_4_CMD",
    157 	"STATE_WAIT_4_SCR",
    158 	"STATE_SC_IN_PROG"
    159 };
    160 
    161 static char *switchChannel_eventDesc[SC_NUM_EVENTS] = {
    162 	"EVENT_START",
    163 	"EVENT_STOP",
    164 	"EVENT_SC_CMD",
    165 	"EVENT_SCR_RUN",
    166 	"EVENT_SCR_FAIL",
    167 	"EVENT_SC_CMPLT",
    168     "EVENT_FW_RESET"
    169 };
    170 
    171 #endif
    172 
    173 
    174 /********************************************************************************/
    175 /*						Internal functions prototypes.							*/
    176 /********************************************************************************/
    177 
    178 
    179 /* SM functions */
    180 static TI_STATUS switchChannel_smStartSwitchChannelCmd(void *pData);
    181 static TI_STATUS switchChannel_smReqSCR_UpdateCmd(void *pData);
    182 static TI_STATUS switchChannel_smSwitchChannelCmplt(void *pData);
    183 static TI_STATUS switchChannel_smFwResetWhileSCInProg(void *pData);
    184 static TI_STATUS switchChannel_smScrFailWhileWait4Scr(void *pData);
    185 static TI_STATUS switchChannel_smNop(void *pData);
    186 static TI_STATUS switchChannel_smUnexpected(void *pData);
    187 static TI_STATUS switchChannel_smStopWhileWait4Cmd(void *pData);
    188 static TI_STATUS switchChannel_smStopWhileWait4Scr(void *pData);
    189 static TI_STATUS switchChannel_smStopWhileSwitchChannelInProg(void *pData);
    190 static TI_STATUS switchChannel_smStart(void *pData);
    191 
    192 
    193 /* other functions */
    194 static void release_module(switchChannel_t *pSwitchChannel, UINT32 initVec);
    195 static TI_STATUS switchChannel_smEvent(UINT8 *currState, UINT8 event, void* data);
    196 static void switchChannel_zeroDatabase(switchChannel_t *pSwitchChannel);
    197 void switchChannel_SwitchChannelCmdCompleteReturn(TI_HANDLE hSwitchChannel);
    198 void switchChannel_scrStatusCB(TI_HANDLE hSwitchChannel, scr_clientRequestStatus_e requestStatus,
    199 						  scr_pendReason_e pendReason );
    200 #ifdef TI_DBG
    201 static void switchChannel_recvCmd4Debug(TI_HANDLE hSwitchChannel, dot11_CHANNEL_SWITCH_t *channelSwitch, BOOL BeaconPacket, UINT8 channel);
    202 #endif
    203 
    204 
    205 /********************************************************************************/
    206 /*						Interface functions Implementation.						*/
    207 /********************************************************************************/
    208 
    209 
    210 /************************************************************************
    211  *                        switchChannel_create							*
    212  ************************************************************************/
    213 /**
    214 *
    215 * \b Description:
    216 *
    217 * This procedure is called by the config manager when the driver is created.
    218 * It creates the SwitchChannel object.
    219 *
    220 * \b ARGS:
    221 *
    222 *  I - hOs - OS context \n
    223 *
    224 * \b RETURNS:
    225 *
    226 *  Handle to the SwitchChannel object.
    227 *
    228 * \sa
    229 */
    230 TI_HANDLE switchChannel_create(TI_HANDLE hOs)
    231 {
    232 	switchChannel_t           *pSwitchChannel = NULL;
    233 	UINT32          initVec = 0;
    234 	TI_STATUS		status;
    235 
    236 	/* allocating the SwitchChannel object */
    237 	pSwitchChannel = os_memoryAlloc(hOs,sizeof(switchChannel_t));
    238 
    239 	if (pSwitchChannel == NULL)
    240 		return NULL;
    241 
    242 	initVec |= (1 << SC_INIT_BIT);
    243 
    244 	os_memoryZero(hOs, pSwitchChannel, sizeof(switchChannel_t));
    245 
    246 	pSwitchChannel->hOs = hOs;
    247 
    248 	status = fsm_Create(hOs, &pSwitchChannel->pSwitchChannelSm, SC_NUM_STATES, SC_NUM_EVENTS);
    249 	if (status != OK)
    250 	{
    251 		release_module(pSwitchChannel, initVec);
    252 	    WLAN_OS_REPORT(("FATAL ERROR: switchChannel_create(): Error Creating pSwitchChannelSm - Aborting\n"));
    253 		return NULL;
    254 	}
    255 	initVec |= (1 << SC_SM_INIT_BIT);
    256 
    257 	return(pSwitchChannel);
    258 }
    259 
    260 /************************************************************************
    261  *                        switchChannel_config							*
    262  ************************************************************************/
    263 /**
    264 *
    265 * \b Description:
    266 *
    267 * This procedure is called by the config manager when the driver is configured.
    268 * It initializes the SwitchChannel object's variables and handlers and creates the SwitchChannel SM.
    269 *
    270 * \b ARGS:
    271 *
    272 *  I - hSwitchChannel - SwitchChannel context \n
    273 *
    274 * \b RETURNS:
    275 *
    276 *  OK on success, NOK otherwise
    277 *
    278 * \sa
    279 */
    280 TI_STATUS switchChannel_config(TI_HANDLE          			hSwitchChannel,
    281 							  TI_HANDLE          			hHalCtrl,
    282 							  TI_HANDLE          			hSiteMgr,
    283 							  TI_HANDLE          			hSCR,
    284 							  TI_HANDLE 					hRegulatoryDomain,
    285 							  TI_HANDLE						hApConn,
    286 							  TI_HANDLE          			hReport,
    287 							  TI_HANDLE          			hOs,
    288                               TI_HANDLE                     hHealthMonitor,
    289 							  SwitchChannelInitParams_t    *SwitchChannelInitParams)
    290 {
    291 	switchChannel_t       *pSwitchChannel = (switchChannel_t *)hSwitchChannel;
    292 	TI_STATUS   status;
    293 
    294 
    295 	/** Roaming State Machine matrix */
    296 	fsm_actionCell_t    switchChannel_SM[SC_NUM_STATES][SC_NUM_EVENTS] =
    297 	{
    298 		/* next state and actions for IDLE state */
    299 		{   {SC_STATE_WAIT_4_CMD, switchChannel_smStart},				/* START        */
    300 			{SC_STATE_IDLE, switchChannel_smNop},						/* STOP         */
    301 			{SC_STATE_IDLE, switchChannel_smNop},						/* SC_CMD      */
    302 			{SC_STATE_IDLE, switchChannel_smUnexpected},				/* SCR_RUN     	*/
    303 			{SC_STATE_IDLE, switchChannel_smUnexpected},				/* SCR_FAIL   	*/
    304 			{SC_STATE_IDLE, switchChannel_smUnexpected},				/* SC_CMPLT    */
    305 			{SC_STATE_IDLE, switchChannel_smUnexpected}					/* FW_RESET	    */
    306 		},
    307 
    308 		/* next state and actions for WAIT_4_CMD state */
    309 		{   {SC_STATE_WAIT_4_CMD, switchChannel_smNop},						/* START        */
    310 			{SC_STATE_IDLE, switchChannel_smStopWhileWait4Cmd},			    /* STOP         */
    311 			{SC_STATE_WAIT_4_SCR, switchChannel_smReqSCR_UpdateCmd},		/* SC_CMD      */
    312 			{SC_STATE_WAIT_4_CMD, switchChannel_smUnexpected},				/* SCR_RUN     	*/
    313 			{SC_STATE_WAIT_4_CMD, switchChannel_smUnexpected},			    /* SCR_FAIL   	*/
    314 			{SC_STATE_WAIT_4_CMD, switchChannel_smUnexpected},				/* SC_CMPLT    */
    315 			{SC_STATE_WAIT_4_CMD, switchChannel_smUnexpected}	            /* FW_RESET    */
    316 
    317 		},
    318 
    319 		/* next state and actions for WAIT_4_SCR state */
    320 		{   {SC_STATE_WAIT_4_SCR, switchChannel_smUnexpected},				    /* START        */
    321 			{SC_STATE_IDLE, switchChannel_smStopWhileWait4Scr},					/* STOP         */
    322 			{SC_STATE_WAIT_4_SCR, switchChannel_smNop},					        /* SC_CMD      */
    323 			{SC_STATE_SC_IN_PROG, switchChannel_smStartSwitchChannelCmd},	    /* SCR_RUN      */
    324 			{SC_STATE_WAIT_4_CMD, switchChannel_smScrFailWhileWait4Scr},	    /* SCR_FAIL    */
    325 			{SC_STATE_WAIT_4_SCR, switchChannel_smUnexpected} ,					/* SC_CMPLT    */
    326 			{SC_STATE_WAIT_4_CMD, switchChannel_smUnexpected}		            /* FW_RESET    */
    327 
    328 		},
    329 
    330 		/* next state and actions for switchChannel_IN_PROG state */
    331 		{   {SC_STATE_SC_IN_PROG, switchChannel_smUnexpected},					 /* START        */
    332 			{SC_STATE_IDLE, switchChannel_smStopWhileSwitchChannelInProg},		 /* STOP         */
    333 			{SC_STATE_SC_IN_PROG, switchChannel_smNop},				             /* SC_CMD      */
    334 			{SC_STATE_SC_IN_PROG, switchChannel_smUnexpected},					 /* SCR_RUN      */
    335 			{SC_STATE_WAIT_4_CMD, switchChannel_smUnexpected},			         /* SCR_FAIL    */
    336 			{SC_STATE_WAIT_4_CMD, switchChannel_smSwitchChannelCmplt},			 /* SC_CMPLT    */
    337 			{SC_STATE_WAIT_4_CMD, switchChannel_smFwResetWhileSCInProg}	         /* FW_RESET    */
    338 
    339 		}
    340 
    341 
    342 	};
    343 
    344 	status = fsm_Config(pSwitchChannel->pSwitchChannelSm,
    345 						&switchChannel_SM[0][0],
    346 						SC_NUM_STATES,
    347 						SC_NUM_EVENTS,
    348 						switchChannel_smEvent, pSwitchChannel->hOs);
    349 	if (status != OK)
    350 	{
    351 		return status;
    352 	}
    353 
    354 
    355 	/* init handlers */
    356 	pSwitchChannel->hHalCtrl  = hHalCtrl;
    357 	pSwitchChannel->hSiteMgr  = hSiteMgr;
    358 	pSwitchChannel->hSCR    = hSCR;
    359 	pSwitchChannel->hRegulatoryDomain= hRegulatoryDomain;
    360 	pSwitchChannel->hApConn     = hApConn;
    361 	pSwitchChannel->hReport   = hReport;
    362 	pSwitchChannel->hOs       = hOs;
    363     pSwitchChannel->hHealthMonitor = hHealthMonitor;
    364 
    365 	/* init variables */
    366 	pSwitchChannel->dot11SpectrumManagementRequired = SwitchChannelInitParams->dot11SpectrumManagementRequired;
    367 	pSwitchChannel->currentState = SC_STATE_IDLE;
    368 	pSwitchChannel->currentChannel = 0;
    369 	pSwitchChannel->switchChannelStarted = FALSE;
    370 
    371 	/* register to SCR */
    372 	scr_registerClientCB(pSwitchChannel->hSCR, SCR_CID_SWITCH_CHANNEL,
    373 						 switchChannel_scrStatusCB, pSwitchChannel);
    374 
    375 	/* register to Switch Channel Complete event in HAL */
    376 	whalCtrl_EventMbox_RegisterForEvent(pSwitchChannel->hHalCtrl,
    377 										HAL_EVENT_SWITCH_CHANNEL_CMPLT,
    378 										(void *)switchChannel_SwitchChannelCmdCompleteReturn,
    379 										pSwitchChannel);
    380 
    381 	whalCtrl_EventMbox_Enable(pSwitchChannel->hHalCtrl, HAL_EVENT_SWITCH_CHANNEL_CMPLT);
    382 #ifdef TI_DBG
    383 	/* for debug */
    384 	pSwitchChannel->debugChannelSwitchCmdParams.hdr.eleId = CHANNEL_SWITCH_ANNOUNCEMENT_IE_ID;
    385 	pSwitchChannel->debugChannelSwitchCmdParams.hdr.eleLen = SC_SWITCH_CHANNEL_CMD_LEN;
    386 	pSwitchChannel->ignoreCancelSwitchChannelCmd = 0;
    387 #endif
    388 	WLAN_REPORT_INIT(hReport, SC_MODULE_LOG,
    389 					 (".....SwitchChannel configured successfully\n"));
    390 
    391 	return OK;
    392 }
    393 
    394 
    395 /************************************************************************
    396  *                        switchChannel_stop							*
    397  ************************************************************************/
    398 /**
    399 *
    400 * \b Description:
    401 *
    402 * This procedure is called by the SME when the state is changed from CONNECTED.
    403 * It generates a STOP event to the SwitchChannel SM.
    404 *
    405 * \b ARGS:
    406 *
    407 *  I - hSwitchChannel - SwitchChannel context \n
    408 *
    409 * \b RETURNS:
    410 *
    411 *  OK on success, NOK otherwise
    412 *
    413 * \sa
    414 */
    415 TI_STATUS switchChannel_stop(TI_HANDLE hSwitchChannel)
    416 {
    417 	switchChannel_t *pSwitchChannel = (switchChannel_t *)hSwitchChannel;
    418 
    419 	pSwitchChannel->switchChannelStarted = FALSE;
    420 	return (switchChannel_smEvent((UINT8*)&pSwitchChannel->currentState, SC_EVENT_STOP, pSwitchChannel));
    421 
    422 }
    423 
    424 /************************************************************************
    425  *                        switchChannel_start							*
    426  ************************************************************************/
    427 /**
    428 *
    429 * \b Description:
    430 *
    431 * This procedure is called by the SME when the state is changed to CONNECTED.
    432 * It generates a START event to the SwitchChannel SM.
    433 *
    434 * \b ARGS:
    435 *
    436 *  I - hSwitchChannel - SwitchChannel context \n
    437 *
    438 * \b RETURNS:
    439 *
    440 *  OK on success, NOK otherwise
    441 *
    442 * \sa
    443 */
    444 TI_STATUS switchChannel_start(TI_HANDLE hSwitchChannel)
    445 {
    446 	switchChannel_t *pSwitchChannel = (switchChannel_t *)hSwitchChannel;
    447 	pSwitchChannel->switchChannelStarted = TRUE;
    448 
    449 	return (switchChannel_smEvent((UINT8*)&pSwitchChannel->currentState, SC_EVENT_START, pSwitchChannel));
    450 
    451 }
    452 
    453 
    454 /************************************************************************
    455  *                        switchChannel_unload							*
    456  ************************************************************************/
    457 /**
    458 *
    459 * \b Description:
    460 *
    461 * This procedure is called by the config manager when the driver is unloaded.
    462 * It frees any memory allocated and timers.
    463 *
    464 * \b ARGS:
    465 *
    466 *  I - hSwitchChannel - SwitchChannel context \n
    467 *
    468 * \b RETURNS:
    469 *
    470 *  OK on success, NOK otherwise
    471 *
    472 * \sa
    473 */
    474 TI_STATUS switchChannel_unload(TI_HANDLE hSwitchChannel)
    475 {
    476 	UINT32              initVec;
    477 	switchChannel_t *pSwitchChannel = (switchChannel_t *)hSwitchChannel;
    478 
    479 	if (pSwitchChannel == NULL)
    480 		return OK;
    481 
    482 	initVec = 0xff;
    483 	release_module(pSwitchChannel, initVec);
    484 
    485 	return OK;
    486 }
    487 
    488 
    489 /************************************************************************
    490  *                        switchChannel_recvCmd							*
    491  ************************************************************************/
    492 /*DESCRIPTION: This function is called by MLME Parser upon receiving of
    493 				Beacon, Probe Response or Action with Switch Channel command,
    494 				or beacon/
    495 				performs the following:
    496 				-	Initializes the switching channel procedure.
    497 				-	Setting timer to the actual switching time(if needed)
    498 
    499 INPUT:      hSwitchChannel		- SwitchChannel handle.
    500 			switchMode			- indicates whether to stop transmission
    501 								    until the scheduled channel switch.
    502 			newChannelNum		- indicates the number of the new channel.
    503 			durationTime		- indicates the time (expressed in ms) until
    504 								    the scheduled channel switch should accure.
    505 
    506 OUTPUT:		None
    507 
    508 RETURN:     OK on success, NOK otherwise
    509 
    510 ************************************************************************/
    511 
    512 void switchChannel_recvCmd(TI_HANDLE hSwitchChannel, dot11_CHANNEL_SWITCH_t *channelSwitch, UINT8 channel)
    513 {
    514 
    515 	switchChannel_t             *pSwitchChannel = (switchChannel_t *)hSwitchChannel;
    516 	paramInfo_t                 param;
    517 
    518 	if (pSwitchChannel==NULL)
    519 	{
    520 		return;
    521 	}
    522 
    523     param.paramType = REGULATORY_DOMAIN_DFS_CHANNELS_RANGE;
    524     regulatoryDomain_getParam(pSwitchChannel->hRegulatoryDomain, &param);
    525 
    526 	if (!pSwitchChannel->dot11SpectrumManagementRequired ||
    527         (channel < param.content.DFS_ChannelRange.minDFS_channelNum) ||
    528         (channel > param.content.DFS_ChannelRange.maxDFS_channelNum))
    529 	{	/* Do not parse Switch Channel IE, when SpectrumManagement is disabled,
    530             or the channel is non-DFS channel */
    531 		return;
    532 	}
    533 #ifdef TI_DBG
    534     /* for debug purposes only */
    535 	if (pSwitchChannel->ignoreCancelSwitchChannelCmd != 0)
    536     {
    537         return;
    538     }
    539 #endif
    540 
    541 	if (channelSwitch == NULL)
    542 	{   /* No SC IE, update regDomain */
    543         param.paramType = REGULATORY_DOMAIN_UPDATE_CHANNEL_VALIDITY;
    544         param.content.channel = channel;
    545         regulatoryDomain_setParam(pSwitchChannel->hRegulatoryDomain, &param);
    546 	}
    547     else
    548 	{   /* SC IE exists */
    549 		WLAN_REPORT_INFORMATION(pSwitchChannel->hReport, SC_MODULE_LOG,
    550 								("switchChannel_recvFrame, SwitchChannel cmd was found, channel no=%d, mode=%d, TBTT=%d \n",
    551 								 channelSwitch->channelNumber, channelSwitch->channelSwitchMode,
    552 								 channelSwitch->channelSwitchCount));
    553 
    554 		/* Checking channel number validity */
    555         param.content.channel = channelSwitch->channelNumber;
    556         param.paramType = REGULATORY_DOMAIN_IS_CHANNEL_SUPPORTED;
    557         regulatoryDomain_getParam(pSwitchChannel->hRegulatoryDomain,&param);
    558         if ( ( !param.content.bIsChannelSupprted )   ||
    559 			(channelSwitch->channelSwitchCount == 0) ||
    560 			(channelSwitch->channelSwitchMode == SC_SWITCH_CHANNEL_MODE_TX_SUS))
    561 		{   /* Trigger Roaming, if TX mode is disabled, the new channel number is invalid,
    562                 or the TBTT count is 0 */
    563             WLAN_REPORT_INFORMATION(pSwitchChannel->hReport, SC_MODULE_LOG,
    564                                     ("report Roaming trigger\n"));
    565 			if (channelSwitch->channelSwitchMode == SC_SWITCH_CHANNEL_MODE_TX_SUS)
    566 			{
    567 				param.paramType = REGULATORY_DOMAIN_SET_CHANNEL_VALIDITY;
    568 				param.content.channelValidity.channelNum = channel;
    569 				param.content.channelValidity.channelValidity = FALSE;
    570 				regulatoryDomain_setParam(pSwitchChannel->hRegulatoryDomain, &param);
    571 			}
    572             apConn_reportRoamingEvent(pSwitchChannel->hApConn, ROAMING_TRIGGER_SWITCH_CHANNEL, NULL);
    573 		}
    574 		else
    575 		{   /* Invoke Switch Channel command */
    576             /* update the new SCC params */
    577             pSwitchChannel->curChannelSwitchCmdParams.channelNumber = channelSwitch->channelNumber;
    578             pSwitchChannel->curChannelSwitchCmdParams.channelSwitchCount = channelSwitch->channelSwitchCount;
    579             pSwitchChannel->curChannelSwitchCmdParams.channelSwitchMode = channelSwitch->channelSwitchMode;
    580             switchChannel_smEvent((UINT8*)&pSwitchChannel->currentState, SC_EVENT_SC_CMD, pSwitchChannel);
    581 		}
    582 
    583 	}
    584 
    585 }
    586 
    587 
    588 /************************************************************************
    589  *                        switchChannel_powerSaveStatusReturn			*
    590  ************************************************************************/
    591 /**
    592 *
    593 * \b Description:
    594 *
    595 * This procedure is called when power save status is returned
    596 *
    597 * \b ARGS:
    598 *
    599 *  I/O - hSwitchChannel - SwitchChannel context \n
    600 *
    601 * \b RETURNS:
    602 *
    603 *  OK on success, NOK otherwise.
    604 *
    605 * \sa
    606 */
    607 void switchChannel_SwitchChannelCmdCompleteReturn(TI_HANDLE hSwitchChannel)
    608 {
    609 	switchChannel_t			*pSwitchChannel = (switchChannel_t*)hSwitchChannel;
    610 
    611 	if (pSwitchChannel == NULL)
    612 	{
    613 		return;
    614 	}
    615 	WLAN_REPORT_INFORMATION(pSwitchChannel->hReport, SC_MODULE_LOG,
    616 							  ("switchChannel_SwitchChannelCmdCompleteReturn \n"));
    617 
    618 	switchChannel_smEvent((UINT8*)&pSwitchChannel->currentState, SC_EVENT_SC_CMPLT, pSwitchChannel);
    619 
    620 }
    621 
    622 /************************************************************************
    623  *                        switchChannel_enableDisableSpectrumMngmt			*
    624  ************************************************************************/
    625 /**
    626 *
    627 * \b Description:
    628 *
    629 * This procedure enables or disables the spectrum management
    630 *
    631 * \b ARGS:
    632 *
    633 *  I - hSwitchChannel - SwitchChannel context \n
    634 *  I - enableDisable - TRUE - Enable, FALSE - Disable
    635 *
    636 * \b RETURNS:
    637 *
    638 *  OK on success, NOK otherwise.
    639 *
    640 * \sa
    641 */
    642 void switchChannel_enableDisableSpectrumMngmt(TI_HANDLE hSwitchChannel, BOOL enableDisable)
    643 {
    644 	switchChannel_t			*pSwitchChannel = (switchChannel_t*)hSwitchChannel;
    645 
    646 
    647 	if (hSwitchChannel == NULL)
    648 	{
    649 		return;
    650 	}
    651 	WLAN_REPORT_INFORMATION(pSwitchChannel->hReport, SC_MODULE_LOG,
    652 							  ("switchChannel_enableDisableSpectrumMngmt, enableDisable=%d \n", enableDisable));
    653 
    654 	pSwitchChannel->dot11SpectrumManagementRequired = enableDisable;
    655 
    656 	if (enableDisable)
    657 	{	/* Enable SC, if it was started invoke start event.
    658 			otherwise, wait for a start event */
    659 		if (pSwitchChannel->switchChannelStarted)
    660 		{
    661 			switchChannel_smEvent((UINT8*)&pSwitchChannel->currentState, SC_EVENT_START, pSwitchChannel);
    662 		}
    663 	}
    664 	else
    665 	{	/* Disable SC */
    666 		switchChannel_smEvent((UINT8*)&pSwitchChannel->currentState, SC_EVENT_STOP, pSwitchChannel);
    667 	}
    668 
    669 }
    670 
    671 
    672 
    673 /************************************************************************
    674  *                        SwitchChannel internal functions				*
    675  ************************************************************************/
    676 
    677 /************************************************************************
    678  *                        switchChannel_smEvent							*
    679  ************************************************************************/
    680 /**
    681 *
    682 * \b Description:
    683 *
    684 * SwitchChannel state machine transition function
    685 *
    686 * \b ARGS:
    687 *
    688 *  I/O - currentState - current state in the state machine\n
    689 *  I   - event - specific event for the state machine\n
    690 *  I   - pData - Data for state machine action function\n
    691 *
    692 * \b RETURNS:
    693 *
    694 *  OK on success, NOK otherwise.
    695 *
    696 * \sa
    697 */
    698 static TI_STATUS switchChannel_smEvent(UINT8 *currState, UINT8 event, void* data)
    699 {
    700 	TI_STATUS       status;
    701 	UINT8           nextState;
    702 	switchChannel_t           *pSwitchChannel = (switchChannel_t*)data;
    703 
    704 
    705 	status = fsm_GetNextState(pSwitchChannel->pSwitchChannelSm, *currState, event, &nextState);
    706 	if (status != OK)
    707 	{
    708 		WLAN_REPORT_ERROR(pSwitchChannel->hReport, SC_MODULE_LOG, ("switchChannel_smEvent, fsm_GetNextState error\n"));
    709 		return(NOK);
    710 	}
    711 
    712 	WLAN_REPORT_SM(pSwitchChannel->hReport, SC_MODULE_LOG,
    713 				   ("<%s, %s> --> %s\n\n",
    714 					switchChannel_stateDesc[*currState],
    715 					switchChannel_eventDesc[event],
    716 					switchChannel_stateDesc[nextState]));
    717 
    718 	status = fsm_Event(pSwitchChannel->pSwitchChannelSm, currState, event, (void *)pSwitchChannel);
    719 
    720 	if (status != OK)
    721 	{
    722 		WLAN_REPORT_ERROR(pSwitchChannel->hReport, SC_MODULE_LOG, ("switchChannel_smEvent fsm_Event error\n"));
    723 		WLAN_REPORT_ERROR(pSwitchChannel->hReport, SC_MODULE_LOG,
    724 						  ("<%s, %s> --> %s\n\n",
    725 						   switchChannel_stateDesc[*currState],
    726 						   switchChannel_eventDesc[event],
    727 						   switchChannel_stateDesc[nextState]));
    728 
    729 	}
    730 	return status;
    731 
    732 }
    733 
    734 
    735 /************************************************************************
    736  *                        switchChannel_smStart							*
    737  ************************************************************************/
    738 /**
    739 *
    740 *
    741 * \b Description:
    742 *
    743 * This function is called when the station becomes connected.
    744  * update the current channel.
    745 *
    746 * \b ARGS:
    747 *
    748 *  I   - pData - pointer to the SwitchChannel SM context  \n
    749 *
    750 * \b RETURNS:
    751 *
    752 *  OK if successful, NOK otherwise.
    753 *
    754 *
    755 *************************************************************************/
    756 static TI_STATUS switchChannel_smStart(void *pData)
    757 {
    758 	switchChannel_t                       *pSwitchChannel = (switchChannel_t*)pData;
    759 	paramInfo_t					param;
    760 	/*scr_clientRequestStatus_e   scrStatus;*/
    761 
    762 	if (pSwitchChannel == NULL)
    763 	{
    764 		return NOK;
    765 	}
    766 
    767 	/* get the current channel number */
    768 	param.paramType = SITE_MGR_CURRENT_CHANNEL_PARAM;
    769 	siteMgr_getParam(pSwitchChannel->hSiteMgr, &param);
    770 	pSwitchChannel->currentChannel = param.content.siteMgrCurrentChannel;
    771 
    772 	WLAN_REPORT_INFORMATION(pSwitchChannel->hReport, SC_MODULE_LOG,
    773 							("switchChannel_smStart, channelNo=%d\n",
    774 							 pSwitchChannel->currentChannel));
    775 	return OK;
    776 
    777 }
    778 
    779 /************************************************************************
    780  *                        switchChannel_smReqSCR_UpdateCmd				*
    781  ************************************************************************/
    782 /**
    783 *
    784 *
    785 * \b Description:
    786 *
    787 * Update the Switch Channel command parameters.
    788  * Request SCR and wait for SCR return.
    789  * if tx status suspend
    790  * 	update regulatory Domain
    791  * 	update tx
    792  * 	start periodic timer
    793 
    794 *
    795 * \b ARGS:
    796 *
    797 *  I   - pData - pointer to the SwitchChannel SM context  \n
    798 *
    799 * \b RETURNS:
    800 *
    801 *  OK if successful, NOK otherwise.
    802 *
    803 *
    804 *************************************************************************/
    805 static TI_STATUS switchChannel_smReqSCR_UpdateCmd(void *pData)
    806 {
    807 	switchChannel_t                       *pSwitchChannel = (switchChannel_t*)pData;
    808 	/*TI_STATUS                   status;*/
    809 	scr_clientRequestStatus_e   scrStatus;
    810 	scr_pendReason_e			scrPendReason;
    811 
    812 	if (pSwitchChannel == NULL)
    813 	{
    814 		return NOK;
    815 	}
    816 	WLAN_REPORT_INFORMATION(pSwitchChannel->hReport, SC_MODULE_LOG,
    817 							("switchChannel_smReqSCR_UpdateCmd, channelNo=%d, TBTT = %d, Mode = %d\n",
    818 							 pSwitchChannel->curChannelSwitchCmdParams.channelNumber,
    819 							 pSwitchChannel->curChannelSwitchCmdParams.channelSwitchCount,
    820 							 pSwitchChannel->curChannelSwitchCmdParams.channelSwitchMode));
    821 
    822 
    823 	/* Save the TS when requesting SCR */
    824 	pSwitchChannel->SCRRequestTimestamp = os_timeStampMs(pSwitchChannel->hOs);
    825 
    826 	scrStatus = scr_clientRequest(pSwitchChannel->hSCR, SCR_CID_SWITCH_CHANNEL, &scrPendReason);
    827 	if ((scrStatus != SCR_CRS_RUN) && (scrStatus != SCR_CRS_PEND))
    828 	{
    829 		WLAN_REPORT_ERROR(pSwitchChannel->hReport, SC_MODULE_LOG,
    830 			("switchChannel_smReqSCR_UpdateCmd():Abort the switch channel, request Roaming, scrStatus=%d\n", scrStatus));
    831 		return (switchChannel_smEvent((UINT8*)&pSwitchChannel->currentState, SC_EVENT_SCR_FAIL, pSwitchChannel));
    832 
    833 	}
    834     if (scrStatus == SCR_CRS_RUN)
    835     {
    836 		switchChannel_scrStatusCB(pSwitchChannel, scrStatus, scrPendReason);
    837     }
    838     else if ((scrPendReason==SCR_PR_OTHER_CLIENT_RUNNING) ||
    839          (scrPendReason==SCR_PR_DIFFERENT_GROUP_RUNNING) )
    840     {   /* No use to wait for the SCR, invoke FAIL */
    841 		return (switchChannel_smEvent((UINT8*)&pSwitchChannel->currentState, SC_EVENT_SCR_FAIL, pSwitchChannel));
    842     }
    843     /* wait for the SCR callback function to be called */
    844 	return OK;
    845 
    846 }
    847 
    848 
    849 /************************************************************************
    850  *                        switchChannel_scrStatusCB						*
    851  ************************************************************************/
    852 /**
    853 *
    854 *
    855 * \b Description:
    856 *
    857 * This function is called by the SCR when:
    858  * the resource is reserved for the SwitchChannel - SCR_CRS_RUN
    859  * recovery occurred - SCR_CRS_ABORT
    860  * other = ERROR
    861 *
    862 * \b ARGS:
    863 *
    864 *  I   - hSwitchChannel - pointer to the SwitchChannel SM context  \n
    865 *  I   - requestStatus - the SCR request status  \n
    866 *  I   - pendReason - The SCR pend status in case of pend reply  \n
    867 *
    868 * \b RETURNS:
    869 *
    870 *  None.
    871 *
    872 *
    873 *************************************************************************/
    874 void switchChannel_scrStatusCB(TI_HANDLE hSwitchChannel, scr_clientRequestStatus_e requestStatus,
    875 						  scr_pendReason_e pendReason )
    876 {
    877 	switchChannel_t             *pSwitchChannel = (switchChannel_t*)hSwitchChannel;
    878     switchChannel_smEvents      scEvent;
    879 
    880 	if (pSwitchChannel == NULL)
    881 	{
    882 		return;
    883 	}
    884 
    885 	switch (requestStatus)
    886 	{
    887     case SCR_CRS_RUN:
    888         scEvent = SC_EVENT_SCR_RUN;
    889 		break;
    890     case SCR_CRS_FW_RESET:
    891         scEvent = SC_EVENT_FW_RESET;
    892 		break;
    893     case SCR_CRS_PEND:
    894         scEvent = SC_EVENT_SCR_FAIL;
    895         break;
    896 	case SCR_CRS_ABORT:
    897 	default:
    898 		WLAN_REPORT_ERROR(pSwitchChannel->hReport, SC_MODULE_LOG,
    899                           ("switchChannel_scrStatusCB scrStatus = %d, pendReason=%d\n",
    900                            requestStatus, pendReason));
    901         scEvent = SC_EVENT_SCR_FAIL;
    902 		break;
    903 	}
    904 
    905     switchChannel_smEvent((UINT8*)&pSwitchChannel->currentState, scEvent, pSwitchChannel);
    906 
    907 }
    908 
    909 
    910 
    911 /************************************************************************
    912  *                        switchChannel_smStartSwitchChannelCmd			*
    913  ************************************************************************/
    914 /**
    915 *
    916 *
    917 * \b Description:
    918 *
    919 * This function is called once SwitchChannel command was received and the SCR
    920  * request returned with reason RUN.
    921  * In this case perform the following:
    922  *  Set CMD to FW
    923 
    924 
    925 *
    926 * \b ARGS:
    927 *
    928 *  I   - pData - pointer to the SwitchChannel SM context  \n
    929 *
    930 * \b RETURNS:
    931 *
    932 *  OK if successful, NOK otherwise.
    933 *
    934 *
    935 *************************************************************************/
    936 static TI_STATUS switchChannel_smStartSwitchChannelCmd(void *pData)
    937 {
    938 	switchChannel_t 							*pSwitchChannel = (switchChannel_t *)pData;
    939 	whalCtrl_switchChannelCmd_t 	pSwitchChannelCmd;
    940 	UINT32							switchChannelTimeDuration;
    941 	paramInfo_t						param;
    942 
    943 	if (pSwitchChannel == NULL)
    944 	{
    945 		return NOK;
    946 	}
    947 
    948 	param.paramType = SITE_MGR_BEACON_INTERVAL_PARAM;
    949 	siteMgr_getParam(pSwitchChannel->hSiteMgr, &param);
    950 
    951 	switchChannelTimeDuration = pSwitchChannel->curChannelSwitchCmdParams.channelSwitchCount * param.content.beaconInterval * 1024 / 1000;
    952 	if (  (switchChannelTimeDuration!=0) &&
    953 		((os_timeStampMs(pSwitchChannel->hOs) - pSwitchChannel->SCRRequestTimestamp) >= switchChannelTimeDuration ))
    954 	{	/* There's no time to perfrom the SCC, set the Count to 1 */
    955         pSwitchChannel->curChannelSwitchCmdParams.channelSwitchCount = 1;
    956 	}
    957 
    958     apConn_indicateSwitchChannelInProgress(pSwitchChannel->hApConn);
    959 
    960     /* suspend self test to avoid wrong tx stuck indications */
    961     healthMonitor_suspendPeriodicTest( pSwitchChannel->hHealthMonitor );
    962 
    963 	pSwitchChannelCmd.channelNumber = pSwitchChannel->curChannelSwitchCmdParams.channelNumber;
    964 	pSwitchChannelCmd.switchTime	= pSwitchChannel->curChannelSwitchCmdParams.channelSwitchCount;
    965 	pSwitchChannelCmd.txFlag		= pSwitchChannel->curChannelSwitchCmdParams.channelSwitchMode;
    966 	pSwitchChannelCmd.flush			= 0;
    967 	whalCtrl_SwitchChannelCmd (pSwitchChannel->hHalCtrl, &pSwitchChannelCmd);
    968 
    969 	WLAN_REPORT_INFORMATION(pSwitchChannel->hReport, SC_MODULE_LOG,
    970 							  ("whalCtrl_SwitchChannelCmd:Set the cmd in HAL. Params:\n channelNumber=%d, switchTime=%d, txFlag=%d, flush=%d \n",
    971 							   pSwitchChannelCmd.channelNumber,
    972 							   pSwitchChannelCmd.switchTime,
    973 							   pSwitchChannelCmd.txFlag,
    974 							   pSwitchChannelCmd.flush));
    975 
    976 	return OK;
    977 
    978 }
    979 
    980 /************************************************************************
    981  *    switchChannel_smFwResetWhileSCInProg			*
    982  ************************************************************************/
    983 /**
    984 *
    985 *
    986 * \b Description:
    987 *
    988 * This function is called when Switch Channel command is cancelled.
    989  * In this case update TX nad regulatory Domain adn HAL.
    990  * Release the SCR and exit PS.
    991 *
    992 * \b ARGS:
    993 *
    994 *  I   - pData - pointer to the SwitchChannel SM context  \n
    995 *
    996 * \b RETURNS:
    997 *
    998 *  OK if successful, NOK otherwise.
    999 *
   1000 *
   1001 *************************************************************************/
   1002 static TI_STATUS switchChannel_smFwResetWhileSCInProg(void *pData)
   1003 {
   1004 	switchChannel_t 	 *pSwitchChannel = (switchChannel_t *)pData;
   1005 	paramInfo_t          param;
   1006 
   1007 	if (pSwitchChannel == NULL)
   1008 	{
   1009 		return NOK;
   1010 	}
   1011 	WLAN_REPORT_INFORMATION(pSwitchChannel->hReport, SC_MODULE_LOG,
   1012 							  ("switchChannel_smFwResetWhileSCInProg \n"));
   1013 
   1014 	/* Update new current channel */
   1015 	param.paramType = SITE_MGR_CURRENT_CHANNEL_PARAM;
   1016 	param.content.siteMgrCurrentChannel = pSwitchChannel->curChannelSwitchCmdParams.channelNumber;
   1017 	siteMgr_setParam(pSwitchChannel->hSiteMgr, &param);
   1018 
   1019     apConn_indicateSwitchChannelFinished(pSwitchChannel->hApConn);
   1020 
   1021     switchChannel_zeroDatabase(pSwitchChannel);
   1022 
   1023     /* resume self test */
   1024     healthMonitor_resumePeriodicTest( pSwitchChannel->hHealthMonitor );
   1025 
   1026     /* release the SCR */
   1027 	scr_clientComplete(pSwitchChannel->hSCR, SCR_CID_SWITCH_CHANNEL);
   1028 
   1029 	return OK;
   1030 
   1031 }
   1032 
   1033 
   1034 /************************************************************************
   1035  *                        switchChannel_smSwitchChannelCmplt			*
   1036  ************************************************************************/
   1037 /**
   1038 *
   1039 *
   1040 * \b Description:
   1041 *
   1042 * This function is called when SwitchChannel command completed in FW.
   1043  * In this case release SCR and update current channel.
   1044  * If TX was sus, it will be enabled only after first Beacon is recieved.
   1045  * Exit PS.
   1046 *
   1047 * \b ARGS:
   1048 *
   1049 *  I   - pData - pointer to the SwitchChannel SM context  \n
   1050 *
   1051 * \b RETURNS:
   1052 *
   1053 *  OK if successful, NOK otherwise.
   1054 *
   1055 *
   1056 *************************************************************************/
   1057 static TI_STATUS switchChannel_smSwitchChannelCmplt(void *pData)
   1058 {
   1059 	switchChannel_t 			*pSwitchChannel = (switchChannel_t *)pData;
   1060 	paramInfo_t		param;
   1061 
   1062 	if (pSwitchChannel == NULL)
   1063 	{
   1064 		return NOK;
   1065 	}
   1066 
   1067 	/* Update new current channel */
   1068 	param.paramType = SITE_MGR_CURRENT_CHANNEL_PARAM;
   1069 	param.content.siteMgrCurrentChannel = pSwitchChannel->curChannelSwitchCmdParams.channelNumber;
   1070 	siteMgr_setParam(pSwitchChannel->hSiteMgr, &param);
   1071 
   1072 	WLAN_REPORT_INFORMATION(pSwitchChannel->hReport, SC_MODULE_LOG,
   1073 							("switchChannel_smSwitchChannelCmplt, new channelNum = %d\n", pSwitchChannel->currentChannel));
   1074 
   1075     apConn_indicateSwitchChannelFinished(pSwitchChannel->hApConn);
   1076     switchChannel_zeroDatabase(pSwitchChannel);
   1077 
   1078     /* resume self test */
   1079     healthMonitor_resumePeriodicTest( pSwitchChannel->hHealthMonitor );
   1080 
   1081 	/* release the SCR */
   1082 	scr_clientComplete(pSwitchChannel->hSCR, SCR_CID_SWITCH_CHANNEL);
   1083 
   1084 	return OK;
   1085 
   1086 }
   1087 
   1088 
   1089 
   1090 /************************************************************************
   1091  *                        switchChannel_smScrFailWhileWait4Scr			*
   1092  ************************************************************************/
   1093 /**
   1094 *
   1095 *
   1096 * \b Description:
   1097 *
   1098 * This function is called when recovery occurred, while waiting for SCR due
   1099  * to previous switch channel command.
   1100  * Exit PS
   1101  * Release SCR.
   1102 *
   1103 * \b ARGS:
   1104 *
   1105 *  I   - pData - pointer to the SwitchChannel SM context  \n
   1106 *
   1107 * \b RETURNS:
   1108 *
   1109 *  OK if successful, NOK otherwise.
   1110 *
   1111 *
   1112 *************************************************************************/
   1113 static TI_STATUS switchChannel_smScrFailWhileWait4Scr(void *pData)
   1114 {
   1115 	switchChannel_t                       *pSwitchChannel = (switchChannel_t*)pData;
   1116 
   1117 	if (pSwitchChannel == NULL)
   1118 	{
   1119 		return NOK;
   1120 	}
   1121 
   1122 	WLAN_REPORT_INFORMATION(pSwitchChannel->hReport, SC_MODULE_LOG,
   1123 							("switchChannel_smScrFailWhileWait4Scr\n"));
   1124 
   1125     switchChannel_zeroDatabase(pSwitchChannel);
   1126 
   1127 	/* release the SCR is not required !!! */
   1128 	scr_clientComplete(pSwitchChannel->hSCR, SCR_CID_SWITCH_CHANNEL);
   1129 
   1130 	return OK;
   1131 }
   1132 
   1133 /************************************************************************
   1134  *                        switchChannel_smStopWhileWait4Cmd				*
   1135  ************************************************************************/
   1136 /**
   1137 *
   1138 *
   1139 * \b Description:
   1140 *
   1141 * This function is called when the station becomes Disconnected and the current
   1142 * state is Wait4Cmd. In this case perfrom:
   1143  * Stop the timer
   1144  * Enable TX if it was disabled
   1145  * Zero the current command parameters
   1146  * Stop the timer
   1147 *
   1148 * \b ARGS:
   1149 *
   1150 *  I   - pData - pointer to the SwitchChannel SM context  \n
   1151 *
   1152 * \b RETURNS:
   1153 *
   1154 *  OK if successful, NOK otherwise.
   1155 *
   1156 *
   1157 *************************************************************************/
   1158 static TI_STATUS switchChannel_smStopWhileWait4Cmd(void *pData)
   1159 {
   1160 	switchChannel_t                       *pSwitchChannel = (switchChannel_t*)pData;
   1161 
   1162 	if (pSwitchChannel == NULL)
   1163 	{
   1164 		return NOK;
   1165 	}
   1166 
   1167 	WLAN_REPORT_INFORMATION(pSwitchChannel->hReport, SC_MODULE_LOG,
   1168 							("switchChannel_smStopWhileWait4Cmd\n"));
   1169 
   1170 	switchChannel_zeroDatabase(pSwitchChannel);
   1171 
   1172 	return OK;
   1173 }
   1174 
   1175 /************************************************************************
   1176  *                        switchChannel_smStopWhileWait4Scr					*
   1177  ************************************************************************/
   1178 /**
   1179 *
   1180 *
   1181 * \b Description:
   1182 *
   1183 * This function is called when the station becomes Disconnected and the current
   1184 * state is Wait4Scr. In this case perfrom:
   1185  * Stop the timer
   1186  * Enable TX if it was disabled
   1187  * Zero the current command parameters
   1188  * Complete SCR
   1189 *
   1190 * \b ARGS:
   1191 *
   1192 *  I   - pData - pointer to the SwitchChannel SM context  \n
   1193 *
   1194 * \b RETURNS:
   1195 *
   1196 *  OK if successful, NOK otherwise.
   1197 *
   1198 *
   1199 *************************************************************************/
   1200 static TI_STATUS switchChannel_smStopWhileWait4Scr(void *pData)
   1201 {
   1202 	switchChannel_t                       *pSwitchChannel = (switchChannel_t*)pData;
   1203 
   1204 	if (pSwitchChannel == NULL)
   1205 	{
   1206 		return NOK;
   1207 	}
   1208 
   1209 	WLAN_REPORT_INFORMATION(pSwitchChannel->hReport, SC_MODULE_LOG,
   1210 							("switchChannel_smStopWhileWait4Scr\n"));
   1211 
   1212 
   1213 	switchChannel_zeroDatabase(pSwitchChannel);
   1214 
   1215 	/* release the SCR */
   1216 	scr_clientComplete(pSwitchChannel->hSCR, SCR_CID_SWITCH_CHANNEL);
   1217 
   1218 	return OK;
   1219 }
   1220 
   1221 /************************************************************************
   1222  *         switchChannel_smStopWhileSwitchChannelInProg					*
   1223  ************************************************************************/
   1224 /**
   1225 *
   1226 *
   1227 * \b Description:
   1228 *
   1229 * This function is called when the station becomes Disconnected and the current
   1230 * state is SwitchChannelInProg. In this case perfrom:
   1231  * Stop the timer
   1232  * Enable TX if it was disabled
   1233  * Zero the current command parameters
   1234  * resume self test
   1235  * Complete SCR
   1236  * Exit PS
   1237 *
   1238 * \b ARGS:
   1239 *
   1240 *  I   - pData - pointer to the SwitchChannel SM context  \n
   1241 *
   1242 * \b RETURNS:
   1243 *
   1244 *  OK if successful, NOK otherwise.
   1245 *
   1246 *
   1247 *************************************************************************/
   1248 static TI_STATUS switchChannel_smStopWhileSwitchChannelInProg(void *pData)
   1249 {
   1250 	switchChannel_t                       *pSwitchChannel = (switchChannel_t*)pData;
   1251 
   1252 	if (pSwitchChannel == NULL)
   1253 	{
   1254 		return NOK;
   1255 	}
   1256 
   1257 	WLAN_REPORT_INFORMATION(pSwitchChannel->hReport, SC_MODULE_LOG,
   1258 							("switchChannel_smStopWhileSwitchChannelInProg\n"));
   1259 
   1260 	/* Exit PS */
   1261 	/*PowerMgr_exitFromDriverMode(pSwitchChannel->hPowerMngr, "SwitchChannel");*/
   1262 
   1263     apConn_indicateSwitchChannelFinished(pSwitchChannel->hApConn);
   1264 
   1265     whalCtrl_SwitchChannelCancelCmd (pSwitchChannel->hHalCtrl, pSwitchChannel->currentChannel);
   1266 	switchChannel_zeroDatabase(pSwitchChannel);
   1267 
   1268     /* resume self test */
   1269     healthMonitor_resumePeriodicTest( pSwitchChannel->hHealthMonitor );
   1270 
   1271 	/* release the SCR */
   1272 	scr_clientComplete(pSwitchChannel->hSCR, SCR_CID_SWITCH_CHANNEL);
   1273 
   1274 	return OK;
   1275 }
   1276 
   1277 
   1278 
   1279 
   1280 /************************************************************************
   1281  *                        switchChannel_zeroDatabase					*
   1282  ************************************************************************/
   1283 /**
   1284 *
   1285 *
   1286 * \b Description:
   1287 *
   1288 * This function is called when the SwitchChannel internal database should be zero.
   1289  * The following parameters are zerod:
   1290  * SwitchChannelChannelRange - the timestamps and validity state of channels
   1291  * curChannelSwitchCmdParams - the current switch channel command parameters
   1292 *
   1293 * \b ARGS:
   1294 *
   1295 *  I   - pSwitchChannel - pointer to the SwitchChannel SM context  \n
   1296 *  I   - channelNum - channel number  \n
   1297 *  I   - timestamp - required timestamp  \n
   1298 *
   1299 * \b RETURNS:
   1300 *
   1301 *  None.
   1302 *
   1303 *
   1304 *************************************************************************/
   1305 static void switchChannel_zeroDatabase(switchChannel_t *pSwitchChannel)
   1306 {
   1307 
   1308 	WLAN_REPORT_INFORMATION(pSwitchChannel->hReport, SC_MODULE_LOG, ("switchChannel_zeroDatabase\n"));
   1309 
   1310 
   1311 	pSwitchChannel->curChannelSwitchCmdParams.channelNumber = 0;
   1312 	pSwitchChannel->curChannelSwitchCmdParams.channelSwitchCount = 0;
   1313 	pSwitchChannel->curChannelSwitchCmdParams.channelSwitchMode = SC_SWITCH_CHANNEL_MODE_NOT_TX_SUS;
   1314 	pSwitchChannel->currentChannel = 0;
   1315 
   1316 }
   1317 
   1318 /***********************************************************************
   1319  *                        release_module
   1320  ***********************************************************************/
   1321 /*
   1322 DESCRIPTION:	Called by the destroy function or by the create function (on failure)
   1323 				Go over the vector, for each bit that is set, release the corresponding module.
   1324 
   1325 INPUT:      pSwitchChannel	-	SwitchChannel pointer.
   1326 			initVec	-	Vector that contains a bit set for each module thah had been initiualized
   1327 
   1328 OUTPUT:
   1329 
   1330 RETURN:     OK on success, NOK otherwise
   1331 
   1332 ************************************************************************/
   1333 static void release_module(switchChannel_t *pSwitchChannel, UINT32 initVec)
   1334 {
   1335     if (pSwitchChannel == NULL)
   1336     {
   1337         return;
   1338     }
   1339     if (initVec & (1 << SC_SM_INIT_BIT))
   1340 	{
   1341 		fsm_Unload(pSwitchChannel->hOs, pSwitchChannel->pSwitchChannelSm);
   1342 	}
   1343 
   1344 	if (initVec & (1 << SC_INIT_BIT))
   1345 	{
   1346 		utils_nullMemoryFree(pSwitchChannel->hOs, pSwitchChannel, sizeof(switchChannel_t));
   1347 	}
   1348 
   1349 	initVec = 0;
   1350 }
   1351 
   1352 
   1353 /**
   1354 *
   1355 * switchChannel_smNop - Do nothing
   1356 *
   1357 * \b Description:
   1358 *
   1359 * Do nothing in the SM.
   1360 *
   1361 * \b ARGS:
   1362 *
   1363 *  I   - pData - pointer to the SwitchChannel SM context  \n
   1364 *
   1365 * \b RETURNS:
   1366 *
   1367 *  OK if successful, NOK otherwise.
   1368 *
   1369 *
   1370 */
   1371 static TI_STATUS switchChannel_smNop(void *pData)
   1372 {
   1373 	switchChannel_t       *pSwitchChannel;
   1374 
   1375 	pSwitchChannel = (switchChannel_t*)pData;
   1376 	if (pSwitchChannel == NULL)
   1377 	{
   1378 		return NOK;
   1379 	}
   1380 	WLAN_REPORT_INFORMATION(pSwitchChannel->hReport, SC_MODULE_LOG,
   1381 							(" switchChannel_smNop\n"));
   1382 
   1383 	return OK;
   1384 }
   1385 
   1386 /**
   1387 *
   1388 * switchChannel_smUnexpected - Unexpected event
   1389 *
   1390 * \b Description:
   1391 *
   1392 * Unexpected event in the SM.
   1393 *
   1394 * \b ARGS:
   1395 *
   1396 *  I   - pData - pointer to the SwitchChannel SM context  \n
   1397 *
   1398 * \b RETURNS:
   1399 *
   1400 *  OK if successful, NOK otherwise.
   1401 *
   1402 *
   1403 */
   1404 static TI_STATUS switchChannel_smUnexpected(void *pData)
   1405 {
   1406 	switchChannel_t       *pSwitchChannel;
   1407 
   1408 	pSwitchChannel = (switchChannel_t*)pData;
   1409 	if (pSwitchChannel == NULL)
   1410 	{
   1411 		return NOK;
   1412 	}
   1413 	WLAN_REPORT_ERROR(pSwitchChannel->hReport, SC_MODULE_LOG,
   1414 					  (" switchChannel_smUnexpected, state = %d\n", pSwitchChannel->currentState));
   1415 
   1416 	return NOK;
   1417 }
   1418 
   1419 /*******************************************************************************
   1420 ***********               			Debug functions 			   	 ***********
   1421 *******************************************************************************/
   1422 #ifdef TI_DBG
   1423 
   1424 /************************************************************************
   1425  *                        switchChannel_recvCmd							*
   1426  ************************************************************************/
   1427 /*DESCRIPTION: This function is called by MLME Parser upon receiving of
   1428 				Beacon, Probe Response or Action with Switch Channel command,
   1429 				or beacon/
   1430 				performs the following:
   1431 				-	Initializes the switching channel procedure.
   1432 				-	Setting timer to the actual switching time(if needed)
   1433 
   1434 INPUT:      hSwitchChannel				-	SwitchChannel handle.
   1435 			switchMode			- indicates whether to stop transmission
   1436 								until the scheduled channel switch.
   1437 			newChannelNum		- indicates the number of the new channel.
   1438 			durationTime		- indicates the time (expressed in ms) until
   1439 								the scheduled channel switch should accure.
   1440 
   1441 OUTPUT:		None
   1442 
   1443 RETURN:     OK on success, NOK otherwise
   1444 
   1445 ************************************************************************/
   1446 
   1447 static void switchChannel_recvCmd4Debug(TI_HANDLE hSwitchChannel, dot11_CHANNEL_SWITCH_t *channelSwitch, BOOL BeaconPacket, UINT8 channel)
   1448 {
   1449 
   1450 	switchChannel_t             *pSwitchChannel = (switchChannel_t *)hSwitchChannel;
   1451 	paramInfo_t                 param;
   1452 
   1453 	if (pSwitchChannel==NULL)
   1454 	{
   1455 		return;
   1456 	}
   1457 
   1458 
   1459 	/* The following is for debug purposes only
   1460 		It will be operated when the Switch Channel cmd is opertated from debug CLI */
   1461 	if (pSwitchChannel->ignoreCancelSwitchChannelCmd != 0)
   1462 	{
   1463 		if (pSwitchChannel->ignoreCancelSwitchChannelCmd == 1)
   1464 		{
   1465             /* update the new SCC params */
   1466             pSwitchChannel->curChannelSwitchCmdParams.channelNumber = channelSwitch->channelNumber;
   1467             pSwitchChannel->curChannelSwitchCmdParams.channelSwitchCount = channelSwitch->channelSwitchCount;
   1468             pSwitchChannel->curChannelSwitchCmdParams.channelSwitchMode = channelSwitch->channelSwitchMode;
   1469 
   1470             pSwitchChannel->ignoreCancelSwitchChannelCmd = 2;
   1471 		}
   1472 		else if (channelSwitch->channelSwitchCount>0)
   1473 		{
   1474 			channelSwitch->channelSwitchCount --;
   1475 		}
   1476 		else
   1477 		{
   1478 			pSwitchChannel->ignoreCancelSwitchChannelCmd = 0;
   1479 		}
   1480 
   1481 
   1482         /* search in the buffer pointer to the beginning of the
   1483             Switch Cahnnel Announcement IE according to the IE ID */
   1484 
   1485         /* SC IE exists on the serving channel */
   1486         WLAN_REPORT_INFORMATION(pSwitchChannel->hReport, SC_MODULE_LOG,
   1487                                 ("switchChannel_recvFrame, SwitchChannel cmd was found, channel no=%d, mode=%d, TBTT=%d \n",
   1488                                  channelSwitch->channelNumber, channelSwitch->channelSwitchMode,
   1489                                  channelSwitch->channelSwitchCount));
   1490 
   1491         /* Checking channel number validity */
   1492         param.content.channel = channelSwitch->channelNumber;
   1493         param.paramType = REGULATORY_DOMAIN_IS_CHANNEL_SUPPORTED;
   1494         regulatoryDomain_getParam(pSwitchChannel->hRegulatoryDomain,&param);
   1495         if (( !param.content.bIsChannelSupprted ) ||
   1496             (channelSwitch->channelSwitchCount == 0) ||
   1497             (channelSwitch->channelSwitchMode == SC_SWITCH_CHANNEL_MODE_TX_SUS))
   1498         {   /* Trigger Roaming, if TX mode is disabled, the new channel number is invalid,
   1499                 or the TBTT count is 0 */
   1500             apConn_reportRoamingEvent(pSwitchChannel->hApConn, ROAMING_TRIGGER_SWITCH_CHANNEL, NULL);
   1501         }
   1502         else
   1503         {   /* Invoke Switch Channel command */
   1504             /* update the new SCC params */
   1505             pSwitchChannel->curChannelSwitchCmdParams.channelNumber = channelSwitch->channelNumber;
   1506             pSwitchChannel->curChannelSwitchCmdParams.channelSwitchCount = channelSwitch->channelSwitchCount;
   1507             pSwitchChannel->curChannelSwitchCmdParams.channelSwitchMode = channelSwitch->channelSwitchMode;
   1508             switchChannel_smEvent((UINT8*)&pSwitchChannel->currentState, SC_EVENT_SC_CMD, pSwitchChannel);
   1509         }
   1510 	}
   1511 
   1512 }
   1513 
   1514 void switchChannelDebug_setCmdParams(TI_HANDLE hSwitchChannel, SC_switchChannelCmdParam_e switchChannelCmdParam, UINT8 param)
   1515 {
   1516 	switchChannel_t       *pSwitchChannel = (switchChannel_t*)hSwitchChannel;
   1517 
   1518 	if (pSwitchChannel == NULL)
   1519 	{
   1520 		return;
   1521 	}
   1522 
   1523 	switch (switchChannelCmdParam)
   1524 	{
   1525 	case SC_SWITCH_CHANNEL_NUM:
   1526 		WLAN_OS_REPORT(("SwitchChannelDebug_setSwitchChannelCmdParams, channelNum=%d \n ", param));
   1527 		pSwitchChannel->debugChannelSwitchCmdParams.channelNumber = param;
   1528 		break;
   1529 	case SC_SWITCH_CHANNEL_TBTT:
   1530 		WLAN_OS_REPORT(("SwitchChannelDebug_setSwitchChannelCmdParams, channelSwitchCount=%d \n ", param));
   1531 		pSwitchChannel->debugChannelSwitchCmdParams.channelSwitchCount = param;
   1532 		break;
   1533 	case SC_SWITCH_CHANNEL_MODE:
   1534 		WLAN_OS_REPORT(("SwitchChannelDebug_setSwitchChannelCmdParams, channelSwitchMode=%d \n ", param));
   1535 		pSwitchChannel->debugChannelSwitchCmdParams.channelSwitchMode = param;
   1536 		break;
   1537 	default:
   1538 		WLAN_OS_REPORT(("ERROR: SwitchChannelDebug_setSwitchChannelCmdParams, wrong switchChannelCmdParam=%d \n ",
   1539 						switchChannelCmdParam));
   1540 			break;
   1541 	}
   1542 
   1543 }
   1544 void switchChannelDebug_SwitchChannelCmdTest(TI_HANDLE hSwitchChannel, BOOL BeaconPacket)
   1545 {
   1546 	switchChannel_t       *pSwitchChannel = (switchChannel_t*)hSwitchChannel;
   1547 
   1548 	if (pSwitchChannel == NULL)
   1549 	{
   1550 		return;
   1551 	}
   1552 
   1553 	WLAN_OS_REPORT(("SwitchChannelDebug_SwitchChannelCmdTest, BeaconPacket=%d \n cmd params: channelNumber=%d, channelSwitchCount=%d, channelSwitchMode=%d \n",
   1554 					BeaconPacket,
   1555 					pSwitchChannel->debugChannelSwitchCmdParams.channelNumber,
   1556 					pSwitchChannel->debugChannelSwitchCmdParams.channelSwitchCount,
   1557 					pSwitchChannel->debugChannelSwitchCmdParams.channelSwitchMode));
   1558 
   1559 
   1560 	pSwitchChannel->ignoreCancelSwitchChannelCmd= 1;
   1561 	switchChannel_recvCmd4Debug(hSwitchChannel, &pSwitchChannel->debugChannelSwitchCmdParams, BeaconPacket, pSwitchChannel->currentChannel);
   1562 }
   1563 
   1564 void switchChannelDebug_CancelSwitchChannelCmdTest(TI_HANDLE hSwitchChannel, BOOL BeaconPacket)
   1565 {
   1566 
   1567 	switchChannel_t       *pSwitchChannel = (switchChannel_t*)hSwitchChannel;
   1568 
   1569 	if (pSwitchChannel == NULL)
   1570 	{
   1571 		return;
   1572 	}
   1573 
   1574 	WLAN_OS_REPORT(("SwitchChannelDebug_SwitchChannelCmdTest, BeaconPacket=%d \n",BeaconPacket));
   1575 
   1576 	pSwitchChannel->ignoreCancelSwitchChannelCmd= 0;
   1577 	switchChannel_recvCmd4Debug(hSwitchChannel, NULL, BeaconPacket, pSwitchChannel->currentChannel);
   1578 }
   1579 
   1580 
   1581 void switchChannelDebug_printStatus(TI_HANDLE hSwitchChannel)
   1582 {
   1583 	switchChannel_t       *pSwitchChannel = (switchChannel_t*)hSwitchChannel;
   1584 
   1585 	if (pSwitchChannel == NULL)
   1586 	{
   1587 		return;
   1588 	}
   1589 
   1590 	WLAN_OS_REPORT(("SwitchChannel debug params are: channelNumber=%d, channelSwitchCount=%d , channelSwitchMode=%d \n",
   1591 					pSwitchChannel->debugChannelSwitchCmdParams.channelNumber,
   1592 					pSwitchChannel->debugChannelSwitchCmdParams.channelSwitchCount,
   1593 					pSwitchChannel->debugChannelSwitchCmdParams.channelSwitchMode));
   1594 
   1595 	WLAN_OS_REPORT(("SwitchChannel state=%d, currentChannel=%d \n", pSwitchChannel->currentState, pSwitchChannel->currentChannel));
   1596 
   1597 
   1598 }
   1599 
   1600 void switchChannelDebug_setChannelValidity(TI_HANDLE hSwitchChannel, UINT8 channelNum, BOOL validity)
   1601 {
   1602     paramInfo_t param;
   1603 
   1604 	switchChannel_t       *pSwitchChannel = (switchChannel_t*)hSwitchChannel;
   1605 
   1606 	if (pSwitchChannel == NULL)
   1607 	{
   1608 		return;
   1609 	}
   1610 
   1611     param.paramType = REGULATORY_DOMAIN_SET_CHANNEL_VALIDITY;
   1612     param.content.channelValidity.channelNum = channelNum;
   1613     param.content.channelValidity.channelValidity = validity;
   1614     regulatoryDomain_setParam(pSwitchChannel->hRegulatoryDomain, &param);
   1615 
   1616 }
   1617 
   1618 #endif
   1619 
   1620 
   1621 
   1622 
   1623 
   1624 
   1625