Home | History | Annotate | Download | only in HealthMonitor
      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