wlan: Low Power Heartbeat feature

New customer requirement, Low power heartbeat
FW will handle TCP/UDP level heartbeat failure detection.
Host will send configuration request to FW with parameters.
Host will use TESTMODE as a command path.

Change-Id: I7a0ad93e409fa432c68b9d73aff64b6c3fc13782
CRs-fixed: 518667
diff --git a/CORE/WDA/src/wlan_qct_wda.c b/CORE/WDA/src/wlan_qct_wda.c
index c6b4992..81c14e6 100644
--- a/CORE/WDA/src/wlan_qct_wda.c
+++ b/CORE/WDA/src/wlan_qct_wda.c
@@ -225,6 +225,11 @@
 VOS_STATUS WDA_ProcessUpdateOpMode(tWDA_CbContext *pWDA, 
                                    tUpdateVHTOpMode *pData);
 #endif
+
+#ifdef FEATURE_WLAN_LPHB
+VOS_STATUS WDA_ProcessLPHBConfReq(tWDA_CbContext *pWDA,
+                                  tSirLPHBReq *pData);
+#endif /* FEATURE_WLAN_LPHB */
 /*
  * FUNCTION: WDA_open
  * Allocate the WDA context 
@@ -11307,6 +11312,13 @@
           WDA_ProcessDHCPStopInd(pWDA, (tAniDHCPInd *)pMsg->bodyptr);
           break;
       }
+#ifdef FEATURE_WLAN_LPHB
+      case WDA_LPHB_CONF_REQ:
+      {
+         WDA_ProcessLPHBConfReq(pWDA, (tSirLPHBReq *)pMsg->bodyptr);
+         break;
+      }
+#endif
       default:
       {
          VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
@@ -11765,6 +11777,47 @@
          break;
       }
   
+#ifdef FEATURE_WLAN_LPHB
+      case WDI_LPHB_WAIT_TIMEOUT_IND:
+      {
+         vos_msg_t            vosMsg;
+         tSirLPHBTimeoutInd  *lphbTimeoutInd;
+
+         lphbTimeoutInd =
+           (tSirLPHBTimeoutInd *)vos_mem_malloc(sizeof(tSirLPHBTimeoutInd));
+         if (NULL == lphbTimeoutInd)
+         {
+            VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+                           "%s: LPHB IND buffer alloc Fail", __func__);
+            return ;
+         }
+
+         lphbTimeoutInd->sessionIdx =
+              wdiLowLevelInd->wdiIndicationData.wdiLPHBTimeoutInd.sessionIdx;
+         lphbTimeoutInd->protocolType =
+              wdiLowLevelInd->wdiIndicationData.wdiLPHBTimeoutInd.protocolType;
+         lphbTimeoutInd->eventReason =
+              wdiLowLevelInd->wdiIndicationData.wdiLPHBTimeoutInd.eventReason;
+
+         VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+                   "Get WDI_LPHB_WAIT_TIMEOUT_IND bssIdx %d",
+                   wdiLowLevelInd->wdiIndicationData.wdiLPHBTimeoutInd.bssIdx);
+
+         vosMsg.type    = eWNI_SME_LPHB_WAIT_TIMEOUT_IND;
+         vosMsg.bodyptr = lphbTimeoutInd;
+         vosMsg.bodyval = 0;
+         /* Send message to SME */
+         if (VOS_STATUS_SUCCESS !=
+             vos_mq_post_message(VOS_MQ_ID_SME, (vos_msg_t*)&vosMsg))
+         {
+            VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_WARN,
+                      "post WDI_LPHB_WAIT_TIMEOUT_IND to SME Failed");
+            vos_mem_free(lphbTimeoutInd);
+         }
+         break;
+      }
+#endif /* FEATURE_WLAN_LPHB */
+
       default:
       {
          /* TODO error */
@@ -14077,3 +14130,83 @@
 {
    WDI_SetEnableSSR(enableSSR);
 }
+
+#ifdef FEATURE_WLAN_LPHB
+/*
+ * FUNCTION: WDA_LPHBconfRspCallback
+ *
+ */
+void WDA_LPHBconfRspCallback(WDI_Status status, void* pUserData)
+{
+   tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData;
+
+   VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+              "<------ %s " ,__func__);
+   if (NULL == pWdaParams)
+   {
+      VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+              "%s: pWdaParams received NULL", __func__);
+      VOS_ASSERT(0) ;
+      return ;
+   }
+
+   /* Do not need to send notification to upper layer
+    * Just free allocated resources */
+   if (pWdaParams != NULL)
+   {
+      if (pWdaParams->wdaWdiApiMsgParam != NULL)
+      {
+         vos_mem_free(pWdaParams->wdaWdiApiMsgParam);
+      }
+      vos_mem_free(pWdaParams->wdaMsgParam) ;
+      vos_mem_free(pWdaParams) ;
+   }
+
+   return;
+}
+
+/*
+ * FUNCTION: WDA_ProcessLPHBConfReq
+ *
+ */
+VOS_STATUS WDA_ProcessLPHBConfReq(tWDA_CbContext *pWDA,
+                                  tSirLPHBReq *pData)
+{
+   WDI_Status wdiStatus;
+   tWDA_ReqParams *pWdaParams ;
+
+   VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+             "------> %s " , __func__);
+
+   pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ;
+   if (NULL == pWdaParams)
+   {
+      VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+                "%s: VOS MEM Alloc Failure", __func__);
+      VOS_ASSERT(0);
+      vos_mem_free(pData);
+      return VOS_STATUS_E_NOMEM;
+   }
+
+   pWdaParams->pWdaContext = pWDA;
+   pWdaParams->wdaMsgParam = (void *)pData;
+   pWdaParams->wdaWdiApiMsgParam = NULL;
+
+   wdiStatus = WDI_LPHBConfReq(pData, pWdaParams, WDA_LPHBconfRspCallback);
+   if (WDI_STATUS_PENDING == wdiStatus)
+   {
+      VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+              "Pending received for %s:%d ", __func__, __LINE__);
+   }
+   else if (WDI_STATUS_SUCCESS != wdiStatus)
+   {
+      VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+              "Failure in %s:%d s %d", __func__, __LINE__, wdiStatus);
+      vos_mem_free(pWdaParams->wdaMsgParam);
+      vos_mem_free(pWdaParams);
+   }
+
+   return CONVERT_WDI2VOS_STATUS(wdiStatus);
+}
+#endif /* FEATURE_WLAN_LPHB */
+