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/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h
index 31266f9..bbb151b 100644
--- a/CORE/HDD/inc/wlan_hdd_main.h
+++ b/CORE/HDD/inc/wlan_hdd_main.h
@@ -858,6 +858,15 @@
    v_TIME_t    lastFrameTs;
 }hdd_traffic_monitor_t;
 
+#ifdef FEATURE_WLAN_LPHB
+typedef struct
+{
+   v_U8_t enable;
+   v_U8_t item;
+   v_U8_t session;
+} lphbEnableStruct;
+#endif /* FEATURE_WLAN_LPHB */
+
 /** Adapter stucture definition */
 
 struct hdd_context_s
@@ -1012,6 +1021,9 @@
 
     vos_timer_t hdd_p2p_go_conn_is_in_progress;
 
+#ifdef FEATURE_WLAN_LPHB
+    lphbEnableStruct  lphbEnableReq;
+#endif /* FEATURE_WLAN_LPHB */
 };
 
 
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index 3993408..9c05427 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -503,6 +503,33 @@
 
 extern struct net_device_ops net_ops_struct;
 
+#ifdef WLAN_NL80211_TESTMODE
+enum wlan_hdd_tm_attr
+{
+    WLAN_HDD_TM_ATTR_INVALID = 0,
+    WLAN_HDD_TM_ATTR_CMD     = 1,
+    WLAN_HDD_TM_ATTR_DATA    = 2,
+    WLAN_HDD_TM_ATTR_TYPE    = 3,
+    /* keep last */
+    WLAN_HDD_TM_ATTR_AFTER_LAST,
+    WLAN_HDD_TM_ATTR_MAX       = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
+};
+
+enum wlan_hdd_tm_cmd
+{
+    WLAN_HDD_TM_CMD_WLAN_HB    = 1,
+};
+
+#define WLAN_HDD_TM_DATA_MAX_LEN    5000
+
+static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
+{
+    [WLAN_HDD_TM_ATTR_CMD]        = { .type = NLA_U32 },
+    [WLAN_HDD_TM_ATTR_DATA]       = { .type = NLA_BINARY,
+                                    .len = WLAN_HDD_TM_DATA_MAX_LEN },
+};
+#endif /* WLAN_NL80211_TESTMODE */
+
 /*
  * FUNCTION: wlan_hdd_cfg80211_init
  * This function is called by hdd_wlan_startup()
@@ -8061,6 +8088,154 @@
     return 0;
 }
 
+#ifdef WLAN_NL80211_TESTMODE
+#ifdef FEATURE_WLAN_LPHB
+static void wlan_hdd_cfg80211_lphb_wait_timeout_ind_handler
+(
+   void *pAdapter,
+   void *indCont
+)
+{
+   tSirLPHBTimeoutInd   *lphbTimeoutInd;
+   struct sk_buff       *skb;
+
+   VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+             "LPHB wait timeout indication arrived");
+
+   if (NULL == indCont)
+   {
+      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                "LPHB timeout, invalid argument");
+      return;
+   }
+
+   lphbTimeoutInd = (tSirLPHBTimeoutInd *)indCont;
+   skb = cfg80211_testmode_alloc_event_skb(
+                  ((hdd_adapter_t *)pAdapter)->wdev.wiphy,
+                  sizeof(tSirLPHBTimeoutInd),
+                  GFP_ATOMIC);
+   if (!skb)
+   {
+      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+             "LPHB timeout, NL buffer alloc fail");
+      return;
+   }
+
+   NLA_PUT_U32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB);
+   NLA_PUT_U32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbTimeoutInd->protocolType);
+   NLA_PUT(skb, WLAN_HDD_TM_ATTR_DATA,
+           sizeof(tSirLPHBTimeoutInd), lphbTimeoutInd);
+   cfg80211_testmode_event(skb, GFP_ATOMIC);
+   return;
+
+nla_put_failure:
+   VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+             "NLA Put fail");
+   kfree_skb(skb);
+
+   return;
+}
+#endif /* FEATURE_WLAN_LPHB */
+
+static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
+{
+    struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
+    int err = 0;
+#ifdef FEATURE_WLAN_LPHB
+    hdd_context_t *pHddCtx = wiphy_priv(wiphy);
+#endif /* FEATURE_WLAN_LPHB */
+
+    err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
+    if (err)
+    {
+        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                  "%s Testmode INV ATTR", __func__);
+        return err;
+    }
+
+    if (!tb[WLAN_HDD_TM_ATTR_CMD])
+    {
+        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                  "%s Testmode INV CMD", __func__);
+        return -EINVAL;
+    }
+
+    switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
+    {
+#ifdef FEATURE_WLAN_LPHB
+        /* Low Power Heartbeat configuration request */
+        case WLAN_HDD_TM_CMD_WLAN_HB:
+        {
+            int   buf_len;
+            void *buf;
+            tSirLPHBReq *hb_params = NULL;
+
+            if (!tb[WLAN_HDD_TM_ATTR_DATA])
+            {
+                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                          "%s Testmode INV DATA", __func__);
+                return -EINVAL;
+            }
+
+            buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
+            buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
+            hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
+            if (NULL == hb_params)
+            {
+                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                          "%s Request Buffer Alloc Fail", __func__);
+                return -EINVAL;
+            }
+
+            vos_mem_copy(hb_params, buf, buf_len);
+
+            /* LPHB enable and disable request will send to FW
+             * when host suspend and resume
+             * host suspend -> enable LPHB
+             * host resume  -> disable LPHB
+             * if host is not suspend, cache into HDD context
+             * and when host goes to suspend, send request to FW */
+            if ((LPHB_SET_EN_PARAMS_INDID == hb_params->cmd) &&
+               (!pHddCtx->hdd_wlan_suspended))
+            {
+               /* Feature enable command cache into HDD context,
+                * if WLAN is not suspend
+                * When WLAN goes into suspend, send enable command to FW */
+               pHddCtx->lphbEnableReq.enable  =
+                                    hb_params->params.lphbEnableReq.enable;
+               pHddCtx->lphbEnableReq.item    =
+                                    hb_params->params.lphbEnableReq.item;
+               pHddCtx->lphbEnableReq.session =
+                                    hb_params->params.lphbEnableReq.session;
+               vos_mem_free(hb_params);
+            }
+            else
+            {
+               eHalStatus smeStatus;
+
+               /* If WLAN is suspend state, send enable command immediately */
+               smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
+                              hb_params,
+                              wlan_hdd_cfg80211_lphb_wait_timeout_ind_handler);
+               if (eHAL_STATUS_SUCCESS != smeStatus)
+               {
+                  VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                            "LPHB Config Fail, disable");
+                  pHddCtx->lphbEnableReq.enable = 0;
+                  vos_mem_free(hb_params);
+               }
+            }
+            return 0;
+         }
+#endif /* FEATURE_WLAN_LPHB */
+        default:
+            return -EOPNOTSUPP;
+    }
+
+   return err;
+}
+#endif /* CONFIG_NL80211_TESTMODE */
+
 /* cfg80211_ops */
 static struct cfg80211_ops wlan_hdd_cfg80211_ops =
 {
@@ -8125,5 +8300,8 @@
      .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
 #endif /*FEATURE_WLAN_SCAN_PNO */
      .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
+#ifdef WLAN_NL80211_TESTMODE
+     .testmode_cmd = wlan_hdd_cfg80211_testmode,
+#endif
 };
 
diff --git a/CORE/HDD/src/wlan_hdd_early_suspend.c b/CORE/HDD/src/wlan_hdd_early_suspend.c
index 34751b3..20510ce 100644
--- a/CORE/HDD/src/wlan_hdd_early_suspend.c
+++ b/CORE/HDD/src/wlan_hdd_early_suspend.c
@@ -961,6 +961,45 @@
    while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
    {
        pAdapter = pAdapterNode->pAdapter;
+
+#ifdef FEATURE_WLAN_LPHB
+       if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
+           (pHddCtx->lphbEnableReq.enable))
+       {
+           tSirLPHBReq *hb_params = NULL;
+
+           hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
+           if (NULL == hb_params)
+           {
+               VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                         "%s: hb_params alloc failed", __func__);
+           }
+           else
+           {
+               eHalStatus smeStatus;
+
+               hb_params->cmd    = LPHB_SET_EN_PARAMS_INDID;
+               hb_params->params.lphbEnableReq.enable  =
+                                    pHddCtx->lphbEnableReq.enable;
+               hb_params->params.lphbEnableReq.item    =
+                                    pHddCtx->lphbEnableReq.item;
+               hb_params->params.lphbEnableReq.session =
+                                    pHddCtx->lphbEnableReq.session;
+               /* If WLAN is suspend state, send enable command immediately */
+               smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
+                                             hb_params,
+                                             NULL);
+               if (eHAL_STATUS_SUCCESS != smeStatus)
+               {
+                   VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                             "LPHB Config Fail, disable");
+                   pHddCtx->lphbEnableReq.enable = 0;
+                   vos_mem_free(hb_params);
+               }
+           }
+       }
+#endif /* FEATURE_WLAN_LPHB */
+
        if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
          && (WLAN_HDD_SOFTAP != pAdapter->device_mode)
          && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
@@ -1272,6 +1311,44 @@
       }
 
       hdd_conf_resume_ind(pAdapter);
+
+#ifdef FEATURE_WLAN_LPHB
+      if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
+          (pHddCtx->lphbEnableReq.enable))
+      {
+         tSirLPHBReq *hb_params = NULL;
+
+         hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
+         if (NULL == hb_params)
+         {
+            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                      "%s: hb_params alloc failed", __func__);
+         }
+         else
+         {
+            eHalStatus smeStatus;
+
+            hb_params->cmd    = LPHB_SET_EN_PARAMS_INDID;
+            hb_params->params.lphbEnableReq.enable  = 0;
+            hb_params->params.lphbEnableReq.item    =
+                              pHddCtx->lphbEnableReq.item;
+            hb_params->params.lphbEnableReq.session =
+                              pHddCtx->lphbEnableReq.session;
+            /* If WLAN is suspend state, send enable command immediately */
+            smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
+                                          hb_params,
+                                          NULL);
+            if (eHAL_STATUS_SUCCESS != smeStatus)
+            {
+               VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                         "LPHB Config Fail, disable");
+               pHddCtx->lphbEnableReq.enable = 0;
+               vos_mem_free(hb_params);
+            }
+         }
+      }
+#endif /* FEATURE_WLAN_LPHB */
+
       status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
       pAdapterNode = pNext;
    }
diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h
index efbed87..4aa2b39 100644
--- a/CORE/MAC/inc/sirApi.h
+++ b/CORE/MAC/inc/sirApi.h
@@ -4249,4 +4249,85 @@
     tSirUpdateChanParam chanParam[1];
 } tSirUpdateChanList, *tpSirUpdateChanList;
 
+#ifdef FEATURE_WLAN_LPHB
+#define SIR_LPHB_FILTER_LEN   64
+
+typedef enum
+{
+   LPHB_SET_EN_PARAMS_INDID,
+   LPHB_SET_TCP_PARAMS_INDID,
+   LPHB_SET_TCP_PKT_FILTER_INDID,
+   LPHB_SET_UDP_PARAMS_INDID,
+   LPHB_SET_UDP_PKT_FILTER_INDID,
+   LPHB_SET_NETWORK_INFO_INDID,
+} LPHBIndType;
+
+typedef struct sSirLPHBEnableStruct
+{
+   v_U8_t enable;
+   v_U8_t item;
+   v_U8_t session;
+} tSirLPHBEnableStruct;
+
+typedef struct sSirLPHBTcpParamStruct
+{
+   v_U32_t      srv_ip;
+   v_U32_t      dev_ip;
+   v_U16_t      src_port;
+   v_U16_t      dst_port;
+   v_U16_t      timeout;
+   v_U8_t       session;
+   tSirMacAddr  gateway_mac;
+} tSirLPHBTcpParamStruct;
+
+typedef struct sSirLPHBTcpFilterStruct
+{
+   v_U16_t length;
+   v_U8_t  offset;
+   v_U8_t  session;
+   v_U8_t  filter[SIR_LPHB_FILTER_LEN];
+} tSirLPHBTcpFilterStruct;
+
+typedef struct sSirLPHBUdpParamStruct
+{
+   v_U32_t      srv_ip;
+   v_U32_t      dev_ip;
+   v_U16_t      src_port;
+   v_U16_t      dst_port;
+   v_U16_t      interval;
+   v_U16_t      timeout;
+   v_U8_t       session;
+   tSirMacAddr  gateway_mac;
+} tSirLPHBUdpParamStruct;
+
+typedef struct sSirLPHBUdpFilterStruct
+{
+   v_U16_t length;
+   v_U8_t  offset;
+   v_U8_t  session;
+   v_U8_t  filter[SIR_LPHB_FILTER_LEN];
+} tSirLPHBUdpFilterStruct;
+
+typedef struct sSirLPHBReq
+{
+   v_U16_t cmd;
+   v_U16_t dummy;
+   union
+   {
+      tSirLPHBEnableStruct     lphbEnableReq;
+      tSirLPHBTcpParamStruct   lphbTcpParamReq;
+      tSirLPHBTcpFilterStruct  lphbTcpFilterReq;
+      tSirLPHBUdpParamStruct   lphbUdpParamReq;
+      tSirLPHBUdpFilterStruct  lphbUdpFilterReq;
+   } params;
+} tSirLPHBReq;
+
+typedef struct sSirLPHBTimeoutInd
+{
+   v_U8_t sessionIdx;
+   v_U8_t protocolType; /*TCP or UDP*/
+   v_U8_t eventReason;
+} tSirLPHBTimeoutInd;
+#endif /* FEATURE_WLAN_LPHB */
+
 #endif /* __SIR_API_H */
diff --git a/CORE/MAC/inc/wniApi.h b/CORE/MAC/inc/wniApi.h
index 129b8d7..65aa11d 100644
--- a/CORE/MAC/inc/wniApi.h
+++ b/CORE/MAC/inc/wniApi.h
@@ -380,6 +380,9 @@
     eWNI_SME_CANDIDATE_FOUND_IND, /*ROAM candidate indication from FW*/
     eWNI_SME_HANDOFF_REQ,/*upper layer requested handoff to driver in STA mode*/
     eWNI_SME_ROAM_SCAN_OFFLOAD_RSP,/*Fwd the LFR scan offload rsp from FW to SME*/
+#ifdef FEATURE_WLAN_LPHB
+    eWNI_SME_LPHB_WAIT_TIMEOUT_IND,
+#endif /* FEATURE_WLAN_LPHB */
     eWNI_SME_MSG_TYPES_END
 };
 
diff --git a/CORE/MAC/src/include/sirParams.h b/CORE/MAC/src/include/sirParams.h
index 0c35bb1..964c756 100644
--- a/CORE/MAC/src/include/sirParams.h
+++ b/CORE/MAC/src/include/sirParams.h
@@ -586,6 +586,9 @@
 #define SIR_HAL_DHCP_START_IND             (SIR_HAL_ITC_MSG_TYPES_BEGIN + 204)
 #define SIR_HAL_DHCP_STOP_IND              (SIR_HAL_ITC_MSG_TYPES_BEGIN + 205)
 
+#define SIR_HAL_LPHB_CONF_IND              (SIR_HAL_ITC_MSG_TYPES_BEGIN + 206)
+#define SIR_HAL_LPHB_WAIT_EXPIRE_IND       (SIR_HAL_ITC_MSG_TYPES_BEGIN + 207)
+
 #define SIR_HAL_MSG_TYPES_END              (SIR_HAL_ITC_MSG_TYPES_BEGIN + 0xFF)
 // CFG message types
 #define SIR_CFG_MSG_TYPES_BEGIN        (SIR_CFG_MODULE_ID << 8)
diff --git a/CORE/SME/inc/smeInternal.h b/CORE/SME/inc/smeInternal.h
index e646d01..cbd8e96 100644
--- a/CORE/SME/inc/smeInternal.h
+++ b/CORE/SME/inc/smeInternal.h
@@ -157,6 +157,9 @@
     void (*pTxPerHitCallback) (void *pCallbackContext); /* callback for Tx PER hit to HDD */ 
     void *pTxPerHitCbContext;
     tVOS_CON_MODE currDeviceMode;
+#ifdef FEATURE_WLAN_LPHB
+    void (*pLphbWaitTimeoutCb) (void *pAdapter, void *indParam);
+#endif /* FEATURE_WLAN_LPHB */
 } tSmeStruct, *tpSmeStruct;
 
 
diff --git a/CORE/SME/inc/sme_Api.h b/CORE/SME/inc/sme_Api.h
index fc49fae..2bbdcd6 100644
--- a/CORE/SME/inc/sme_Api.h
+++ b/CORE/SME/inc/sme_Api.h
@@ -2918,4 +2918,19 @@
  * return status
 */
 VOS_STATUS sme_isSta_p2p_clientConnected(tHalHandle hHal);
+
+#ifdef FEATURE_WLAN_LPHB
+/* ---------------------------------------------------------------------------
+    \fn sme_LPHBConfigReq
+    \API to make configuration LPHB within FW.
+    \param hHal - The handle returned by macOpen
+    \param lphdReq - LPHB request argument by client
+    \param pCallbackfn - LPHB timeout notification callback function pointer
+    \- return Configuration message posting status, SUCCESS or Fail
+    -------------------------------------------------------------------------*/
+eHalStatus sme_LPHBConfigReq(
+                      tHalHandle hHal,
+                      tSirLPHBReq *lphdReq,
+                      void (*pCallbackfn)(void *pAdapter, void *indParam));
+#endif /* FEATURE_WLAN_LPHB */
 #endif //#if !defined( __SME_API_H )
diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c
index fdc2331..07b6b43 100644
--- a/CORE/SME/src/sme_common/sme_Api.c
+++ b/CORE/SME/src/sme_common/sme_Api.c
@@ -1806,6 +1806,19 @@
                 }
                 break ;
 #endif
+
+#ifdef FEATURE_WLAN_LPHB
+          /* LPHB timeout indication arrived, send IND to client */
+          case eWNI_SME_LPHB_WAIT_TIMEOUT_IND:
+                if (pMac->sme.pLphbWaitTimeoutCb)
+                {
+                   pMac->sme.pLphbWaitTimeoutCb(pMac->pAdapter, pMsg->bodyptr);
+                }
+                vos_mem_free(pMsg->bodyptr);
+
+                break;
+#endif /* FEATURE_WLAN_LPHB */
+
           default:
 
              if ( ( pMsg->type >= eWNI_SME_MSG_TYPES_BEGIN )
@@ -8706,3 +8719,59 @@
     return VOS_STATUS_E_FAILURE;
 }
 
+
+#ifdef FEATURE_WLAN_LPHB
+/* ---------------------------------------------------------------------------
+    \fn sme_LPHBConfigReq
+    \API to make configuration LPHB within FW.
+    \param hHal - The handle returned by macOpen
+    \param lphdReq - LPHB request argument by client
+    \param pCallbackfn - LPHB timeout notification callback function pointer
+    \- return Configuration message posting status, SUCCESS or Fail
+    -------------------------------------------------------------------------*/
+eHalStatus sme_LPHBConfigReq
+(
+   tHalHandle hHal,
+   tSirLPHBReq *lphdReq,
+   void (*pCallbackfn)(void *pAdapter, void *indParam)
+)
+{
+    eHalStatus          status    = eHAL_STATUS_SUCCESS;
+    VOS_STATUS          vosStatus = VOS_STATUS_SUCCESS;
+    tpAniSirGlobal      pMac      = PMAC_STRUCT(hHal);
+    vos_msg_t           vosMessage;
+
+    status = sme_AcquireGlobalLock(&pMac->sme);
+    if (eHAL_STATUS_SUCCESS == status)
+    {
+        if ((LPHB_SET_EN_PARAMS_INDID == lphdReq->cmd) &&
+            (NULL == pCallbackfn) &&
+            (NULL == pMac->sme.pLphbWaitTimeoutCb))
+        {
+           VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+                     "%s: Indication Call back did not registered", __func__);
+           sme_ReleaseGlobalLock(&pMac->sme);
+           return eHAL_STATUS_FAILURE;
+        }
+        else if (NULL != pCallbackfn)
+        {
+           pMac->sme.pLphbWaitTimeoutCb = pCallbackfn;
+        }
+
+        /* serialize the req through MC thread */
+        vosMessage.bodyptr = lphdReq;
+        vosMessage.type    = WDA_LPHB_CONF_REQ;
+        vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage);
+        if (!VOS_IS_STATUS_SUCCESS(vosStatus))
+        {
+           VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+                     "%s: Post Config LPHB MSG fail", __func__);
+           status = eHAL_STATUS_FAILURE;
+        }
+        sme_ReleaseGlobalLock(&pMac->sme);
+    }
+
+    return(status);
+}
+#endif /* FEATURE_WLAN_LPHB */
+
diff --git a/CORE/WDA/inc/wlan_qct_wda.h b/CORE/WDA/inc/wlan_qct_wda.h
index 2cadd0a..5a94f6b 100644
--- a/CORE/WDA/inc/wlan_qct_wda.h
+++ b/CORE/WDA/inc/wlan_qct_wda.h
@@ -1085,6 +1085,11 @@
 #define WDA_UPDATE_CHAN_LIST_RSP    SIR_HAL_UPDATE_CHAN_LIST_RSP
 #define WDA_RX_SCAN_EVENT           SIR_HAL_RX_SCAN_EVENT
 
+#ifdef FEATURE_WLAN_LPHB
+#define WDA_LPHB_CONF_REQ          SIR_HAL_LPHB_CONF_IND
+#define WDA_LPHB_WAIT_EXPIRE_IND   SIR_HAL_LPHB_WAIT_EXPIRE_IND
+#endif /* FEATURE_WLAN_LPHB */
+
 tSirRetStatus wdaPostCtrlMsg(tpAniSirGlobal pMac, tSirMsgQ *pMsg);
 
 eHalStatus WDA_SetRegDomain(void * clientCtxt, v_REGDOMAIN_t regId);
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 */
+
diff --git a/CORE/WDI/CP/inc/wlan_qct_wdi.h b/CORE/WDI/CP/inc/wlan_qct_wdi.h
index 51edf88..0c565e6 100644
--- a/CORE/WDI/CP/inc/wlan_qct_wdi.h
+++ b/CORE/WDI/CP/inc/wlan_qct_wdi.h
@@ -393,6 +393,9 @@
   /* TDLS_Indication */
   WDI_TDLS_IND,
 
+  /* LPHB Timeout Indication from FW to umac */
+  WDI_LPHB_WAIT_TIMEOUT_IND,
+
   WDI_MAX_IND
 }WDI_LowLevelIndEnumType;
 
@@ -601,6 +604,18 @@
     wpt_uint8       bssIdx;  /*bssidx on which beacon is missed*/
 } WDI_MissedBeaconIndType;
 
+#ifdef FEATURE_WLAN_LPHB
+/*---------------------------------------------------------------------------
+ WDI_LPHBTimeoutIndData
+-----------------------------------------------------------------------------*/
+typedef struct
+{
+   wpt_uint8 bssIdx;
+   wpt_uint8 sessionIdx;
+   wpt_uint8 protocolType; /*TCP or UDP*/
+   wpt_uint8 eventReason;
+} WDI_LPHBTimeoutIndData;
+#endif /* FEATURE_WLAN_LPHB */
 
 /*---------------------------------------------------------------------------
   WDI_LowLevelIndType
@@ -651,6 +666,9 @@
     WDI_WakeReasonIndType        wdiWakeReasonInd;
 #endif // WLAN_WAKEUP_EVENTS
     WDI_MissedBeaconIndType      wdiMissedBeaconInd;
+#ifdef FEATURE_WLAN_LPHB
+    WDI_LPHBTimeoutIndData       wdiLPHBTimeoutInd;
+#endif /* FEATURE_WLAN_LPHB */
   }  wdiIndicationData;
 }WDI_LowLevelIndType;
 
@@ -4305,6 +4323,83 @@
   WDI_Status   wdiStatus; 
 }WDI_SuspendResumeRspParamsType;
 
+#ifdef FEATURE_WLAN_LPHB
+/*---------------------------------------------------------------------------
+  WDI Low Power Heart Beat Config request
+  Copy from sirApi.h to avoid compile error
+---------------------------------------------------------------------------*/
+#define WDI_LPHB_FILTER_LEN   64
+
+typedef enum
+{
+   WDI_LPHB_SET_EN_PARAMS_INDID = 0x0001,
+   WDI_LPHB_SET_TCP_PARAMS_INDID,
+   WDI_LPHB_SET_TCP_PKT_FILTER_INDID,
+   WDI_LPHB_SET_UDP_PARAMS_INDID,
+   WDI_LPHB_SET_UDP_PKT_FILTER_INDID,
+   WDI_LPHB_SET_NETWORK_INFO_INDID,
+} WDI_LPHBIndType;
+
+typedef struct
+{
+   wpt_uint8 enable;
+   wpt_uint8 item;
+   wpt_uint8 session;
+} WDI_LPHBEnableStruct;
+
+typedef struct
+{
+   wpt_uint32 srv_ip;
+   wpt_uint32 dev_ip;
+   wpt_uint16 src_port;
+   wpt_uint16 dst_port;
+   wpt_uint16 timeout;
+   wpt_uint8  session;
+   wpt_uint8  gateway_mac[WDI_MAC_ADDR_LEN];
+} WDI_LPHBTcpParamStruct;
+
+typedef struct
+{
+   wpt_uint16 length;
+   wpt_uint8  offset;
+   wpt_uint8  session;
+   wpt_uint8  filter[WDI_LPHB_FILTER_LEN];
+} WDI_LPHBTcpFilterStruct;
+
+typedef struct
+{
+   wpt_uint32 srv_ip;
+   wpt_uint32 dev_ip;
+   wpt_uint16 src_port;
+   wpt_uint16 dst_port;
+   wpt_uint16 interval;
+   wpt_uint16 timeout;
+   wpt_uint8  session;
+   wpt_uint8  gateway_mac[WDI_MAC_ADDR_LEN];
+} WDI_LPHBUdpParamStruct;
+
+typedef struct
+{
+   wpt_uint16 length;
+   wpt_uint8  offset;
+   wpt_uint8  session;
+   wpt_uint8  filter[WDI_LPHB_FILTER_LEN];
+} WDI_LPHBUdpFilterStruct;
+
+typedef struct
+{
+   wpt_uint16 cmd;
+   wpt_uint16 dummy;
+   union
+   {
+      WDI_LPHBEnableStruct     lphbEnableReq;
+      WDI_LPHBTcpParamStruct   lphbTcpParamReq;
+      WDI_LPHBTcpFilterStruct  lphbTcpFilterReq;
+      WDI_LPHBUdpParamStruct   lphbUdpParamReq;
+      WDI_LPHBUdpFilterStruct  lphbUdpFilterReq;
+   } params;
+} WDI_LPHBReq;
+#endif /* FEATURE_WLAN_LPHB */
 
 #ifdef FEATURE_WLAN_SCAN_PNO
 
@@ -4989,6 +5084,16 @@
   void*            pUserData;
 }WDI_SetTmLevelRspType;
 
+#ifdef FEATURE_WLAN_LPHB
+/*---------------------------------------------------------------------------
+  WDI_LPHBConfigParamsType
+---------------------------------------------------------------------------*/
+typedef struct
+{
+  void*             pLphsConfIndData;
+}WDI_LPHBConfigParamsType;
+#endif /* FEATURE_WLAN_LPHB */
+
 /*----------------------------------------------------------------------------
  *   WDI callback types
  *--------------------------------------------------------------------------*/
@@ -6788,6 +6893,10 @@
                                 void*        pUserData);
 #endif
 
+#ifdef FEATURE_WLAN_LPHB
+typedef void  (*WDI_LphbCfgCb)(WDI_Status   wdiStatus,
+                                void*        pUserData);
+#endif /* FEATURE_WLAN_LPHB */
 
 /*========================================================================
  *     Function Declarations and Documentation
@@ -9699,6 +9808,24 @@
 */
 void WDI_SetEnableSSR(wpt_boolean  enableSSR);
 
+#ifdef FEATURE_WLAN_LPHB
+/**
+ @brief WDI_LPHBConfReq
+    This API is called to config FW LPHB rule
+
+ @param lphbconfParam : LPHB rule should config to FW
+        usrData : Client context
+        lphbCfgCb : Configuration status callback
+ @see
+ @return SUCCESS or FAIL
+*/
+WDI_Status WDI_LPHBConfReq
+(
+   void *lphbconfParam,
+   void *usrData,
+   WDI_LphbCfgCb lphbCfgCb
+);
+#endif /* FEATURE_WLAN_LPHB */
 #ifdef __cplusplus
  }
 #endif 
diff --git a/CORE/WDI/CP/inc/wlan_qct_wdi_i.h b/CORE/WDI/CP/inc/wlan_qct_wdi_i.h
index 9965b35..026f01a 100644
--- a/CORE/WDI/CP/inc/wlan_qct_wdi_i.h
+++ b/CORE/WDI/CP/inc/wlan_qct_wdi_i.h
@@ -449,6 +449,8 @@
 
   WDI_TDLS_LINK_ESTABLISH_REQ                   = 84,
 
+  /* WLAN FW LPHB config request */
+  WDI_LPHB_CFG_REQ                              = 85,
 
   WDI_MAX_REQ,
 
@@ -724,6 +726,10 @@
   WDI_ROAM_SCAN_OFFLOAD_RESP                    = 82,
 
   WDI_TDLS_LINK_ESTABLISH_REQ_RESP              = 83,
+
+  /* WLAN FW LPHB Config response */
+  WDI_LPHB_CFG_RESP                             = 84,
+
   /*-------------------------------------------------------------------------
     Indications
      !! Keep these last in the enum if possible
@@ -774,6 +780,8 @@
   /* TDLS Indication from FW to Host */
   WDI_HAL_TDLS_IND                     = WDI_HAL_IND_MIN + 13,
 
+  /* LPHB timeout indication */
+  WDI_HAL_LPHB_WAIT_TIMEOUT_IND        = WDI_HAL_IND_MIN + 14,
   WDI_MAX_RESP
 }WDI_ResponseEnumType; 
 
@@ -2729,6 +2737,24 @@
   WDI_EventInfoType*     pEventData
 );
 
+#ifdef FEATURE_WLAN_LPHB
+/**
+ @brief WDI_ProcessLPHBConfReq -
+    LPHB configuration request to FW
+
+ @param  pWDICtx : wdi context
+         pEventData : indication data
+
+ @see
+ @return esult of the function call
+*/
+WDI_Status WDI_ProcessLPHBConfReq
+(
+  WDI_ControlBlockType*  pWDICtx,
+  WDI_EventInfoType*     pEventData
+);
+#endif /* FEATURE_WLAN_LPHB */
+
 /*=========================================================================
                              Indications
 =========================================================================*/
@@ -4222,6 +4248,26 @@
   WDI_EventInfoType*     pEventData
 );
 
+#ifdef FEATURE_WLAN_LPHB
+/**
+ @brief WDI_ProcessLphbWaitTimeoutInd -
+    This function will be invoked when FW detects low power
+    heart beat failure
+
+ @param  pWDICtx : wdi context
+         pEventData : indication data
+
+ @see
+ @return Result of the function call
+*/
+WDI_Status
+WDI_ProcessLphbWaitTimeoutInd
+(
+  WDI_ControlBlockType*  pWDICtx,
+  WDI_EventInfoType*     pEventData
+);
+#endif /* FEATURE_WLAN_LPHB */
+
 #ifdef WLAN_FEATURE_VOWIFI_11R
 /**
  @brief Process Aggrgated Add TSpec Request function (called when Main FSM
@@ -5282,5 +5328,23 @@
 );
 #endif
 
+#ifdef FEATURE_WLAN_LPHB
+/**
+ @brief WDI_ProcessLphbCfgRsp -
+    LPHB configuration response from FW
+
+ @param  pWDICtx : wdi context
+         pEventData : indication data
+
+ @see
+ @return Result of the function call
+*/
+WDI_Status WDI_ProcessLphbCfgRsp
+(
+  WDI_ControlBlockType*  pWDICtx,
+  WDI_EventInfoType*     pEventData
+);
+#endif /* FEATURE_WLAN_LPHB */
+
 #endif /*WLAN_QCT_WDI_I_H*/
 
diff --git a/CORE/WDI/CP/src/wlan_qct_wdi.c b/CORE/WDI/CP/src/wlan_qct_wdi.c
index 8a14608..e2afdec 100644
--- a/CORE/WDI/CP/src/wlan_qct_wdi.c
+++ b/CORE/WDI/CP/src/wlan_qct_wdi.c
@@ -364,6 +364,11 @@
 #else
  NULL,
 #endif
+#ifdef FEATURE_WLAN_LPHB
+  WDI_ProcessLPHBConfReq,               /* WDI_LPHB_CFG_REQ */
+#else
+  NULL,
+#endif /* FEATURE_WLAN_LPHB */
   /*-------------------------------------------------------------------------
     Indications
   -------------------------------------------------------------------------*/
@@ -554,6 +559,11 @@
 #else
   NULL,
 #endif
+#ifdef FEATURE_WLAN_LPHB
+    WDI_ProcessLphbCfgRsp,             /* WDI_LPHB_CFG_RESP */
+#else
+    NULL,
+#endif /* FEATURE_WLAN_LPHB */
   /*---------------------------------------------------------------------
     Indications
   ---------------------------------------------------------------------*/
@@ -590,6 +600,12 @@
 #else
   NULL,
 #endif
+
+#ifdef FEATURE_WLAN_LPHB
+  WDI_ProcessLphbWaitTimeoutInd,    /* WDI_HAL_LPHB_WAIT_TIMEOUT_IND */
+#else
+  NULL,
+#endif /* FEATURE_WLAN_LPHB */
 };
 
 
@@ -22269,6 +22285,10 @@
     return WLAN_HAL_DHCP_START_IND;
   case WDI_DHCP_STOP_IND:
     return WLAN_HAL_DHCP_STOP_IND;
+#ifdef FEATURE_WLAN_LPHB
+   case WDI_LPHB_CFG_REQ:
+      return WLAN_HAL_LPHB_CFG_REQ;
+#endif /* FEATURE_WLAN_LPHB */
   default:
     return WLAN_HAL_MSG_MAX;
   }
@@ -22504,6 +22524,12 @@
   case WLAN_HAL_GET_ROAM_RSSI_RSP:
     return WDI_GET_ROAM_RSSI_RESP;
 #endif
+#ifdef FEATURE_WLAN_LPHB
+  case WLAN_HAL_LPHB_IND:
+    return WDI_HAL_LPHB_WAIT_TIMEOUT_IND;
+  case WLAN_HAL_LPHB_CFG_RSP:
+    return WDI_LPHB_CFG_RESP;
+#endif /* FEATURE_WLAN_LPHB */
   default:
     return eDRIVER_TYPE_MAX;
   }
@@ -27593,3 +27619,315 @@
 {
    gWDICb.bEnableSSR = enableSSR;
 }
+
+
+#ifdef FEATURE_WLAN_LPHB
+/**
+ @brief WDI_ProcessLphbWaitTimeoutInd -
+    This function will be invoked when FW detects low power
+    heart beat failure
+
+ @param  pWDICtx : wdi context
+         pEventData : indication data
+
+ @see
+ @return Result of the function call
+*/
+WDI_Status
+WDI_ProcessLphbWaitTimeoutInd
+(
+  WDI_ControlBlockType*  pWDICtx,
+  WDI_EventInfoType*     pEventData
+)
+{
+  WDI_LowLevelIndType  wdiInd;
+  tHalLowPowerHeartBeatIndMsg *lphbIndicationParam;
+  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+  /*-------------------------------------------------------------------------
+  Sanity check
+ -------------------------------------------------------------------------*/
+  if ((NULL == pWDICtx) || (NULL == pEventData) ||
+      (NULL == pEventData->pEventData))
+  {
+     WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
+                 "%s: Invalid parameters", __func__);
+     WDI_ASSERT(0);
+     return WDI_STATUS_E_FAILURE;
+  }
+
+  /*-------------------------------------------------------------------------
+  Extract indication and send it to UMAC
+ -------------------------------------------------------------------------*/
+  lphbIndicationParam = (tHalLowPowerHeartBeatIndMsg *)pEventData->pEventData;
+
+  wdiInd.wdiIndicationType = WDI_LPHB_WAIT_TIMEOUT_IND;
+  wdiInd.wdiIndicationData.wdiLPHBTimeoutInd.bssIdx =
+               lphbIndicationParam->lowPowerHeartBeatIndParams.bssIdx;
+  wdiInd.wdiIndicationData.wdiLPHBTimeoutInd.sessionIdx =
+               lphbIndicationParam->lowPowerHeartBeatIndParams.sessionIdx;
+  wdiInd.wdiIndicationData.wdiLPHBTimeoutInd.protocolType =
+               lphbIndicationParam->lowPowerHeartBeatIndParams.protocolType;
+  wdiInd.wdiIndicationData.wdiLPHBTimeoutInd.eventReason =
+               lphbIndicationParam->lowPowerHeartBeatIndParams.eventReason;
+  /*Notify UMAC*/
+  if (pWDICtx->wdiLowLevelIndCB)
+  {
+    pWDICtx->wdiLowLevelIndCB(&wdiInd, pWDICtx->pIndUserData);
+  }
+
+  return WDI_STATUS_SUCCESS;
+}
+
+/**
+ @brief WDI_ProcessLphbCfgRsp -
+    LPHB configuration response from FW
+
+ @param  pWDICtx : wdi context
+         pEventData : indication data
+
+ @see
+ @return Result of the function call
+*/
+WDI_Status WDI_ProcessLphbCfgRsp
+(
+  WDI_ControlBlockType*  pWDICtx,
+  WDI_EventInfoType*     pEventData
+)
+{
+   WDI_Status           wdiStatus;
+   eHalStatus           halStatus;
+   WDI_LphbCfgCb        wdiLphbCfgCb;
+   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+   /*-------------------------------------------------------------------------
+     Sanity check
+   -------------------------------------------------------------------------*/
+   if ((NULL == pWDICtx) || (NULL == pEventData) ||
+       (NULL == pEventData->pEventData))
+   {
+      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
+                  "%s: Invalid parameters", __func__);
+      WDI_ASSERT(0);
+      return WDI_STATUS_E_FAILURE;
+   }
+
+   wdiLphbCfgCb = (WDI_LphbCfgCb)pWDICtx->pfncRspCB;
+
+   /*-------------------------------------------------------------------------
+     Extract response and send it to UMAC
+   -------------------------------------------------------------------------*/
+   halStatus = *((eHalStatus*)pEventData->pEventData);
+   wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus);
+
+   WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
+              "LPHB Cfg Rsp Return status %d", wdiStatus);
+   /*Notify UMAC*/
+   if (NULL != wdiLphbCfgCb)
+   {
+      wdiLphbCfgCb(wdiStatus, pWDICtx->pRspCBUserData);
+   }
+
+   return WDI_STATUS_SUCCESS;
+}
+
+/**
+ @brief WDI_ProcessLPHBConfReq -
+    LPHB configuration request to FW
+
+ @param  pWDICtx : wdi context
+         pEventData : indication data
+
+ @see
+ @return none
+*/
+WDI_Status WDI_ProcessLPHBConfReq
+(
+  WDI_ControlBlockType*  pWDICtx,
+  WDI_EventInfoType*     pEventData
+)
+{
+  WDI_LPHBReq                   *pLphbReqParams;
+  WDI_Status                     wdiStatus;
+  wpt_uint8*                     pSendBuffer        = NULL;
+  wpt_uint16                     usDataOffset       = 0;
+  wpt_uint16                     usSendSize         = 0;
+  tHalLowPowerHeartBeatReq      *halLphbReqRarams;
+  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+  /*-------------------------------------------------------------------------
+     Sanity check
+  -------------------------------------------------------------------------*/
+  if ((NULL == pEventData) || (NULL == pEventData->pEventData))
+  {
+      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
+               "%s: Invalid parameters in Suspend ind",__func__);
+      WDI_ASSERT(0);
+      return WDI_STATUS_E_FAILURE;
+  }
+
+  pLphbReqParams = (WDI_LPHBReq *)pEventData->pEventData;
+
+   /*-----------------------------------------------------------------------
+     Get message buffer
+   -----------------------------------------------------------------------*/
+  if ((WDI_STATUS_SUCCESS != WDI_GetMessageBuffer(pWDICtx,
+                              WDI_LPHB_CFG_REQ,
+                              sizeof(tHalLowPowerHeartBeatReqMsg),
+                              &pSendBuffer, &usDataOffset, &usSendSize))||
+      (usSendSize < (usDataOffset + sizeof(tHalLowPowerHeartBeatReqMsg))))
+  {
+      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_WARN,
+                  "Unable to get send buffer in LPHB Ind ");
+      WDI_ASSERT(0);
+      return WDI_STATUS_E_FAILURE;
+  }
+
+  halLphbReqRarams = (tHalLowPowerHeartBeatReq *)(pSendBuffer + usDataOffset);
+  wpalMemoryZero(halLphbReqRarams, sizeof(tHalLowPowerHeartBeatReq));
+
+  halLphbReqRarams->lowPowerHeartBeatCmdType =
+                     (tANI_U16)(++pLphbReqParams->cmd);
+  switch ((tANI_U16)pLphbReqParams->cmd)
+  {
+    case WDI_LPHB_SET_EN_PARAMS_INDID:
+      halLphbReqRarams->sessionIdx =
+                                pLphbReqParams->params.lphbEnableReq.session;
+      halLphbReqRarams->options.control.heartBeatEnable =
+                                pLphbReqParams->params.lphbEnableReq.enable;
+      halLphbReqRarams->options.control.heartBeatType =
+                                pLphbReqParams->params.lphbEnableReq.item;
+      break;
+
+    case WDI_LPHB_SET_TCP_PARAMS_INDID:
+      halLphbReqRarams->sessionIdx =
+                                pLphbReqParams->params.lphbTcpParamReq.session;
+      halLphbReqRarams->options.tcpParams.timeOutSec =
+                                pLphbReqParams->params.lphbTcpParamReq.timeout;
+      wpalMemoryCopy(&halLphbReqRarams->options.tcpParams.hostIpv4Addr,
+                     &pLphbReqParams->params.lphbTcpParamReq.dev_ip,
+                     sizeof(v_U32_t));
+      wpalMemoryCopy(&halLphbReqRarams->options.tcpParams.destIpv4Addr,
+                     &pLphbReqParams->params.lphbTcpParamReq.srv_ip,
+                     sizeof(v_U32_t));
+
+      wpalMemoryCopy(halLphbReqRarams->options.tcpParams.gatewayMacAddr,
+                     pLphbReqParams->params.lphbTcpParamReq.gateway_mac,
+                     WDI_MAC_ADDR_LEN);
+
+      halLphbReqRarams->options.tcpParams.hostPort =
+                                pLphbReqParams->params.lphbTcpParamReq.src_port;
+      halLphbReqRarams->options.tcpParams.destPort =
+                                pLphbReqParams->params.lphbTcpParamReq.dst_port;
+      break;
+
+    case WDI_LPHB_SET_TCP_PKT_FILTER_INDID:
+      halLphbReqRarams->sessionIdx =
+                               pLphbReqParams->params.lphbTcpFilterReq.session;
+      halLphbReqRarams->options.tcpUdpFilter.offset =
+                               pLphbReqParams->params.lphbTcpFilterReq.offset;
+      halLphbReqRarams->options.tcpUdpFilter.filterLength =
+                               pLphbReqParams->params.lphbTcpFilterReq.length;
+      wpalMemoryCopy(halLphbReqRarams->options.tcpUdpFilter.filter,
+                     pLphbReqParams->params.lphbTcpFilterReq.filter,
+                     WDI_LPHB_FILTER_LEN);
+      break;
+
+    case WDI_LPHB_SET_UDP_PARAMS_INDID:
+      halLphbReqRarams->sessionIdx =
+                                pLphbReqParams->params.lphbUdpParamReq.session;
+      halLphbReqRarams->options.udpParams.timeOutSec =
+                                pLphbReqParams->params.lphbUdpParamReq.timeout;
+      halLphbReqRarams->options.udpParams.timePeriodSec =
+                                pLphbReqParams->params.lphbUdpParamReq.interval;
+      wpalMemoryCopy(&halLphbReqRarams->options.udpParams.hostIpv4Addr,
+                     &pLphbReqParams->params.lphbUdpParamReq.dev_ip,
+                     sizeof(v_U32_t));
+      wpalMemoryCopy(&halLphbReqRarams->options.udpParams.destIpv4Addr,
+                     &pLphbReqParams->params.lphbUdpParamReq.srv_ip,
+                     sizeof(v_U32_t));
+
+      wpalMemoryCopy(halLphbReqRarams->options.udpParams.gatewayMacAddr,
+                     pLphbReqParams->params.lphbUdpParamReq.gateway_mac,
+                     WDI_MAC_ADDR_LEN);
+
+      halLphbReqRarams->options.udpParams.hostPort =
+                                pLphbReqParams->params.lphbUdpParamReq.src_port;
+      halLphbReqRarams->options.udpParams.destPort =
+                                pLphbReqParams->params.lphbUdpParamReq.dst_port;
+      break;
+
+    case WDI_LPHB_SET_UDP_PKT_FILTER_INDID:
+      halLphbReqRarams->sessionIdx =
+                                pLphbReqParams->params.lphbUdpFilterReq.session;
+      halLphbReqRarams->options.tcpUdpFilter.offset =
+                                pLphbReqParams->params.lphbUdpFilterReq.offset;
+      halLphbReqRarams->options.tcpUdpFilter.filterLength =
+                                pLphbReqParams->params.lphbUdpFilterReq.length;
+      wpalMemoryCopy(halLphbReqRarams->options.tcpUdpFilter.filter,
+                     pLphbReqParams->params.lphbUdpFilterReq.filter,
+                     WDI_LPHB_FILTER_LEN);
+      break;
+
+    case WDI_LPHB_SET_NETWORK_INFO_INDID:
+      /* NA */
+      break;
+
+    default:
+      break;
+  }
+
+  /*-------------------------------------------------------------------------
+    Send Suspend Request to HAL
+  -------------------------------------------------------------------------*/
+  pWDICtx->pfncRspCB          = pEventData->pCBfnc;
+  pWDICtx->pReqStatusUserData = pEventData->pUserData;
+
+  wdiStatus = WDI_SendMsg(pWDICtx, pSendBuffer,
+                          usSendSize, pWDICtx->pfncRspCB,
+                          pWDICtx->pReqStatusUserData,
+                          WDI_LPHB_CFG_RESP);
+
+  return wdiStatus;
+}
+
+/**
+ @brief WDI_LPHBConfReq -
+    LPHB configuration request API
+
+ @param  lphbconfParam : configuration parameter
+         usrData : client context
+         lphbCfgCb : callback function pointer
+
+ @see
+ @return Success or fail status code
+*/
+WDI_Status WDI_LPHBConfReq(void *lphbconfParam,
+                           void *usrData, WDI_LphbCfgCb lphbCfgCb)
+{
+  WDI_EventInfoType      wdiEventData;
+
+  /*------------------------------------------------------------------------
+    Sanity Check
+  ------------------------------------------------------------------------*/
+  if (eWLAN_PAL_FALSE == gWDIInitialized)
+  {
+    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
+              "WDI API call before module is initialized - Fail request");
+
+    return WDI_STATUS_E_NOT_ALLOWED;
+  }
+
+  /*------------------------------------------------------------------------
+    Fill in Event data and post to the Main FSM
+  ------------------------------------------------------------------------*/
+  wdiEventData.wdiRequest      = WDI_LPHB_CFG_REQ;
+  wdiEventData.pEventData      = lphbconfParam;
+  wdiEventData.uEventDataSize  = sizeof(WDI_LPHBReq);
+  wdiEventData.pCBfnc          = lphbCfgCb;
+  wdiEventData.pUserData       = usrData;
+
+  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
+}
+#endif /* FEATURE_WLAN_LPHB */
+