• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */
switchChannel_create(TI_HANDLE hOs)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 */
switchChannel_config(TI_HANDLE hSwitchChannel,TI_HANDLE hHalCtrl,TI_HANDLE hSiteMgr,TI_HANDLE hSCR,TI_HANDLE hRegulatoryDomain,TI_HANDLE hApConn,TI_HANDLE hReport,TI_HANDLE hOs,TI_HANDLE hHealthMonitor,SwitchChannelInitParams_t * SwitchChannelInitParams)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 */
switchChannel_stop(TI_HANDLE hSwitchChannel)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 */
switchChannel_start(TI_HANDLE hSwitchChannel)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 */
switchChannel_unload(TI_HANDLE hSwitchChannel)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 
switchChannel_recvCmd(TI_HANDLE hSwitchChannel,dot11_CHANNEL_SWITCH_t * channelSwitch,UINT8 channel)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 */
switchChannel_SwitchChannelCmdCompleteReturn(TI_HANDLE hSwitchChannel)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 */
switchChannel_enableDisableSpectrumMngmt(TI_HANDLE hSwitchChannel,BOOL enableDisable)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 */
switchChannel_smEvent(UINT8 * currState,UINT8 event,void * data)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 *************************************************************************/
switchChannel_smStart(void * pData)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 *************************************************************************/
switchChannel_smReqSCR_UpdateCmd(void * pData)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 *************************************************************************/
switchChannel_scrStatusCB(TI_HANDLE hSwitchChannel,scr_clientRequestStatus_e requestStatus,scr_pendReason_e pendReason)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 *************************************************************************/
switchChannel_smStartSwitchChannelCmd(void * pData)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 *************************************************************************/
switchChannel_smFwResetWhileSCInProg(void * pData)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 *************************************************************************/
switchChannel_smSwitchChannelCmplt(void * pData)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 *************************************************************************/
switchChannel_smScrFailWhileWait4Scr(void * pData)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 *************************************************************************/
switchChannel_smStopWhileWait4Cmd(void * pData)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 *************************************************************************/
switchChannel_smStopWhileWait4Scr(void * pData)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 *************************************************************************/
switchChannel_smStopWhileSwitchChannelInProg(void * pData)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 *************************************************************************/
switchChannel_zeroDatabase(switchChannel_t * pSwitchChannel)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 ************************************************************************/
release_module(switchChannel_t * pSwitchChannel,UINT32 initVec)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 */
switchChannel_smNop(void * pData)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 */
switchChannel_smUnexpected(void * pData)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 
switchChannel_recvCmd4Debug(TI_HANDLE hSwitchChannel,dot11_CHANNEL_SWITCH_t * channelSwitch,BOOL BeaconPacket,UINT8 channel)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 
switchChannelDebug_setCmdParams(TI_HANDLE hSwitchChannel,SC_switchChannelCmdParam_e switchChannelCmdParam,UINT8 param)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 }
switchChannelDebug_SwitchChannelCmdTest(TI_HANDLE hSwitchChannel,BOOL BeaconPacket)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 
switchChannelDebug_CancelSwitchChannelCmdTest(TI_HANDLE hSwitchChannel,BOOL BeaconPacket)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 
switchChannelDebug_printStatus(TI_HANDLE hSwitchChannel)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 
switchChannelDebug_setChannelValidity(TI_HANDLE hSwitchChannel,UINT8 channelNum,BOOL validity)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