--- /dev/null
+/*
+ * healthMonitor.c
+ *
+ * Copyright(c) 1998 - 2009 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;
+}
+
+
+
+