1 /** \file healthMonitor.c
2 * \brief Firmware Recovery Mechanism
3 */
4 /****************************************************************************
5 **+-----------------------------------------------------------------------+**
6 **| |**
7 **| Copyright(c) 1998 - 2008 Texas Instruments. All rights reserved. |**
8 **| All rights reserved. |**
9 **| |**
10 **| Redistribution and use in source and binary forms, with or without |**
11 **| modification, are permitted provided that the following conditions |**
12 **| are met: |**
13 **| |**
14 **| * Redistributions of source code must retain the above copyright |**
15 **| notice, this list of conditions and the following disclaimer. |**
16 **| * Redistributions in binary form must reproduce the above copyright |**
17 **| notice, this list of conditions and the following disclaimer in |**
18 **| the documentation and/or other materials provided with the |**
19 **| distribution. |**
20 **| * Neither the name Texas Instruments nor the names of its |**
21 **| contributors may be used to endorse or promote products derived |**
22 **| from this software without specific prior written permission. |**
23 **| |**
24 **| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |**
25 **| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |**
26 **| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |**
27 **| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |**
28 **| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |**
29 **| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |**
30 **| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |**
31 **| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |**
32 **| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |**
33 **| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |**
34 **| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |**
35 **| |**
36 **+-----------------------------------------------------------------------+**
37 ****************************************************************************/
38
39 /****************************************************************************/
40 /* */
41 /* MODULE: healthMonitor.c */
42 /* PURPOSE: Driver interface to OS abstraction layer */
43 /* */
44 /****************************************************************************/
45 #include "healthMonitor.h"
46
47 #ifdef _WINDOWS
48 #endif
49
50 #include "osApi.h"
51 #include "utils.h"
52 #include "report.h"
53 #include "siteMgrApi.h"
54 #include "whalCtrl_api.h"
55 #include "PowerMgr_API.h"
56 #include "currBss.h"
57 #include "DataCtrl_Api.h"
58 #include "TNETW_Driver_api.h"
59 #include "srcApi.h"
60 #include "SoftGeminiApi.h"
61 #include "currBss.h"
62 #include "whalCtrl_api.h"
63 #include "public_host_int.h"
64 #include "rsnApi.h"
65 #ifdef DEBUG_FIRMWARE
66 #include "whalCtrl.h"
67 #endif
68
69 #include "recoveryMgr_API.h"
70
71 /* Keep-alive period */
72 #define KEEP_ALIVE_TIEMOUT 10000
73
74
75 static void healthMonitor_proccessFailureEvent (TI_HANDLE hHealthMonitor);
76 static void healthMonitor_RSSI_CB (TI_HANDLE hHealthMonitor);
77
78
79 #ifdef REPORT_LOG
80
81 static char* sRecoveryTriggersNames [MAX_FAILURE_EVENTS] =
82 {
83 "NO_SCAN_COMPLETE_FAILURE",
84 "MBOX_FAILURE",
85 "HW_AWAKE_FAILURE",
86 "BUS_ERROR",
87 "DEVICE_ERROR",
88 "TX_STUCK",
89 "DISCONNECT_TIMEOUT",
90 "POWER_SAVE_FAILURE",
91 "MEASUREMENT_FAILURE",
92 };
93
94 #endif
95
96
97 /***********************************************************************
98 * healthMonitor_create
99 ***********************************************************************
100 DESCRIPTION:
101
102
103 INPUT:
104
105 OUTPUT:
106
107 RETURN:
108
109 ************************************************************************/
healthMonitor_create(TI_HANDLE hOs)110 TI_HANDLE healthMonitor_create (TI_HANDLE hOs)
111 {
112 healthMonitor_t *pHealthMonitor;
113
114 /* Allocate memory for the health monitor object and nullify it */
115 pHealthMonitor = (healthMonitor_t*)os_memoryAlloc (hOs, sizeof(healthMonitor_t));
116 if (pHealthMonitor == NULL)
117 {
118 return NULL;
119 }
120 os_memoryZero (hOs, pHealthMonitor, sizeof(healthMonitor_t));
121
122 /* Store OS object handle */
123 pHealthMonitor->hOs = hOs;
124
125 /* Create periodic health check timer */
126 pHealthMonitor->hHealtheCheckTimer = os_timerCreate (hOs, healthMonitor_performTest, (TI_HANDLE)pHealthMonitor);
127 if (NULL == pHealthMonitor->hHealtheCheckTimer)
128 {
129 healthMonitor_unload ((TI_HANDLE)pHealthMonitor);
130 return NULL;
131 }
132
133 /* Create recovery request timer */
134 pHealthMonitor->hFailTimer = os_timerCreate (hOs, healthMonitor_proccessFailureEvent, (TI_HANDLE)pHealthMonitor);
135 if (NULL == pHealthMonitor->hFailTimer)
136 {
137 healthMonitor_unload ((TI_HANDLE)pHealthMonitor);
138 return NULL;
139 }
140
141 return (TI_HANDLE)pHealthMonitor;
142 }
143
144
145 /***********************************************************************
146 * healthMonitor_config
147 ***********************************************************************
148 DESCRIPTION:
149
150 INPUT:
151
152 OUTPUT:
153
154 RETURN:
155
156 ************************************************************************/
healthMonitor_config(TI_HANDLE hHealthMonitor,TI_HANDLE hReport,TI_HANDLE hHalCtrl,TI_HANDLE hSiteMgr,TI_HANDLE hScr,TI_HANDLE hSoftGemini,TI_HANDLE hTnetwDrv,TI_HANDLE hMemMgr,TI_HANDLE hConfigMgr,TI_HANDLE hTxData,TI_HANDLE hCurrBss,TI_HANDLE hRsn,healthMonitorInitParams_t * healthMonitorInitParams,TI_HANDLE hRecoveryMgr)157 TI_STATUS healthMonitor_config (TI_HANDLE hHealthMonitor,
158 TI_HANDLE hReport,
159 TI_HANDLE hHalCtrl,
160 TI_HANDLE hSiteMgr,
161 TI_HANDLE hScr,
162 TI_HANDLE hSoftGemini,
163 TI_HANDLE hTnetwDrv,
164 TI_HANDLE hMemMgr,
165 TI_HANDLE hConfigMgr,
166 TI_HANDLE hTxData,
167 TI_HANDLE hCurrBss,
168 TI_HANDLE hRsn,
169 healthMonitorInitParams_t *healthMonitorInitParams,
170 TI_HANDLE hRecoveryMgr)
171 {
172 healthMonitor_t *pHealthMonitor = hHealthMonitor;
173 int i;
174
175 pHealthMonitor->hReport = hReport;
176 pHealthMonitor->hHalCtrl = hHalCtrl;
177 pHealthMonitor->hSiteMgr = hSiteMgr;
178 pHealthMonitor->hScr = hScr;
179 pHealthMonitor->hSoftGemini = hSoftGemini;
180 pHealthMonitor->hTnetwDrv = hTnetwDrv;
181 pHealthMonitor->hMemMgr = hMemMgr;
182 pHealthMonitor->hConfigMgr = hConfigMgr;
183 pHealthMonitor->hTxData = hTxData;
184 pHealthMonitor->hCurrBss = hCurrBss;
185 pHealthMonitor->hRsn = hRsn;
186 pHealthMonitor->state = HEALTH_MONITOR_STATE_DISCONNECTED;
187 pHealthMonitor->bRunSoftRecovery = FALSE;
188 pHealthMonitor->failureEvent = (UINT32)NO_FAILURE;
189 pHealthMonitor->hRecoveryMgr = hRecoveryMgr;
190
191 /* Registry configuration */
192 pHealthMonitor->bFullRecoveryEnable = healthMonitorInitParams->FullRecoveryEnable;
193 pHealthMonitor->timerInterval = healthMonitorInitParams->healthCheckPeriod;
194
195 for (i = 0; i < MAX_FAILURE_EVENTS; i++)
196 {
197 pHealthMonitor->recoveryTriggerEnabled[i] = healthMonitorInitParams->recoveryTriggerEnabled[i];
198 }
199
200 /*
201 * Set the keep-alive Interval, which is used to signal at how many timer intervals
202 * a keep alive (null data) packet needs to be sent to the AP. A packet should be sent every
203 * KEEP_ALIVE_TIEMOUT seconds (default is 10 seconds).
204 */
205 if (pHealthMonitor->timerInterval != 0)
206 {
207 pHealthMonitor->keepAliveIntervals = KEEP_ALIVE_TIEMOUT / pHealthMonitor->timerInterval;
208 }
209 else
210 {
211 pHealthMonitor->keepAliveIntervals = 1;
212 }
213 pHealthMonitor->currentKeepAliveCounter = 0;
214
215 /* Register the failure event callback */
216 TnetwDrv_Register_CB (hTnetwDrv,
217 TNETW_DRIVER_EVENT_FAILURE,
218 (void *)healthMonitor_sendFailureEvent,
219 hHealthMonitor);
220
221 return OK;
222 }
223
224
225 /***********************************************************************
226 * healthMonitor_unload
227 ***********************************************************************
228 DESCRIPTION:
229
230 INPUT:
231
232 OUTPUT:
233
234 RETURN:
235
236 ************************************************************************/
healthMonitor_unload(TI_HANDLE hHealthMonitor)237 TI_STATUS healthMonitor_unload (TI_HANDLE hHealthMonitor)
238 {
239 healthMonitor_t *pHealthMonitor;
240
241 pHealthMonitor = (healthMonitor_t*)hHealthMonitor;
242
243 if (pHealthMonitor != NULL)
244 {
245 if (NULL != pHealthMonitor->hHealtheCheckTimer)
246 {
247 /* Release the timer */
248 os_timerDestroy (pHealthMonitor->hOs, pHealthMonitor->hHealtheCheckTimer);
249 }
250
251 if (NULL != pHealthMonitor->hFailTimer)
252 {
253 /* Release the timer */
254 os_timerDestroy (pHealthMonitor->hOs, pHealthMonitor->hFailTimer);
255 }
256
257 /* Freeing the object should be called last !!!!!!!!!!!! */
258 os_memoryFree (pHealthMonitor->hOs, pHealthMonitor, sizeof(healthMonitor_t));
259 }
260
261 return OK;
262 }
263
264
265 /***********************************************************************
266 * healthMonitor_setState
267 ***********************************************************************
268 DESCRIPTION:
269
270
271 INPUT:
272
273 OUTPUT:
274
275 RETURN:
276
277 ************************************************************************/
healthMonitor_setState(TI_HANDLE hHealthMonitor,healthMonitorState_e state)278 void healthMonitor_setState (TI_HANDLE hHealthMonitor, healthMonitorState_e state)
279 {
280 healthMonitor_t *pHealthMonitor = (healthMonitor_t*)hHealthMonitor;
281
282 pHealthMonitor->state = state;
283
284 switch (state)
285 {
286 case HEALTH_MONITOR_STATE_DISCONNECTED:
287 /* Stop health monitor check */
288 os_timerStop (pHealthMonitor->hOs, pHealthMonitor->hHealtheCheckTimer);
289 break;
290
291 case HEALTH_MONITOR_STATE_CONNECTED:
292 /* Start health monitor check */
293 os_timerStart (pHealthMonitor->hOs, pHealthMonitor->hHealtheCheckTimer, pHealthMonitor->timerInterval, TRUE);
294 break;
295 }
296 }
297
298
299 /***********************************************************************
300 * healthMonitor_suspendPeriodicTest
301 ***********************************************************************
302 DESCRIPTION:
303
304 INPUT:
305
306 OUTPUT:
307
308 RETURN:
309
310 ************************************************************************/
healthMonitor_suspendPeriodicTest(TI_HANDLE hHealthMonitor)311 void healthMonitor_suspendPeriodicTest (TI_HANDLE hHealthMonitor)
312 {
313 healthMonitor_t *pHealthMonitor = (healthMonitor_t*)hHealthMonitor;
314
315 WLAN_REPORT_INFORMATION (pHealthMonitor->hReport, SITE_MGR_MODULE_LOG,
316 ("%s: state=%d, suspend=%d\n",
317 __FUNCTION__, pHealthMonitor->state, pHealthMonitor->bSuspended));
318
319 pHealthMonitor->bSuspended = TRUE;
320 }
321
322
323 /***********************************************************************
324 * healthMonitor_resumePeriodicTest
325 ***********************************************************************
326 DESCRIPTION:
327
328
329 INPUT:
330
331 OUTPUT:
332
333 RETURN:
334
335 ************************************************************************/
healthMonitor_resumePeriodicTest(TI_HANDLE hHealthMonitor)336 void healthMonitor_resumePeriodicTest(TI_HANDLE hHealthMonitor)
337 {
338 healthMonitor_t *pHealthMonitor = (healthMonitor_t*)hHealthMonitor;
339
340 WLAN_REPORT_INFORMATION (pHealthMonitor->hReport, SITE_MGR_MODULE_LOG,
341 ("%s: state=%d, suspend=%d\n",
342 __FUNCTION__, pHealthMonitor->state, pHealthMonitor->bSuspended) );
343
344 pHealthMonitor->bSuspended = FALSE;
345 }
346
347
348 /***********************************************************************
349 * healthMonitor_performTest
350 ***********************************************************************
351 DESCRIPTION: every T s ( 5sec ) will be called by TX Power Adjust timer
352
353 INPUT:
354
355 OUTPUT:
356
357 RETURN:
358
359 ************************************************************************/
healthMonitor_performTest(TI_HANDLE hHealthMonitor)360 void healthMonitor_performTest (TI_HANDLE hHealthMonitor)
361 {
362 healthMonitor_t *pHealthMonitor = (healthMonitor_t*)hHealthMonitor;
363
364 if (FALSE == pHealthMonitor->bSuspended)
365 {
366 /*
367 * The following call is disabled, because there's no point to send health check command if
368 * the get RSSI is sent anyhow. When these operations will be
369 * separated, the health test should be returned.
370 */
371
372 /*
373 pHealthMonitor->numOfHealthTests++;
374 #ifdef USE_RECOVERY
375 whalCtrl_CheckHwStatus(pHealthMonitor->hHalCtrl);
376 #endif
377 */
378
379 /* NOTE: This call is important to update the siteMgr and roamingMgr, so be carefully if you wish to remove it */
380 whalCtrl_GetAsynRSSI (pHealthMonitor->hHalCtrl,
381 (PVOID)healthMonitor_RSSI_CB,
382 hHealthMonitor,
383 (PUINT8)&pHealthMonitor->statTable);
384
385 pHealthMonitor->currentKeepAliveCounter++;
386 if (pHealthMonitor->currentKeepAliveCounter >= pHealthMonitor->keepAliveIntervals)
387 {
388 siteMgr_keepAliveSendNullDataTimer (pHealthMonitor->hSiteMgr);
389 pHealthMonitor->currentKeepAliveCounter = 0;
390 }
391 }
392 }
393
394
395 /***********************************************************************
396 * healthMonitor_RSSI_CB
397 ***********************************************************************
398 DESCRIPTION:
399
400 INPUT:
401
402 OUTPUT:
403
404 RETURN:
405
406 ************************************************************************/
healthMonitor_RSSI_CB(TI_HANDLE hHealthMonitor)407 void healthMonitor_RSSI_CB (TI_HANDLE hHealthMonitor)
408 {
409 healthMonitor_t *pHealthMonitor = (healthMonitor_t*)hHealthMonitor;
410 /* Update Rx signal in currBss in order to check if roaming trigger on BG scan occured */
411 /* and to update the site Mgr with the updated RSSI. (Those values are averaged) */
412 currBSS_updateRxSignal (pHealthMonitor->hCurrBss,
413 pHealthMonitor->statTable.snr,
414 pHealthMonitor->statTable.rssi,
415 TRUE);
416
417 if (pHealthMonitor->state == HEALTH_MONITOR_STATE_CONNECTED)
418 {
419 /* TX Power Adjust - if the RSSI is good lower the Tx Power */
420 siteMgr_checkTxPower( pHealthMonitor->hSiteMgr );
421 }
422 }
423
424
425 /***********************************************************************
426 * healthMonitor_sendFailureEvent
427 ***********************************************************************
428 DESCRIPTION: Entry point for all low level modules to send a failure evrnt
429
430 INPUT: handle - health monitor handle
431 failureEvent - the error
432
433 OUTPUT:
434
435 RETURN:
436
437 ************************************************************************/
healthMonitor_sendFailureEvent(TI_HANDLE hHealthMonitor,failureEvent_e failureEvent)438 void healthMonitor_sendFailureEvent (TI_HANDLE hHealthMonitor, failureEvent_e failureEvent)
439 {
440 healthMonitor_t *pHealthMonitor = (healthMonitor_t*)hHealthMonitor;
441
442 /* Check the recovery process is already running */
443 if (pHealthMonitor->failureEvent < MAX_FAILURE_EVENTS)
444 {
445 WLAN_REPORT_WARNING (pHealthMonitor->hReport, SITE_MGR_MODULE_LOG,
446 ("%s: recovery process is already running\n", __FUNCTION__));
447 }
448
449 /* Recovery is performed only if this trigger is enabled in the .INI file */
450 else if (TRUE == pHealthMonitor->recoveryTriggerEnabled[failureEvent])
451 {
452 pHealthMonitor->failureEvent = failureEvent;
453 /*
454 * NOTE: start timer with minimum expiry for recovery will start
455 * from the top of the stack
456 */
457 os_timerStart (pHealthMonitor->hOs, pHealthMonitor->hFailTimer, 1, FALSE);
458 }
459 }
460
461
462 /***********************************************************************
463 * healthMonitor_proccessFailureEvent
464 ***********************************************************************
465 DESCRIPTION: this is the central error function - will be passed as call back
466 to the TnetWDriver modules. it will parse the error and dispatch the
467 relevant action (recovery or not)
468
469 INPUT: handle - health monitor handle
470 failureEvent - the error
471
472 OUTPUT:
473
474 RETURN:
475
476 ************************************************************************/
healthMonitor_proccessFailureEvent(TI_HANDLE hHealthMonitor)477 void healthMonitor_proccessFailureEvent (TI_HANDLE hHealthMonitor)
478 {
479 healthMonitor_t *pHealthMonitor = (healthMonitor_t*)hHealthMonitor;
480
481 /* Check failure event validity */
482 if (pHealthMonitor->failureEvent < MAX_FAILURE_EVENTS)
483 {
484 pHealthMonitor->recoveryTriggersNumber[pHealthMonitor->failureEvent] ++;
485
486 WLAN_OS_REPORT (("***** recovery trigger: %s *****\n", sRecoveryTriggersNames[pHealthMonitor->failureEvent]));
487
488 recoveryMgr_recoveryProcess(pHealthMonitor->hRecoveryMgr);/* CE20 */
489
490 pHealthMonitor->failureEvent = (UINT32)NO_FAILURE;
491 }
492 else
493 {
494 WLAN_REPORT_ERROR (pHealthMonitor->hReport, SITE_MGR_MODULE_LOG,
495 ("%s: unsupported failure event = %d\n",
496 pHealthMonitor->failureEvent));
497 }
498 }
499
500
501 /***********************************************************************
502 * healthMonitor_printFailureEvents
503 ***********************************************************************
504 DESCRIPTION:
505
506 INPUT:
507
508 OUTPUT:
509
510 RETURN:
511 ************************************************************************/
healthMonitor_printFailureEvents(TI_HANDLE hHealthMonitor)512 void healthMonitor_printFailureEvents(TI_HANDLE hHealthMonitor)
513 {
514 #ifdef TI_DBG
515 healthMonitor_t *pHealthMonitor = (healthMonitor_t*)hHealthMonitor;
516 int i;
517
518 WLAN_OS_REPORT(("-------------- STA Health Failure Statistics ---------------\n"));
519 WLAN_OS_REPORT(("FULL RECOVERY PERFORMED = %d\n", pHealthMonitor->numOfRecoveryPerformed));
520 for (i = 0; i < MAX_FAILURE_EVENTS; i++)
521 {
522 WLAN_OS_REPORT(("%27s= %d\n",
523 sRecoveryTriggersNames[ i ], pHealthMonitor->recoveryTriggersNumber[ i ]));
524 }
525 WLAN_OS_REPORT(("Maximum number of commands in mailbox queue = %d\n",whalCtrl_getMaxNumberOfCommandsInQueue(pHealthMonitor->hHalCtrl)));
526 WLAN_OS_REPORT(("Health Test Perfomrd = %d\n", pHealthMonitor->numOfHealthTests));
527 WLAN_OS_REPORT(("\n"));
528
529 #ifdef USE_RECOVERY
530 whalCtrl_PrintHwStatus(pHealthMonitor->hHalCtrl);
531 #endif
532
533 #endif /* TI_DBG */
534 }
535
536