Commit 12309b6b authored by Kiran Kumar Lokere's avatar Kiran Kumar Lokere Committed by Madan Mohan Koyyalamudi
Browse files

qcacld: Add support to self recover when SME command stuck.

Add support for self recovery when SME command stuck happens.
Add knob to control the self recovery support and dump the
recovery stats with ioctl command.

Change-Id: I2f60d7ede88df939b9cb48d52f0d7e8c0bf79fcf
CRs-Fixed: 700189
parent 654dd3e2
......@@ -3164,6 +3164,10 @@ This feature requires the dependent cfg.ini "gRoamPrefer5GHz" set to 1 */
#define CFG_WOW_PULSE_INTERVAL_HIGH_DEFAULT (20)
#endif
#define CFG_ENABLE_SELF_RECOVERY "gEnableSelfRecovery"
#define CFG_ENABLE_SELF_RECOVERY_MIN ( 0 )
#define CFG_ENABLE_SELF_RECOVERY_MAX ( 1 )
#define CFG_ENABLE_SELF_RECOVERY_DEFAULT ( 1 )
/*---------------------------------------------------------------------------
Type declarations
......@@ -3845,6 +3849,7 @@ typedef struct
uint16_t wow_pulse_interval_high;
uint16_t wow_pulse_interval_low;
#endif
v_BOOL_t enableSelfRecovery;
} hdd_config_t;
#ifdef WLAN_FEATURE_MBSSID
......
......@@ -4216,6 +4216,12 @@ REG_TABLE_ENTRY g_registry_table[] =
CFG_WOW_PULSE_INTERVAL_HIGH_MIN,
CFG_WOW_PULSE_INTERVAL_HIGH_MAX),
#endif
REG_VARIABLE( CFG_ENABLE_SELF_RECOVERY, WLAN_PARAM_Integer,
hdd_config_t, enableSelfRecovery,
VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
CFG_ENABLE_SELF_RECOVERY_DEFAULT,
CFG_ENABLE_SELF_RECOVERY_MIN,
CFG_ENABLE_SELF_RECOVERY_MAX ),
};
#ifdef WLAN_FEATURE_MBSSID
......@@ -4862,6 +4868,10 @@ static void print_hdd_cfg(hdd_context_t *pHddCtx)
hddLog(LOG2, "Name = [gP2PListenDeferInterval] Value = [%u]",
pHddCtx->cfg_ini->p2p_listen_defer_interval);
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
"Name = [gEnableSelfRecovery] Value = [%u]",
pHddCtx->cfg_ini->enableSelfRecovery);
}
#define CFG_VALUE_MAX_LEN 256
......@@ -6699,6 +6709,7 @@ VOS_STATUS hdd_set_sme_config( hdd_context_t *pHddCtx )
smeConfig->enable5gEBT = pHddCtx->cfg_ini->enable5gEBT;
smeConfig->enableSelfRecovery = pHddCtx->cfg_ini->enableSelfRecovery;
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
smeConfig->csrConfig.isRoamOffloadEnabled =
pHddCtx->cfg_ini->isRoamOffloadEnabled;
......
......@@ -374,6 +374,7 @@ static const hdd_freq_chan_map_t freq_chan_map[] = { {2412, 1}, {2417, 2},
#define WE_DUMP_PCIE_LOG 16
#endif
#endif
#define WE_GET_RECOVERY_STAT 17
/* Private ioctls and their sub-ioctls */
#define WLAN_PRIV_SET_VAR_INT_GET_NONE (SIOCIWFIRSTPRIV + 7)
......@@ -7373,6 +7374,14 @@ static int iw_setnone_getnone(struct net_device *dev, struct iw_request_info *in
memset(&pAdapter->hdd_stats, 0, sizeof(pAdapter->hdd_stats));
break;
}
case WE_GET_RECOVERY_STAT:
{
tHalHandle hal = WLAN_HDD_GET_HAL_CTX(pAdapter);
sme_getRecoveryStats(hal);
break;
}
#ifdef WLAN_BTAMP_FEATURE
case WE_ENABLE_AMP:
{
......@@ -10672,6 +10681,12 @@ static const struct iw_priv_args we_private_args[] = {
0,
0,
"clearStats" },
{ WE_GET_RECOVERY_STAT,
0,
0,
"getRecoverStat" },
#ifdef WLAN_BTAMP_FEATURE
{ WE_ENABLE_AMP,
0,
......
......@@ -124,6 +124,20 @@ typedef struct sStatsExtEvent {
tANI_U8 event_data[];
} tStatsExtEvent, *tpStatsExtEvent;
#define MAX_ACTIVE_CMD_STATS 16
typedef struct sActiveCmdStats {
eSmeCommandType command;
tANI_U32 reason;
tANI_U32 sessionId;
v_U64_t timestamp;
} tActiveCmdStats;
typedef struct sSelfRecoveryStats {
tActiveCmdStats activeCmdStats[MAX_ACTIVE_CMD_STATS];
tANI_U8 cmdStatsIndx;
} tSelfRecoveryStats;
typedef struct tagSmeStruct
{
eSmeState state;
......@@ -170,6 +184,8 @@ typedef struct tagSmeStruct
#endif
int (*get_tsf_cb)(void *pcb_cxt, struct stsf *ptsf);
void *get_tsf_cxt;
v_BOOL_t enableSelfRecovery;
} tSmeStruct, *tpSmeStruct;
......
......@@ -134,6 +134,7 @@ typedef struct _smeConfigParams
tANI_U8 fEnableDebugLog;
tANI_U8 max_intf_count;
tANI_BOOLEAN enable5gEBT;
tANI_BOOLEAN enableSelfRecovery;
} tSmeConfigParams, *tpSmeConfigParams;
typedef enum
......@@ -1856,6 +1857,15 @@ VOS_STATUS sme_BtcGetConfig (tHalHandle hHal, tpSmeBtcConfig pSmeBtcConfig);
---------------------------------------------------------------------------*/
void sme_SetCfgPrivacy(tHalHandle hHal, tCsrRoamProfile *pProfile, tANI_BOOLEAN fPrivacy);
/* ---------------------------------------------------------------------------
\fn sme_getRecoveryStats
\brief API to get recovery stats for SME stuck cmds.
\param hHal - The handle returned by macOpen.
\return void
---------------------------------------------------------------------------*/
void sme_getRecoveryStats(tHalHandle hHal);
#if defined WLAN_FEATURE_VOWIFI
/* ---------------------------------------------------------------------------
\fn sme_NeighborReportRequest
......
......@@ -74,7 +74,6 @@
#include "nan_Api.h"
#endif
 
extern tSirRetStatus uMacPostCtrlMsg(void* pSirGlobal, tSirMbMsg* pMb);
 
#include <wlan_qct_pal_api.h>
......@@ -82,6 +81,7 @@ extern tSirRetStatus uMacPostCtrlMsg(void* pSirGlobal, tSirMbMsg* pMb);
#define READ_MEMORY_DUMP_CMD 9
#define TL_INIT_STATE 0
 
static tSelfRecoveryStats gSelfRecoveryStats;
 
 
// TxMB Functions
......@@ -1665,6 +1665,7 @@ eHalStatus sme_UpdateConfig(tHalHandle hHal, tpSmeConfigParams pSmeConfigParams)
pMac->sme.max_intf_count = pSmeConfigParams->max_intf_count;
 
pMac->enable5gEBT = pSmeConfigParams->enable5gEBT;
pMac->sme.enableSelfRecovery = pSmeConfigParams->enableSelfRecovery;
 
return status;
}
......@@ -4246,6 +4247,7 @@ eHalStatus sme_GetConfigParam(tHalHandle hHal, tSmeConfigParams *pParam)
pParam->fScanOffload = pMac->fScanOffload;
pParam->fP2pListenOffload = pMac->fP2pListenOffload;
pParam->max_intf_count = pMac->sme.max_intf_count;
pParam->enableSelfRecovery = pMac->sme.enableSelfRecovery;
sme_ReleaseGlobalLock( &pMac->sme );
}
 
......@@ -12191,6 +12193,66 @@ eHalStatus sme_StopBatchScanInd
 
#endif
 
void sme_getRecoveryStats(tHalHandle hHal) {
tANI_U8 i;
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "Self Recovery Stats");
for (i = 0; i < MAX_ACTIVE_CMD_STATS; i++) {
if (eSmeNoCommand != gSelfRecoveryStats.activeCmdStats[i].command) {
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
"timestamp %llu: command 0x%0X: reason %d: session %d",
gSelfRecoveryStats.activeCmdStats[i].timestamp,
gSelfRecoveryStats.activeCmdStats[i].command,
gSelfRecoveryStats.activeCmdStats[i].reason,
gSelfRecoveryStats.activeCmdStats[i].sessionId);
}
}
}
void sme_SaveActiveCmdStats(tHalHandle hHal) {
tSmeCmd *pTempCmd = NULL;
tListElem *pEntry;
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
tANI_U8 statsIndx = 0;
if (NULL == pMac) {
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
"%s: pMac is NULL", __func__);
return;
}
pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK);
if (pEntry) {
pTempCmd = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
}
if (pTempCmd) {
if (eSmeCsrCommandMask & pTempCmd->command) {
statsIndx = gSelfRecoveryStats.cmdStatsIndx;
gSelfRecoveryStats.activeCmdStats[statsIndx].command =
pTempCmd->command;
gSelfRecoveryStats.activeCmdStats[statsIndx].sessionId =
pTempCmd->sessionId;
gSelfRecoveryStats.activeCmdStats[statsIndx].timestamp =
vos_get_monotonic_boottime();
if (eSmeCommandRoam == pTempCmd->command) {
gSelfRecoveryStats.activeCmdStats[statsIndx].reason =
pTempCmd->u.roamCmd.roamReason;
} else if (eSmeCommandScan == pTempCmd->command) {
gSelfRecoveryStats.activeCmdStats[statsIndx].reason =
pTempCmd->u.scanCmd.reason;
} else {
gSelfRecoveryStats.activeCmdStats[statsIndx].reason = 0xFF;
}
gSelfRecoveryStats.cmdStatsIndx =
((gSelfRecoveryStats.cmdStatsIndx + 1) &
(MAX_ACTIVE_CMD_STATS - 1));
}
}
return;
}
void activeListCmdTimeoutHandle(void *userData)
{
if (NULL == userData)
......@@ -12199,7 +12261,13 @@ void activeListCmdTimeoutHandle(void *userData)
"%s: Active List command timeout Cmd List Count %d", __func__,
csrLLCount(&((tpAniSirGlobal) userData)->sme.smeCmdActiveList) );
smeGetCommandQStatus((tHalHandle) userData);
VOS_BUG(0);
if (((tpAniSirGlobal)userData)->sme.enableSelfRecovery) {
sme_SaveActiveCmdStats((tHalHandle)userData);
vos_trigger_recovery();
} else {
VOS_BUG(0);
}
}
 
VOS_STATUS sme_notify_modem_power_state(tHalHandle hHal, tANI_U32 value)
......
......@@ -334,6 +334,8 @@ v_BOOL_t vos_is_packet_log_enabled(void);
v_U64_t vos_get_monotonic_boottime(void);
void vos_trigger_recovery(void);
#ifdef FEATURE_WLAN_D0WOW
v_VOID_t vos_pm_control(v_BOOL_t vote);
#endif
......
......@@ -2643,6 +2643,23 @@ v_BOOL_t vos_is_packet_log_enabled(void)
return pHddCtx->cfg_ini->enablePacketLog;
}
#if defined(CONFIG_CNSS)
/* worker thread to recover when target does not respond over PCIe */
void self_recovery_work_handler(struct work_struct *recovery)
{
cnss_device_self_recovery();
}
static DECLARE_WORK(self_recovery_work, self_recovery_work_handler);
#endif
void vos_trigger_recovery(void)
{
#ifdef CONFIG_CNSS
schedule_work(&self_recovery_work);
#endif
}
v_U64_t vos_get_monotonic_boottime(void)
{
#ifdef CONFIG_CNSS
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment