Added a ini parameter isAndroidPsEn to control  the current BMPS logic.

Added a ini parameter Which provide a option for upper layers
to control Powersave mechanism.

CRs-fixed: 414887

Change-Id: Ia69a14db28f0061aa62a045b16ca83dafca6431b
diff --git a/CORE/HDD/inc/wlan_hdd_cfg.h b/CORE/HDD/inc/wlan_hdd_cfg.h
index d7bac61..ea06076 100644
--- a/CORE/HDD/inc/wlan_hdd_cfg.h
+++ b/CORE/HDD/inc/wlan_hdd_cfg.h
@@ -1319,6 +1319,16 @@
 #define CFG_SAP_AUTO_CHANNEL_SELECTION_MAX        ( 1 )
 #define CFG_SAP_AUTO_CHANNEL_SELECTION_DEFAULT    ( 0 )
 
+/*BMPS Logic
+ * Notes:
+ * 1 - Then Host driver and above layers control the PS mechanism
+ * 0 - Diver/Core Stack internally control the Power saving mechanism
+ */
+#define CFG_ANDRIOD_POWER_SAVE_NAME      "isAndroidPsEn"
+#define CFG_ANDRIOD_POWER_SAVE_MIN       ( 0 )
+#define CFG_ANDRIOD_POWER_SAVE_MAX       ( 1 )
+#define CFG_ANDRIOD_POWER_SAVE_DEFAULT   ( 0 )
+
 
 /*
  * Enable Dynamic DTIM
@@ -1833,6 +1843,7 @@
    v_U8_t                      scanAgingTimeout;
    v_BOOL_t                    enableTxLdpc;
    v_U8_t                      enableMCCAdaptiveScheduler;
+   v_BOOL_t                    isAndroidPsEn;
 } hdd_config_t;
 /*--------------------------------------------------------------------------- 
   Function declarations and documenation
diff --git a/CORE/HDD/src/wlan_hdd_cfg.c b/CORE/HDD/src/wlan_hdd_cfg.c
index e69e282..e849145 100644
--- a/CORE/HDD/src/wlan_hdd_cfg.c
+++ b/CORE/HDD/src/wlan_hdd_cfg.c
@@ -1832,11 +1832,19 @@
               CFG_TX_LDPC_ENABLE_FEATURE_MAX ),
 
 REG_VARIABLE( CFG_ENABLE_MCC_ADATIVE_SCHEDULER_ENABLED_NAME, WLAN_PARAM_Integer,
-             hdd_config_t, enableMCCAdaptiveScheduler, 
-             VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, 
-             CFG_ENABLE_MCC_ADATIVE_SCHEDULER_ENABLED_DEFAULT, 
-             CFG_ENABLE_MCC_ADATIVE_SCHEDULER_ENABLED_MIN, 
-             CFG_ENABLE_MCC_ADATIVE_SCHEDULER_ENABLED_MAX ),             
+             hdd_config_t, enableMCCAdaptiveScheduler,
+             VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+             CFG_ENABLE_MCC_ADATIVE_SCHEDULER_ENABLED_DEFAULT,
+             CFG_ENABLE_MCC_ADATIVE_SCHEDULER_ENABLED_MIN,
+             CFG_ENABLE_MCC_ADATIVE_SCHEDULER_ENABLED_MAX ),
+
+REG_VARIABLE( CFG_ANDRIOD_POWER_SAVE_NAME, WLAN_PARAM_Integer,
+              hdd_config_t, isAndroidPsEn,
+              VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+              CFG_ANDRIOD_POWER_SAVE_DEFAULT,
+              CFG_ANDRIOD_POWER_SAVE_MIN,
+              CFG_ANDRIOD_POWER_SAVE_MAX),
+
 };
 
 /*
@@ -2687,6 +2695,10 @@
       sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
    }
 
+  /*If isAndroidPsEn is 1 then Host driver and above layers control the PS mechanism
+    If Value set to 0 Driver/Core Stack internally control the Power saving mechanism */
+   sme_SetHostPowerSave (pHddCtx->hHal, pConfig->isAndroidPsEn);
+
    if (pConfig->fIsBmpsEnabled)
    {
       sme_EnablePowerSave (pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
diff --git a/CORE/HDD/src/wlan_hdd_early_suspend.c b/CORE/HDD/src/wlan_hdd_early_suspend.c
index 2e3931a..35616ad 100644
--- a/CORE/HDD/src/wlan_hdd_early_suspend.c
+++ b/CORE/HDD/src/wlan_hdd_early_suspend.c
@@ -1323,13 +1323,16 @@
                         "Switch to DTIM%d \n",powerRequest.uListenInterval);
          sme_SetPowerParams( WLAN_HDD_GET_HAL_CTX(pAdapter), &powerRequest);    
 
-         /* put the device into full power */
-         wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
+         if (BMPS == pmcGetPmcState(pHddCtx->hHal))
+         {
+             /* put the device into full power */
+             wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
 
-         /* put the device back into BMPS */
-         wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
+             /* put the device back into BMPS */
+             wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
 
-         pHddCtx->hdd_ignore_dtim_enabled = FALSE;
+             pHddCtx->hdd_ignore_dtim_enabled = FALSE;
+         }
       }
 
          if(pHddCtx->hdd_mcastbcast_filter_set == TRUE) {
diff --git a/CORE/SME/inc/pmc.h b/CORE/SME/inc/pmc.h
index 87bf590..04b5a9f 100644
--- a/CORE/SME/inc/pmc.h
+++ b/CORE/SME/inc/pmc.h
@@ -213,6 +213,10 @@
     void (*wakeReasonIndCB) (void *callbackContext, tpSirWakeReasonInd pWakeReasonInd);  /* routine to call for Wake Reason Indication */ 
     void *wakeReasonIndCBContext;  /* value to be passed as parameter to routine specified above */
 #endif // WLAN_WAKEUP_EVENTS
+
+/* If TRUE driver will go to BMPS only if host operatiing system asks to enter BMPS.
+* For android wlan_hdd_cfg80211_set_power_mgmt API will be used to set host powersave*/
+   v_BOOL_t    isHostPsEn;
 } tPmcInfo, *tpPmcInfo;
 
 
diff --git a/CORE/SME/inc/sme_Api.h b/CORE/SME/inc/sme_Api.h
index d53e8f7..49f91ae 100644
--- a/CORE/SME/inc/sme_Api.h
+++ b/CORE/SME/inc/sme_Api.h
@@ -895,6 +895,17 @@
    tHalHandle hHal,
    tPmcPowerSavingMode psMode);
 
+ /* ---------------------------------------------------------------------------
+   \fn sme_SetHostPowerSave
+    \brief   The BMPS logic is controlled by the User level Apps
+    \param  hHal - The handle returned by macOpen.
+    \param  psMode - The power saving mode to enable.
+    \return eHalStatus
+  ---------------------------------------------------------------------------*/
+extern eHalStatus sme_SetHostPowerSave (
+   tHalHandle hHal,
+   v_BOOL_t psMode);
+
 /* ---------------------------------------------------------------------------
     \fn sme_StartAutoBmpsTimer
     \brief  Starts a timer that periodically polls all the registered
diff --git a/CORE/SME/src/pmc/pmc.c b/CORE/SME/src/pmc/pmc.c
index adbfd58..b420df6 100644
--- a/CORE/SME/src/pmc/pmc.c
+++ b/CORE/SME/src/pmc/pmc.c
@@ -2558,6 +2558,12 @@
         return eANI_BOOLEAN_FALSE;
     }
 
+    if(pMac->pmc.isHostPsEn && pMac->pmc.remainInPowerActiveTillDHCP)
+    {
+        smsLog(pMac, LOG1, FL("Host controlled ps enabled and host wants active mode, so dont allow BMPS"));
+        return eANI_BOOLEAN_FALSE;
+    }
+
     if ((vos_concurrent_sessions_running()) &&
         ((csrIsConcurrentInfraConnected( pMac ) ||
         (vos_get_concurrency_mode()& VOS_SAP) ||
diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c
index 7fcab6c..6e28201 100644
--- a/CORE/SME/src/sme_common/sme_Api.c
+++ b/CORE/SME/src/sme_common/sme_Api.c
@@ -3215,6 +3215,25 @@
  }
 
 /* ---------------------------------------------------------------------------
++    \fn sme_SetHostPowerSave
++    \brief   Enables BMPS logic to be controlled by User level apps
++    \param  hHal - The handle returned by macOpen.
++    \param  psMode - The power saving mode to disable. Disabling does not imply
++                     that device will be brought out of the current PS mode. This
++                     is purely a configuration API.
++    \return eHalStatus
++  ---------------------------------------------------------------------------*/
+eHalStatus sme_SetHostPowerSave (tHalHandle hHal, v_BOOL_t psMode)
+{
+   eHalStatus status = eHAL_STATUS_FAILURE;
+   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
+
+   pMac->pmc.isHostPsEn = psMode;
+
+   return (status);
+}
+
+/* ---------------------------------------------------------------------------
     \fn sme_StartAutoBmpsTimer
     \brief  Starts a timer that periodically polls all the registered
             module for entry into Bmps mode. This timer is started only if BMPS is
diff --git a/firmware_bin/WCNSS_qcom_cfg.ini b/firmware_bin/WCNSS_qcom_cfg.ini
index 6c96603..32dd9ce 100644
--- a/firmware_bin/WCNSS_qcom_cfg.ini
+++ b/firmware_bin/WCNSS_qcom_cfg.ini
@@ -369,6 +369,12 @@
 #If Set to 0 it will not enable the feature
 gScanAgingTime=0
 
+#Enable Power saving mechanism Based on Android Framework
+#If set to 0 Driver internally control the Power saving mechanism
+#If set to 1 Android Framwrok control the Power saving mechanism
+isAndroidPsEn=0
+
+
 END
 
 # Note: Configuration parser would not read anything past the END marker