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