wlan: Roam if RSSI(candidate) > RSSI(curr AP) by gImmediateRoamRssiDiff.

If the potential roam candidate(s) found after the scan are much better
than the current AP, then there is no need to register for reassoc
threshold and wait until the notification is received to trigger the
roam. Since this duration is non-deterministic, the results/RSSI values
obtained from the scan (which are used to sort the candidates) might be
outdated. This could lead to roaming to a bad AP. This problem is being
fixed as follows:

Add a new configuration parameter in the INI file, namely,
gImmediateRoamRssiDiff. By default, this is set to 0. It can be
configured to a value in the range [0 .. 125] by issuing the following
command:
adb shell iwpriv wlan0 setConfig gImmediateRoamRssiDiff=<value>

Following a scan and if potential roam candidate(s) are found,
then determine whether to register for reassoc threshold or roam
immediately based on the above configuration parameter. If the RSSI of
any available candidate is better than the currently associated AP by at
least gImmediateRoamRssiDiff, then being to roam immediately (without
registering for reassoc threshold).

Fixed CRs: 427062

Change-Id: I56a86c039d680a635b38ee5d38c47f6451841a57
diff --git a/CORE/HDD/src/wlan_hdd_cfg.c b/CORE/HDD/src/wlan_hdd_cfg.c
index 3090c2c..3548baa 100644
--- a/CORE/HDD/src/wlan_hdd_cfg.c
+++ b/CORE/HDD/src/wlan_hdd_cfg.c
@@ -54,11 +54,19 @@
 #include <pmcApi.h>
 #include <wlan_hdd_misc.h>
 
+#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
 static void cbNotifySetRoamPrefer5GHz(hdd_context_t *pHddCtx, unsigned long NotifyId)
 {
     sme_UpdateRoamPrefer5GHz((tHalHandle)(pHddCtx->hHal), pHddCtx->cfg_ini->nRoamPrefer5GHz);
 }
 
+static void cbNotifySetImmediateRoamRssiDiff(hdd_context_t *pHddCtx, unsigned long NotifyId)
+{
+    sme_UpdateImmediateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), 
+                                    pHddCtx->cfg_ini->nImmediateRoamRssiDiff);
+}
+#endif
+
 REG_TABLE_ENTRY g_registry_table[] =
 {
    REG_VARIABLE( CFG_RTS_THRESHOLD_NAME, WLAN_PARAM_Integer,
@@ -884,6 +892,14 @@
                  CFG_ROAM_RSSI_DIFF_DEFAULT, 
                  CFG_ROAM_RSSI_DIFF_MIN, 
                  CFG_ROAM_RSSI_DIFF_MAX),
+
+   REG_DYNAMIC_VARIABLE( CFG_IMMEDIATE_ROAM_RSSI_DIFF_NAME, WLAN_PARAM_Integer,
+                         hdd_config_t, nImmediateRoamRssiDiff, 
+                         VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, 
+                         CFG_IMMEDIATE_ROAM_RSSI_DIFF_DEFAULT, 
+                         CFG_IMMEDIATE_ROAM_RSSI_DIFF_MIN, 
+                         CFG_IMMEDIATE_ROAM_RSSI_DIFF_MAX,
+                         cbNotifySetImmediateRoamRssiDiff, 0),
 #endif
 
    REG_VARIABLE( CFG_QOS_WMM_PKT_CLASSIFY_BASIS_NAME , WLAN_PARAM_Integer,
@@ -2009,6 +2025,7 @@
 #endif 
 #if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
   VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [RoamRssiDiff] Value = [%lu] ",pHddCtx->cfg_ini->RoamRssiDiff);
+  VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [ImmediateRoamRssiDiff] Value = [%lu] ",pHddCtx->cfg_ini->nImmediateRoamRssiDiff);
 #endif
   VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraDirAcVo] Value = [%u] ",pHddCtx->cfg_ini->InfraDirAcVo);
   VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraNomMsduSizeAcVo] Value = [0x%x] ",pHddCtx->cfg_ini->InfraNomMsduSizeAcVo);
@@ -3279,6 +3296,7 @@
 #if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
    smeConfig.csrConfig.isFastTransitionEnabled = pConfig->isFastTransitionEnabled;
    smeConfig.csrConfig.RoamRssiDiff = pConfig->RoamRssiDiff;
+   smeConfig.csrConfig.nImmediateRoamRssiDiff = pConfig->nImmediateRoamRssiDiff;
 #endif
 
 #ifdef WLAN_FEATURE_NEIGHBOR_ROAMING