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 */
80typedef 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 */
90typedef 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 */
108typedef 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
154static 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
161static 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 */
180static TI_STATUS switchChannel_smStartSwitchChannelCmd(void *pData);
181static TI_STATUS switchChannel_smReqSCR_UpdateCmd(void *pData);
182static TI_STATUS switchChannel_smSwitchChannelCmplt(void *pData);
183static TI_STATUS switchChannel_smFwResetWhileSCInProg(void *pData);
184static TI_STATUS switchChannel_smScrFailWhileWait4Scr(void *pData);
185static TI_STATUS switchChannel_smNop(void *pData);
186static TI_STATUS switchChannel_smUnexpected(void *pData);
187static TI_STATUS switchChannel_smStopWhileWait4Cmd(void *pData);
188static TI_STATUS switchChannel_smStopWhileWait4Scr(void *pData);
189static TI_STATUS switchChannel_smStopWhileSwitchChannelInProg(void *pData);
190static TI_STATUS switchChannel_smStart(void *pData);
191
192
193/* other functions */
194static void release_module(switchChannel_t *pSwitchChannel, UINT32 initVec);
195static TI_STATUS switchChannel_smEvent(UINT8 *currState, UINT8 event, void* data);
196static void switchChannel_zeroDatabase(switchChannel_t *pSwitchChannel);
197void switchChannel_SwitchChannelCmdCompleteReturn(TI_HANDLE hSwitchChannel);
198void switchChannel_scrStatusCB(TI_HANDLE hSwitchChannel, scr_clientRequestStatus_e requestStatus,
199						  scr_pendReason_e pendReason );
200#ifdef TI_DBG
201static 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*/
230TI_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*/
280TI_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*/
415TI_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*/
444TI_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*/
474TI_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
499INPUT:      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
506OUTPUT:		None
507
508RETURN:     OK on success, NOK otherwise
509
510************************************************************************/
511
512void 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*/
607void 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*/
642void 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*/
698static 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*************************************************************************/
756static 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*************************************************************************/
805static 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*************************************************************************/
874void 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*************************************************************************/
936static 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*************************************************************************/
1002static 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*************************************************************************/
1057static 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*************************************************************************/
1113static 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*************************************************************************/
1158static 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*************************************************************************/
1200static 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*************************************************************************/
1248static 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*************************************************************************/
1305static 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/*
1322DESCRIPTION:	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
1325INPUT:      pSwitchChannel	-	SwitchChannel pointer.
1326			initVec	-	Vector that contains a bit set for each module thah had been initiualized
1327
1328OUTPUT:
1329
1330RETURN:     OK on success, NOK otherwise
1331
1332************************************************************************/
1333static 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*/
1371static 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*/
1404static 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
1434INPUT:      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
1441OUTPUT:		None
1442
1443RETURN:     OK on success, NOK otherwise
1444
1445************************************************************************/
1446
1447static 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
1514void 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}
1544void 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
1564void 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
1581void 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
1600void 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