Home | History | Annotate | Download | only in Ctrl_Interface
      1 /*
      2  * DrvMain.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 
     35 /** \file   DrvMain.c
     36  *  \brief  The DrvMain module. Handles driver init, stop and recovery processes.
     37  *
     38  *  \see    DrvMain.h
     39  */
     40 
     41 #define __FILE_ID__  FILE_ID_49
     42 #include "tidef.h"
     43 #include "osApi.h"
     44 #include "report.h"
     45 #include "context.h"
     46 #include "timer.h"
     47 #include "CmdHndlr.h"
     48 #include "DrvMain.h"
     49 #include "scrApi.h"
     50 #include "EvHandler.h"
     51 #include "connApi.h"
     52 #include "siteMgrApi.h"
     53 #include "sme.h"
     54 #include "SoftGeminiApi.h"
     55 #include "roamingMngrApi.h"
     56 #include "qosMngr_API.h"
     57 #include "TrafficMonitor.h"
     58 #include "PowerMgr_API.h"
     59 #include "EvHandler.h"
     60 #include "apConn.h"
     61 #include "currBss.h"
     62 #include "SwitchChannelApi.h"
     63 #include "ScanCncn.h"
     64 #include "healthMonitor.h"
     65 #include "scanMngrApi.h"
     66 #include "regulatoryDomainApi.h"
     67 #include "measurementMgrApi.h"
     68 #ifdef XCC_MODULE_INCLUDED
     69 #include "XCCMngr.h"
     70 #endif
     71 #include "TxnQueue.h"
     72 #include "TWDriver.h"
     73 #include "debug.h"
     74 #include "host_platform.h"
     75 #include "StaCap.h"
     76 #include "WlanDrvCommon.h"
     77 #include "DrvMainModules.h"
     78 #include "CmdDispatcher.h"
     79 
     80 
     81 #define SM_WATCHDOG_TIME_MS     20000  /* SM processes timeout is 20 sec. */
     82 
     83 #define SDIO_CONNECT_THRESHOLD  8
     84 
     85 
     86 /* Handle failure status from the SM callbacks by triggering the SM with FAILURE event */
     87 #define HANDLE_CALLBACKS_FAILURE_STATUS(hDrvMain, eStatus)      \
     88             if (eStatus != TI_OK) { drvMain_SmEvent (hDrvMain, SM_EVENT_FAILURE);  return; }
     89 
     90 /* The DrvMain SM states */
     91 typedef enum
     92 {
     93     /*  0 */ SM_STATE_IDLE,
     94     /*  1 */ SM_STATE_WAIT_INI_FILE,
     95     /*  2 */ SM_STATE_WAIT_NVS_FILE,
     96     /*  3 */ SM_STATE_HW_INIT,
     97     /*  4 */ SM_STATE_DOWNLOAD_FW_FILE,
     98     /*  5 */ SM_STATE_WAIT_FW_FILE,
     99     /*  6 */ SM_STATE_FW_INIT,
    100     /*  7 */ SM_STATE_FW_CONFIG,
    101     /*  8 */ SM_STATE_OPERATIONAL,
    102     /*  9 */ SM_STATE_DISCONNECTING,
    103     /* 10 */ SM_STATE_STOPPING,
    104     /* 11 */ SM_STATE_STOPPED,
    105     /* 12 */ SM_STATE_STOPPING_ON_FAIL,
    106     /* 13 */ SM_STATE_FAILED
    107 
    108 } ESmState;
    109 
    110 /* The DrvMain SM events */
    111 typedef enum
    112 {
    113     /*  0 */ SM_EVENT_START,
    114     /*  1 */ SM_EVENT_INI_FILE_READY,
    115     /*  2 */ SM_EVENT_NVS_FILE_READY,
    116     /*  3 */ SM_EVENT_HW_INIT_COMPLETE,
    117     /*  4 */ SM_EVENT_FW_FILE_READY,
    118     /*  5 */ SM_EVENT_FW_INIT_COMPLETE,
    119     /*  6 */ SM_EVENT_FW_CONFIG_COMPLETE,
    120     /*  7 */ SM_EVENT_STOP,
    121     /*  8 */ SM_EVENT_RECOVERY,
    122     /*  9 */ SM_EVENT_DISCONNECTED,
    123     /* 10 */ SM_EVENT_STOP_COMPLETE,
    124     /* 11 */ SM_EVENT_FAILURE
    125 
    126 } ESmEvent;
    127 
    128 /* The module's object */
    129 typedef struct
    130 {
    131     TStadHandlesList  tStadHandles; /* All STAD modules handles (distributed in driver init process) */
    132     TI_BOOL           bRecovery;    /* Indicates if we are during recovery process */
    133     ESmState          eSmState;     /* The DrvMain SM state. */
    134     ESmEvent          ePendingEvent;/* A pending event issued when the SM is busy */
    135     TI_UINT32         uPendingEventsCount; /* Counts the number of events pending for SM execution */
    136     TFileInfo         tFileInfo;    /* Information of last file retrieved by os_GetFile() */
    137     TI_UINT32         uContextId;   /* ID allocated to this module on registration to context module */
    138     EActionType       eAction;      /* The last action (start/stop) inserted to the driver */
    139     void             *hSignalObj;   /* The signal object used for waiting for action completion */
    140     TI_HANDLE         hWatchdogTimer;/* SM Watchdog timer - expires upon deadlock in Start/Stop/Recovery processes. */
    141     TBusDrvCfg        tBusDrvCfg;   /* A union (struc per each supported bus type) for the bus driver configuration */
    142 
    143 } TDrvMain;
    144 
    145 
    146 static void drvMain_Init (TI_HANDLE hDrvMain);
    147 static void drvMain_InitHwCb (TI_HANDLE hDrvMain, TI_STATUS eStatus);
    148 static void drvMain_InitFwCb (TI_HANDLE hDrvMain, TI_STATUS eStatus);
    149 static void drvMain_ConfigFwCb (TI_HANDLE hDrvMain, TI_STATUS eStatus);
    150 static void drvMain_TwdStopCb (TI_HANDLE hDrvMain, TI_STATUS eStatus);
    151 static void drvMain_InitFailCb (TI_HANDLE hDrvMain, TI_STATUS eStatus);
    152 static void drvMain_InitLocals (TDrvMain *pDrvMain);
    153 /* static void drvMain_SmWatchdogTimeout (TI_HANDLE hDrvMain); */
    154 static void drvMain_SmEvent (TI_HANDLE hDrvMain, ESmEvent eEvent);
    155 static void drvMain_Sm (TI_HANDLE hDrvMain, ESmEvent eEvent);
    156 
    157 /* External functions prototypes */
    158 
    159 /** \brief WLAN Driver I/F Get file
    160  *
    161  * \param  hOs         - OS module object handle
    162  * \param  pFileInfo   - Pointer to output file information
    163  * \return TI_OK on success or TI_NOK on failure
    164  *
    165  * \par Description
    166  * This function provides access to a requested init file:
    167  * It provides the requested file information and call the requester callback.
    168  * Note that in Linux the files were previously loaded to driver memory by the loader
    169  *
    170  * \sa
    171  */
    172 extern int  wlanDrvIf_GetFile (TI_HANDLE hOs, TFileInfo *pFileInfo);
    173 /** \brief WLAN Driver I/F Update Driver State
    174  *
    175  * \param  hOs          - OS module object handle
    176  * \param  eDriverState - New Driver State
    177  * \return void
    178  *
    179  * \par Description
    180  * This function Update the driver state (Idle | Running | Stopped |Failed):
    181  *
    182  * \sa
    183  */
    184 extern void wlanDrvIf_UpdateDriverState (TI_HANDLE hOs, EDriverSteadyState eDriverState);
    185 /** \brief WLAN Driver I/F Set MAC Address
    186  *
    187  * \param  hOs          - OS module object handle
    188  * \param  pMacAddr     - Pointer to MAC address to set
    189  * \return void
    190  *
    191  * \par Description
    192  * This function Update the driver MAC address by copy it to the network interface structure
    193  *
    194  * \sa
    195  */
    196 extern void wlanDrvIf_SetMacAddress (TI_HANDLE hOs, TI_UINT8 *pMacAddr);
    197 /** \brief OS Init Table INI File
    198  *
    199  * \param  hOs              - OS module object handle
    200  * \param  InitTable        - Pointer to initialization table
    201  * \param  file_buf         - Pointer to Input buffer from INI file
    202  * \param  file_length      - Length of input buffer from INI file
    203  * \return void
    204  *
    205  * \par Description
    206  * This function perform Initializing of init table accrding to data from INI file and driver defaults
    207  *
    208  * \sa
    209  */
    210 extern int  osInitTable_IniFile (TI_HANDLE hOs, TInitTable *InitTable, char *file_buf, int file_length);
    211 
    212 
    213 
    214 /*
    215  * \fn     drvMain_Create
    216  * \brief  Create the driver modules
    217  *
    218  * Create all STAD and TWD modules.
    219  * Then call all modules init functions which initializes their handles and variables.
    220  *
    221  * \note
    222  * \param  hOs          - Handle to the Os Abstraction Layer
    223  * \param  pDrvMainHndl - Pointer for returning the DrvMain handle.
    224  * \param  pCmdHndlr    - Pointer for returning the CmdHndlr handle.
    225  * \param  pContext     - Pointer for returning the Context handle.
    226  * \param  pTxDataQ     - Pointer for returning the TxDataQ handle.
    227  * \param  pTxMgmtQ     - Pointer for returning the TxMgmtQ handle.
    228  * \param  pTxCtrl      - Pointer for returning the TxCtrl handle.
    229  * \param  pTwd         - Pointer for returning the TWD handle.
    230  * \param  pEvHandler   - Pointer for returning the EvHndler handle.
    231  * \return Handle to the DrvMain module (NULL if failed)
    232  * \sa
    233  */
    234 TI_STATUS drvMain_Create (TI_HANDLE  hOs,
    235                           TI_HANDLE *pDrvMainHndl,
    236                           TI_HANDLE *pCmdHndlr,
    237                           TI_HANDLE *pContext,
    238                           TI_HANDLE *pTxDataQ,
    239                           TI_HANDLE *pTxMgmtQ,
    240                           TI_HANDLE *pTxCtrl,
    241                           TI_HANDLE *pTwd,
    242                           TI_HANDLE *pEvHandler)
    243 {
    244     /* Create the DrvMain module object. */
    245     TDrvMain *pDrvMain = (TDrvMain *) os_memoryAlloc (hOs, sizeof(TDrvMain));
    246 
    247     if (pDrvMain == NULL)
    248     {
    249         return TI_NOK;
    250     }
    251 
    252     os_memoryZero (hOs, (void *)pDrvMain, sizeof(TDrvMain));
    253 
    254     pDrvMain->tStadHandles.hDrvMain = (TI_HANDLE)pDrvMain;
    255     pDrvMain->tStadHandles.hOs = hOs;
    256 
    257     /* Create watchdog timer to detect deadlocks in the DrvMain SM processes. */
    258     /* return thr timer later on */
    259     /*pDrvMain->hWatchdogTimer = os_timerCreate (hOs, drvMain_SmWatchdogTimeout, (TI_HANDLE)pDrvMain);
    260     if (pDrvMain->hWatchdogTimer == NULL)
    261     {
    262         drvMain_Destroy (pDrvMain);
    263         return TI_NOK;
    264     }*/
    265 
    266 /*
    267  *   Create all driver modules
    268  *   =========================
    269  */
    270 
    271     pDrvMain->tStadHandles.hContext = context_Create (hOs);
    272     if (pDrvMain->tStadHandles.hContext == NULL)
    273     {
    274         drvMain_Destroy (pDrvMain);
    275         return TI_NOK;
    276     }
    277 
    278     pDrvMain->tStadHandles.hTimer = tmr_Create (hOs);
    279     if (pDrvMain->tStadHandles.hTimer == NULL)
    280     {
    281         drvMain_Destroy (pDrvMain);
    282         return TI_NOK;
    283     }
    284 
    285     pDrvMain->tStadHandles.hSCR = scr_create (hOs);
    286     if (pDrvMain->tStadHandles.hSCR == NULL)
    287     {
    288         drvMain_Destroy (pDrvMain);
    289         return TI_NOK;
    290     }
    291 
    292     pDrvMain->tStadHandles.hTxnQ = txnQ_Create (hOs);
    293     if (pDrvMain->tStadHandles.hTxnQ == NULL)
    294     {
    295         drvMain_Destroy (pDrvMain);
    296         return TI_NOK;
    297     }
    298 
    299     pDrvMain->tStadHandles.hEvHandler = EvHandler_Create (hOs);
    300     if (pDrvMain->tStadHandles.hEvHandler == NULL)
    301     {
    302         drvMain_Destroy (pDrvMain);
    303         return TI_NOK;
    304     }
    305 
    306     pDrvMain->tStadHandles.hReport = report_Create (hOs);
    307     if (pDrvMain->tStadHandles.hReport == NULL)
    308     {
    309         drvMain_Destroy (pDrvMain);
    310         return TI_NOK;
    311     }
    312 
    313     pDrvMain->tStadHandles.hConn = conn_create (hOs);
    314     if (pDrvMain->tStadHandles.hConn == NULL)
    315     {
    316         drvMain_Destroy (pDrvMain);
    317         return TI_NOK;
    318     }
    319 
    320     pDrvMain->tStadHandles.hScanCncn = scanCncn_Create (hOs);
    321     if (pDrvMain->tStadHandles.hScanCncn == NULL)
    322     {
    323         drvMain_Destroy (pDrvMain);
    324         return TI_NOK;
    325     }
    326 
    327     pDrvMain->tStadHandles.hSme = sme_Create (hOs);
    328     if (pDrvMain->tStadHandles.hSme == NULL)
    329     {
    330         drvMain_Destroy (pDrvMain);
    331         return TI_NOK;
    332     }
    333 
    334     pDrvMain->tStadHandles.hSiteMgr = siteMgr_create (hOs);
    335     if (pDrvMain->tStadHandles.hSiteMgr == NULL)
    336     {
    337         drvMain_Destroy (pDrvMain);
    338         return TI_NOK;
    339     }
    340 
    341     pDrvMain->tStadHandles.hMlmeSm = mlme_create (hOs);
    342     if (pDrvMain->tStadHandles.hMlmeSm == NULL)
    343     {
    344         drvMain_Destroy (pDrvMain);
    345         return TI_NOK;
    346     }
    347 
    348     pDrvMain->tStadHandles.hAuth = auth_create (hOs);
    349     if (pDrvMain->tStadHandles.hAuth == NULL)
    350     {
    351         drvMain_Destroy (pDrvMain);
    352         return TI_NOK;
    353     }
    354 
    355     pDrvMain->tStadHandles.hAssoc = assoc_create (hOs);
    356     if (pDrvMain->tStadHandles.hAssoc == NULL)
    357     {
    358         drvMain_Destroy (pDrvMain);
    359         return TI_NOK;
    360     }
    361 
    362     pDrvMain->tStadHandles.hRxData = rxData_create (hOs);
    363     if (pDrvMain->tStadHandles.hRxData == NULL)
    364     {
    365         drvMain_Destroy (pDrvMain);
    366         return TI_NOK;
    367     }
    368 
    369     pDrvMain->tStadHandles.hTxCtrl = txCtrl_Create (hOs);
    370     if (pDrvMain->tStadHandles.hTxCtrl == NULL)
    371     {
    372         drvMain_Destroy (pDrvMain);
    373         return TI_NOK;
    374     }
    375 
    376     pDrvMain->tStadHandles.hTxDataQ = txDataQ_Create(hOs);
    377     if (pDrvMain->tStadHandles.hTxDataQ == NULL)
    378     {
    379         drvMain_Destroy (pDrvMain);
    380         return TI_NOK;
    381     }
    382 
    383     pDrvMain->tStadHandles.hTxMgmtQ = txMgmtQ_Create(hOs);
    384     if (pDrvMain->tStadHandles.hTxMgmtQ == NULL)
    385     {
    386         drvMain_Destroy (pDrvMain);
    387         return TI_NOK;
    388     }
    389 
    390     pDrvMain->tStadHandles.hTxPort = txPort_create (hOs);
    391     if (pDrvMain->tStadHandles.hTxPort == NULL)
    392     {
    393         drvMain_Destroy (pDrvMain);
    394         return TI_NOK;
    395     }
    396 
    397     pDrvMain->tStadHandles.hCtrlData = ctrlData_create (hOs);
    398     if (pDrvMain->tStadHandles.hCtrlData == NULL)
    399     {
    400         drvMain_Destroy (pDrvMain);
    401         return TI_NOK;
    402     }
    403 
    404     pDrvMain->tStadHandles.hTrafficMon = TrafficMonitor_create (hOs);
    405     if (pDrvMain->tStadHandles.hTrafficMon == NULL)
    406     {
    407         drvMain_Destroy (pDrvMain);
    408         return TI_NOK;
    409     }
    410 
    411     pDrvMain->tStadHandles.hRsn = rsn_create (hOs);
    412     if (pDrvMain->tStadHandles.hRsn == NULL)
    413     {
    414         drvMain_Destroy (pDrvMain);
    415         return TI_NOK;
    416     }
    417 
    418     pDrvMain->tStadHandles.hRegulatoryDomain = regulatoryDomain_create (hOs);
    419     if (pDrvMain->tStadHandles.hRegulatoryDomain == NULL)
    420     {
    421         drvMain_Destroy (pDrvMain);
    422         return TI_NOK;
    423     }
    424 
    425     pDrvMain->tStadHandles.hMeasurementMgr = measurementMgr_create (hOs);
    426     if (pDrvMain->tStadHandles.hMeasurementMgr == NULL)
    427     {
    428         drvMain_Destroy (pDrvMain);
    429         return TI_NOK;
    430     }
    431 
    432     pDrvMain->tStadHandles.hSoftGemini = SoftGemini_create (hOs);
    433     if (pDrvMain->tStadHandles.hSoftGemini == NULL)
    434     {
    435         drvMain_Destroy (pDrvMain);
    436         return TI_NOK;
    437     }
    438 
    439 #ifdef XCC_MODULE_INCLUDED
    440     pDrvMain->tStadHandles.hXCCMngr = XCCMngr_create (hOs);
    441     if (pDrvMain->tStadHandles.hXCCMngr == NULL)
    442     {
    443         drvMain_Destroy (pDrvMain);
    444         return TI_NOK;
    445     }
    446 #else
    447     pDrvMain->tStadHandles.hXCCMngr = NULL;
    448 #endif
    449 
    450     pDrvMain->tStadHandles.hRoamingMngr = roamingMngr_create (hOs);
    451     if (pDrvMain->tStadHandles.hRoamingMngr == NULL)
    452     {
    453         drvMain_Destroy (pDrvMain);
    454         return TI_NOK;
    455     }
    456 
    457     pDrvMain->tStadHandles.hAPConnection = apConn_create (hOs);
    458     if (pDrvMain->tStadHandles.hAPConnection == NULL)
    459     {
    460         drvMain_Destroy (pDrvMain);
    461         return TI_NOK;
    462     }
    463 
    464     pDrvMain->tStadHandles.hCurrBss = currBSS_create (hOs);
    465     if (pDrvMain->tStadHandles.hCurrBss == NULL)
    466     {
    467         drvMain_Destroy (pDrvMain);
    468         return TI_NOK;
    469     }
    470 
    471     pDrvMain->tStadHandles.hQosMngr = qosMngr_create (hOs);
    472     if (pDrvMain->tStadHandles.hQosMngr == NULL)
    473     {
    474         drvMain_Destroy (pDrvMain);
    475         return TI_NOK;
    476     }
    477 
    478     pDrvMain->tStadHandles.hPowerMgr = PowerMgr_create (hOs);
    479     if (pDrvMain->tStadHandles.hPowerMgr == NULL)
    480     {
    481         drvMain_Destroy (pDrvMain);
    482         return TI_NOK;
    483     }
    484 
    485     pDrvMain->tStadHandles.hSwitchChannel = switchChannel_create (hOs);
    486     if (pDrvMain->tStadHandles.hSwitchChannel == NULL)
    487     {
    488         drvMain_Destroy (pDrvMain);
    489         return TI_NOK;
    490     }
    491 
    492     pDrvMain->tStadHandles.hScanMngr = scanMngr_create (hOs);
    493     if (NULL == pDrvMain->tStadHandles.hScanMngr)
    494     {
    495         drvMain_Destroy (pDrvMain);
    496         return TI_NOK;
    497     }
    498 
    499     pDrvMain->tStadHandles.hHealthMonitor = healthMonitor_create (hOs);
    500     if (NULL == pDrvMain->tStadHandles.hHealthMonitor)
    501     {
    502         drvMain_Destroy (pDrvMain);
    503         return TI_NOK;
    504     }
    505 
    506     pDrvMain->tStadHandles.hTWD = TWD_Create (hOs);
    507     if (pDrvMain->tStadHandles.hTWD == NULL)
    508     {
    509         drvMain_Destroy (pDrvMain);
    510         return TI_NOK;
    511     }
    512 
    513     pDrvMain->tStadHandles.hCmdHndlr = cmdHndlr_Create (hOs, pDrvMain->tStadHandles.hEvHandler);
    514     if (pDrvMain->tStadHandles.hCmdHndlr == NULL)
    515     {
    516         drvMain_Destroy (pDrvMain);
    517         return TI_NOK;
    518     }
    519 
    520     pDrvMain->tStadHandles.hCmdDispatch = cmdDispatch_Create (hOs);
    521     if (pDrvMain->tStadHandles.hCmdDispatch == NULL)
    522     {
    523         drvMain_Destroy (pDrvMain);
    524         return TI_NOK;
    525     }
    526 
    527     pDrvMain->tStadHandles.hStaCap = StaCap_Create (hOs);
    528     if (pDrvMain->tStadHandles.hStaCap == NULL)
    529     {
    530         drvMain_Destroy (pDrvMain);
    531         return TI_NOK;
    532     }
    533 
    534     /* Bind all modules handles */
    535     drvMain_Init ((TI_HANDLE)pDrvMain);
    536 
    537 
    538     /* Provide required handles to the OAL */
    539     *pDrvMainHndl = (TI_HANDLE)pDrvMain;
    540     *pCmdHndlr    = pDrvMain->tStadHandles.hCmdHndlr;
    541     *pContext     = pDrvMain->tStadHandles.hContext;
    542     *pTxDataQ     = pDrvMain->tStadHandles.hTxDataQ;
    543     *pTxMgmtQ     = pDrvMain->tStadHandles.hTxMgmtQ;
    544     *pTxCtrl      = pDrvMain->tStadHandles.hTxCtrl;
    545     *pTwd         = pDrvMain->tStadHandles.hTWD;
    546     *pEvHandler   = pDrvMain->tStadHandles.hEvHandler;
    547 
    548     WLAN_INIT_REPORT (("drvMain_Create: success\n"));
    549 
    550     return TI_OK;
    551 }
    552 
    553 /*
    554  * \fn     drvMain_Destroy
    555  * \brief  Destroy driver
    556  *
    557  * Destroy all STAD and TWD modules and resources.
    558  *
    559  * \note
    560  * \param  hDrvMain - The DrvMain object
    561  * \return TI_OK if succeeded, TI_NOK if failed.
    562  * \sa     drvMain_Create
    563  */
    564 TI_STATUS drvMain_Destroy (TI_HANDLE  hDrvMain)
    565 {
    566     TDrvMain *pDrvMain = (TDrvMain *)hDrvMain;
    567 
    568     hPlatform_Wlan_Hardware_DeInit ();
    569 
    570     if (pDrvMain == NULL)
    571     {
    572         return TI_NOK;
    573     }
    574 
    575     if (pDrvMain->tStadHandles.hScanMngr != NULL)
    576     {
    577         scanMngr_unload (pDrvMain->tStadHandles.hScanMngr);
    578     }
    579 
    580     if (pDrvMain->tStadHandles.hSiteMgr != NULL)
    581     {
    582         siteMgr_unLoad (pDrvMain->tStadHandles.hSiteMgr);
    583     }
    584 
    585     if (pDrvMain->tStadHandles.hSme != NULL)
    586     {
    587         sme_Destroy (pDrvMain->tStadHandles.hSme);
    588     }
    589 
    590     if (pDrvMain->tStadHandles.hConn != NULL)
    591     {
    592         conn_unLoad (pDrvMain->tStadHandles.hConn);
    593     }
    594 
    595     if (pDrvMain->tStadHandles.hTWD != NULL)
    596     {
    597         TWD_Destroy (pDrvMain->tStadHandles.hTWD);
    598     }
    599 
    600     if (pDrvMain->tStadHandles.hScanCncn != NULL)
    601     {
    602         scanCncn_Destroy (pDrvMain->tStadHandles.hScanCncn);
    603     }
    604 
    605     if (pDrvMain->tStadHandles.hTrafficMon != NULL)
    606     {
    607         TrafficMonitor_Destroy (pDrvMain->tStadHandles.hTrafficMon);
    608     }
    609 
    610     if (pDrvMain->tStadHandles.hCtrlData != NULL)
    611     {
    612         ctrlData_unLoad (pDrvMain->tStadHandles.hCtrlData);
    613     }
    614 
    615     if (pDrvMain->tStadHandles.hTxCtrl != NULL)
    616     {
    617         txCtrl_Unload (pDrvMain->tStadHandles.hTxCtrl);
    618     }
    619 
    620     if (pDrvMain->tStadHandles.hTxDataQ != NULL)
    621     {
    622         txDataQ_Destroy (pDrvMain->tStadHandles.hTxDataQ);
    623     }
    624 
    625     if (pDrvMain->tStadHandles.hTxMgmtQ != NULL)
    626     {
    627         txMgmtQ_Destroy (pDrvMain->tStadHandles.hTxMgmtQ);
    628     }
    629 
    630     if (pDrvMain->tStadHandles.hTxPort != NULL)
    631     {
    632         txPort_unLoad (pDrvMain->tStadHandles.hTxPort);
    633     }
    634 
    635     if (pDrvMain->tStadHandles.hRxData != NULL)
    636     {
    637         rxData_unLoad (pDrvMain->tStadHandles.hRxData);
    638     }
    639 
    640     if (pDrvMain->tStadHandles.hAssoc != NULL)
    641     {
    642         assoc_unload (pDrvMain->tStadHandles.hAssoc);
    643     }
    644 
    645     if (pDrvMain->tStadHandles.hAuth != NULL)
    646     {
    647         auth_unload (pDrvMain->tStadHandles.hAuth);
    648     }
    649 
    650     if (pDrvMain->tStadHandles.hMlmeSm != NULL)
    651     {
    652         mlme_unload (pDrvMain->tStadHandles.hMlmeSm);
    653     }
    654 
    655     if (pDrvMain->tStadHandles.hSCR != NULL)
    656     {
    657         scr_release (pDrvMain->tStadHandles.hSCR);
    658     }
    659 
    660     if (pDrvMain->tStadHandles.hTxnQ != NULL)
    661     {
    662         txnQ_Destroy (pDrvMain->tStadHandles.hTxnQ);
    663     }
    664 
    665     if (pDrvMain->tStadHandles.hRsn != NULL)
    666     {
    667         rsn_unload (pDrvMain->tStadHandles.hRsn);
    668     }
    669 
    670     if (pDrvMain->tStadHandles.hRegulatoryDomain != NULL)
    671     {
    672         regulatoryDomain_destroy (pDrvMain->tStadHandles.hRegulatoryDomain);
    673     }
    674 
    675     if (pDrvMain->tStadHandles.hMeasurementMgr != NULL)
    676     {
    677         measurementMgr_destroy (pDrvMain->tStadHandles.hMeasurementMgr);
    678     }
    679 
    680     if (pDrvMain->tStadHandles.hSoftGemini != NULL)
    681     {
    682         SoftGemini_destroy (pDrvMain->tStadHandles.hSoftGemini);
    683     }
    684 
    685 #ifdef XCC_MODULE_INCLUDED
    686     if (pDrvMain->tStadHandles.hXCCMngr != NULL)
    687     {
    688         XCCMngr_unload (pDrvMain->tStadHandles.hXCCMngr);
    689     }
    690 #endif
    691 
    692     if (pDrvMain->tStadHandles.hRoamingMngr != NULL)
    693     {
    694         roamingMngr_unload (pDrvMain->tStadHandles.hRoamingMngr);
    695     }
    696 
    697     if (pDrvMain->tStadHandles.hQosMngr != NULL)
    698     {
    699         qosMngr_destroy (pDrvMain->tStadHandles.hQosMngr);
    700     }
    701 
    702     if (pDrvMain->tStadHandles.hPowerMgr != NULL)
    703     {
    704         PowerMgr_destroy (pDrvMain->tStadHandles.hPowerMgr);
    705     }
    706 
    707     if (pDrvMain->tStadHandles.hAPConnection != NULL)
    708     {
    709         apConn_unload (pDrvMain->tStadHandles.hAPConnection);
    710     }
    711 
    712     if (pDrvMain->tStadHandles.hCurrBss != NULL)
    713     {
    714         currBSS_unload (pDrvMain->tStadHandles.hCurrBss);
    715     }
    716 
    717     if (pDrvMain->tStadHandles.hSwitchChannel != NULL)
    718     {
    719         switchChannel_unload (pDrvMain->tStadHandles.hSwitchChannel);
    720     }
    721 
    722     if (pDrvMain->tStadHandles.hHealthMonitor != NULL)
    723     {
    724         healthMonitor_unload (pDrvMain->tStadHandles.hHealthMonitor);
    725     }
    726 
    727     if (pDrvMain->tStadHandles.hCmdHndlr && pDrvMain->tStadHandles.hEvHandler)
    728     {
    729         cmdHndlr_Destroy (pDrvMain->tStadHandles.hCmdHndlr, pDrvMain->tStadHandles.hEvHandler);
    730     }
    731 
    732     if (pDrvMain->tStadHandles.hEvHandler != NULL)
    733     {
    734          EvHandlerUnload (pDrvMain->tStadHandles.hEvHandler);
    735     }
    736 
    737     if (pDrvMain->tStadHandles.hCmdDispatch)
    738     {
    739         cmdDispatch_Destroy (pDrvMain->tStadHandles.hCmdDispatch);
    740     }
    741 
    742     /* Note: The Timer module must be destroyed last, so all created timers are already destroyed!! */
    743     if (pDrvMain->tStadHandles.hTimer != NULL)
    744     {
    745         tmr_Destroy (pDrvMain->tStadHandles.hTimer);
    746     }
    747 
    748     /* Destroy the SM watchdog timer */
    749     if (pDrvMain->hWatchdogTimer != NULL)
    750     {
    751         os_timerDestroy (pDrvMain->tStadHandles.hOs, pDrvMain->hWatchdogTimer);
    752     }
    753 
    754     /* Note: Moved after timers for locks */
    755     if (pDrvMain->tStadHandles.hContext != NULL)
    756     {
    757         context_Destroy (pDrvMain->tStadHandles.hContext);
    758     }
    759 
    760     if (pDrvMain->tStadHandles.hStaCap != NULL)
    761     {
    762         StaCap_Destroy (pDrvMain->tStadHandles.hStaCap);
    763     }
    764 
    765     if (pDrvMain->tStadHandles.hReport != NULL)
    766     {
    767         report_Unload (pDrvMain->tStadHandles.hReport);
    768     }
    769 
    770     /* Destroy the DrvMain object */
    771     os_memoryFree (pDrvMain->tStadHandles.hOs, hDrvMain, sizeof(TDrvMain));
    772 
    773     return TI_OK;
    774 }
    775 
    776 void drvMain_SmeStop (TI_HANDLE hDrvMain)
    777 {
    778     drvMain_SmEvent (hDrvMain, SM_EVENT_DISCONNECTED);
    779 }
    780 
    781 
    782 /*
    783  * \fn     drvMain_Init
    784  * \brief  Init driver modules
    785  *
    786  * Called from OS context following the driver creation.
    787  * Calls all STAD and TWD modules Init functions, which are saving other modules handles,
    788  *     registering to other modules and initializing their variables.
    789  *
    790  * \note
    791  * \param  hDrvMain - The DrvMain object
    792  * \return void
    793  * \sa     drvMain_Create
    794  */
    795 static void drvMain_Init (TI_HANDLE hDrvMain)
    796 {
    797     TDrvMain    *pDrvMain = (TDrvMain *) hDrvMain;
    798     TStadHandlesList *pModules = &pDrvMain->tStadHandles; /* The STAD modules handles list */
    799 
    800     /*
    801      *  Init all modules handles, variables and registries
    802      */
    803     context_Init (pModules->hContext, pModules->hOs, pModules->hReport);
    804     tmr_Init (pModules->hTimer, pModules->hOs, pModules->hReport, pModules->hContext);
    805     txnQ_Init (pModules->hTxnQ, pModules->hOs, pModules->hReport, pModules->hContext);
    806     scr_init (pModules);
    807     conn_init (pModules);
    808     ctrlData_init (pModules,
    809                  #ifdef XCC_MODULE_INCLUDED
    810                    XCCMngr_LinkTestRetriesUpdate, pModules->hXCCMngr);
    811                  #else
    812                    NULL, NULL);
    813                  #endif
    814     siteMgr_init (pModules);
    815     regulatoryDomain_init (pModules);
    816     scanCncn_Init (pModules);
    817     auth_init (pModules);
    818     mlme_init (pModules);
    819     assoc_init (pModules);
    820     rxData_init (pModules);
    821     txCtrl_Init (pModules);
    822     txDataQ_Init (pModules);
    823     txMgmtQ_Init (pModules);
    824     txPort_init (pModules);
    825     TrafficMonitor_Init (pModules, 1000 /* pInitTable->trafficMonitorMinIntervalPercentage */);
    826     sme_Init (pModules);
    827     rsn_init (pModules);
    828     measurementMgr_init (pModules);
    829 #ifdef XCC_MODULE_INCLUDED
    830     XCCMngr_init (pModules);
    831 #endif
    832     scanMngr_init (pModules);
    833     currBSS_init (pModules);
    834     apConn_init (pModules);
    835     roamingMngr_init (pModules);
    836     qosMngr_init (pModules);
    837     switchChannel_init (pModules);
    838     healthMonitor_init (pModules);
    839     PowerMgr_init (pModules);
    840     SoftGemini_init (pModules);
    841     cmdDispatch_Init (pModules);
    842     StaCap_Init (pModules);
    843     cmdHndlr_Init (pModules);
    844 
    845     /* Init TWD component (handles, variables and registries) and provide callbacks for next steps */
    846     TWD_Init (pModules->hTWD,
    847               pModules->hReport,
    848               pModules->hDrvMain,
    849               pModules->hTimer,
    850               pModules->hContext,
    851               pModules->hTxnQ,
    852               (TTwdCallback)drvMain_InitHwCb,
    853               (TTwdCallback)drvMain_InitFwCb,
    854               (TTwdCallback)drvMain_ConfigFwCb,
    855               (TTwdCallback)drvMain_TwdStopCb,
    856               (TTwdCallback)drvMain_InitFailCb);
    857 
    858     /* Init DrvMain module local variables */
    859     drvMain_InitLocals (pDrvMain);
    860 }
    861 
    862 
    863 /*
    864  * \fn     drvMain_SetDefaults
    865  * \brief  Set driver default configuration
    866  *
    867  * Configure all STAD and TWD modules with their default settings from the ini-file.
    868  * Timers creation is also done at this stage.
    869  *
    870  * \note
    871  * \param  hDrvMain - The DrvMain object
    872  * \param  pBuf     - The ini-file data.
    873  * \param  uLength  - The ini-file length.
    874  * \return TI_OK if succeeded, TI_NOK if failed.
    875  * \sa     drvMain_Init
    876  */
    877 static TI_STATUS drvMain_SetDefaults (TI_HANDLE hDrvMain, TI_UINT8 *pBuf, TI_UINT32 uLength)
    878 {
    879     TDrvMain   *pDrvMain = (TDrvMain *) hDrvMain;
    880     TInitTable *pInitTable;
    881     TI_STATUS   eStatus;
    882 
    883     pInitTable = os_memoryAlloc (pDrvMain->tStadHandles.hOs, sizeof(TInitTable));
    884 
    885     /* Parse defaults */
    886     eStatus = osInitTable_IniFile (pDrvMain->tStadHandles.hOs, pInitTable, (char*)pBuf, (int)uLength);
    887 
    888     /*
    889      *  Configure modules with their default settings
    890      */
    891     report_SetDefaults (pDrvMain->tStadHandles.hReport, &pInitTable->tReport);
    892     context_SetDefaults (pDrvMain->tStadHandles.hContext, &pInitTable->tContextInitParams);
    893     TWD_SetDefaults (pDrvMain->tStadHandles.hTWD, &pInitTable->twdInitParams);
    894     conn_SetDefaults (pDrvMain->tStadHandles.hConn, &pInitTable->connInitParams);
    895     ctrlData_SetDefaults (pDrvMain->tStadHandles.hCtrlData, &pInitTable->ctrlDataInitParams);
    896     siteMgr_SetDefaults (pDrvMain->tStadHandles.hSiteMgr, &pInitTable->siteMgrInitParams);
    897     regulatoryDomain_SetDefaults (pDrvMain->tStadHandles.hRegulatoryDomain, &pInitTable->regulatoryDomainInitParams);
    898     scanCncn_SetDefaults (pDrvMain->tStadHandles.hScanCncn, &pInitTable->tScanCncnInitParams);
    899     auth_SetDefaults (pDrvMain->tStadHandles.hAuth, &pInitTable->authInitParams);
    900     assoc_SetDefaults (pDrvMain->tStadHandles.hAssoc, &pInitTable->assocInitParams);
    901     rxData_SetDefaults (pDrvMain->tStadHandles.hRxData, &pInitTable->rxDataInitParams);
    902     sme_SetDefaults (pDrvMain->tStadHandles.hSme, &pInitTable->tSmeModifiedInitParams, &pInitTable->tSmeInitParams);
    903     rsn_SetDefaults (pDrvMain->tStadHandles.hRsn, &pInitTable->rsnInitParams);
    904     measurementMgr_SetDefaults (pDrvMain->tStadHandles.hMeasurementMgr, &pInitTable->measurementInitParams);
    905 #ifdef XCC_MODULE_INCLUDED
    906     XCCMngr_SetDefaults (pDrvMain->tStadHandles.hXCCMngr, &pInitTable->XCCMngrParams);
    907 #endif /*XCC_MODULE_INCLUDED*/
    908     apConn_SetDefaults (pDrvMain->tStadHandles.hAPConnection, &pInitTable->apConnParams);
    909     qosMngr_SetDefaults (pDrvMain->tStadHandles.hQosMngr, &pInitTable->qosMngrInitParams);
    910     switchChannel_SetDefaults (pDrvMain->tStadHandles.hSwitchChannel, &pInitTable->SwitchChannelInitParams);
    911     healthMonitor_SetDefaults (pDrvMain->tStadHandles.hHealthMonitor, &pInitTable->healthMonitorInitParams);
    912     PowerMgr_SetDefaults (pDrvMain->tStadHandles.hPowerMgr, &pInitTable->PowerMgrInitParams);
    913     SoftGemini_SetDefaults (pDrvMain->tStadHandles.hSoftGemini, &pInitTable->SoftGeminiInitParams);
    914     txDataQ_SetDefaults (pDrvMain->tStadHandles.hTxDataQ, &pInitTable->txDataInitParams);
    915     txCtrl_SetDefaults (pDrvMain->tStadHandles.hTxCtrl, &pInitTable->txDataInitParams);
    916     currBSS_SetDefaults (pDrvMain->tStadHandles.hCurrBss, &pInitTable->tCurrBssInitParams);
    917     mlme_SetDefaults (pDrvMain->tStadHandles.hMlmeSm, &pInitTable->tMlmeInitParams);
    918 
    919     scanMngr_SetDefaults(pDrvMain->tStadHandles.hScanMngr, &pInitTable->tRoamScanMngrInitParams);
    920     roamingMngr_setDefaults(pDrvMain->tStadHandles.hRoamingMngr, &pInitTable->tRoamScanMngrInitParams);
    921 
    922     /* Set DrvMain local defaults */
    923     pDrvMain->tBusDrvCfg.tSdioCfg.uBlkSizeShift         = pInitTable->tDrvMainParams.uSdioBlkSizeShift;
    924     pDrvMain->tBusDrvCfg.tSdioCfg.uBusDrvThreadPriority = pInitTable->tDrvMainParams.uBusDrvThreadPriority;
    925     os_SetDrvThreadPriority (pDrvMain->tStadHandles.hOs, pInitTable->tDrvMainParams.uWlanDrvThreadPriority);
    926 
    927     /* Release the init table memory */
    928     os_memoryFree (pDrvMain->tStadHandles.hOs, pInitTable, sizeof(TInitTable));
    929 
    930     return eStatus;
    931 }
    932 
    933 
    934 /*
    935  * \fn     drvMain_xxx...Cb
    936  * \brief  Callback functions for the init/stop stages completion
    937  *
    938  * The following callback functions are called from other modules (most from TWD)
    939  *     when the current init/stop step is completed.
    940  * Note that the callbacks are called anyway, either in the original context (if completed), or
    941  *     in another context if pending.
    942  * The first case (same context) may lead to a recursion of the SM, so a special handling is added
    943  *     to the SM to prevent recursion (see drvMain_Sm).
    944  *
    945  * drvMain_InitHwCb   - HW init completion callback
    946  * drvMain_InitFwCb   - FW init (mainly download) completion callback
    947  * drvMain_ConfigFwCb - FW configuration completion callback
    948  * drvMain_TwdStopCb  - TWD stopping completion callback
    949  * drvMain_InitFailCb - FW init faulty completion callback
    950  * drvMain_SmeStopCb  - SME stopping completion callback
    951  * drvMain_GetFileCb  - Getting-file completion callback
    952  *
    953  * \note
    954  * \param  hDrvMain - The DrvMain object
    955  * \param  eStatus  - The process result (TI_OK if succeeded, TI_NOK if failed)
    956  * \return void
    957  * \sa     drvMain_Create
    958  */
    959 static void drvMain_InitHwCb (TI_HANDLE hDrvMain, TI_STATUS eStatus)
    960 {
    961     HANDLE_CALLBACKS_FAILURE_STATUS(hDrvMain, eStatus);
    962     drvMain_SmEvent (hDrvMain, SM_EVENT_HW_INIT_COMPLETE);
    963 }
    964 
    965 static void drvMain_InitFwCb (TI_HANDLE hDrvMain, TI_STATUS eStatus)
    966 {
    967     HANDLE_CALLBACKS_FAILURE_STATUS(hDrvMain, eStatus);
    968     drvMain_SmEvent (hDrvMain, SM_EVENT_FW_INIT_COMPLETE);
    969 }
    970 
    971 static void drvMain_ConfigFwCb (TI_HANDLE hDrvMain, TI_STATUS eStatus)
    972 {
    973     HANDLE_CALLBACKS_FAILURE_STATUS(hDrvMain, eStatus);
    974     drvMain_SmEvent (hDrvMain, SM_EVENT_FW_CONFIG_COMPLETE);
    975 }
    976 
    977 static void drvMain_TwdStopCb (TI_HANDLE hDrvMain, TI_STATUS eStatus)
    978 {
    979     HANDLE_CALLBACKS_FAILURE_STATUS(hDrvMain, eStatus);
    980     drvMain_SmEvent (hDrvMain, SM_EVENT_STOP_COMPLETE);
    981 }
    982 
    983 static void drvMain_InitFailCb (TI_HANDLE hDrvMain, TI_STATUS eStatus)
    984 {
    985     drvMain_SmEvent (hDrvMain, SM_EVENT_FAILURE);
    986     /*
    987      * Note that this call will pass the SM to the FAILED state, since this event
    988      *     is not handled by any state.
    989      */
    990 }
    991 
    992 static void drvMain_InvokeAction (TI_HANDLE hDrvMain)
    993 {
    994     TDrvMain *pDrvMain = (TDrvMain *)hDrvMain;
    995 
    996     switch (pDrvMain->eAction)
    997     {
    998     case ACTION_TYPE_START:
    999         drvMain_SmEvent (hDrvMain, SM_EVENT_START);
   1000         break;
   1001     case ACTION_TYPE_STOP:
   1002         drvMain_SmEvent (hDrvMain, SM_EVENT_STOP);
   1003         break;
   1004         default:
   1005             TRACE1(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_ERROR , "drvMain_InvokeAction(): Action=%d\n", pDrvMain->eAction);
   1006     }
   1007 }
   1008 
   1009 static void drvMain_GetFileCb (TI_HANDLE hDrvMain)
   1010 {
   1011     TDrvMain *pDrvMain = (TDrvMain *)hDrvMain;
   1012     ESmEvent  eSmEvent;
   1013 
   1014     switch (pDrvMain->tFileInfo.eFileType)
   1015     {
   1016         case FILE_TYPE_INI:     eSmEvent = SM_EVENT_INI_FILE_READY;    break;
   1017         case FILE_TYPE_NVS:     eSmEvent = SM_EVENT_NVS_FILE_READY;    break;
   1018         case FILE_TYPE_FW:      eSmEvent = SM_EVENT_FW_FILE_READY;     break;
   1019         case FILE_TYPE_FW_NEXT: eSmEvent = SM_EVENT_FW_FILE_READY;     break;
   1020         default:
   1021             TRACE1(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_ERROR , "drvMain_GetFileCb(): Unknown eFileType=%d\n", pDrvMain->tFileInfo.eFileType);
   1022             return;
   1023     }
   1024     drvMain_SmEvent (hDrvMain, eSmEvent);
   1025 }
   1026 
   1027 
   1028 /*
   1029  * \fn     drvMain_InitLocals
   1030  * \brief  Init DrvMain module
   1031  *
   1032  * Init the DrvMain variables, register to other modules and set device power to off.
   1033  *
   1034  * \note
   1035  * \param  pDrvMain - The DrvMain object
   1036  * \return void
   1037  * \sa     drvMain_Init
   1038  */
   1039 static void drvMain_InitLocals (TDrvMain *pDrvMain)
   1040 {
   1041     /* Initialize the module's local varniables to default values */
   1042     pDrvMain->tFileInfo.eFileType   = FILE_TYPE_INI;
   1043     pDrvMain->tFileInfo.fCbFunc     = drvMain_GetFileCb;
   1044     pDrvMain->tFileInfo.hCbHndl     = (TI_HANDLE)pDrvMain;
   1045     pDrvMain->eSmState              = SM_STATE_IDLE;
   1046     pDrvMain->uPendingEventsCount   = 0;
   1047     pDrvMain->bRecovery             = TI_FALSE;
   1048     pDrvMain->eAction               = ACTION_TYPE_NONE;
   1049 
   1050     /* Register the Action callback to the context engine and get the client ID */
   1051     pDrvMain->uContextId = context_RegisterClient (pDrvMain->tStadHandles.hContext,
   1052                                                    drvMain_InvokeAction,
   1053                                                    (TI_HANDLE)pDrvMain,
   1054                                                    TI_TRUE,
   1055                                                    "ACTION",
   1056                                                    sizeof("ACTION"));
   1057 
   1058     /* Platform specific HW preparations */
   1059 	hPlatform_Wlan_Hardware_Init(pDrvMain->tStadHandles.hOs);
   1060 
   1061     /* Insure that device power is off (expected to be) */
   1062     hPlatform_DevicePowerOff ();
   1063 }
   1064 
   1065 
   1066 /*
   1067  * \fn     drvMain_InitHw & drvMain_InitFw
   1068  * \brief  Init HW and Init FW sequences
   1069  *
   1070  * drvMain_InitHw - HW init sequence which writes and reads some HW registers
   1071  *                      that are needed prior to FW download.
   1072  * drvMain_InitFw - FW init sequence which downloads the FW image and waits for
   1073  *                      FW init-complete indication.
   1074  *
   1075  * \note
   1076  * \param  hDrvMain - The DrvMain object
   1077  * \param  pBuf     - The file data (NVS for HW-init, FW-Image for FW-init).
   1078  * \param  uLength  - The file length.
   1079  * \return TI_OK if succeeded, TI_NOK if failed.
   1080  * \sa
   1081  */
   1082 static TI_STATUS drvMain_InitHw (TI_HANDLE hDrvMain, TI_UINT8 *pbuf, TI_UINT32 uLength)
   1083 {
   1084     TDrvMain   *pDrvMain = (TDrvMain *) hDrvMain;
   1085 
   1086     return TWD_InitHw (pDrvMain->tStadHandles.hTWD, pbuf, uLength);
   1087 }
   1088 
   1089 static TI_STATUS drvMain_InitFw (TI_HANDLE hDrvMain, TFileInfo *pFileInfo)
   1090 {
   1091     TDrvMain   *pDrvMain = (TDrvMain *) hDrvMain;
   1092 
   1093     return TWD_InitFw (pDrvMain->tStadHandles.hTWD, pFileInfo);
   1094 }
   1095 
   1096 
   1097 /*
   1098  * \fn     drvMain_ConfigFw
   1099  * \brief  Configure the FW
   1100  *
   1101  * The step that follows the FW Init (mainly FW download).
   1102  * The Command-Mailbox interface is enabled here and the FW is configured.
   1103  *
   1104  * \note
   1105  * \param  pDrvMain - The DrvMain object
   1106  * \return TI_OK
   1107  * \sa     drvMain_Init
   1108  */
   1109 static TI_STATUS drvMain_ConfigFw (TI_HANDLE hDrvMain)
   1110 {
   1111     TDrvMain    *pDrvMain = (TDrvMain *) hDrvMain;
   1112 
   1113     /* get pointer to FW static info (already in driver memory) */
   1114     TFwInfo     *pFwInfo  = TWD_GetFWInfo (pDrvMain->tStadHandles.hTWD);
   1115     TI_UINT8    *pMacAddr = (TI_UINT8 *)pFwInfo->macAddress; /* STA MAC address */
   1116 
   1117     /* Update driver's MAC address */
   1118     wlanDrvIf_SetMacAddress (pDrvMain->tStadHandles.hOs, pMacAddr);
   1119 
   1120     /*
   1121      *  Exit from init mode should be before smeSM starts. this enable us to send
   1122      *  command to the MboxQueue(that store the command) while the interrupts are masked.
   1123      *  the interrupt would be enable at the end of the init process.
   1124      */
   1125     TWD_ExitFromInitMode (pDrvMain->tStadHandles.hTWD);
   1126 
   1127     /* Configure the FW from the TWD DB */
   1128     TWD_ConfigFw (pDrvMain->tStadHandles.hTWD);
   1129 
   1130     TRACE0(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_INIT , "EXIT FROM INIT\n");
   1131 
   1132     /* Print the driver and firmware version and the mac address */
   1133     os_printf("\n");
   1134     os_printf("-----------------------------------------------------\n");
   1135     os_printf("Driver Version  : %s\n", SW_VERSION_STR);
   1136     os_printf("Firmware Version: %s\n", pFwInfo->fwVer);
   1137     os_printf("Station ID      : %02X-%02X-%02X-%02X-%02X-%02X\n",
   1138               pMacAddr[0], pMacAddr[1], pMacAddr[2], pMacAddr[3], pMacAddr[4], pMacAddr[5]);
   1139     os_printf("-----------------------------------------------------\n");
   1140     os_printf("\n");
   1141 
   1142     return TI_OK;
   1143 }
   1144 
   1145 
   1146 /*
   1147  * \fn     drvMain_StopActivities
   1148  * \brief  Freeze driver activities
   1149  *
   1150  * Freeze all driver activities due to stop command or recovery process.
   1151  *
   1152  * \note
   1153  * \param  pDrvMain - The DrvMain object
   1154  * \return TI_OK if succeeded, TI_NOK if failed.
   1155  * \sa     drvMain_EnableActivities
   1156  */
   1157 static TI_STATUS drvMain_StopActivities (TDrvMain *pDrvMain)
   1158 {
   1159     txPort_suspendTx (pDrvMain->tStadHandles.hTxPort);
   1160 
   1161     /* Disable External Inputs (IRQs and commands) */
   1162     TWD_DisableInterrupts(pDrvMain->tStadHandles.hTWD);
   1163     cmdHndlr_Disable (pDrvMain->tStadHandles.hCmdHndlr);
   1164 
   1165     /* Initiate TWD Restart */
   1166     return TWD_Stop (pDrvMain->tStadHandles.hTWD);
   1167 }
   1168 
   1169 
   1170 /*
   1171  * \fn     drvMain_EnableActivities
   1172  * \brief  Enable driver activities
   1173  *
   1174  * Enable driver activities after init or recovery process completion.
   1175  *
   1176  * \note
   1177  * \param  pDrvMain - The DrvMain object
   1178  * \return void
   1179  * \sa     drvMain_StopActivities
   1180  */
   1181 static void drvMain_EnableActivities (TDrvMain *pDrvMain)
   1182 {
   1183     txPort_resumeTx (pDrvMain->tStadHandles.hTxPort);
   1184 
   1185    /* Enable External Inputs (IRQ is enabled elsewhere) */
   1186     cmdHndlr_Enable (pDrvMain->tStadHandles.hCmdHndlr);
   1187 
   1188     /* Enable external events from FW */
   1189     TWD_EnableExternalEvents (pDrvMain->tStadHandles.hTWD);
   1190 
   1191 
   1192 }
   1193 
   1194 
   1195 /*
   1196  * \fn     drvMain_ClearQueuedEvents
   1197  * \brief  Enable driver activities
   1198  *
   1199  * Clear all external events queues (Tx, commands and timers) upon driver stop.
   1200  *
   1201  * \note
   1202  * \param  pDrvMain - The DrvMain object
   1203  * \return void
   1204  * \sa
   1205  */
   1206 static void drvMain_ClearQueuedEvents (TDrvMain *pDrvMain)
   1207 {
   1208     txDataQ_ClearQueues (pDrvMain->tStadHandles.hTxDataQ);
   1209     txMgmtQ_ClearQueues (pDrvMain->tStadHandles.hTxMgmtQ);
   1210     cmdHndlr_ClearQueue (pDrvMain->tStadHandles.hCmdHndlr);
   1211     tmr_ClearOperQueue (pDrvMain->tStadHandles.hTimer);
   1212 }
   1213 
   1214 
   1215 /*
   1216  * \fn     drvMain_InsertAction
   1217  * \brief  Get start/stop action and trigger handling
   1218  *
   1219  * Get start or stop action command from OAL, save it and trigger driver task
   1220  *     for handling it.
   1221  * Wait on a signal object until the requested process is completed.
   1222  *
   1223  * \note
   1224  * \param  hDrvMain - The DrvMain object
   1225  * \param  eAction  - The requested action
   1226  * \return void
   1227  * \sa
   1228  */
   1229 TI_STATUS drvMain_InsertAction (TI_HANDLE hDrvMain, EActionType eAction)
   1230 {
   1231     TDrvMain *pDrvMain = (TDrvMain *) hDrvMain;
   1232 
   1233     context_EnterCriticalSection(pDrvMain->tStadHandles.hContext);
   1234     if (pDrvMain->eAction == eAction)
   1235     {
   1236         context_LeaveCriticalSection(pDrvMain->tStadHandles.hContext);
   1237         TRACE0(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_CONSOLE, "Action is identical to last action!\n");
   1238         WLAN_OS_REPORT(("Action %d is identical to last action!\n", eAction));
   1239         return TI_NOK;
   1240     }
   1241 
   1242     /* Save the requested action */
   1243     pDrvMain->eAction = eAction;
   1244     context_LeaveCriticalSection(pDrvMain->tStadHandles.hContext);
   1245 
   1246     /* Create signal object */
   1247     /*
   1248      * Notice that we must create the signal object before asking for ReSchedule,
   1249      * because we might receive it immidiatly, and then we will be in a different context
   1250      * with null signal object.
   1251      */
   1252     pDrvMain->hSignalObj = os_SignalObjectCreate (pDrvMain->tStadHandles.hOs);
   1253     if (pDrvMain->hSignalObj == NULL)
   1254     {
   1255         TRACE0(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_ERROR , "drvMain_InsertAction(): Couldn't allocate signal object!\n");
   1256         return TI_NOK;
   1257     }
   1258 
   1259     /* Request driver task schedule for action handling */
   1260     context_RequestSchedule (pDrvMain->tStadHandles.hContext, pDrvMain->uContextId);
   1261 
   1262     /* Wait for the action processing completion */
   1263     os_SignalObjectWait (pDrvMain->tStadHandles.hOs, pDrvMain->hSignalObj);
   1264 
   1265     /* After "wait" - the action has already been processed in the driver's context */
   1266 
   1267     /* Free signalling object */
   1268     os_SignalObjectFree (pDrvMain->tStadHandles.hOs, pDrvMain->hSignalObj);
   1269     pDrvMain->hSignalObj = NULL;
   1270 
   1271     if (pDrvMain->eSmState == SM_STATE_FAILED)
   1272     return TI_NOK;
   1273 
   1274     return TI_OK;
   1275 }
   1276 
   1277 
   1278 /*
   1279  * \fn     drvMain_Recovery
   1280  * \brief  Initiate recovery process
   1281  *
   1282  * Initiate recovery process upon HW/FW error detection (in the Health-Monitor).
   1283  *
   1284  * \note
   1285  * \param  hDrvMain - The DrvMain object
   1286  * \return TI_OK if started recovery, TI_NOK if recovery is already in progress.
   1287  * \sa
   1288  */
   1289 TI_STATUS drvMain_Recovery (TI_HANDLE hDrvMain)
   1290 {
   1291     TDrvMain         *pDrvMain = (TDrvMain *) hDrvMain;
   1292 
   1293     if (!pDrvMain->bRecovery)
   1294     {
   1295         TRACE1(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_CONSOLE,".....drvMain_Recovery, ts=%d\n", os_timeStampMs(pDrvMain->tStadHandles.hOs));
   1296 #ifdef REPORT_LOG
   1297         WLAN_OS_REPORT((".....drvMain_Recovery, ts=%d\n", os_timeStampMs(pDrvMain->tStadHandles.hOs)));
   1298 #else
   1299         printk("%s\n",__func__);
   1300 #endif
   1301         pDrvMain->bRecovery = TI_TRUE;
   1302         drvMain_SmEvent (hDrvMain, SM_EVENT_RECOVERY);
   1303         return TI_OK;
   1304     }
   1305     else
   1306     {
   1307         TRACE0(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_ERROR, "drvMain_Recovery: ****  Recovery already in progress!  ****\n");
   1308         return TI_NOK;
   1309     }
   1310 }
   1311 
   1312 
   1313 /*
   1314  * \fn     drvMain_RecoveryNotify
   1315  * \brief  Notify STAD modules about recovery
   1316  *
   1317  * Notify the relevant STAD modules that recovery took place (after completed).
   1318  *
   1319  * \note
   1320  * \param  pDrvMain - The DrvMain object
   1321  * \return void
   1322  * \sa
   1323  */
   1324 static void drvMain_RecoveryNotify (TDrvMain *pDrvMain)
   1325 {
   1326     txCtrl_NotifyFwReset (pDrvMain->tStadHandles.hTxCtrl);
   1327     scr_notifyFWReset (pDrvMain->tStadHandles.hSCR);
   1328     PowerMgr_notifyFWReset (pDrvMain->tStadHandles.hPowerMgr);
   1329 
   1330     TRACE1(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_CONSOLE, ".....drvMain_RecoveryNotify: End Of Recovery, ts=%d\n", os_timeStampMs(pDrvMain->tStadHandles.hOs));
   1331     WLAN_OS_REPORT((".....drvMain_RecoveryNotify: End Of Recovery, ts=%d\n", os_timeStampMs(pDrvMain->tStadHandles.hOs)));
   1332 }
   1333 
   1334 
   1335 /*
   1336  * \fn     drvMain_SmWatchdogTimeout
   1337  * \brief  SM watchdog timer expiry handler
   1338  *
   1339  * This is the callback function called upon expiartion of the watchdog timer.
   1340  * It is called by the OS-API in timer expiry context, and it issues a failure event to the SM.
   1341  * Note that we can't switch to the driver task as for other timers, since we are using
   1342  *     this timer to protect the init processes, and anyway we just need to stop the driver.
   1343  *
   1344  * \note
   1345  * \param  hDrvMain - The DrvMain object
   1346  * \return void
   1347  * \sa
   1348  */
   1349 
   1350 #if 0
   1351 static void drvMain_SmWatchdogTimeout (TI_HANDLE hDrvMain)
   1352 {
   1353     TDrvMain *pDrvMain = (TDrvMain *)hDrvMain;
   1354 
   1355     TRACE1(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_ERROR , "drvMain_SmWatchdogTimeout():  State = %d\n", pDrvMain->eSmState);
   1356 
   1357     /* Send failure event directly to the SM (so the drvMain_SmEvent won't block it).  */
   1358 
   1359     drvMain_Sm ((TI_HANDLE)pDrvMain, SM_EVENT_FAILURE);
   1360 }
   1361 #endif
   1362 
   1363 /*
   1364  * \fn     drvMain_SmEvent
   1365  * \brief  Issue DrvMain SM event
   1366  *
   1367  * Each event that is handled by the DrvMain state machine, is introduced through this function.
   1368  * To prevent SM recursion, the SM is invoeked only if it's not already handling the
   1369  *      previous event.
   1370  * If the SM is busy, the current event is saved until the previous handling is completed.
   1371  *
   1372  * \note   Recursion may happen because some SM activities generate SM events in the same context.
   1373  * \param  hDrvMain - The DrvMain object
   1374  * \param  eEvent   - The event issued to the SM
   1375  * \return void
   1376  * \sa
   1377  */
   1378 static void drvMain_SmEvent (TI_HANDLE hDrvMain, ESmEvent eEvent)
   1379 {
   1380     TDrvMain *pDrvMain = (TDrvMain *)hDrvMain;
   1381 
   1382     /* Increment pending events counter and save last event. */
   1383     pDrvMain->uPendingEventsCount++;
   1384     pDrvMain->ePendingEvent = eEvent;
   1385 
   1386     /* If the SM is busy, save event and exit (will be handled when current event is finished) */
   1387     if (pDrvMain->uPendingEventsCount > 1)
   1388     {
   1389         /* Only one pending event is expected (in addition to the handled one, so two together). */
   1390         if (pDrvMain->uPendingEventsCount > 2)
   1391         {
   1392             TRACE3(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_ERROR , "drvMain_SmEvent():  Multiple pending events (%d), State = %d, Event = %d\n", pDrvMain->uPendingEventsCount, pDrvMain->eSmState, eEvent);
   1393         }
   1394 
   1395         /* Exit. The current event will be handled by the following while loop of the first instance. */
   1396         return;
   1397     }
   1398 
   1399     /* Invoke the SM with the current event and further events issued by the last SM invocation. */
   1400     while (pDrvMain->uPendingEventsCount > 0)
   1401     {
   1402         drvMain_Sm (hDrvMain, pDrvMain->ePendingEvent);
   1403 
   1404         /*
   1405          * Note: The SM may issue another event by calling this function and incrementing
   1406          *           the counter.
   1407          *       In this case, only the upper part of this function is run, and the pending
   1408          *           event is hanlded in the next while loo[.
   1409          */
   1410 
   1411         pDrvMain->uPendingEventsCount--;
   1412     }
   1413 }
   1414 
   1415 
   1416 /*
   1417  * \fn     drvMain_Sm
   1418  * \brief  The DrvMain state machine
   1419  *
   1420  * The DrvMain state machine, which handles all driver init, recovery and stop processes.
   1421  *
   1422  * \note   Since the SM may be called back from its own context, recursion is prevented
   1423  *             by postponing the last event.
   1424  * \param  hDrvMain - The DrvMain object
   1425  * \param  eEvent   - The event that triggers the SM
   1426  * \return void
   1427  * \sa
   1428  */
   1429 static void drvMain_Sm (TI_HANDLE hDrvMain, ESmEvent eEvent)
   1430 {
   1431     TDrvMain    *pDrvMain   = (TDrvMain *)hDrvMain;
   1432     TI_STATUS    eStatus    = TI_NOK;
   1433     TI_HANDLE    hOs        = pDrvMain->tStadHandles.hOs;
   1434     TI_UINT32    uSdioConIndex = 0;
   1435 
   1436     TRACE2(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_INFORMATION , "drvMain_Sm():  State = %d, Event = %d\n", pDrvMain->eSmState, eEvent);
   1437 
   1438     /*
   1439      *  General explenations:
   1440      *  =====================
   1441      *  1) This SM calls some functions that may complete their processing in another context.
   1442      *     All of these functions (wlanDrvIf_GetFile, drvMain_InitHw, drvMain_InitFw, drvMain_ConfigFw,
   1443      *         drvMain_StopActivities, smeSm_start, smeSm_stop) are provided with a callback which
   1444      *         they always call upon completion, even if they are completed in the original (SM) context.
   1445      *     Since these callbacks are calling the SM, a simple mechanism is added to prevent
   1446      *         recursion, by postponing the last event if the SM is still in the previous event's context.
   1447      *  2) In any case of unexpected event, the eStatus remains TI_NOK, leading to the FAILED state!
   1448      *     FAILED state is also reached if any of the functions listed in note 1 returns TI_NOK.
   1449      *     Note that if these functions detect a failure in another context, they may call their callback
   1450      *         with the eStatus parameter set to TI_NOK, or call the drvMain_InitFailCb callback.
   1451      *     All these cases lead to FAILED state which terminates all driver activities and wait for destroy.
   1452      *  3) Note that the wlanDrvIf_GetFile is always completed in the original context, and the
   1453      *         option of completion in a later context is only for future use.
   1454      *  4) All processes (Start, Stop, Relcovery) are protected by a watchdog timer to let
   1455      *         the user free the driver in case of deadlock during the process.
   1456      */
   1457 
   1458     switch (pDrvMain->eSmState)
   1459     {
   1460     case SM_STATE_IDLE:
   1461         /*
   1462          * We get a START action after all modules are created and linked.
   1463          * Disable further actions, start watchdog timer and request for the ini-file.
   1464          */
   1465         if (eEvent == SM_EVENT_START)
   1466         {
   1467             /* return thr timer later on */
   1468             /*os_timerStart (hOs, pDrvMain->hWatchdogTimer, SM_WATCHDOG_TIME_MS);*/
   1469             pDrvMain->eSmState = SM_STATE_WAIT_INI_FILE;
   1470             context_DisableClient (pDrvMain->tStadHandles.hContext, pDrvMain->uContextId);
   1471             pDrvMain->tFileInfo.eFileType = FILE_TYPE_INI;
   1472             eStatus = wlanDrvIf_GetFile (hOs, &pDrvMain->tFileInfo);
   1473         }
   1474         break;
   1475     case SM_STATE_WAIT_INI_FILE:
   1476         /*
   1477          * We've got the ini-file.
   1478          * Set STAD and TWD modules defaults according to the ini-file,
   1479          *     turn on the device and request for the NVS file.
   1480          */
   1481         if (eEvent == SM_EVENT_INI_FILE_READY)
   1482         {
   1483             pDrvMain->eSmState = SM_STATE_WAIT_NVS_FILE;
   1484             drvMain_SetDefaults (hDrvMain, pDrvMain->tFileInfo.pBuffer, pDrvMain->tFileInfo.uLength);
   1485             hPlatform_DevicePowerOn ();
   1486 
   1487             pDrvMain->tFileInfo.eFileType = FILE_TYPE_NVS;
   1488             eStatus = wlanDrvIf_GetFile (hOs, &pDrvMain->tFileInfo);
   1489         }
   1490         break;
   1491 
   1492     case SM_STATE_WAIT_NVS_FILE:
   1493 
   1494         /* SDBus Connect connection validation  */
   1495         for(uSdioConIndex=0; (uSdioConIndex < SDIO_CONNECT_THRESHOLD) && (eStatus != TI_OK); uSdioConIndex++)
   1496         {
   1497 			/* : We should split the call to txnQ_ConnectBus to other state in order to support Async bus connection */
   1498             eStatus = txnQ_ConnectBus(pDrvMain->tStadHandles.hTxnQ, &pDrvMain->tBusDrvCfg, NULL, NULL);
   1499 
   1500 			if((eStatus != TI_OK) &&
   1501 			   (uSdioConIndex < (SDIO_CONNECT_THRESHOLD - 1)))
   1502             {
   1503                      TRACE0(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_WARNING , "SDBus Connect Failed\n");
   1504                      WLAN_OS_REPORT(("Try to SDBus Connect again...\n"));
   1505                      if (uSdioConIndex > 1)
   1506 						hPlatform_DevicePowerOffSetLongerDelay();
   1507 					 else
   1508 						hPlatform_DevicePowerOff();
   1509                      hPlatform_DevicePowerOn();
   1510             }
   1511         }
   1512 
   1513 		if(eStatus != TI_OK)
   1514 		{
   1515 			WLAN_OS_REPORT(("SDBus Connect Failed, Set Object Event !!\r\n"));
   1516 			TRACE0(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_ERROR , "SDBus Connect Failed, Set Object Event !!\r\n");
   1517 			if (!pDrvMain->bRecovery)
   1518 			{
   1519 				os_SignalObjectSet(hOs, pDrvMain->hSignalObj);
   1520 			}
   1521                         else
   1522 			{
   1523 				/* in case recovery fails, stop the sme which will send disassociation event to os */
   1524 				sme_Stop(pDrvMain->tStadHandles.hSme);
   1525 			}
   1526 		}
   1527 		else /* SDBus Connect success */
   1528         {
   1529             /*
   1530              * We've got the NVS file.
   1531              * Start HW-Init process providing the NVS file.
   1532              */
   1533 			if (eEvent == SM_EVENT_NVS_FILE_READY)
   1534             {
   1535                 pDrvMain->eSmState = SM_STATE_HW_INIT;
   1536                 eStatus = drvMain_InitHw (hDrvMain, pDrvMain->tFileInfo.pBuffer, pDrvMain->tFileInfo.uLength);
   1537             }
   1538         }
   1539         break;
   1540     case SM_STATE_HW_INIT:
   1541         /*
   1542          * HW-Init process is completed.
   1543          * Request for the FW image file.
   1544          */
   1545         if (eEvent == SM_EVENT_HW_INIT_COMPLETE)
   1546         {
   1547             pDrvMain->tFileInfo.eFileType = FILE_TYPE_FW;
   1548             pDrvMain->eSmState = SM_STATE_DOWNLOAD_FW_FILE;
   1549             eStatus = wlanDrvIf_GetFile (hOs, &pDrvMain->tFileInfo);
   1550         }
   1551         break;
   1552     case SM_STATE_DOWNLOAD_FW_FILE:
   1553         if (eEvent == SM_EVENT_FW_FILE_READY)
   1554         {
   1555             pDrvMain->tFileInfo.eFileType = FILE_TYPE_FW_NEXT;
   1556             if (pDrvMain->tFileInfo.bLast == TI_TRUE)
   1557             {
   1558             pDrvMain->eSmState = SM_STATE_FW_INIT;
   1559             }
   1560             else
   1561             {
   1562                 pDrvMain->eSmState = SM_STATE_WAIT_FW_FILE;
   1563             }
   1564             /*
   1565              * We've got the FW image file.
   1566              * Start FW-Init process (mainly FW image download) providing the FW image file.
   1567              */
   1568             eStatus = drvMain_InitFw (hDrvMain, &pDrvMain->tFileInfo);
   1569         }
   1570         break;
   1571     case SM_STATE_WAIT_FW_FILE:
   1572         if (eEvent == SM_EVENT_FW_INIT_COMPLETE)
   1573         {
   1574             pDrvMain->eSmState = SM_STATE_DOWNLOAD_FW_FILE;
   1575             eStatus = wlanDrvIf_GetFile (hOs, &pDrvMain->tFileInfo);
   1576         }
   1577         break;
   1578     case SM_STATE_FW_INIT:
   1579         /*
   1580          * FW-Init process is completed.
   1581          * Free the semaphore of the START action to enable the OS interface.
   1582          * Enable interrupts (or polling for debug).
   1583          * Start FW-Configuration process, and free the semaphore of the START action.
   1584          *
   1585          * Note that in some OSs, the semaphore must be released in order to enable the
   1586          *     interrupts, and the interrupts are needed for the configuration process!
   1587          */
   1588         if (eEvent == SM_EVENT_FW_INIT_COMPLETE)
   1589         {
   1590             pDrvMain->eSmState = SM_STATE_FW_CONFIG;
   1591             TWD_EnableInterrupts(pDrvMain->tStadHandles.hTWD);
   1592           #ifdef PRIODIC_INTERRUPT
   1593             /* Start periodic interrupts. It means that every period of time the FwEvent SM will be called */
   1594             os_periodicIntrTimerStart (hOs);
   1595           #endif
   1596             eStatus = drvMain_ConfigFw (hDrvMain);
   1597         }
   1598         break;
   1599     case SM_STATE_FW_CONFIG:
   1600         /*
   1601          * FW-configuration process is completed.
   1602          * Stop watchdog timer.
   1603          * For recovery, notify the relevant STAD modules.
   1604          * For regular start, start the SME which handles the connection process.
   1605          * Update timer and OAL about entering OPERATIONAL state (OAL ignores recovery)
   1606          * Enable driver activities and external events.
   1607          * Enable STOP action
   1608          * We are now in OPERATIONAL state, i.e. the driver is fully operational!
   1609          */
   1610 
   1611         if (eEvent == SM_EVENT_FW_CONFIG_COMPLETE)
   1612         {
   1613             pDrvMain->eSmState = SM_STATE_OPERATIONAL;
   1614             /* return thr timer later on */
   1615             /*os_timerStop (hOs, pDrvMain->hWatchdogTimer);*/
   1616             if (pDrvMain->bRecovery)
   1617             {
   1618                 drvMain_RecoveryNotify (pDrvMain);
   1619                 pDrvMain->bRecovery = TI_FALSE;
   1620             }
   1621             else
   1622             {
   1623                 sme_Start (pDrvMain->tStadHandles.hSme);
   1624                 wlanDrvIf_UpdateDriverState (hOs, DRV_STATE_RUNNING);
   1625             }
   1626             tmr_UpdateDriverState (pDrvMain->tStadHandles.hTimer, TI_TRUE);
   1627             drvMain_EnableActivities (pDrvMain);
   1628             context_EnableClient (pDrvMain->tStadHandles.hContext, pDrvMain->uContextId);
   1629             eStatus = TI_OK;
   1630 
   1631         }
   1632         if (!pDrvMain->bRecovery)
   1633         {
   1634             os_SignalObjectSet(hOs, pDrvMain->hSignalObj);
   1635         }
   1636         break;
   1637     case SM_STATE_OPERATIONAL:
   1638         /*
   1639          * Disable start/stop commands and start watchdog timer.
   1640          * Update timer and OAL about exiting OPERATIONAL state (OAL ignores recovery).
   1641          * For STOP, stop SME (handle disconnection) and move to DISCONNECTING state.
   1642          * For recovery, stop driver activities and move to STOPPING state.
   1643          * Note that driver-stop process may be Async if we are during Async bus transaction.
   1644          */
   1645 
   1646         context_DisableClient (pDrvMain->tStadHandles.hContext, pDrvMain->uContextId);
   1647         /* return thr timer later on */
   1648         /*os_timerStart (hOs, pDrvMain->hWatchdogTimer, SM_WATCHDOG_TIME_MS);*/
   1649         tmr_UpdateDriverState (pDrvMain->tStadHandles.hTimer, TI_FALSE);
   1650         if (eEvent == SM_EVENT_STOP)
   1651         {
   1652             pDrvMain->eSmState = SM_STATE_DISCONNECTING;
   1653             wlanDrvIf_UpdateDriverState (hOs, DRV_STATE_STOPING);
   1654             sme_Stop (pDrvMain->tStadHandles.hSme);
   1655             eStatus = TI_OK;
   1656         }
   1657         else if (eEvent == SM_EVENT_RECOVERY)
   1658         {
   1659             pDrvMain->eSmState = SM_STATE_STOPPING;
   1660             eStatus = drvMain_StopActivities (pDrvMain);
   1661         }
   1662 
   1663         break;
   1664     case SM_STATE_DISCONNECTING:
   1665         /*
   1666          * Note that this state is not relevant for recovery.
   1667          * SME stop is completed
   1668          * Stop driver activities and move to STOPPING state.
   1669          * Note that driver stop process may be Async if we are during Async bus transaction.
   1670          */
   1671 
   1672         if (eEvent == SM_EVENT_DISCONNECTED)
   1673         {
   1674             pDrvMain->eSmState = SM_STATE_STOPPING;
   1675             eStatus = drvMain_StopActivities (pDrvMain);
   1676         }
   1677         break;
   1678     case SM_STATE_STOPPING:
   1679         /*
   1680          * Driver stopping process is done.
   1681          * Turn device power off.
   1682          * For recovery, turn device power back on, request NVS file and continue with
   1683          *     the init process (recover back all the way to OPERATIONAL state).
   1684          * For STOP process, the driver is now fully stopped (STOPPED state), so stop watchdog timer,
   1685          *     clear all events queues, free the semaphore of the STOP action and enable START action.
   1686          */
   1687 
   1688         if (eEvent == SM_EVENT_STOP_COMPLETE)
   1689         {
   1690             txnQ_DisconnectBus (pDrvMain->tStadHandles.hTxnQ);
   1691             hPlatform_DevicePowerOff ();
   1692             if (pDrvMain->bRecovery)
   1693             {
   1694                 hPlatform_DevicePowerOn ();
   1695                 pDrvMain->eSmState = SM_STATE_WAIT_NVS_FILE;
   1696                 pDrvMain->tFileInfo.eFileType = FILE_TYPE_NVS;
   1697                 eStatus = wlanDrvIf_GetFile (hOs, &pDrvMain->tFileInfo);
   1698             }
   1699             else
   1700             {
   1701                 pDrvMain->eSmState = SM_STATE_STOPPED;
   1702                 /* return thr timer later on */
   1703                 /*os_timerStop (hOs, pDrvMain->hWatchdogTimer);*/
   1704                 drvMain_ClearQueuedEvents (pDrvMain);
   1705                 scr_notifyFWReset(pDrvMain->tStadHandles.hSCR);
   1706                 os_SignalObjectSet (hOs, pDrvMain->hSignalObj);
   1707                 context_EnableClient (pDrvMain->tStadHandles.hContext, pDrvMain->uContextId);
   1708                 wlanDrvIf_UpdateDriverState (hOs, DRV_STATE_STOPPED);
   1709                 eStatus = TI_OK;
   1710             }
   1711         }
   1712 
   1713         break;
   1714     case SM_STATE_STOPPED:
   1715         /*
   1716          * A START action command was inserted, so we go through the init process.
   1717          * Disable further actions, start watchdog timer, turn on device and request NVS file.
   1718          */
   1719 
   1720         context_DisableClient (pDrvMain->tStadHandles.hContext, pDrvMain->uContextId);
   1721         /* return thr timer later on */
   1722         /*os_timerStart (hOs, pDrvMain->hWatchdogTimer, SM_WATCHDOG_TIME_MS);*/
   1723         if (eEvent == SM_EVENT_START)
   1724         {
   1725             hPlatform_DevicePowerOn ();
   1726             pDrvMain->eSmState = SM_STATE_WAIT_NVS_FILE;
   1727             pDrvMain->tFileInfo.eFileType = FILE_TYPE_NVS;
   1728             eStatus = wlanDrvIf_GetFile (hOs, &pDrvMain->tFileInfo);
   1729         }
   1730         break;
   1731     case SM_STATE_STOPPING_ON_FAIL:
   1732         /*
   1733          * Driver stopping process upon failure is completed.
   1734          * Turn off the device and move to FAILED state.
   1735          */
   1736 
   1737         pDrvMain->eSmState = SM_STATE_FAILED;
   1738         txnQ_DisconnectBus (pDrvMain->tStadHandles.hTxnQ);
   1739         hPlatform_DevicePowerOff ();
   1740         WLAN_OS_REPORT(("[WLAN] Exit application\n"));
   1741         if (!pDrvMain->bRecovery)
   1742         {
   1743             os_SignalObjectSet (hOs, pDrvMain->hSignalObj);
   1744         }
   1745         break;
   1746     case SM_STATE_FAILED:
   1747         /* Nothing to do except waiting for Destroy */
   1748         break;
   1749  default:
   1750         TRACE2(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_ERROR , "drvMain_Sm: Unknown state, eEvent=%u at state=%u\n", eEvent, pDrvMain->eSmState);
   1751         /* Note: Handled below as a failure since the status remains TI_NOK */
   1752         break;
   1753     }
   1754 
   1755     /* Handle failures (status = NOK) if not handled yet */
   1756     if ((eStatus == TI_NOK) &&
   1757         (pDrvMain->eSmState != SM_STATE_FAILED) &&
   1758         (pDrvMain->eSmState != SM_STATE_STOPPING_ON_FAIL))
   1759     {
   1760         TRACE3(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_ERROR , "drvMain_Sm: eEvent=%u at state=%u, status=%d\n", eEvent, pDrvMain->eSmState, eStatus);
   1761         pDrvMain->eSmState = SM_STATE_STOPPING_ON_FAIL;
   1762         wlanDrvIf_UpdateDriverState (hOs, DRV_STATE_FAILED);
   1763 
   1764         /*
   1765          * Stop all activities. This may be completed in a different context if
   1766          *     we should wait for an Async bus transaction completion.
   1767          * The drvMain_TwdStopCb is called from the TWD in any case to pass
   1768          *     us to the SM_STATE_FAILED state (where we wait for Destroy).
   1769          */
   1770         eStatus = drvMain_StopActivities (pDrvMain);
   1771     }
   1772 }
   1773