• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
healthMonitor_create(TI_HANDLE hOs)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  */
healthMonitor_init(TStadHandlesList * pStadHandles)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  */
healthMonitor_SetDefaults(TI_HANDLE hHealthMonitor,healthMonitorInitParams_t * healthMonitorInitParams)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 ************************************************************************/
healthMonitor_unload(TI_HANDLE hHealthMonitor)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 ************************************************************************/
healthMonitor_setState(TI_HANDLE hHealthMonitor,healthMonitorState_e state)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 ************************************************************************/
healthMonitor_PerformTest(TI_HANDLE hHealthMonitor,TI_BOOL bTwdInitOccured)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 ************************************************************************/
healthMonitor_sendFailureEvent(TI_HANDLE hHealthMonitor,EFailureEvent failureEvent)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 ************************************************************************/
healthMonitor_proccessFailureEvent(TI_HANDLE hHealthMonitor,TI_BOOL bTwdInitOccured)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 ************************************************************************/
healthMonitor_printFailureEvents(TI_HANDLE hHealthMonitor)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 ************************************************************************/
healthMonitor_SetParam(TI_HANDLE hHealthMonitor,paramInfo_t * pParam)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 ************************************************************************/
healthMonitor_GetParam(TI_HANDLE hHealthMonitor,paramInfo_t * pParam)480 TI_STATUS healthMonitor_GetParam (TI_HANDLE hHealthMonitor, paramInfo_t *pParam)
481 {
482 	return TI_OK;
483 }
484 
485 
486 
487 
488