Home | History | Annotate | Download | only in Sta_Management
      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  */
    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  */
    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  */
    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 ************************************************************************/
    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 ************************************************************************/
    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 ************************************************************************/
    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 ************************************************************************/
    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 ************************************************************************/
    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 ************************************************************************/
    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 ************************************************************************/
    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 ************************************************************************/
    480 TI_STATUS healthMonitor_GetParam (TI_HANDLE hHealthMonitor, paramInfo_t *pParam)
    481 {
    482 	return TI_OK;
    483 }
    484 
    485 
    486 
    487 
    488