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 */
80typedef enum
81{
82    SC_STATE_IDLE           = 0,
83    SC_STATE_WAIT_4_CMD     = 1,
84    SC_STATE_WAIT_4_SCR     = 2,
85    SC_STATE_SC_IN_PROG     = 3,
86    SC_STATE_LAST           = 4
87} switchChannel_smStates;
88
89/** State machine events */
90typedef enum
91{
92    SC_EVENT_START          = 0,
93    SC_EVENT_STOP           = 1,
94    SC_EVENT_SC_CMD         = 2,
95    SC_EVENT_SCR_RUN        = 3,
96    SC_EVENT_SCR_FAIL       = 4,
97    SC_EVENT_SC_CMPLT       = 5,
98    SC_EVENT_FW_RESET       = 6,
99    SC_EVENT_LAST           = 7
100} switchChannel_smEvents;
101
102
103#define SC_NUM_STATES       SC_STATE_LAST
104#define SC_NUM_EVENTS       SC_EVENT_LAST
105
106
107/* Structures */
108typedef struct
109{
110
111    /* SwitchChannel parameters that can be configured externally */
112    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 */
158static TI_STATUS switchChannel_smStartSwitchChannelCmd(void *pData);
159static TI_STATUS switchChannel_smReqSCR_UpdateCmd(void *pData);
160static TI_STATUS switchChannel_smSwitchChannelCmplt(void *pData);
161static TI_STATUS switchChannel_smFwResetWhileSCInProg(void *pData);
162static TI_STATUS switchChannel_smScrFailWhileWait4Scr(void *pData);
163static TI_STATUS switchChannel_smNop(void *pData);
164static TI_STATUS switchChannel_smUnexpected(void *pData);
165static TI_STATUS switchChannel_smStopWhileWait4Cmd(void *pData);
166static TI_STATUS switchChannel_smStopWhileWait4Scr(void *pData);
167static TI_STATUS switchChannel_smStopWhileSwitchChannelInProg(void *pData);
168static TI_STATUS switchChannel_smStart(void *pData);
169
170
171/* other functions */
172static void release_module(switchChannel_t *pSwitchChannel, TI_UINT32 initVec);
173static TI_STATUS switchChannel_smEvent(TI_UINT8 *currState, TI_UINT8 event, void* data);
174static void switchChannel_zeroDatabase(switchChannel_t *pSwitchChannel);
175void switchChannel_SwitchChannelCmdCompleteReturn(TI_HANDLE hSwitchChannel);
176void switchChannel_scrStatusCB(TI_HANDLE hSwitchChannel, EScrClientRequestStatus requestStatus,
177                               EScrResourceId eResource, EScePendReason pendReason );
178#ifdef TI_DBG
179static 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*/
208TI_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*/
258void 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
325TI_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*/
378TI_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*/
407TI_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*/
437TI_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
462INPUT:      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
469OUTPUT:     None
470
471RETURN:     TI_OK on success, TI_NOK otherwise
472
473************************************************************************/
474
475void 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*/
566void 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*/
600void 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*/
655static 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*************************************************************************/
704static 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*************************************************************************/
750static 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*************************************************************************/
815void 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*************************************************************************/
875static 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*************************************************************************/
933static 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*************************************************************************/
984static 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*************************************************************************/
1036static 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*************************************************************************/
1080static 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*************************************************************************/
1121static 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*************************************************************************/
1168static 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*************************************************************************/
1221static 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/*
1238DESCRIPTION:    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
1241INPUT:      pSwitchChannel  -   SwitchChannel pointer.
1242            initVec -   Vector that contains a bit set for each module thah had been initiualized
1243
1244OUTPUT:
1245
1246RETURN:     TI_OK on success, TI_NOK otherwise
1247
1248************************************************************************/
1249static 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*/
1287static 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*/
1319static 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
1348INPUT:      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
1355OUTPUT:     None
1356
1357RETURN:     TI_OK on success, TI_NOK otherwise
1358
1359************************************************************************/
1360
1361static 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
1425void 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}
1455void 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
1475void 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
1492void 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
1511void 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