| /* |
| * healthMonitor.c |
| * |
| * Copyright(c) 1998 - 2010 Texas Instruments. All rights reserved. |
| * All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * |
| * * Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * * Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in |
| * the documentation and/or other materials provided with the |
| * distribution. |
| * * Neither the name Texas Instruments nor the names of its |
| * contributors may be used to endorse or promote products derived |
| * from this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| /** \file healthMonitor.c |
| * \brief Firmware Recovery Mechanism |
| */ |
| |
| /** \file healthMonitor.c |
| * \brief The health monitor module. Gets failures indications and handle them. |
| * |
| * For periodic check, use HW watchdog mechanizem instead of local periodic timer check |
| * |
| * \see healthMonitor.h |
| */ |
| |
| #define __FILE_ID__ FILE_ID_66 |
| #include "healthMonitor.h" |
| #include "osApi.h" |
| #include "timer.h" |
| #include "report.h" |
| #include "siteMgrApi.h" |
| #include "PowerMgr_API.h" |
| #include "currBss.h" |
| #include "DataCtrl_Api.h" |
| #include "TWDriver.h" |
| #include "SoftGeminiApi.h" |
| #include "currBss.h" |
| #include "rsnApi.h" |
| #include "DrvMain.h" |
| #include "DrvMainModules.h" |
| #include "TWDriverInternal.h" |
| |
| |
| typedef struct |
| { |
| /* handles to other modules */ |
| TI_HANDLE hOs; /* handle to the OS object */ |
| TI_HANDLE hReport; /* handle to the report object */ |
| TI_HANDLE hTWD; /* handle to the TWD object */ |
| TI_HANDLE hSiteMgr; /* handle to the site manager object */ |
| TI_HANDLE hScr; /* handle to the SCR object */ |
| TI_HANDLE hSoftGemini; /* handle to the Soft Gemini object */ |
| TI_HANDLE hDrvMain; /* handle to the Recovery Mgr object */ |
| TI_HANDLE hTxCtrl; /* handle to the TX Ctrl object */ |
| TI_HANDLE hCurrBss; /* handle to the currBss object */ |
| TI_HANDLE hRsn; /* handle to the RSN */ |
| TI_HANDLE hTimer; /* handle to the Timer module object */ |
| TI_HANDLE hContext; /* handle to the context-engine object */ |
| |
| /* Timers handles */ |
| TI_HANDLE hFailTimer; /* failure event timer */ |
| |
| /* Management variables */ |
| TI_UINT32 numOfHealthTests; /* number of health tests performed counter */ |
| healthMonitorState_e state; /* health monitor state */ |
| TI_BOOL bFullRecoveryEnable; /* full recovery enable flag */ |
| TI_BOOL recoveryTriggerEnabled [MAX_FAILURE_EVENTS]; |
| /* recovery enable flags per trigger type */ |
| TI_UINT32 failureEvent; /* current recovery trigger */ |
| TI_UINT32 keepAliveIntervals; /* number of health monitor timer intervals at which keep alive should be sent */ |
| TI_UINT32 currentKeepAliveCounter;/* counting how many timer intervals had passed w/o a keep alive */ |
| |
| /* Recoveries Statistics */ |
| TI_UINT32 recoveryTriggersNumber [MAX_FAILURE_EVENTS]; |
| /* Number of times each recovery trigger occured */ |
| TI_UINT32 numOfRecoveryPerformed; /* number of recoveries performed */ |
| |
| } THealthMonitor; |
| |
| |
| static void healthMonitor_proccessFailureEvent (TI_HANDLE hHealthMonitor, TI_BOOL bTwdInitOccured); |
| |
| |
| #ifdef REPORT_LOG |
| |
| static char* sRecoveryTriggersNames [MAX_FAILURE_EVENTS] = |
| { |
| "NO_SCAN_COMPLETE_FAILURE", |
| "MBOX_FAILURE", |
| "HW_AWAKE_FAILURE", |
| "TX_STUCK", |
| "DISCONNECT_TIMEOUT", |
| "POWER_SAVE_FAILURE", |
| "MEASUREMENT_FAILURE", |
| "BUS_FAILURE", |
| "HW_WD_EXPIRE", |
| "RX_XFER_FAILURE" |
| }; |
| #endif |
| |
| |
| /** |
| * \fn healthMonitor_create |
| * \brief Create module object |
| * |
| * Create module object. |
| * |
| * \note |
| * \param hOs - The OS adaptation handle |
| * \return The created module handle |
| * \sa |
| */ |
| TI_HANDLE healthMonitor_create (TI_HANDLE hOs) |
| { |
| THealthMonitor *pHealthMonitor; |
| |
| /* Allocate memory for the health monitor object and nullify it */ |
| pHealthMonitor = (THealthMonitor*)os_memoryAlloc (hOs, sizeof(THealthMonitor)); |
| if (pHealthMonitor == NULL) |
| { |
| return NULL; |
| } |
| os_memoryZero (hOs, pHealthMonitor, sizeof(THealthMonitor)); |
| |
| /* Store OS object handle */ |
| pHealthMonitor->hOs = hOs; |
| |
| return (TI_HANDLE)pHealthMonitor; |
| } |
| |
| |
| /** |
| * \fn healthMonitor_init |
| * \brief Init module handles and variables |
| * |
| * Init module handles and variables. |
| * |
| * \note |
| * \param pStadHandles - The driver modules handles |
| * \return void |
| * \sa |
| */ |
| void healthMonitor_init (TStadHandlesList *pStadHandles) |
| { |
| THealthMonitor *pHealthMonitor = (THealthMonitor *)(pStadHandles->hHealthMonitor); |
| |
| pHealthMonitor->hReport = pStadHandles->hReport; |
| pHealthMonitor->hTWD = pStadHandles->hTWD; |
| pHealthMonitor->hSiteMgr = pStadHandles->hSiteMgr; |
| pHealthMonitor->hScr = pStadHandles->hSCR; |
| pHealthMonitor->hSoftGemini = pStadHandles->hSoftGemini; |
| pHealthMonitor->hDrvMain = pStadHandles->hDrvMain; |
| pHealthMonitor->hTxCtrl = pStadHandles->hTxCtrl; |
| pHealthMonitor->hCurrBss = pStadHandles->hCurrBss; |
| pHealthMonitor->hRsn = pStadHandles->hRsn; |
| pHealthMonitor->hTimer = pStadHandles->hTimer; |
| pHealthMonitor->hContext = pStadHandles->hContext; |
| |
| pHealthMonitor->state = HEALTH_MONITOR_STATE_DISCONNECTED; |
| pHealthMonitor->failureEvent = (TI_UINT32)NO_FAILURE; |
| |
| /* Register the failure event callback */ |
| TWD_RegisterCb (pHealthMonitor->hTWD, |
| TWD_EVENT_FAILURE, |
| (void *)healthMonitor_sendFailureEvent, |
| (void *)pHealthMonitor); |
| } |
| |
| |
| /** |
| * \fn healthMonitor_SetDefaults |
| * \brief Set module defaults and create timers |
| * |
| * Set module defaults from Ini-file and create timers. |
| * |
| * \note |
| * \param hHealthMonitor - The module's handle |
| * \param healthMonitorInitParams - The module's parameters default values (from Ini-file). |
| * \return void |
| * \sa |
| */ |
| TI_STATUS healthMonitor_SetDefaults (TI_HANDLE hHealthMonitor, healthMonitorInitParams_t *healthMonitorInitParams) |
| { |
| THealthMonitor *pHealthMonitor = hHealthMonitor; |
| int i; |
| |
| /* Registry configuration */ |
| pHealthMonitor->bFullRecoveryEnable = healthMonitorInitParams->FullRecoveryEnable; |
| |
| for (i = 0; i < MAX_FAILURE_EVENTS; i++) |
| { |
| pHealthMonitor->recoveryTriggerEnabled[i] = healthMonitorInitParams->recoveryTriggerEnabled[i]; |
| } |
| |
| /* Create recovery request timer */ |
| pHealthMonitor->hFailTimer = tmr_CreateTimer (pHealthMonitor->hTimer); |
| if (pHealthMonitor->hFailTimer == NULL) |
| { |
| TRACE0(pHealthMonitor->hReport, REPORT_SEVERITY_ERROR, "healthMonitor_SetDefaults(): Failed to create hFailTimer!\n"); |
| return TI_NOK; |
| } |
| |
| return TI_OK; |
| } |
| |
| |
| /*********************************************************************** |
| * healthMonitor_unload |
| *********************************************************************** |
| DESCRIPTION: |
| |
| INPUT: |
| |
| OUTPUT: |
| |
| RETURN: |
| |
| ************************************************************************/ |
| TI_STATUS healthMonitor_unload (TI_HANDLE hHealthMonitor) |
| { |
| THealthMonitor *pHealthMonitor; |
| |
| pHealthMonitor = (THealthMonitor*)hHealthMonitor; |
| |
| if (pHealthMonitor != NULL) |
| { |
| if (NULL != pHealthMonitor->hFailTimer) |
| { |
| /* Release the timer */ |
| tmr_DestroyTimer (pHealthMonitor->hFailTimer); |
| } |
| |
| /* Freeing the object should be called last !!!!!!!!!!!! */ |
| os_memoryFree (pHealthMonitor->hOs, pHealthMonitor, sizeof(THealthMonitor)); |
| } |
| |
| return TI_OK; |
| } |
| |
| |
| /*********************************************************************** |
| * healthMonitor_setState |
| *********************************************************************** |
| DESCRIPTION: |
| |
| |
| INPUT: |
| |
| OUTPUT: |
| |
| RETURN: |
| |
| ************************************************************************/ |
| void healthMonitor_setState (TI_HANDLE hHealthMonitor, healthMonitorState_e state) |
| { |
| THealthMonitor *pHealthMonitor = (THealthMonitor*)hHealthMonitor; |
| |
| pHealthMonitor->state = state; |
| } |
| |
| |
| /*********************************************************************** |
| * healthMonitor_PerformTest |
| *********************************************************************** |
| DESCRIPTION: Called periodically by timer every few seconds (depends on connection state), |
| or optionally by external application. |
| |
| INPUT: hHealthMonitor - Module handle. |
| bTwdInitOccured - Indicates if TWDriver recovery occured since timer started |
| |
| OUTPUT: |
| |
| RETURN: |
| |
| ************************************************************************/ |
| void healthMonitor_PerformTest (TI_HANDLE hHealthMonitor, TI_BOOL bTwdInitOccured) |
| { |
| THealthMonitor *pHealthMonitor = (THealthMonitor*)hHealthMonitor; |
| |
| pHealthMonitor->numOfHealthTests++; |
| |
| /* Send health-check command to FW, just to ensure command complete is accepted */ |
| TWD_CmdHealthCheck (pHealthMonitor->hTWD); |
| } |
| |
| |
| /*********************************************************************** |
| * healthMonitor_sendFailureEvent |
| *********************************************************************** |
| DESCRIPTION: Entry point for all low level modules to send a failure evrnt |
| |
| INPUT: handle - health monitor handle |
| failureEvent - the error |
| |
| OUTPUT: |
| |
| RETURN: |
| |
| ************************************************************************/ |
| void healthMonitor_sendFailureEvent (TI_HANDLE hHealthMonitor, EFailureEvent failureEvent) |
| { |
| THealthMonitor *pHealthMonitor = (THealthMonitor*)hHealthMonitor; |
| |
| /* Check the recovery process is already running */ |
| if (pHealthMonitor->failureEvent < MAX_FAILURE_EVENTS) |
| { |
| TRACE0(pHealthMonitor->hReport, REPORT_SEVERITY_WARNING , ": recovery process is already handling , new trigger is \n"); |
| } |
| |
| /* Recovery is performed only if this trigger is enabled in the .INI file */ |
| else if (pHealthMonitor->recoveryTriggerEnabled[failureEvent]) |
| { |
| pHealthMonitor->failureEvent = failureEvent; |
| /* |
| * NOTE: start timer with minimum expiry (1 msec) for recovery will start |
| * from the top of the stack |
| */ |
| tmr_StartTimer (pHealthMonitor->hFailTimer, |
| healthMonitor_proccessFailureEvent, |
| (TI_HANDLE)pHealthMonitor, |
| 1, |
| TI_FALSE); |
| } |
| else |
| { |
| TRACE0(pHealthMonitor->hReport, REPORT_SEVERITY_ERROR , ": Recovery trigger is disabled!\n"); |
| } |
| } |
| |
| |
| /*********************************************************************** |
| * healthMonitor_proccessFailureEvent |
| *********************************************************************** |
| DESCRIPTION: this is the central error function - will be passed as call back |
| to the TnetWDriver modules. it will parse the error and dispatch the |
| relevant action (recovery or not) |
| |
| INPUT: hHealthMonitor - health monitor handle |
| bTwdInitOccured - Indicates if TWDriver recovery occured since timer started |
| |
| OUTPUT: |
| |
| RETURN: |
| |
| ************************************************************************/ |
| void healthMonitor_proccessFailureEvent (TI_HANDLE hHealthMonitor, TI_BOOL bTwdInitOccured) |
| { |
| THealthMonitor *pHealthMonitor = (THealthMonitor*)hHealthMonitor; |
| |
| /* Check failure event validity */ |
| if (pHealthMonitor->failureEvent < MAX_FAILURE_EVENTS) |
| { |
| pHealthMonitor->recoveryTriggersNumber[pHealthMonitor->failureEvent] ++; |
| |
| TRACE2(pHealthMonitor->hReport, REPORT_SEVERITY_CONSOLE, "***** recovery trigger: failureEvent =%d *****, ts=%d\n", pHealthMonitor->failureEvent, os_timeStampMs(pHealthMonitor->hOs)); |
| WLAN_OS_REPORT (("***** recovery trigger: %s *****, ts=%d\n", sRecoveryTriggersNames[pHealthMonitor->failureEvent], os_timeStampMs(pHealthMonitor->hOs))); |
| |
| if (TWD_RecoveryEnabled (pHealthMonitor->hTWD)) |
| { |
| pHealthMonitor->numOfRecoveryPerformed ++; |
| drvMain_Recovery (pHealthMonitor->hDrvMain); |
| } |
| else |
| { |
| TRACE0(pHealthMonitor->hReport, REPORT_SEVERITY_CONSOLE, "healthMonitor_proccessFailureEvent: Recovery is disabled in tiwlan.ini, abort recovery process\n"); |
| WLAN_OS_REPORT(("healthMonitor_proccessFailureEvent: Recovery is disabled in tiwlan.ini, abort recovery process\n")); |
| } |
| |
| pHealthMonitor->failureEvent = (TI_UINT32)NO_FAILURE; |
| } |
| else |
| { |
| TRACE1(pHealthMonitor->hReport, REPORT_SEVERITY_ERROR , "unsupported failure event = %d\n", pHealthMonitor->failureEvent); |
| } |
| } |
| |
| |
| /*********************************************************************** |
| * healthMonitor_printFailureEvents |
| *********************************************************************** |
| DESCRIPTION: |
| |
| INPUT: |
| |
| OUTPUT: |
| |
| RETURN: |
| ************************************************************************/ |
| void healthMonitor_printFailureEvents(TI_HANDLE hHealthMonitor) |
| { |
| #ifdef TI_DBG |
| #ifdef REPORT_LOG |
| THealthMonitor *pHealthMonitor = (THealthMonitor*)hHealthMonitor; |
| int i; |
| |
| WLAN_OS_REPORT(("-------------- STA Health Failure Statistics ---------------\n")); |
| WLAN_OS_REPORT(("FULL RECOVERY PERFORMED = %d\n", pHealthMonitor->numOfRecoveryPerformed)); |
| for (i = 0; i < MAX_FAILURE_EVENTS; i++) |
| { |
| WLAN_OS_REPORT(("%27s= %d\n", sRecoveryTriggersNames[ i ], pHealthMonitor->recoveryTriggersNumber[ i ])); |
| } |
| WLAN_OS_REPORT(("Maximum number of commands in mailbox queue = %u\n", TWD_GetMaxNumberOfCommandsInQueue(pHealthMonitor->hTWD))); |
| WLAN_OS_REPORT(("Health Test Performed = %d\n", pHealthMonitor->numOfHealthTests)); |
| WLAN_OS_REPORT(("\n")); |
| #endif |
| #endif /* TI_DBG */ |
| } |
| |
| |
| /*********************************************************************** |
| * healthMonitor_SetParam |
| *********************************************************************** |
| DESCRIPTION: Set module parameters from the external command interface |
| |
| INPUT: hHealthMonitor - module handle. |
| pParam - Pointer to the parameter |
| |
| OUTPUT: |
| |
| RETURN: TI_OK on success, TI_NOK otherwise |
| ************************************************************************/ |
| TI_STATUS healthMonitor_SetParam (TI_HANDLE hHealthMonitor, paramInfo_t *pParam) |
| { |
| THealthMonitor *pHealthMonitor = (THealthMonitor*)hHealthMonitor; |
| TI_STATUS eStatus = TI_OK; |
| |
| TRACE1(pHealthMonitor->hReport, REPORT_SEVERITY_INFORMATION, "healthMonitor_SetParam() - %d\n", pParam->paramType); |
| |
| switch(pParam->paramType) |
| { |
| |
| case HEALTH_MONITOR_CHECK_DEVICE: |
| /* Send health check command to FW if we are not disconnceted */ |
| if (pHealthMonitor->state != HEALTH_MONITOR_STATE_DISCONNECTED) |
| { |
| healthMonitor_PerformTest (hHealthMonitor, TI_FALSE); |
| } |
| break; |
| |
| default: |
| TRACE1(pHealthMonitor->hReport, REPORT_SEVERITY_ERROR, "healthMonitor_SetParam(): Params is not supported, %d\n", pParam->paramType); |
| } |
| |
| return eStatus; |
| } |
| |
| |
| /*********************************************************************** |
| * healthMonitor_GetParam |
| *********************************************************************** |
| DESCRIPTION: Get module parameters from the external command interface |
| |
| INPUT: hHealthMonitor - module handle. |
| pParam - Pointer to the parameter |
| |
| OUTPUT: |
| |
| RETURN: TI_OK on success, TI_NOK otherwise |
| ************************************************************************/ |
| TI_STATUS healthMonitor_GetParam (TI_HANDLE hHealthMonitor, paramInfo_t *pParam) |
| { |
| return TI_OK; |
| } |
| |
| |
| |
| |