OSDN Git Service

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