OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / hardware / ti / wlan / wl1271 / stad / src / Sta_Management / healthMonitor.c
1 /*
2  * healthMonitor.c
3  *
4  * Copyright(c) 1998 - 2010 Texas Instruments. All rights reserved.      
5  * All rights reserved.                                                  
6  *                                                                       
7  * Redistribution and use in source and binary forms, with or without    
8  * modification, are permitted provided that the following conditions    
9  * are met:                                                              
10  *                                                                       
11  *  * Redistributions of source code must retain the above copyright     
12  *    notice, this list of conditions and the following disclaimer.      
13  *  * Redistributions in binary form must reproduce the above copyright  
14  *    notice, this list of conditions and the following disclaimer in    
15  *    the documentation and/or other materials provided with the         
16  *    distribution.                                                      
17  *  * Neither the name Texas Instruments nor the names of its            
18  *    contributors may be used to endorse or promote products derived    
19  *    from this software without specific prior written permission.      
20  *                                                                       
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS   
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT     
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
24  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT  
25  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
26  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT      
27  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT   
30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 /** \file healthMonitor.c
35  *  \brief Firmware Recovery Mechanism
36  */
37
38 /** \file   healthMonitor.c 
39  *  \brief  The health monitor module. Gets failures indications and handle them.
40  *
41  *  For periodic check, use HW watchdog mechanizem instead of local periodic timer check 
42  *
43  *  \see    healthMonitor.h
44  */
45
46 #define __FILE_ID__  FILE_ID_66
47 #include "healthMonitor.h"
48 #include "osApi.h"
49 #include "timer.h"
50 #include "report.h"
51 #include "siteMgrApi.h"
52 #include "PowerMgr_API.h"
53 #include "currBss.h"
54 #include "DataCtrl_Api.h"
55 #include "TWDriver.h"
56 #include "SoftGeminiApi.h"
57 #include "currBss.h"
58 #include "rsnApi.h"
59 #include "DrvMain.h"
60 #include "DrvMainModules.h"
61 #include "TWDriverInternal.h"
62
63
64 typedef struct
65 {
66     /* handles to other modules */
67     TI_HANDLE            hOs;                    /* handle to the OS object */
68     TI_HANDLE            hReport;                /* handle to the report object */
69     TI_HANDLE            hTWD;                   /* handle to the TWD object */
70     TI_HANDLE            hSiteMgr;               /* handle to the site manager object */
71     TI_HANDLE            hScr;                   /* handle to the SCR object */
72     TI_HANDLE            hSoftGemini;            /* handle to the Soft Gemini object */
73         TI_HANDLE            hDrvMain;               /* handle to the Recovery Mgr object */
74     TI_HANDLE            hTxCtrl;                /* handle to the TX Ctrl object */
75     TI_HANDLE            hCurrBss;               /* handle to the currBss object */
76         TI_HANDLE            hRsn;                   /* handle to the RSN */
77         TI_HANDLE            hTimer;                 /* handle to the Timer module object */
78         TI_HANDLE            hContext;               /* handle to the context-engine object */
79
80     /* Timers handles */
81     TI_HANDLE            hFailTimer;             /* failure event timer */
82     
83     /* Management variables */
84     TI_UINT32            numOfHealthTests;       /* number of health tests performed counter */
85     healthMonitorState_e state;                  /* health monitor state */
86     TI_BOOL              bFullRecoveryEnable;    /* full recovery enable flag */
87     TI_BOOL              recoveryTriggerEnabled [MAX_FAILURE_EVENTS];
88                                                  /* recovery enable flags per trigger type */
89     TI_UINT32            failureEvent;           /* current recovery trigger */
90     TI_UINT32            keepAliveIntervals;     /* number of health monitor timer intervals at which keep alive should be sent */
91     TI_UINT32            currentKeepAliveCounter;/* counting how many timer intervals had passed w/o a keep alive */
92
93     /* Recoveries Statistics */
94     TI_UINT32            recoveryTriggersNumber [MAX_FAILURE_EVENTS];                                                  
95                                                  /* Number of times each recovery trigger occured */
96     TI_UINT32            numOfRecoveryPerformed; /* number of recoveries performed */
97     
98 } THealthMonitor;
99
100
101 static void healthMonitor_proccessFailureEvent (TI_HANDLE hHealthMonitor, TI_BOOL bTwdInitOccured);
102
103
104 #ifdef REPORT_LOG
105
106 static char* sRecoveryTriggersNames [MAX_FAILURE_EVENTS] = 
107 {
108     "NO_SCAN_COMPLETE_FAILURE",
109     "MBOX_FAILURE",
110     "HW_AWAKE_FAILURE",
111     "TX_STUCK",
112     "DISCONNECT_TIMEOUT",
113     "POWER_SAVE_FAILURE",
114     "MEASUREMENT_FAILURE",
115     "BUS_FAILURE",
116     "HW_WD_EXPIRE",
117     "RX_XFER_FAILURE"
118 };
119 #endif
120
121
122 /** 
123  * \fn     healthMonitor_create 
124  * \brief  Create module object
125  * 
126  * Create module object.
127  * 
128  * \note    
129  * \param  hOs  - The OS adaptation handle
130  * \return The created module handle  
131  * \sa     
132  */ 
133 TI_HANDLE healthMonitor_create (TI_HANDLE hOs)
134 {
135     THealthMonitor *pHealthMonitor;
136  
137     /* Allocate memory for the health monitor object and nullify it */
138     pHealthMonitor = (THealthMonitor*)os_memoryAlloc (hOs, sizeof(THealthMonitor));
139     if (pHealthMonitor == NULL)
140     {
141         return NULL;
142     }
143     os_memoryZero (hOs, pHealthMonitor, sizeof(THealthMonitor));
144
145     /* Store OS object handle */
146     pHealthMonitor->hOs = hOs;
147
148     return (TI_HANDLE)pHealthMonitor;
149 }
150
151
152 /** 
153  * \fn     healthMonitor_init 
154  * \brief  Init module handles and variables
155  * 
156  * Init module handles and variables.
157  * 
158  * \note    
159  * \param  pStadHandles  - The driver modules handles
160  * \return void  
161  * \sa     
162  */ 
163 void healthMonitor_init (TStadHandlesList *pStadHandles)
164 {
165     THealthMonitor *pHealthMonitor = (THealthMonitor *)(pStadHandles->hHealthMonitor);
166
167     pHealthMonitor->hReport         = pStadHandles->hReport;
168     pHealthMonitor->hTWD            = pStadHandles->hTWD;
169     pHealthMonitor->hSiteMgr        = pStadHandles->hSiteMgr;
170     pHealthMonitor->hScr            = pStadHandles->hSCR;
171     pHealthMonitor->hSoftGemini     = pStadHandles->hSoftGemini;
172     pHealthMonitor->hDrvMain        = pStadHandles->hDrvMain;
173         pHealthMonitor->hTxCtrl             = pStadHandles->hTxCtrl;
174     pHealthMonitor->hCurrBss        = pStadHandles->hCurrBss;
175     pHealthMonitor->hRsn            = pStadHandles->hRsn;
176     pHealthMonitor->hTimer          = pStadHandles->hTimer;
177     pHealthMonitor->hContext        = pStadHandles->hContext;
178
179     pHealthMonitor->state           = HEALTH_MONITOR_STATE_DISCONNECTED;
180     pHealthMonitor->failureEvent    = (TI_UINT32)NO_FAILURE;
181
182     /* Register the failure event callback */
183     TWD_RegisterCb (pHealthMonitor->hTWD, 
184                     TWD_EVENT_FAILURE, 
185                     (void *)healthMonitor_sendFailureEvent, 
186                     (void *)pHealthMonitor);
187 }
188
189
190 /** 
191  * \fn     healthMonitor_SetDefaults 
192  * \brief  Set module defaults and create timers
193  * 
194  * Set module defaults from Ini-file and create timers.
195  * 
196  * \note    
197  * \param  hHealthMonitor  - The module's handle
198  * \param  healthMonitorInitParams  - The module's parameters default values (from Ini-file).
199  * \return void  
200  * \sa     
201  */ 
202 TI_STATUS healthMonitor_SetDefaults (TI_HANDLE    hHealthMonitor, healthMonitorInitParams_t *healthMonitorInitParams)
203 {
204     THealthMonitor *pHealthMonitor = hHealthMonitor;
205     int i;
206
207     /* Registry configuration */
208     pHealthMonitor->bFullRecoveryEnable   = healthMonitorInitParams->FullRecoveryEnable;
209
210     for (i = 0; i < MAX_FAILURE_EVENTS; i++)
211     {
212         pHealthMonitor->recoveryTriggerEnabled[i] = healthMonitorInitParams->recoveryTriggerEnabled[i];
213     }
214
215     /* Create recovery request timer */
216     pHealthMonitor->hFailTimer = tmr_CreateTimer (pHealthMonitor->hTimer);
217     if (pHealthMonitor->hFailTimer == NULL)
218     {
219         TRACE0(pHealthMonitor->hReport, REPORT_SEVERITY_ERROR, "healthMonitor_SetDefaults(): Failed to create hFailTimer!\n");
220                 return TI_NOK;
221     }
222
223     return TI_OK;
224 }
225
226
227 /***********************************************************************
228  *                        healthMonitor_unload
229  ***********************************************************************
230 DESCRIPTION: 
231            
232 INPUT:      
233
234 OUTPUT:
235
236 RETURN: 
237
238 ************************************************************************/
239 TI_STATUS healthMonitor_unload (TI_HANDLE hHealthMonitor)
240 {
241     THealthMonitor *pHealthMonitor;
242
243     pHealthMonitor = (THealthMonitor*)hHealthMonitor;
244
245     if (pHealthMonitor != NULL)
246     {
247         if (NULL != pHealthMonitor->hFailTimer)
248         {
249             /* Release the timer */
250             tmr_DestroyTimer (pHealthMonitor->hFailTimer);
251         }
252
253         /* Freeing the object should be called last !!!!!!!!!!!! */
254         os_memoryFree (pHealthMonitor->hOs, pHealthMonitor, sizeof(THealthMonitor));
255     }
256
257     return TI_OK;
258 }
259
260
261 /***********************************************************************
262  *                        healthMonitor_setState
263  ***********************************************************************
264 DESCRIPTION: 
265            
266
267 INPUT:      
268
269 OUTPUT:
270
271 RETURN: 
272
273 ************************************************************************/
274 void healthMonitor_setState (TI_HANDLE hHealthMonitor, healthMonitorState_e state)
275 {
276     THealthMonitor *pHealthMonitor = (THealthMonitor*)hHealthMonitor;
277
278     pHealthMonitor->state = state;
279 }
280
281
282 /***********************************************************************
283  *                        healthMonitor_PerformTest
284  ***********************************************************************
285 DESCRIPTION: Called periodically by timer every few seconds (depends on connection state),
286              or optionally by external application.
287            
288 INPUT:      hHealthMonitor      -       Module handle.
289             bTwdInitOccured -   Indicates if TWDriver recovery occured since timer started 
290
291 OUTPUT:
292
293 RETURN: 
294
295 ************************************************************************/
296 void healthMonitor_PerformTest (TI_HANDLE hHealthMonitor, TI_BOOL bTwdInitOccured)
297 {
298     THealthMonitor *pHealthMonitor = (THealthMonitor*)hHealthMonitor;
299
300     pHealthMonitor->numOfHealthTests++;
301
302     /* Send health-check command to FW, just to ensure command complete is accepted */
303     TWD_CmdHealthCheck (pHealthMonitor->hTWD);
304 }
305
306
307 /***********************************************************************
308  *                        healthMonitor_sendFailureEvent
309  ***********************************************************************
310 DESCRIPTION:    Entry point for all low level modules to send a failure evrnt
311
312 INPUT:          handle - health monitor handle
313                 failureEvent - the error
314
315 OUTPUT:
316
317 RETURN:    
318
319 ************************************************************************/
320 void healthMonitor_sendFailureEvent (TI_HANDLE hHealthMonitor, EFailureEvent failureEvent)
321 {
322     THealthMonitor *pHealthMonitor = (THealthMonitor*)hHealthMonitor;
323
324     /* Check the recovery process is already running */
325     if (pHealthMonitor->failureEvent < MAX_FAILURE_EVENTS)
326     {
327         TRACE0(pHealthMonitor->hReport, REPORT_SEVERITY_WARNING , ": recovery process is already handling , new trigger is \n");
328     }
329
330     /* Recovery is performed only if this trigger is enabled in the .INI file */
331     else if (pHealthMonitor->recoveryTriggerEnabled[failureEvent])
332     {
333         pHealthMonitor->failureEvent = failureEvent;
334         /* 
335          * NOTE: start timer with minimum expiry (1 msec) for recovery will start
336          *       from the top of the stack 
337          */
338         tmr_StartTimer (pHealthMonitor->hFailTimer,
339                         healthMonitor_proccessFailureEvent,
340                         (TI_HANDLE)pHealthMonitor,
341                         1,
342                         TI_FALSE);
343     }
344     else 
345     {
346         TRACE0(pHealthMonitor->hReport, REPORT_SEVERITY_ERROR , ": Recovery trigger  is disabled!\n");
347     }
348 }
349
350
351 /***********************************************************************
352  *                        healthMonitor_proccessFailureEvent
353  ***********************************************************************
354 DESCRIPTION:    this is the central error function - will be passed as call back 
355                 to the TnetWDriver modules. it will parse the error and dispatch the 
356                 relevant action (recovery or not) 
357
358 INPUT:      hHealthMonitor - health monitor handle
359             bTwdInitOccured -   Indicates if TWDriver recovery occured since timer started 
360
361 OUTPUT:
362
363 RETURN:    
364
365 ************************************************************************/
366 void healthMonitor_proccessFailureEvent (TI_HANDLE hHealthMonitor, TI_BOOL bTwdInitOccured)
367 {
368     THealthMonitor *pHealthMonitor = (THealthMonitor*)hHealthMonitor;
369
370     /* Check failure event validity */
371     if (pHealthMonitor->failureEvent < MAX_FAILURE_EVENTS)
372     {
373         pHealthMonitor->recoveryTriggersNumber[pHealthMonitor->failureEvent] ++;
374
375         TRACE2(pHealthMonitor->hReport, REPORT_SEVERITY_CONSOLE, "***** recovery trigger: failureEvent =%d *****, ts=%d\n", pHealthMonitor->failureEvent, os_timeStampMs(pHealthMonitor->hOs));
376         WLAN_OS_REPORT (("***** recovery trigger: %s *****, ts=%d\n", sRecoveryTriggersNames[pHealthMonitor->failureEvent], os_timeStampMs(pHealthMonitor->hOs)));
377
378         if (TWD_RecoveryEnabled (pHealthMonitor->hTWD))
379         {
380             pHealthMonitor->numOfRecoveryPerformed ++;
381             drvMain_Recovery (pHealthMonitor->hDrvMain);
382         }
383         else
384         {
385             TRACE0(pHealthMonitor->hReport, REPORT_SEVERITY_CONSOLE, "healthMonitor_proccessFailureEvent: Recovery is disabled in tiwlan.ini, abort recovery process\n");
386             WLAN_OS_REPORT(("healthMonitor_proccessFailureEvent: Recovery is disabled in tiwlan.ini, abort recovery process\n"));
387         }
388
389         pHealthMonitor->failureEvent = (TI_UINT32)NO_FAILURE;
390     }
391     else
392     {
393         TRACE1(pHealthMonitor->hReport, REPORT_SEVERITY_ERROR , "unsupported failure event = %d\n", pHealthMonitor->failureEvent);
394     }    
395 }
396
397
398 /***********************************************************************
399  *                        healthMonitor_printFailureEvents
400  ***********************************************************************
401 DESCRIPTION:
402
403 INPUT:
404
405 OUTPUT:
406
407 RETURN:
408 ************************************************************************/
409 void healthMonitor_printFailureEvents(TI_HANDLE hHealthMonitor)
410 {
411 #ifdef TI_DBG
412 #ifdef REPORT_LOG
413     THealthMonitor  *pHealthMonitor = (THealthMonitor*)hHealthMonitor;
414     int i;
415
416     WLAN_OS_REPORT(("-------------- STA Health Failure Statistics ---------------\n"));
417     WLAN_OS_REPORT(("FULL RECOVERY PERFORMED    = %d\n", pHealthMonitor->numOfRecoveryPerformed));
418     for (i = 0; i < MAX_FAILURE_EVENTS; i++)
419     {
420         WLAN_OS_REPORT(("%27s= %d\n", sRecoveryTriggersNames[ i ], pHealthMonitor->recoveryTriggersNumber[ i ]));
421     }
422     WLAN_OS_REPORT(("Maximum number of commands in mailbox queue = %u\n", TWD_GetMaxNumberOfCommandsInQueue(pHealthMonitor->hTWD)));
423     WLAN_OS_REPORT(("Health Test Performed       = %d\n", pHealthMonitor->numOfHealthTests));
424     WLAN_OS_REPORT(("\n"));
425 #endif
426 #endif /* TI_DBG */
427 }
428
429
430 /***********************************************************************
431  *                        healthMonitor_SetParam                                                                        
432  ***********************************************************************
433 DESCRIPTION: Set module parameters from the external command interface  
434                                                                                                    
435 INPUT:      hHealthMonitor      -       module handle.
436                         pParam          -       Pointer to the parameter                
437
438 OUTPUT:         
439
440 RETURN:     TI_OK on success, TI_NOK otherwise
441 ************************************************************************/
442 TI_STATUS healthMonitor_SetParam (TI_HANDLE hHealthMonitor, paramInfo_t *pParam)
443 {
444     THealthMonitor *pHealthMonitor = (THealthMonitor*)hHealthMonitor;
445         TI_STATUS eStatus = TI_OK;
446
447     TRACE1(pHealthMonitor->hReport, REPORT_SEVERITY_INFORMATION, "healthMonitor_SetParam() - %d\n", pParam->paramType);
448         
449         switch(pParam->paramType)
450         {
451
452         case HEALTH_MONITOR_CHECK_DEVICE:
453         /* Send health check command to FW if we are not disconnceted */
454         if (pHealthMonitor->state != HEALTH_MONITOR_STATE_DISCONNECTED) 
455         {
456             healthMonitor_PerformTest (hHealthMonitor, TI_FALSE);
457         }
458                 break;
459
460         default:
461         TRACE1(pHealthMonitor->hReport, REPORT_SEVERITY_ERROR, "healthMonitor_SetParam(): Params is not supported, %d\n", pParam->paramType);
462         }
463
464         return eStatus;
465 }
466
467
468 /***********************************************************************
469  *                            healthMonitor_GetParam                                                                    
470  ***********************************************************************
471 DESCRIPTION: Get module parameters from the external command interface
472                                                                                                    
473 INPUT:      hHealthMonitor      -       module handle.
474                         pParam          -       Pointer to the parameter                
475
476 OUTPUT:         
477
478 RETURN:     TI_OK on success, TI_NOK otherwise
479 ************************************************************************/
480 TI_STATUS healthMonitor_GetParam (TI_HANDLE hHealthMonitor, paramInfo_t *pParam)
481
482         return TI_OK;
483 }
484
485
486
487