• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
drvMain_Create(TI_HANDLE hOs,TI_HANDLE * pDrvMainHndl,TI_HANDLE * pCmdHndlr,TI_HANDLE * pContext,TI_HANDLE * pTxDataQ,TI_HANDLE * pTxMgmtQ,TI_HANDLE * pTxCtrl,TI_HANDLE * pTwd,TI_HANDLE * pEvHandler)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  */
drvMain_Destroy(TI_HANDLE hDrvMain)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 
drvMain_SmeStop(TI_HANDLE hDrvMain)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  */
drvMain_Init(TI_HANDLE hDrvMain)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  */
drvMain_SetDefaults(TI_HANDLE hDrvMain,TI_UINT8 * pBuf,TI_UINT32 uLength)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  */
drvMain_InitHwCb(TI_HANDLE hDrvMain,TI_STATUS eStatus)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 
drvMain_InitFwCb(TI_HANDLE hDrvMain,TI_STATUS eStatus)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 
drvMain_ConfigFwCb(TI_HANDLE hDrvMain,TI_STATUS eStatus)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 
drvMain_TwdStopCb(TI_HANDLE hDrvMain,TI_STATUS eStatus)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 
drvMain_InitFailCb(TI_HANDLE hDrvMain,TI_STATUS eStatus)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 
drvMain_InvokeAction(TI_HANDLE hDrvMain)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 
drvMain_GetFileCb(TI_HANDLE hDrvMain)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  */
drvMain_InitLocals(TDrvMain * pDrvMain)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  */
drvMain_InitHw(TI_HANDLE hDrvMain,TI_UINT8 * pbuf,TI_UINT32 uLength)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 
drvMain_InitFw(TI_HANDLE hDrvMain,TFileInfo * pFileInfo)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  */
drvMain_ConfigFw(TI_HANDLE hDrvMain)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  */
drvMain_StopActivities(TDrvMain * pDrvMain)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  */
drvMain_EnableActivities(TDrvMain * pDrvMain)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  */
drvMain_ClearQueuedEvents(TDrvMain * pDrvMain)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  */
drvMain_InsertAction(TI_HANDLE hDrvMain,EActionType eAction)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  */
drvMain_Recovery(TI_HANDLE hDrvMain)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  */
drvMain_RecoveryNotify(TDrvMain * pDrvMain)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  */
drvMain_SmEvent(TI_HANDLE hDrvMain,ESmEvent eEvent)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  */
drvMain_Sm(TI_HANDLE hDrvMain,ESmEvent eEvent)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