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 ************************************************************************/ 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 ************************************************************************/ 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 ************************************************************************/ 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 ************************************************************************/ 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 ************************************************************************/ 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 ************************************************************************/ 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 ************************************************************************/ 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 ************************************************************************/ 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 ************************************************************************/ 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 ************************************************************************/ 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 ************************************************************************/ 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