• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * SwitchChannel.c
3  *
4  * Copyright(c) 1998 - 2009 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 */
switchChannel_create(TI_HANDLE hOs)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 */
switchChannel_init(TStadHandlesList * pStadHandles)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 
switchChannel_SetDefaults(TI_HANDLE hSwitchChannel,SwitchChannelInitParams_t * SwitchChannelInitParams)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 */
switchChannel_stop(TI_HANDLE hSwitchChannel)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 */
switchChannel_start(TI_HANDLE hSwitchChannel)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 */
switchChannel_unload(TI_HANDLE hSwitchChannel)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 
switchChannel_recvCmd(TI_HANDLE hSwitchChannel,dot11_CHANNEL_SWITCH_t * channelSwitch,TI_UINT8 channel)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             apConn_reportRoamingEvent(pSwitchChannel->hApConn, ROAMING_TRIGGER_SWITCH_CHANNEL, NULL);
532         }
533         else
534         {   /* Invoke Switch Channel command */
535             /* update the new SCC params */
536             pSwitchChannel->curChannelSwitchCmdParams.channelNumber = channelSwitch->channelNumber;
537             pSwitchChannel->curChannelSwitchCmdParams.channelSwitchCount = channelSwitch->channelSwitchCount;
538             pSwitchChannel->curChannelSwitchCmdParams.channelSwitchMode = channelSwitch->channelSwitchMode;
539             switchChannel_smEvent((TI_UINT8*)&pSwitchChannel->currentState, SC_EVENT_SC_CMD, pSwitchChannel);
540         }
541 
542     }
543 
544 }
545 
546 
547 /************************************************************************
548  *                        switchChannel_powerSaveStatusReturn           *
549  ************************************************************************/
550 /**
551 *
552 * \b Description:
553 *
554 * This procedure is called when power save status is returned
555 *
556 * \b ARGS:
557 *
558 *  I/O - hSwitchChannel - SwitchChannel context \n
559 *
560 * \b RETURNS:
561 *
562 *  TI_OK on success, TI_NOK otherwise.
563 *
564 * \sa
565 */
switchChannel_SwitchChannelCmdCompleteReturn(TI_HANDLE hSwitchChannel)566 void switchChannel_SwitchChannelCmdCompleteReturn(TI_HANDLE hSwitchChannel)
567 {
568     switchChannel_t         *pSwitchChannel = (switchChannel_t*)hSwitchChannel;
569 
570     if (pSwitchChannel == NULL)
571     {
572         return;
573     }
574     TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_SwitchChannelCmdCompleteReturn \n");
575 
576     switchChannel_smEvent((TI_UINT8*)&pSwitchChannel->currentState, SC_EVENT_SC_CMPLT, pSwitchChannel);
577 
578 }
579 
580 /************************************************************************
581  *                        switchChannel_enableDisableSpectrumMngmt          *
582  ************************************************************************/
583 /**
584 *
585 * \b Description:
586 *
587 * This procedure enables or disables the spectrum management
588 *
589 * \b ARGS:
590 *
591 *  I - hSwitchChannel - SwitchChannel context \n
592 *  I - enableDisable - TI_TRUE - Enable, TI_FALSE - Disable
593 *
594 * \b RETURNS:
595 *
596 *  TI_OK on success, TI_NOK otherwise.
597 *
598 * \sa
599 */
switchChannel_enableDisableSpectrumMngmt(TI_HANDLE hSwitchChannel,TI_BOOL enableDisable)600 void switchChannel_enableDisableSpectrumMngmt(TI_HANDLE hSwitchChannel, TI_BOOL enableDisable)
601 {
602     switchChannel_t         *pSwitchChannel = (switchChannel_t*)hSwitchChannel;
603 
604 
605     if (hSwitchChannel == NULL)
606     {
607         return;
608     }
609     TRACE1(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_enableDisableSpectrumMngmt, enableDisable=%d \n", enableDisable);
610 
611     pSwitchChannel->dot11SpectrumManagementRequired = enableDisable;
612 
613     if (enableDisable)
614     {   /* Enable SC, if it was started invoke start event.
615             otherwise, wait for a start event */
616         if (pSwitchChannel->switchChannelStarted)
617         {
618             switchChannel_smEvent((TI_UINT8*)&pSwitchChannel->currentState, SC_EVENT_START, pSwitchChannel);
619         }
620     }
621     else
622     {   /* Disable SC */
623         switchChannel_smEvent((TI_UINT8*)&pSwitchChannel->currentState, SC_EVENT_STOP, pSwitchChannel);
624     }
625 
626 }
627 
628 
629 
630 /************************************************************************
631  *                        SwitchChannel internal functions              *
632  ************************************************************************/
633 
634 /************************************************************************
635  *                        switchChannel_smEvent                         *
636  ************************************************************************/
637 /**
638 *
639 * \b Description:
640 *
641 * SwitchChannel state machine transition function
642 *
643 * \b ARGS:
644 *
645 *  I/O - currentState - current state in the state machine\n
646 *  I   - event - specific event for the state machine\n
647 *  I   - pData - Data for state machine action function\n
648 *
649 * \b RETURNS:
650 *
651 *  TI_OK on success, TI_NOK otherwise.
652 *
653 * \sa
654 */
switchChannel_smEvent(TI_UINT8 * currState,TI_UINT8 event,void * data)655 static TI_STATUS switchChannel_smEvent(TI_UINT8 *currState, TI_UINT8 event, void* data)
656 {
657     TI_STATUS       status;
658     TI_UINT8           nextState;
659     switchChannel_t           *pSwitchChannel = (switchChannel_t*)data;
660 
661 
662     status = fsm_GetNextState(pSwitchChannel->pSwitchChannelSm, *currState, event, &nextState);
663     if (status != TI_OK)
664     {
665         TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_ERROR, "switchChannel_smEvent, fsm_GetNextState error\n");
666         return(TI_NOK);
667     }
668 
669 	TRACE3(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_smEvent: <currentState = %d, event = %d> --> nextState = %d\n", *currState, event, nextState);
670 
671 	status = fsm_Event(pSwitchChannel->pSwitchChannelSm, currState, event, (void *)pSwitchChannel);
672 
673     if (status != TI_OK)
674     {
675         TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_ERROR, "switchChannel_smEvent fsm_Event error\n");
676 		TRACE3(pSwitchChannel->hReport, REPORT_SEVERITY_ERROR, "switchChannel_smEvent: <currentState = %d, event = %d> --> nextState = %d\n", *currState, event, nextState);
677     }
678     return status;
679 
680 }
681 
682 
683 /************************************************************************
684  *                        switchChannel_smStart                         *
685  ************************************************************************/
686 /**
687 *
688 *
689 * \b Description:
690 *
691 * This function is called when the station becomes connected.
692  * update the current channel.
693 *
694 * \b ARGS:
695 *
696 *  I   - pData - pointer to the SwitchChannel SM context  \n
697 *
698 * \b RETURNS:
699 *
700 *  TI_OK if successful, TI_NOK otherwise.
701 *
702 *
703 *************************************************************************/
switchChannel_smStart(void * pData)704 static TI_STATUS switchChannel_smStart(void *pData)
705 {
706     switchChannel_t                       *pSwitchChannel = (switchChannel_t*)pData;
707     paramInfo_t                 param;
708 
709     if (pSwitchChannel == NULL)
710     {
711         return TI_NOK;
712     }
713 
714     /* get the current channel number */
715     param.paramType = SITE_MGR_CURRENT_CHANNEL_PARAM;
716     siteMgr_getParam(pSwitchChannel->hSiteMgr, &param);
717     pSwitchChannel->currentChannel = param.content.siteMgrCurrentChannel;
718 
719     TRACE1(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_smStart, channelNo=%d\n", pSwitchChannel->currentChannel);
720     return TI_OK;
721 
722 }
723 
724 /************************************************************************
725  *                        switchChannel_smReqSCR_UpdateCmd              *
726  ************************************************************************/
727 /**
728 *
729 *
730 * \b Description:
731 *
732 * Update the Switch Channel command parameters.
733  * Request SCR and wait for SCR return.
734  * if tx status suspend
735  *  update regulatory Domain
736  *  update tx
737  *  start periodic timer
738 
739 *
740 * \b ARGS:
741 *
742 *  I   - pData - pointer to the SwitchChannel SM context  \n
743 *
744 * \b RETURNS:
745 *
746 *  TI_OK if successful, TI_NOK otherwise.
747 *
748 *
749 *************************************************************************/
switchChannel_smReqSCR_UpdateCmd(void * pData)750 static TI_STATUS switchChannel_smReqSCR_UpdateCmd(void *pData)
751 {
752     switchChannel_t             *pSwitchChannel = (switchChannel_t*)pData;
753     EScrClientRequestStatus     scrStatus;
754     EScePendReason              scrPendReason;
755 
756     if (pSwitchChannel == NULL)
757     {
758         return TI_NOK;
759     }
760     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);
761 
762 
763     /* Save the TS when requesting SCR */
764     pSwitchChannel->SCRRequestTimestamp = os_timeStampMs(pSwitchChannel->hOs);
765 
766     scrStatus = scr_clientRequest(pSwitchChannel->hSCR, SCR_CID_SWITCH_CHANNEL,
767                                   SCR_RESOURCE_SERVING_CHANNEL, &scrPendReason);
768     if ((scrStatus != SCR_CRS_RUN) && (scrStatus != SCR_CRS_PEND))
769     {
770         TRACE1(pSwitchChannel->hReport, REPORT_SEVERITY_ERROR, "switchChannel_smReqSCR_UpdateCmd():Abort the switch channel, request Roaming, scrStatus=%d\n", scrStatus);
771         return (switchChannel_smEvent((TI_UINT8*)&pSwitchChannel->currentState, SC_EVENT_SCR_FAIL, pSwitchChannel));
772 
773     }
774     if (scrStatus == SCR_CRS_RUN)
775     {
776         switchChannel_scrStatusCB(pSwitchChannel, scrStatus, SCR_RESOURCE_SERVING_CHANNEL, scrPendReason);
777     }
778     else if ((scrPendReason==SCR_PR_OTHER_CLIENT_RUNNING) ||
779          (scrPendReason==SCR_PR_DIFFERENT_GROUP_RUNNING) )
780     {   /* No use to wait for the SCR, invoke FAIL */
781         return (switchChannel_smEvent((TI_UINT8*)&pSwitchChannel->currentState, SC_EVENT_SCR_FAIL, pSwitchChannel));
782     }
783     /* wait for the SCR callback function to be called */
784     return TI_OK;
785 
786 }
787 
788 
789 /************************************************************************
790  *                        switchChannel_scrStatusCB                     *
791  ************************************************************************/
792 /**
793 *
794 *
795 * \b Description:
796 *
797 * This function is called by the SCR when:
798  * the resource is reserved for the SwitchChannel - SCR_CRS_RUN
799  * recovery occurred - SCR_CRS_ABORT
800  * other = ERROR
801 *
802 * \b ARGS:
803 *
804 *  I   - hSwitchChannel - pointer to the SwitchChannel SM context  \n
805 *  I   - requestStatus - the SCR request status  \n
806 *  I   - eResource - the resource for which the CB is issued  \n
807 *  I   - pendReason - The SCR pend status in case of pend reply  \n
808 *
809 * \b RETURNS:
810 *
811 *  None.
812 *
813 *
814 *************************************************************************/
switchChannel_scrStatusCB(TI_HANDLE hSwitchChannel,EScrClientRequestStatus requestStatus,EScrResourceId eResource,EScePendReason pendReason)815 void switchChannel_scrStatusCB(TI_HANDLE hSwitchChannel, EScrClientRequestStatus requestStatus,
816                                EScrResourceId eResource, EScePendReason pendReason )
817 {
818     switchChannel_t             *pSwitchChannel = (switchChannel_t*)hSwitchChannel;
819     switchChannel_smEvents      scEvent;
820 
821     if (pSwitchChannel == NULL)
822     {
823         return;
824     }
825 
826     switch (requestStatus)
827     {
828     case SCR_CRS_RUN:
829         scEvent = SC_EVENT_SCR_RUN;
830         break;
831     case SCR_CRS_FW_RESET:
832         scEvent = SC_EVENT_FW_RESET;
833         break;
834     case SCR_CRS_PEND:
835         scEvent = SC_EVENT_SCR_FAIL;
836         break;
837     case SCR_CRS_ABORT:
838     default:
839         TRACE2(pSwitchChannel->hReport, REPORT_SEVERITY_ERROR, "switchChannel_scrStatusCB scrStatus = %d, pendReason=%d\n", requestStatus, pendReason);
840         scEvent = SC_EVENT_SCR_FAIL;
841         break;
842     }
843 
844     switchChannel_smEvent((TI_UINT8*)&pSwitchChannel->currentState, scEvent, pSwitchChannel);
845 
846 }
847 
848 
849 
850 /************************************************************************
851  *                        switchChannel_smStartSwitchChannelCmd         *
852  ************************************************************************/
853 /**
854 *
855 *
856 * \b Description:
857 *
858 * This function is called once SwitchChannel command was received and the SCR
859  * request returned with reason RUN.
860  * In this case perform the following:
861  *  Set CMD to FW
862 
863 
864 *
865 * \b ARGS:
866 *
867 *  I   - pData - pointer to the SwitchChannel SM context  \n
868 *
869 * \b RETURNS:
870 *
871 *  TI_OK if successful, TI_NOK otherwise.
872 *
873 *
874 *************************************************************************/
switchChannel_smStartSwitchChannelCmd(void * pData)875 static TI_STATUS switchChannel_smStartSwitchChannelCmd(void *pData)
876 {
877     switchChannel_t         *pSwitchChannel = (switchChannel_t *)pData;
878     TSwitchChannelParams    pSwitchChannelCmd;
879     TI_UINT32                   switchChannelTimeDuration;
880     paramInfo_t             param;
881 
882     if (pSwitchChannel == NULL)
883     {
884         return TI_NOK;
885     }
886 
887     param.paramType = SITE_MGR_BEACON_INTERVAL_PARAM;
888     siteMgr_getParam(pSwitchChannel->hSiteMgr, &param);
889 
890     switchChannelTimeDuration = pSwitchChannel->curChannelSwitchCmdParams.channelSwitchCount * param.content.beaconInterval * 1024 / 1000;
891     if (  (switchChannelTimeDuration!=0) &&
892         ((os_timeStampMs(pSwitchChannel->hOs) - pSwitchChannel->SCRRequestTimestamp) >= switchChannelTimeDuration ))
893     {   /* There's no time to perfrom the SCC, set the Count to 1 */
894         pSwitchChannel->curChannelSwitchCmdParams.channelSwitchCount = 1;
895     }
896 
897     apConn_indicateSwitchChannelInProgress(pSwitchChannel->hApConn);
898 
899     pSwitchChannelCmd.channelNumber = pSwitchChannel->curChannelSwitchCmdParams.channelNumber;
900     pSwitchChannelCmd.switchTime    = pSwitchChannel->curChannelSwitchCmdParams.channelSwitchCount;
901     pSwitchChannelCmd.txFlag        = pSwitchChannel->curChannelSwitchCmdParams.channelSwitchMode;
902     pSwitchChannelCmd.flush         = 0;
903     TWD_CmdSwitchChannel (pSwitchChannel->hTWD, &pSwitchChannelCmd);
904 
905     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);
906 
907     return TI_OK;
908 
909 }
910 
911 /************************************************************************
912  *    switchChannel_smFwResetWhileSCInProg          *
913  ************************************************************************/
914 /**
915 *
916 *
917 * \b Description:
918 *
919 * This function is called when Switch Channel command is cancelled.
920  * In this case update TX nad regulatory Domain adn HAL.
921  * Release the SCR and exit PS.
922 *
923 * \b ARGS:
924 *
925 *  I   - pData - pointer to the SwitchChannel SM context  \n
926 *
927 * \b RETURNS:
928 *
929 *  TI_OK if successful, TI_NOK otherwise.
930 *
931 *
932 *************************************************************************/
switchChannel_smFwResetWhileSCInProg(void * pData)933 static TI_STATUS switchChannel_smFwResetWhileSCInProg(void *pData)
934 {
935     switchChannel_t      *pSwitchChannel = (switchChannel_t *)pData;
936     paramInfo_t          param;
937 
938     if (pSwitchChannel == NULL)
939     {
940         return TI_NOK;
941     }
942     TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_smFwResetWhileSCInProg \n");
943 
944     /* Update new current channel */
945     param.paramType = SITE_MGR_CURRENT_CHANNEL_PARAM;
946     param.content.siteMgrCurrentChannel = pSwitchChannel->curChannelSwitchCmdParams.channelNumber;
947     siteMgr_setParam(pSwitchChannel->hSiteMgr, &param);
948 
949     apConn_indicateSwitchChannelFinished(pSwitchChannel->hApConn);
950 
951     switchChannel_zeroDatabase(pSwitchChannel);
952 
953     /* release the SCR */
954     scr_clientComplete(pSwitchChannel->hSCR, SCR_CID_SWITCH_CHANNEL, SCR_RESOURCE_SERVING_CHANNEL);
955 
956     return TI_OK;
957 
958 }
959 
960 
961 /************************************************************************
962  *                        switchChannel_smSwitchChannelCmplt            *
963  ************************************************************************/
964 /**
965 *
966 *
967 * \b Description:
968 *
969 * This function is called when SwitchChannel command completed in FW.
970  * In this case release SCR and update current channel.
971  * If TX was sus, it will be enabled only after first Beacon is recieved.
972  * Exit PS.
973 *
974 * \b ARGS:
975 *
976 *  I   - pData - pointer to the SwitchChannel SM context  \n
977 *
978 * \b RETURNS:
979 *
980 *  TI_OK if successful, TI_NOK otherwise.
981 *
982 *
983 *************************************************************************/
switchChannel_smSwitchChannelCmplt(void * pData)984 static TI_STATUS switchChannel_smSwitchChannelCmplt(void *pData)
985 {
986     switchChannel_t             *pSwitchChannel = (switchChannel_t *)pData;
987     paramInfo_t     param;
988 
989     if (pSwitchChannel == NULL)
990     {
991         return TI_NOK;
992     }
993 
994     /* Update new current channel */
995     param.paramType = SITE_MGR_CURRENT_CHANNEL_PARAM;
996     param.content.siteMgrCurrentChannel = pSwitchChannel->curChannelSwitchCmdParams.channelNumber;
997     siteMgr_setParam(pSwitchChannel->hSiteMgr, &param);
998 
999     TRACE1(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_smSwitchChannelCmplt, new channelNum = %d\n", pSwitchChannel->currentChannel);
1000 
1001     apConn_indicateSwitchChannelFinished(pSwitchChannel->hApConn);
1002     switchChannel_zeroDatabase(pSwitchChannel);
1003 
1004     /* release the SCR */
1005     scr_clientComplete(pSwitchChannel->hSCR, SCR_CID_SWITCH_CHANNEL, SCR_RESOURCE_SERVING_CHANNEL);
1006 
1007     return TI_OK;
1008 
1009 }
1010 
1011 
1012 
1013 /************************************************************************
1014  *                        switchChannel_smScrFailWhileWait4Scr          *
1015  ************************************************************************/
1016 /**
1017 *
1018 *
1019 * \b Description:
1020 *
1021 * This function is called when recovery occurred, while waiting for SCR due
1022  * to previous switch channel command.
1023  * Exit PS
1024  * Release SCR.
1025 *
1026 * \b ARGS:
1027 *
1028 *  I   - pData - pointer to the SwitchChannel SM context  \n
1029 *
1030 * \b RETURNS:
1031 *
1032 *  TI_OK if successful, TI_NOK otherwise.
1033 *
1034 *
1035 *************************************************************************/
switchChannel_smScrFailWhileWait4Scr(void * pData)1036 static TI_STATUS switchChannel_smScrFailWhileWait4Scr(void *pData)
1037 {
1038     switchChannel_t                       *pSwitchChannel = (switchChannel_t*)pData;
1039 
1040     if (pSwitchChannel == NULL)
1041     {
1042         return TI_NOK;
1043     }
1044 
1045     TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_smScrFailWhileWait4Scr\n");
1046 
1047     switchChannel_zeroDatabase(pSwitchChannel);
1048 
1049     /* release the SCR is not required !!! */
1050     scr_clientComplete(pSwitchChannel->hSCR, SCR_CID_SWITCH_CHANNEL, SCR_RESOURCE_SERVING_CHANNEL);
1051 
1052     return TI_OK;
1053 }
1054 
1055 /************************************************************************
1056  *                        switchChannel_smStopWhileWait4Cmd             *
1057  ************************************************************************/
1058 /**
1059 *
1060 *
1061 * \b Description:
1062 *
1063 * This function is called when the station becomes Disconnected and the current
1064 * state is Wait4Cmd. In this case perfrom:
1065  * Stop the timer
1066  * Enable TX if it was disabled
1067  * Zero the current command parameters
1068  * Stop the timer
1069 *
1070 * \b ARGS:
1071 *
1072 *  I   - pData - pointer to the SwitchChannel SM context  \n
1073 *
1074 * \b RETURNS:
1075 *
1076 *  TI_OK if successful, TI_NOK otherwise.
1077 *
1078 *
1079 *************************************************************************/
switchChannel_smStopWhileWait4Cmd(void * pData)1080 static TI_STATUS switchChannel_smStopWhileWait4Cmd(void *pData)
1081 {
1082     switchChannel_t                       *pSwitchChannel = (switchChannel_t*)pData;
1083 
1084     if (pSwitchChannel == NULL)
1085     {
1086         return TI_NOK;
1087     }
1088 
1089     TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_smStopWhileWait4Cmd\n");
1090 
1091     switchChannel_zeroDatabase(pSwitchChannel);
1092 
1093     return TI_OK;
1094 }
1095 
1096 /************************************************************************
1097  *                        switchChannel_smStopWhileWait4Scr                 *
1098  ************************************************************************/
1099 /**
1100 *
1101 *
1102 * \b Description:
1103 *
1104 * This function is called when the station becomes Disconnected and the current
1105 * state is Wait4Scr. In this case perfrom:
1106  * Stop the timer
1107  * Enable TX if it was disabled
1108  * Zero the current command parameters
1109  * Complete SCR
1110 *
1111 * \b ARGS:
1112 *
1113 *  I   - pData - pointer to the SwitchChannel SM context  \n
1114 *
1115 * \b RETURNS:
1116 *
1117 *  TI_OK if successful, TI_NOK otherwise.
1118 *
1119 *
1120 *************************************************************************/
switchChannel_smStopWhileWait4Scr(void * pData)1121 static TI_STATUS switchChannel_smStopWhileWait4Scr(void *pData)
1122 {
1123     switchChannel_t                       *pSwitchChannel = (switchChannel_t*)pData;
1124 
1125     if (pSwitchChannel == NULL)
1126     {
1127         return TI_NOK;
1128     }
1129 
1130     TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_smStopWhileWait4Scr\n");
1131 
1132 
1133     switchChannel_zeroDatabase(pSwitchChannel);
1134 
1135     /* release the SCR */
1136     scr_clientComplete(pSwitchChannel->hSCR, SCR_CID_SWITCH_CHANNEL, SCR_RESOURCE_SERVING_CHANNEL);
1137 
1138     return TI_OK;
1139 }
1140 
1141 /************************************************************************
1142  *         switchChannel_smStopWhileSwitchChannelInProg                 *
1143  ************************************************************************/
1144 /**
1145 *
1146 *
1147 * \b Description:
1148 *
1149 * This function is called when the station becomes Disconnected and the current
1150 * state is SwitchChannelInProg. In this case perfrom:
1151  * Stop the timer
1152  * Enable TX if it was disabled
1153  * Zero the current command parameters
1154  * resume self test
1155  * Complete SCR
1156  * Exit PS
1157 *
1158 * \b ARGS:
1159 *
1160 *  I   - pData - pointer to the SwitchChannel SM context  \n
1161 *
1162 * \b RETURNS:
1163 *
1164 *  TI_OK if successful, TI_NOK otherwise.
1165 *
1166 *
1167 *************************************************************************/
switchChannel_smStopWhileSwitchChannelInProg(void * pData)1168 static TI_STATUS switchChannel_smStopWhileSwitchChannelInProg(void *pData)
1169 {
1170     switchChannel_t                       *pSwitchChannel = (switchChannel_t*)pData;
1171 
1172     if (pSwitchChannel == NULL)
1173     {
1174         return TI_NOK;
1175     }
1176 
1177     TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_smStopWhileSwitchChannelInProg\n");
1178 
1179     /* Exit PS */
1180     /*PowerMgr_exitFromDriverMode(pSwitchChannel->hPowerMngr, "SwitchChannel");*/
1181 
1182     apConn_indicateSwitchChannelFinished(pSwitchChannel->hApConn);
1183 
1184     TWD_CmdSwitchChannelCancel (pSwitchChannel->hTWD, pSwitchChannel->currentChannel);
1185     switchChannel_zeroDatabase(pSwitchChannel);
1186 
1187     /* release the SCR */
1188     scr_clientComplete(pSwitchChannel->hSCR, SCR_CID_SWITCH_CHANNEL, SCR_RESOURCE_SERVING_CHANNEL);
1189 
1190     return TI_OK;
1191 }
1192 
1193 
1194 
1195 
1196 /************************************************************************
1197  *                        switchChannel_zeroDatabase                    *
1198  ************************************************************************/
1199 /**
1200 *
1201 *
1202 * \b Description:
1203 *
1204 * This function is called when the SwitchChannel internal database should be zero.
1205  * The following parameters are zerod:
1206  * SwitchChannelChannelRange - the timestamps and validity state of channels
1207  * curChannelSwitchCmdParams - the current switch channel command parameters
1208 *
1209 * \b ARGS:
1210 *
1211 *  I   - pSwitchChannel - pointer to the SwitchChannel SM context  \n
1212 *  I   - channelNum - channel number  \n
1213 *  I   - timestamp - required timestamp  \n
1214 *
1215 * \b RETURNS:
1216 *
1217 *  None.
1218 *
1219 *
1220 *************************************************************************/
switchChannel_zeroDatabase(switchChannel_t * pSwitchChannel)1221 static void switchChannel_zeroDatabase(switchChannel_t *pSwitchChannel)
1222 {
1223 
1224     TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, "switchChannel_zeroDatabase\n");
1225 
1226 
1227     pSwitchChannel->curChannelSwitchCmdParams.channelNumber = 0;
1228     pSwitchChannel->curChannelSwitchCmdParams.channelSwitchCount = 0;
1229     pSwitchChannel->curChannelSwitchCmdParams.channelSwitchMode = SC_SWITCH_CHANNEL_MODE_NOT_TX_SUS;
1230     pSwitchChannel->currentChannel = 0;
1231 
1232 }
1233 
1234 /***********************************************************************
1235  *                        release_module
1236  ***********************************************************************/
1237 /*
1238 DESCRIPTION:    Called by the destroy function or by the create function (on failure)
1239                 Go over the vector, for each bit that is set, release the corresponding module.
1240 
1241 INPUT:      pSwitchChannel  -   SwitchChannel pointer.
1242             initVec -   Vector that contains a bit set for each module thah had been initiualized
1243 
1244 OUTPUT:
1245 
1246 RETURN:     TI_OK on success, TI_NOK otherwise
1247 
1248 ************************************************************************/
release_module(switchChannel_t * pSwitchChannel,TI_UINT32 initVec)1249 static void release_module(switchChannel_t *pSwitchChannel, TI_UINT32 initVec)
1250 {
1251     if (pSwitchChannel == NULL)
1252     {
1253         return;
1254     }
1255     if (initVec & (1 << SC_SM_INIT_BIT))
1256     {
1257         fsm_Unload(pSwitchChannel->hOs, pSwitchChannel->pSwitchChannelSm);
1258     }
1259 
1260     if (initVec & (1 << SC_INIT_BIT))
1261     {
1262         os_memoryFree(pSwitchChannel->hOs, pSwitchChannel, sizeof(switchChannel_t));
1263     }
1264 
1265     initVec = 0;
1266 }
1267 
1268 
1269 /**
1270 *
1271 * switchChannel_smNop - Do nothing
1272 *
1273 * \b Description:
1274 *
1275 * Do nothing in the SM.
1276 *
1277 * \b ARGS:
1278 *
1279 *  I   - pData - pointer to the SwitchChannel SM context  \n
1280 *
1281 * \b RETURNS:
1282 *
1283 *  TI_OK if successful, TI_NOK otherwise.
1284 *
1285 *
1286 */
switchChannel_smNop(void * pData)1287 static TI_STATUS switchChannel_smNop(void *pData)
1288 {
1289     switchChannel_t       *pSwitchChannel;
1290 
1291     pSwitchChannel = (switchChannel_t*)pData;
1292     if (pSwitchChannel == NULL)
1293     {
1294         return TI_NOK;
1295     }
1296     TRACE0(pSwitchChannel->hReport, REPORT_SEVERITY_INFORMATION, " switchChannel_smNop\n");
1297 
1298     return TI_OK;
1299 }
1300 
1301 /**
1302 *
1303 * switchChannel_smUnexpected - Unexpected event
1304 *
1305 * \b Description:
1306 *
1307 * Unexpected event in the SM.
1308 *
1309 * \b ARGS:
1310 *
1311 *  I   - pData - pointer to the SwitchChannel SM context  \n
1312 *
1313 * \b RETURNS:
1314 *
1315 *  TI_OK if successful, TI_NOK otherwise.
1316 *
1317 *
1318 */
switchChannel_smUnexpected(void * pData)1319 static TI_STATUS switchChannel_smUnexpected(void *pData)
1320 {
1321     switchChannel_t       *pSwitchChannel;
1322 
1323     pSwitchChannel = (switchChannel_t*)pData;
1324     if (pSwitchChannel == NULL)
1325     {
1326         return TI_NOK;
1327     }
1328     TRACE1(pSwitchChannel->hReport, REPORT_SEVERITY_ERROR, " switchChannel_smUnexpected, state = %d\n", pSwitchChannel->currentState);
1329 
1330     return TI_NOK;
1331 }
1332 
1333 /*******************************************************************************
1334 ***********                         Debug functions                  ***********
1335 *******************************************************************************/
1336 #ifdef TI_DBG
1337 
1338 /************************************************************************
1339  *                        switchChannel_recvCmd                         *
1340  ************************************************************************/
1341 /*DESCRIPTION: This function is called by MLME Parser upon receiving of
1342                 Beacon, Probe Response or Action with Switch Channel command,
1343                 or beacon/
1344                 performs the following:
1345                 -   Initializes the switching channel procedure.
1346                 -   Setting timer to the actual switching time(if needed)
1347 
1348 INPUT:      hSwitchChannel              -   SwitchChannel handle.
1349             switchMode          - indicates whether to stop transmission
1350                                 until the scheduled channel switch.
1351             newChannelNum       - indicates the number of the new channel.
1352             durationTime        - indicates the time (expressed in ms) until
1353                                 the scheduled channel switch should accure.
1354 
1355 OUTPUT:     None
1356 
1357 RETURN:     TI_OK on success, TI_NOK otherwise
1358 
1359 ************************************************************************/
1360 
switchChannel_recvCmd4Debug(TI_HANDLE hSwitchChannel,dot11_CHANNEL_SWITCH_t * channelSwitch,TI_BOOL BeaconPacket,TI_UINT8 channel)1361 static void switchChannel_recvCmd4Debug(TI_HANDLE hSwitchChannel, dot11_CHANNEL_SWITCH_t *channelSwitch, TI_BOOL BeaconPacket, TI_UINT8 channel)
1362 {
1363 
1364     switchChannel_t             *pSwitchChannel = (switchChannel_t *)hSwitchChannel;
1365     paramInfo_t                 param;
1366 
1367     if (pSwitchChannel==NULL)
1368     {
1369         return;
1370     }
1371 
1372 
1373     /* The following is for debug purposes only
1374         It will be operated when the Switch Channel cmd is opertated from debug CLI */
1375     if (pSwitchChannel->ignoreCancelSwitchChannelCmd != 0)
1376     {
1377         if (pSwitchChannel->ignoreCancelSwitchChannelCmd == 1)
1378         {
1379             /* update the new SCC params */
1380             pSwitchChannel->curChannelSwitchCmdParams.channelNumber = channelSwitch->channelNumber;
1381             pSwitchChannel->curChannelSwitchCmdParams.channelSwitchCount = channelSwitch->channelSwitchCount;
1382             pSwitchChannel->curChannelSwitchCmdParams.channelSwitchMode = channelSwitch->channelSwitchMode;
1383 
1384             pSwitchChannel->ignoreCancelSwitchChannelCmd = 2;
1385         }
1386         else if (channelSwitch->channelSwitchCount>0)
1387         {
1388             channelSwitch->channelSwitchCount --;
1389         }
1390         else
1391         {
1392             pSwitchChannel->ignoreCancelSwitchChannelCmd = 0;
1393         }
1394 
1395 
1396         /* search in the buffer pointer to the beginning of the
1397             Switch Cahnnel Announcement IE according to the IE ID */
1398 
1399         /* SC IE exists on the serving channel */
1400         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);
1401 
1402         /* Checking channel number validity */
1403         param.content.channel = channelSwitch->channelNumber;
1404         param.paramType = REGULATORY_DOMAIN_IS_CHANNEL_SUPPORTED;
1405         regulatoryDomain_getParam(pSwitchChannel->hRegulatoryDomain,&param);
1406         if (( !param.content.bIsChannelSupprted ) ||
1407             (channelSwitch->channelSwitchCount == 0) ||
1408             (channelSwitch->channelSwitchMode == SC_SWITCH_CHANNEL_MODE_TX_SUS))
1409         {   /* Trigger Roaming, if TX mode is disabled, the new channel number is invalid,
1410                 or the TBTT count is 0 */
1411             apConn_reportRoamingEvent(pSwitchChannel->hApConn, ROAMING_TRIGGER_SWITCH_CHANNEL, NULL);
1412         }
1413         else
1414         {   /* Invoke Switch Channel command */
1415             /* update the new SCC params */
1416             pSwitchChannel->curChannelSwitchCmdParams.channelNumber = channelSwitch->channelNumber;
1417             pSwitchChannel->curChannelSwitchCmdParams.channelSwitchCount = channelSwitch->channelSwitchCount;
1418             pSwitchChannel->curChannelSwitchCmdParams.channelSwitchMode = channelSwitch->channelSwitchMode;
1419             switchChannel_smEvent((TI_UINT8*)&pSwitchChannel->currentState, SC_EVENT_SC_CMD, pSwitchChannel);
1420         }
1421     }
1422 
1423 }
1424 
switchChannelDebug_setCmdParams(TI_HANDLE hSwitchChannel,SC_switchChannelCmdParam_e switchChannelCmdParam,TI_UINT8 param)1425 void switchChannelDebug_setCmdParams(TI_HANDLE hSwitchChannel, SC_switchChannelCmdParam_e switchChannelCmdParam, TI_UINT8 param)
1426 {
1427     switchChannel_t       *pSwitchChannel = (switchChannel_t*)hSwitchChannel;
1428 
1429     if (pSwitchChannel == NULL)
1430     {
1431         return;
1432     }
1433 
1434     switch (switchChannelCmdParam)
1435     {
1436     case SC_SWITCH_CHANNEL_NUM:
1437         WLAN_OS_REPORT(("SwitchChannelDebug_setSwitchChannelCmdParams, channelNum=%d \n ", param));
1438         pSwitchChannel->debugChannelSwitchCmdParams.channelNumber = param;
1439         break;
1440     case SC_SWITCH_CHANNEL_TBTT:
1441         WLAN_OS_REPORT(("SwitchChannelDebug_setSwitchChannelCmdParams, channelSwitchCount=%d \n ", param));
1442         pSwitchChannel->debugChannelSwitchCmdParams.channelSwitchCount = param;
1443         break;
1444     case SC_SWITCH_CHANNEL_MODE:
1445         WLAN_OS_REPORT(("SwitchChannelDebug_setSwitchChannelCmdParams, channelSwitchMode=%d \n ", param));
1446         pSwitchChannel->debugChannelSwitchCmdParams.channelSwitchMode = param;
1447         break;
1448     default:
1449         WLAN_OS_REPORT(("ERROR: SwitchChannelDebug_setSwitchChannelCmdParams, wrong switchChannelCmdParam=%d \n ",
1450                         switchChannelCmdParam));
1451             break;
1452     }
1453 
1454 }
switchChannelDebug_SwitchChannelCmdTest(TI_HANDLE hSwitchChannel,TI_BOOL BeaconPacket)1455 void switchChannelDebug_SwitchChannelCmdTest(TI_HANDLE hSwitchChannel, TI_BOOL BeaconPacket)
1456 {
1457     switchChannel_t       *pSwitchChannel = (switchChannel_t*)hSwitchChannel;
1458 
1459     if (pSwitchChannel == NULL)
1460     {
1461         return;
1462     }
1463 
1464     WLAN_OS_REPORT(("SwitchChannelDebug_SwitchChannelCmdTest, BeaconPacket=%d \n cmd params: channelNumber=%d, channelSwitchCount=%d, channelSwitchMode=%d \n",
1465                     BeaconPacket,
1466                     pSwitchChannel->debugChannelSwitchCmdParams.channelNumber,
1467                     pSwitchChannel->debugChannelSwitchCmdParams.channelSwitchCount,
1468                     pSwitchChannel->debugChannelSwitchCmdParams.channelSwitchMode));
1469 
1470 
1471     pSwitchChannel->ignoreCancelSwitchChannelCmd= 1;
1472     switchChannel_recvCmd4Debug(hSwitchChannel, &pSwitchChannel->debugChannelSwitchCmdParams, BeaconPacket, pSwitchChannel->currentChannel);
1473 }
1474 
switchChannelDebug_CancelSwitchChannelCmdTest(TI_HANDLE hSwitchChannel,TI_BOOL BeaconPacket)1475 void switchChannelDebug_CancelSwitchChannelCmdTest(TI_HANDLE hSwitchChannel, TI_BOOL BeaconPacket)
1476 {
1477 
1478     switchChannel_t       *pSwitchChannel = (switchChannel_t*)hSwitchChannel;
1479 
1480     if (pSwitchChannel == NULL)
1481     {
1482         return;
1483     }
1484 
1485     WLAN_OS_REPORT(("SwitchChannelDebug_SwitchChannelCmdTest, BeaconPacket=%d \n",BeaconPacket));
1486 
1487     pSwitchChannel->ignoreCancelSwitchChannelCmd= 0;
1488     switchChannel_recvCmd4Debug(hSwitchChannel, NULL, BeaconPacket, pSwitchChannel->currentChannel);
1489 }
1490 
1491 
switchChannelDebug_printStatus(TI_HANDLE hSwitchChannel)1492 void switchChannelDebug_printStatus(TI_HANDLE hSwitchChannel)
1493 {
1494     switchChannel_t       *pSwitchChannel = (switchChannel_t*)hSwitchChannel;
1495 
1496     if (pSwitchChannel == NULL)
1497     {
1498         return;
1499     }
1500 
1501     WLAN_OS_REPORT(("SwitchChannel debug params are: channelNumber=%d, channelSwitchCount=%d , channelSwitchMode=%d \n",
1502                     pSwitchChannel->debugChannelSwitchCmdParams.channelNumber,
1503                     pSwitchChannel->debugChannelSwitchCmdParams.channelSwitchCount,
1504                     pSwitchChannel->debugChannelSwitchCmdParams.channelSwitchMode));
1505 
1506     WLAN_OS_REPORT(("SwitchChannel state=%d, currentChannel=%d \n", pSwitchChannel->currentState, pSwitchChannel->currentChannel));
1507 
1508 
1509 }
1510 
switchChannelDebug_setChannelValidity(TI_HANDLE hSwitchChannel,TI_UINT8 channelNum,TI_BOOL validity)1511 void switchChannelDebug_setChannelValidity(TI_HANDLE hSwitchChannel, TI_UINT8 channelNum, TI_BOOL validity)
1512 {
1513     paramInfo_t param;
1514 
1515     switchChannel_t       *pSwitchChannel = (switchChannel_t*)hSwitchChannel;
1516 
1517     if (pSwitchChannel == NULL)
1518     {
1519         return;
1520     }
1521 
1522     param.paramType = REGULATORY_DOMAIN_SET_CHANNEL_VALIDITY;
1523     param.content.channelValidity.channelNum = channelNum;
1524     param.content.channelValidity.channelValidity = validity;
1525     regulatoryDomain_setParam(pSwitchChannel->hRegulatoryDomain, &param);
1526 
1527 }
1528 
1529 #endif  /* TI_DBG */
1530 
1531 
1532 
1533 
1534 
1535 
1536