wlan: Add support for host based wake lock events

This change adds new DIAG (EVENT_WLAN_WAKE_LOCK)
event within our existing DIAG framework. This
event will be generated whenever wake locks are
handled within the driver.

Change-Id: I7a602da9e0e8e77d0f14487ee09057e70e9048b4
CRs-Fixed: 832837
diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h
index b6a8777..fa1c59b 100644
--- a/CORE/HDD/inc/wlan_hdd_main.h
+++ b/CORE/HDD/inc/wlan_hdd_main.h
@@ -1323,10 +1323,8 @@
    /* Thermal mitigation information */
    hdd_thermal_mitigation_info_t tmInfo;
 
-#ifdef WLAN_OPEN_SOURCE
 #ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
-   struct wake_lock rx_wake_lock;
-#endif
+    vos_wake_lock_t rx_wake_lock;
 #endif
 
    /* 
@@ -1345,11 +1343,7 @@
    /*is_dyanmic_channel_range_set is set to 1 when Softap_set_channel_range
         is invoked*/
    v_BOOL_t is_dynamic_channel_range_set;
-
-#ifdef WLAN_OPEN_SOURCE
-   struct wake_lock sap_wake_lock;
-#endif
-
+   vos_wake_lock_t sap_wake_lock;
 #ifdef FEATURE_WLAN_TDLS
     eTDLSSupportMode tdls_mode;
     eTDLSSupportMode tdls_mode_last;
@@ -1548,9 +1542,9 @@
 void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx,
                                   tVOS_CON_MODE mode);
 void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter);
-void hdd_prevent_suspend(void);
-void hdd_allow_suspend(void);
-void hdd_prevent_suspend_timeout(v_U32_t timeout);
+void hdd_prevent_suspend(uint32_t reason);
+void hdd_allow_suspend(uint32_t reason);
+void hdd_prevent_suspend_timeout(v_U32_t timeout, uint32_t reason);
 bool hdd_is_ssr_required(void);
 void hdd_set_ssr_required(e_hdd_ssr_required value);
 
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index de15ff5..f068292 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -10372,13 +10372,13 @@
 
 allow_suspend:
     /* release the wake lock at the end of the scan*/
-    hdd_allow_suspend();
+    hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
 
     /* Acquire wakelock to handle the case where APP's tries to suspend
      * immediatly after the driver gets connect request(i.e after scan)
      * from supplicant, this result in app's is suspending and not able
      * to process the connect request to AP */
-    hdd_prevent_suspend_timeout(1000);
+    hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
 
 #ifdef FEATURE_WLAN_TDLS
     wlan_hdd_tdls_scan_done_callback(pAdapter);
@@ -10902,7 +10902,7 @@
      * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
      * be stuck in full power because of resume BMPS
      */
-    hdd_prevent_suspend();
+    hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
 
     hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
            "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
@@ -10923,7 +10923,7 @@
 
         if(status != VOS_STATUS_SUCCESS)
         {
-            hdd_allow_suspend();
+            hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
             status = -EFAULT;
 #ifdef FEATURE_WLAN_TDLS
         wlan_hdd_tdls_scan_done_callback(pAdapter);
@@ -10949,7 +10949,7 @@
         } else {
                 status = -EIO;
         }
-        hdd_allow_suspend();
+        hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
 
 #ifdef FEATURE_WLAN_TDLS
         wlan_hdd_tdls_scan_done_callback(pAdapter);
@@ -16282,7 +16282,8 @@
                  * results in app's is in suspended state and not able to
                  * process the connect request to AP
                  */
-                hdd_prevent_suspend_timeout(2000);
+                hdd_prevent_suspend_timeout(2000,
+                                    WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
                 cfg80211_sched_scan_results(pHddCtx->wiphy);
             }
 
diff --git a/CORE/HDD/src/wlan_hdd_early_suspend.c b/CORE/HDD/src/wlan_hdd_early_suspend.c
index d488f35..524d193 100644
--- a/CORE/HDD/src/wlan_hdd_early_suspend.c
+++ b/CORE/HDD/src/wlan_hdd_early_suspend.c
@@ -1820,7 +1820,7 @@
    hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Preventing the phone from going to suspend",__func__);
 
    // Prevent the phone from going to sleep
-   hdd_prevent_suspend();
+   hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT);
 
    return VOS_STATUS_SUCCESS;
 }
@@ -2081,7 +2081,7 @@
 
    struct device *dev = NULL;
    hdd_ssr_timer_del();
-   hdd_prevent_suspend();
+   hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT);
 
 #ifdef HAVE_WCNSS_CAL_DOWNLOAD
    /* wait until WCNSS driver downloads NV */
@@ -2249,7 +2249,7 @@
       goto err_bap_stop;
    }
    /* Allow the phone to go to sleep */
-   hdd_allow_suspend();
+   hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT);
    /* register for riva power on lock */
    if (req_riva_power_on_lock("wlan"))
    {
@@ -2323,7 +2323,7 @@
 
 err_re_init:
    /* Allow the phone to go to sleep */
-   hdd_allow_suspend();
+   hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT);
    vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE);
    VOS_BUG(0);
    return -EPERM;
diff --git a/CORE/HDD/src/wlan_hdd_hostapd.c b/CORE/HDD/src/wlan_hdd_hostapd.c
index 2aafc0c..7e2319f 100644
--- a/CORE/HDD/src/wlan_hdd_hostapd.c
+++ b/CORE/HDD/src/wlan_hdd_hostapd.c
@@ -1031,9 +1031,13 @@
 #ifdef WLAN_OPEN_SOURCE
             if (wake_lock_active(&pHddCtx->sap_wake_lock))
             {
-               wake_unlock(&pHddCtx->sap_wake_lock);
+               vos_wake_lock_release(&pHddCtx->sap_wake_lock,
+                                      WIFI_POWER_EVENT_WAKELOCK_SAP);
             }
-            wake_lock_timeout(&pHddCtx->sap_wake_lock, msecs_to_jiffies(HDD_SAP_WAKE_LOCK_DURATION));
+            vos_wake_lock_timeout_release(&pHddCtx->sap_wake_lock,
+                                          HDD_SAP_WAKE_LOCK_DURATION,
+                                          WIFI_POWER_EVENT_WAKELOCK_SAP);
+
 #endif
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
             {
diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c
index 7bd1b19..9467205 100755
--- a/CORE/HDD/src/wlan_hdd_main.c
+++ b/CORE/HDD/src/wlan_hdd_main.c
@@ -194,9 +194,8 @@
 //wait time for beacon miss rate.
 #define BCN_MISS_RATE_TIME 500
 
-#ifdef WLAN_OPEN_SOURCE
-static struct wake_lock wlan_wake_lock;
-#endif
+static vos_wake_lock_t wlan_wake_lock;
+
 /* set when SSR is needed after unload */
 static e_hdd_ssr_required isSsrRequired = HDD_SSR_NOT_REQUIRED;
 
@@ -8556,14 +8555,12 @@
          "%s: Failed to close VOSS Scheduler",__func__);
       VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
    }
-#ifdef WLAN_OPEN_SOURCE
 #ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
    /* Destroy the wake lock */
-   wake_lock_destroy(&pHddCtx->rx_wake_lock);
+   vos_wake_lock_destroy(&pHddCtx->rx_wake_lock);
 #endif
    /* Destroy the wake lock */
-   wake_lock_destroy(&pHddCtx->sap_wake_lock);
-#endif
+   vos_wake_lock_destroy(&pHddCtx->sap_wake_lock);
 
 #ifdef CONFIG_ENABLE_LINUX_REG
    vosStatus = vos_nv_close();
@@ -8748,31 +8745,26 @@
 }
 
 /* wake lock APIs for HDD */
-void hdd_prevent_suspend(void)
+void hdd_prevent_suspend(uint32_t reason)
 {
-#ifdef WLAN_OPEN_SOURCE
-    wake_lock(&wlan_wake_lock);
-#else
-    wcnss_prevent_suspend();
-#endif
+
+    vos_wake_lock_acquire(&wlan_wake_lock, reason);
+
 }
 
-void hdd_allow_suspend(void)
+void hdd_allow_suspend(uint32_t reason)
 {
-#ifdef WLAN_OPEN_SOURCE
-    wake_unlock(&wlan_wake_lock);
-#else
-    wcnss_allow_suspend();
-#endif
+
+    vos_wake_lock_release(&wlan_wake_lock, reason);
+
 }
 
-void hdd_prevent_suspend_timeout(v_U32_t timeout)
+void hdd_prevent_suspend_timeout(v_U32_t timeout, uint32_t reason)
 {
-#ifdef WLAN_OPEN_SOURCE
-    wake_lock_timeout(&wlan_wake_lock, msecs_to_jiffies(timeout));
-#else
-    /* Do nothing as there is no API in wcnss for timeout*/
-#endif
+
+    vos_wake_lock_timeout_release(&wlan_wake_lock, timeout,
+                                      reason);
+
 }
 
 /**---------------------------------------------------------------------------
@@ -9309,7 +9301,7 @@
    vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
 
    pHddCtx->wiphy = wiphy;
-   hdd_prevent_suspend();
+   hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
    pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
 
    vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
@@ -10027,26 +10019,23 @@
    mutex_init(&pHddCtx->sap_lock);
    mutex_init(&pHddCtx->roc_lock);
 
-
-#ifdef WLAN_OPEN_SOURCE
 #ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
    /* Initialize the wake lcok */
-   wake_lock_init(&pHddCtx->rx_wake_lock,
-           WAKE_LOCK_SUSPEND,
+   vos_wake_lock_init(&pHddCtx->rx_wake_lock,
            "qcom_rx_wakelock");
+
 #endif
    /* Initialize the wake lcok */
-   wake_lock_init(&pHddCtx->sap_wake_lock,
-           WAKE_LOCK_SUSPEND,
+   vos_wake_lock_init(&pHddCtx->sap_wake_lock,
            "qcom_sap_wakelock");
-#endif
+
 
    vos_event_init(&pHddCtx->scan_info.scan_finished_event);
    pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
 
    pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
    vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
-   hdd_allow_suspend();
+   hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
 
 #ifdef FEATURE_WLAN_SCAN_PNO
    /*SME must send channel update configuration to RIVA*/
@@ -10176,7 +10165,7 @@
    pHddCtx->cfg_ini= NULL;
 
 err_free_hdd_context:
-   hdd_allow_suspend();
+   hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
    wiphy_free(wiphy) ;
    //kfree(wdev) ;
    VOS_BUG(1);
@@ -10227,9 +10216,7 @@
 
    ENTER();
 
-#ifdef WLAN_OPEN_SOURCE
-   wake_lock_init(&wlan_wake_lock, WAKE_LOCK_SUSPEND, "wlan");
-#endif
+   vos_wake_lock_init(&wlan_wake_lock, "wlan");
 
    pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
            QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
@@ -10250,10 +10237,7 @@
 
    if (max_retries >= 5) {
       hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
-#ifdef WLAN_OPEN_SOURCE
-      wake_lock_destroy(&wlan_wake_lock);
-#endif
-
+      vos_wake_lock_destroy(&wlan_wake_lock);
 #ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
       wlan_logging_sock_deinit_svc();
 #endif
@@ -10323,11 +10307,7 @@
 #ifdef MEMORY_DEBUG
       vos_mem_exit();
 #endif
-
-#ifdef WLAN_OPEN_SOURCE
-      wake_lock_destroy(&wlan_wake_lock);
-#endif
-
+      vos_wake_lock_destroy(&wlan_wake_lock);
 #ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
       wlan_logging_sock_deinit_svc();
 #endif
@@ -10487,9 +10467,7 @@
 #endif
 
 done:
-#ifdef WLAN_OPEN_SOURCE
-   wake_lock_destroy(&wlan_wake_lock);
-#endif
+   vos_wake_lock_destroy(&wlan_wake_lock);
 
    pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
 }
diff --git a/CORE/HDD/src/wlan_hdd_p2p.c b/CORE/HDD/src/wlan_hdd_p2p.c
index cc60e5c..cb0e652 100644
--- a/CORE/HDD/src/wlan_hdd_p2p.c
+++ b/CORE/HDD/src/wlan_hdd_p2p.c
@@ -254,7 +254,7 @@
         complete(&pAdapter->rem_on_chan_ready_event);
     complete(&pAdapter->cancel_rem_on_chan_var);
     pAdapter->is_roc_inprogress = FALSE;
-    hdd_allow_suspend();
+    hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_ROC);
     return eHAL_STATUS_SUCCESS;
 }
 
@@ -341,7 +341,7 @@
                           " ready indication %d",
                            __func__, status);
               }
-              hdd_allow_suspend();
+              hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_ROC);
          }
          else
          {
@@ -442,7 +442,7 @@
         WLANSAP_CancelRemainOnChannel(
                 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
     }
-    hdd_allow_suspend();
+    hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_ROC);
 }
 
 static int wlan_hdd_p2p_start_remain_on_channel(
@@ -505,7 +505,7 @@
         status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
         pAdapterNode = pNext;
     }
-    hdd_prevent_suspend();
+    hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_ROC);
     //call sme API to start remain on channel.
     if ( ( WLAN_HDD_INFRA_STATION == pAdapter->device_mode ) ||
             ( WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ) ||
@@ -525,7 +525,7 @@
             cfgState->remain_on_chan_ctx = NULL;
             vos_timer_destroy(&pRemainChanCtx->hdd_remain_on_chan_timer);
             vos_mem_free (pRemainChanCtx);
-            hdd_allow_suspend();
+            hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_ROC);
             return -EINVAL;
         }
 
@@ -555,7 +555,7 @@
             cfgState->remain_on_chan_ctx = NULL;
             vos_timer_destroy(&pRemainChanCtx->hdd_remain_on_chan_timer);
             vos_mem_free (pRemainChanCtx);
-            hdd_allow_suspend();
+            hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_ROC);
             return -EINVAL;
         }
 
@@ -569,7 +569,7 @@
                     "%s: WLANSAP_RegisterMgmtFrame returned fail", __func__);
             WLANSAP_CancelRemainOnChannel(
                     (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
-            hdd_allow_suspend();
+            hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_ROC);
             return -EINVAL;
         }
 
@@ -1011,7 +1011,7 @@
         hddLog( LOGE,
               "%s:wait on cancel_rem_on_chan_var failed %d", __func__, status);
     }
-    hdd_allow_suspend();
+    hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_ROC);
 
     EXIT();
     return 0;
@@ -2151,7 +2151,9 @@
      skb->ip_summed = CHECKSUM_NONE;
 #ifdef WLAN_OPEN_SOURCE
 #ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
-     wake_lock_timeout(&pHddCtx->rx_wake_lock, msecs_to_jiffies(HDD_WAKE_LOCK_DURATION));
+     vos_wake_lock_timeout_release(&pHddCtx->rx_wake_lock,
+                                   HDD_WAKE_LOCK_DURATION,
+                                   WIFI_POWER_EVENT_WAKELOCK_HOLD_RX);
 #endif
 #endif
      rxstat = netif_rx_ni(skb);
@@ -2569,7 +2571,9 @@
     memset( skb->cb, 0, sizeof( skb->cb ) );
 #ifdef WLAN_OPEN_SOURCE
 #ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
-    wake_lock_timeout(&pHddCtx->rx_wake_lock, msecs_to_jiffies(HDD_WAKE_LOCK_DURATION));
+    vos_wake_lock_timeout_release(&pHddCtx->rx_wake_lock,
+                                  HDD_WAKE_LOCK_DURATION,
+                                  WIFI_POWER_EVENT_WAKELOCK_HOLD_RX);
 #endif
 #endif
     if (in_interrupt())
diff --git a/CORE/HDD/src/wlan_hdd_softap_tx_rx.c b/CORE/HDD/src/wlan_hdd_softap_tx_rx.c
index 0999ee7..2277e3e 100644
--- a/CORE/HDD/src/wlan_hdd_softap_tx_rx.c
+++ b/CORE/HDD/src/wlan_hdd_softap_tx_rx.c
@@ -1355,8 +1355,6 @@
    {
       if (TRUE == hdd_IsEAPOLPacket( pVosPacket ))
       {
-         VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_HIGH,
-                    "%s: VOS packet is EAPOL packet", __func__);
          pPktMetaInfo->ucIsEapol = 1;
          wlan_hdd_log_eapol(skb,
                             WIFI_EVENT_DRIVER_EAPOL_FRAME_TRANSMIT_REQUESTED);
@@ -1677,10 +1675,11 @@
 
          skb->protocol = eth_type_trans(skb, skb->dev);
          skb->ip_summed = CHECKSUM_NONE;
-#ifdef WLAN_OPEN_SOURCE
 #ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
-         wake_lock_timeout(&pHddCtx->rx_wake_lock, msecs_to_jiffies(HDD_WAKE_LOCK_DURATION));
-#endif
+       vos_wake_lock_timeout_release(&pHddCtx->rx_wake_lock,
+                    HDD_WAKE_LOCK_DURATION,
+                    WIFI_POWER_EVENT_WAKELOCK_HOLD_RX);
+
 #endif
          rxstat = netif_rx_ni(skb);
          if (NET_RX_SUCCESS == rxstat)
diff --git a/CORE/HDD/src/wlan_hdd_tx_rx.c b/CORE/HDD/src/wlan_hdd_tx_rx.c
index 1b7e466..821e274 100644
--- a/CORE/HDD/src/wlan_hdd_tx_rx.c
+++ b/CORE/HDD/src/wlan_hdd_tx_rx.c
@@ -2616,10 +2616,10 @@
       ++pAdapter->hdd_stats.hddTxRxStats.rxPackets;
       ++pAdapter->stats.rx_packets;
       pAdapter->stats.rx_bytes += skb->len;
-#ifdef WLAN_OPEN_SOURCE
 #ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
-      wake_lock_timeout(&pHddCtx->rx_wake_lock, msecs_to_jiffies(HDD_WAKE_LOCK_DURATION));
-#endif
+       vos_wake_lock_timeout_release(&pHddCtx->rx_wake_lock,
+                          HDD_WAKE_LOCK_DURATION,
+                          WIFI_POWER_EVENT_WAKELOCK_HOLD_RX);
 #endif
       rxstat = netif_rx_ni(skb);
       if (NET_RX_SUCCESS == rxstat)
diff --git a/CORE/SME/inc/smeInternal.h b/CORE/SME/inc/smeInternal.h
index 1861b3b..b4dd819 100644
--- a/CORE/SME/inc/smeInternal.h
+++ b/CORE/SME/inc/smeInternal.h
@@ -52,6 +52,7 @@
 #include "vos_memory.h"
 #include "vos_types.h"
 #include "csrLinkList.h"
+#include "vos_diag_core_event.h"
 
 /*-------------------------------------------------------------------------- 
   Type declarations
diff --git a/CORE/SME/inc/sme_Api.h b/CORE/SME/inc/sme_Api.h
index 3ffd334..846f62a 100644
--- a/CORE/SME/inc/sme_Api.h
+++ b/CORE/SME/inc/sme_Api.h
@@ -56,6 +56,7 @@
 #include "btcApi.h"
 #include "vos_nvitem.h"
 #include "p2p_Api.h"
+#include "smeInternal.h"
 
 #ifdef FEATURE_OEM_DATA_SUPPORT
 #include "oemDataApi.h"
diff --git a/CORE/SVC/inc/wlan_nlink_srv.h b/CORE/SVC/inc/wlan_nlink_srv.h
index 092a3ea..369332d 100644
--- a/CORE/SVC/inc/wlan_nlink_srv.h
+++ b/CORE/SVC/inc/wlan_nlink_srv.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
diff --git a/CORE/SVC/src/nlink/wlan_nlink_srv.c b/CORE/SVC/src/nlink/wlan_nlink_srv.c
index b7ae679..706cb2d 100644
--- a/CORE/SVC/src/nlink/wlan_nlink_srv.c
+++ b/CORE/SVC/src/nlink/wlan_nlink_srv.c
@@ -391,7 +391,7 @@
 }
 #endif /* WLAN_KD_READY_NOTIFIER */
 
-/**
+/*
  * nl_srv_is_initialized() - This function is used check if the netlink
  * service is initialized
  *
diff --git a/CORE/VOSS/inc/event_defs.h b/CORE/VOSS/inc/event_defs.h
index 926e9be..4d2ba20 100644
--- a/CORE/VOSS/inc/event_defs.h
+++ b/CORE/VOSS/inc/event_defs.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -1902,6 +1902,7 @@
   EVENT_SNS_DRV_MOTION_DETECT_SIG = 0x767,
   EVENT_SNS_DRV_OPMODE_CHANGE = 0x768,
   EVENT_WLAN_EAPOL = 0xA8D,/* 18 bytes payload */
+  EVENT_WLAN_WAKE_LOCK = 0xAA2, /* 96 bytes payload */
 
   EVENT_NEXT_UNUSED_EVENT,
   EVENT_RSVD_START = 0x0800,
diff --git a/CORE/VOSS/inc/i_vos_diag_core_event.h b/CORE/VOSS/inc/i_vos_diag_core_event.h
index a99d446..5d8bb09 100644
--- a/CORE/VOSS/inc/i_vos_diag_core_event.h
+++ b/CORE/VOSS/inc/i_vos_diag_core_event.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -87,6 +87,17 @@
 /*------------------------------------------------------------------------- 
   Function declarations and documenation
   ------------------------------------------------------------------------*/
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+void vos_log_wlock_diag(uint32_t reason, const char *wake_lock_name,
+                              uint32_t timeout, uint32_t status);
+#else
+static inline void vos_log_wlock_diag(uint32_t reason,
+                                 const char *wake_lock_name,
+                           uint32_t timeout, uint32_t status)
+{
+
+}
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
 
 #ifdef __cplusplus
 }
diff --git a/CORE/VOSS/inc/i_vos_lock.h b/CORE/VOSS/inc/i_vos_lock.h
index 2ba86ba..0a66103 100644
--- a/CORE/VOSS/inc/i_vos_lock.h
+++ b/CORE/VOSS/inc/i_vos_lock.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -46,6 +46,10 @@
 #include <linux/mutex.h>
 #include <linux/spinlock.h>
 #include <linux/sched.h>
+#if defined(WLAN_OPEN_SOURCE)
+#include <linux/wakelock.h>
+#endif
+
 
 /*-------------------------------------------------------------------------- 
   Preprocessor definitions and constants
@@ -68,6 +72,13 @@
 
 typedef spinlock_t vos_spin_lock_t;
 
+#if defined(WLAN_OPEN_SOURCE)
+typedef struct wake_lock vos_wake_lock_t;
+#else
+typedef int vos_wake_lock_t;
+#endif
+
+
 /*------------------------------------------------------------------------- 
   Function declarations and documenation
   ------------------------------------------------------------------------*/
diff --git a/CORE/VOSS/inc/vos_api.h b/CORE/VOSS/inc/vos_api.h
index 6d10490..6c3660a 100644
--- a/CORE/VOSS/inc/vos_api.h
+++ b/CORE/VOSS/inc/vos_api.h
@@ -349,5 +349,5 @@
 v_U8_t vos_is_fw_logging_supported(void);
 void vos_set_multicast_logging(uint8_t value);
 v_U8_t vos_is_multicast_logging(void);
-
+bool vos_is_wakelock_enabled(void);
 #endif // if !defined __VOS_NVITEM_H
diff --git a/CORE/VOSS/inc/vos_diag_core_event.h b/CORE/VOSS/inc/vos_diag_core_event.h
index a9d81b1..715fbd2 100644
--- a/CORE/VOSS/inc/vos_diag_core_event.h
+++ b/CORE/VOSS/inc/vos_diag_core_event.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -55,6 +55,9 @@
 extern "C" {
 #endif /* __cplusplus */
 
+#define WAKE_LOCK_NAME_LEN 80
+
+
 /*------------------------------------------------------------------------- 
   Event ID: EVENT_WLAN_SECURITY
   ------------------------------------------------------------------------*/
@@ -257,6 +260,29 @@
        uint8_t   dest_addr[6];
        uint8_t   src_addr[6];
 };
+/*-------------------------------------------------------------------------
+  Event ID: EVENT_WLAN_WAKE_LOCK
+  ------------------------------------------------------------------------*/
+/*
+ * struct vos_event_wlan_wake_lock - Structure holding the wakelock information
+ * @status: Whether the wakelock is taken/released
+ * @reason: Reason for taking this wakelock
+ * @timeout: Timeout value in case of timed wakelocks
+ * @name_len: Length of the name of the wakelock that will follow
+ * @name: Name of the wakelock
+ *
+ * This structure will hold the wakelock informations
+ */
+struct vos_event_wlan_wake_lock
+{
+       uint32_t status;
+       uint32_t reason;
+       uint32_t timeout;
+       uint32_t name_len;
+       char     name[WAKE_LOCK_NAME_LEN];
+};
+
+
 
 
 /*------------------------------------------------------------------------- 
@@ -266,6 +292,28 @@
        WIFI_EVENT_DRIVER_EAPOL_FRAME_TRANSMIT_REQUESTED,
        WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED,
 };
+
+/*
+ * enum wake_lock_reason - Reason for taking wakelock
+* @WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT: Driver initialization
+ * @WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT: Driver re-initialization
+ * @WIFI_POWER_EVENT_WAKELOCK_SCAN: Scan request/response handling
+ * @WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN: Driver resume
+ * @WIFI_POWER_EVENT_WAKELOCK_ROC: Remain on channel request/response handling
+ * @WIFI_POWER_EVENT_WAKELOCK_HOLD_RX: Wakelocks taken for receive
+ * @WIFI_POWER_EVENT_WAKELOCK_SAP: SoftAP related wakelocks
+ * This enum has the reason codes why the wakelocks were taken/released
+ */
+enum wake_lock_reason {
+       WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT,
+       WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT,
+       WIFI_POWER_EVENT_WAKELOCK_SCAN,
+       WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN,
+       WIFI_POWER_EVENT_WAKELOCK_ROC,
+       WIFI_POWER_EVENT_WAKELOCK_HOLD_RX,
+       WIFI_POWER_EVENT_WAKELOCK_SAP,
+};
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
diff --git a/CORE/VOSS/inc/vos_lock.h b/CORE/VOSS/inc/vos_lock.h
index c7e60d8..9cce950 100644
--- a/CORE/VOSS/inc/vos_lock.h
+++ b/CORE/VOSS/inc/vos_lock.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -248,5 +248,63 @@
   ------------------------------------------------------------------------*/
 VOS_STATUS vos_spin_lock_destroy(vos_spin_lock_t *pLock);
 
+/*--------------------------------------------------------------------------
+
+  \brief vos_wake_lock_init() - initializes a vOSS wake lock
+
+  \param pLock - the wake lock to initialize
+              name - wakelock name
+
+  \return VOS_STATUS_SUCCESS - wake lock was successfully initialized and
+          is ready to be used.
+  --------------------------------------------------------------------------*/
+VOS_STATUS vos_wake_lock_init(vos_wake_lock_t *pLock, const char *name);
+
+/*--------------------------------------------------------------------------
+
+  \brief vos_wake_lock_acquire() - acquires a wake lock
+
+  \param pLock - the wake lock to acquire
+         reason - reason for taking wakelock
+
+  \return VOS_STATUS_SUCCESS - the wake lock was successfully acquired
+
+  ------------------------------------------------------------------------*/
+VOS_STATUS vos_wake_lock_acquire(vos_wake_lock_t *pLock, uint32_t reason);
+/*--------------------------------------------------------------------------
+
+  \brief vos_wake_lock_timeout_release() - release a wake lock with a timeout
+
+  \param pLock - the wake lock to release
+         reason - reason for taking wakelock
+
+  \return VOS_STATUS_SUCCESS - the wake lock was successfully released
+
+  ------------------------------------------------------------------------*/
+VOS_STATUS vos_wake_lock_timeout_release(vos_wake_lock_t *pLock,
+                                            v_U32_t msec, uint32_t reason);
+
+/*--------------------------------------------------------------------------
+
+  \brief vos_wake_lock_release() - releases a wake lock
+
+  \param pLock - the wake lock to release
+         reason - reason for taking wakelock
+
+  \return VOS_STATUS_SUCCESS - the lock was successfully released
+
+  ------------------------------------------------------------------------*/
+VOS_STATUS vos_wake_lock_release(vos_wake_lock_t *pLock, uint32_t reason);
+
+/*--------------------------------------------------------------------------
+
+  \brief vos_wake_lock_destroy() - destroys a wake lock
+
+  \param pLock - the wake lock to destroy
+
+  \return VOS_STATUS_SUCCESS - the lock was successfully destroyed
+
+  ------------------------------------------------------------------------*/
+VOS_STATUS vos_wake_lock_destroy(vos_wake_lock_t *pLock);
 
 #endif // __VOSS_LOCK_H
diff --git a/CORE/VOSS/src/vos_diag.c b/CORE/VOSS/src/vos_diag.c
index 0c63814..d506d11 100644
--- a/CORE/VOSS/src/vos_diag.c
+++ b/CORE/VOSS/src/vos_diag.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -198,6 +198,39 @@
     return;
 }
 
+/**
+ * vos_log_wlock_diag() - This function is used to send wake lock diag events
+ * @reason: Reason why the wakelock was taken or released
+ * @wake_lock_name: Function in which the wakelock was taken or released
+ * @timeout: Timeout value in case of timed wakelocks
+ * @status: Status field indicating whether the wake lock was taken/released
+ *
+ * This function is used to send wake lock diag events to user space
+ *
+ * Return: None
+ *
+ */
+void vos_log_wlock_diag(uint32_t reason, const char *wake_lock_name,
+                              uint32_t timeout, uint32_t status)
+{
+     WLAN_VOS_DIAG_EVENT_DEF(wlan_diag_event,
+     struct vos_event_wlan_wake_lock);
+
+     if (nl_srv_is_initialized() != 0)
+          return;
+
+     wlan_diag_event.status = status;
+     wlan_diag_event.reason = reason;
+     wlan_diag_event.timeout = timeout;
+     wlan_diag_event.name_len = strlen(wake_lock_name);
+     strlcpy(&wlan_diag_event.name[0],
+             wake_lock_name,
+             wlan_diag_event.name_len+1);
+
+     WLAN_VOS_DIAG_EVENT_REPORT(&wlan_diag_event, EVENT_WLAN_WAKE_LOCK);
+}
+
+
 /**---------------------------------------------------------------------------
   
   \brief vos_event_report_payload() - 
diff --git a/CORE/VOSS/src/vos_lock.c b/CORE/VOSS/src/vos_lock.c
index 825804b..56f57df 100644
--- a/CORE/VOSS/src/vos_lock.c
+++ b/CORE/VOSS/src/vos_lock.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -49,12 +49,20 @@
 #include "vos_lock.h"
 #include "vos_memory.h"
 #include "vos_trace.h"
+#include "i_vos_diag_core_event.h"
+#include <net/cnss.h>
+#include "vos_diag_core_event.h"
+#include <linux/wcnss_wlan.h>
 
 
 /*----------------------------------------------------------------------------
  * Preprocessor Definitions and Constants
  * -------------------------------------------------------------------------*/
 
+#define WIFI_POWER_EVENT_DEFAULT_WAKELOCK_TIMEOUT 0
+#define WIFI_POWER_EVENT_WAKELOCK_TAKEN 0
+#define WIFI_POWER_EVENT_WAKELOCK_RELEASED 1
+
 /*----------------------------------------------------------------------------
  * Type Declarations
  * -------------------------------------------------------------------------*/
@@ -474,3 +482,142 @@
 
    return VOS_STATUS_SUCCESS;
 }
+
+/*--------------------------------------------------------------------------
+
+  \brief vos_wake_lock_init() - initializes a vOSS wake lock
+
+  \param pLock - the wake lock to initialize
+              name - wakelock name
+
+  \return VOS_STATUS_SUCCESS - wake lock was successfully initialized and
+          is ready to be used.
+  --------------------------------------------------------------------------*/
+VOS_STATUS vos_wake_lock_init(vos_wake_lock_t *pLock, const char *name)
+{
+#if defined(WLAN_OPEN_SOURCE)
+    wake_lock_init(pLock, WAKE_LOCK_SUSPEND, name);
+#endif
+    return VOS_STATUS_SUCCESS;
+}
+
+
+/*--------------------------------------------------------------------------
+ * vos_wake_lock_name() - This function returns the name of the wakelock
+ * @pLock: Pointer to the wakelock
+ *
+ * This function returns the name of the wakelock
+ *
+ * Return: Pointer to the name if it is valid or a default string
+ *
+   --------------------------------------------------------------------------*/
+static const char* vos_wake_lock_name(vos_wake_lock_t *pLock)
+{
+#if !(defined(WLAN_OPEN_SOURCE) && defined(CONFIG_HAS_WAKELOCK))
+    return "UNNAMED_WAKELOCK";
+#else
+    if (pLock->ws.name)
+        return pLock->ws.name;
+    else
+        return "UNNAMED_WAKELOCK";
+#endif
+}
+
+/*--------------------------------------------------------------------------
+
+  \brief vos_wake_lock_acquire() - acquires a wake lock
+
+  \param pLock - the wake lock to acquire
+
+  \return VOS_STATUS_SUCCESS - the wake lock was successfully acquired
+
+  ------------------------------------------------------------------------*/
+VOS_STATUS vos_wake_lock_acquire(vos_wake_lock_t *pLock,
+                                 uint32_t reason)
+{
+    vos_log_wlock_diag(reason, vos_wake_lock_name(pLock),
+                       WIFI_POWER_EVENT_DEFAULT_WAKELOCK_TIMEOUT,
+                       WIFI_POWER_EVENT_WAKELOCK_TAKEN);
+#if defined(WLAN_OPEN_SOURCE)
+    wake_lock(pLock);
+#else
+    wcnss_prevent_suspend();
+#endif
+    return VOS_STATUS_SUCCESS;
+
+}
+
+/*--------------------------------------------------------------------------
+
+  \brief vos_wake_lock_timeout_release() - release a wake lock with a timeout
+
+  \param pLock - the wake lock to release
+         reason - reason for taking wakelock
+
+  \return VOS_STATUS_SUCCESS - the wake lock was successfully released
+
+  ------------------------------------------------------------------------*/
+VOS_STATUS vos_wake_lock_timeout_release(vos_wake_lock_t *pLock,
+                                            v_U32_t msec, uint32_t reason)
+{
+    /* Avoid reporting rx and tx wavelocks
+     * event to diag as it may cause performance
+     * issues.
+     */
+    if (WIFI_POWER_EVENT_WAKELOCK_HOLD_RX != reason)
+    {
+        vos_log_wlock_diag(reason, vos_wake_lock_name(pLock), msec,
+                                   WIFI_POWER_EVENT_WAKELOCK_TAKEN);
+    }
+
+#if defined(WLAN_OPEN_SOURCE)
+    wake_lock_timeout(pLock, msecs_to_jiffies(msec));
+#else
+    /* Do nothing as there is no API in wcnss for timeout*/
+#endif
+   return VOS_STATUS_SUCCESS;
+
+}
+
+/*--------------------------------------------------------------------------
+
+  \brief vos_wake_lock_release() - releases a wake lock
+
+  \param pLock - the wake lock to release
+
+  \return VOS_STATUS_SUCCESS - the lock was successfully released
+
+  ------------------------------------------------------------------------*/
+VOS_STATUS vos_wake_lock_release(vos_wake_lock_t *pLock, uint32_t reason)
+{
+    vos_log_wlock_diag(reason, vos_wake_lock_name(pLock),
+                       WIFI_POWER_EVENT_DEFAULT_WAKELOCK_TIMEOUT,
+                       WIFI_POWER_EVENT_WAKELOCK_RELEASED);
+
+#if defined(WLAN_OPEN_SOURCE)
+    wake_unlock(pLock);
+#else
+    wcnss_allow_suspend();
+#endif
+    return VOS_STATUS_SUCCESS;
+
+
+}
+
+/*--------------------------------------------------------------------------
+
+  \brief vos_wake_lock_destroy() - destroys a wake lock
+
+  \param pLock - the wake lock to destroy
+
+  \return VOS_STATUS_SUCCESS - the lock was successfully destroyed
+
+  ------------------------------------------------------------------------*/
+VOS_STATUS vos_wake_lock_destroy(vos_wake_lock_t *pLock)
+{
+
+#if defined(WLAN_OPEN_SOURCE)
+    wake_lock_destroy(pLock);
+#endif
+    return VOS_STATUS_SUCCESS;
+}