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