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