Merge "wlan: Enable IMPS/BMPS if TDLS is disabled internally" into wlan-driver.lnx.1.0-dev.1.0
diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h
index 84e3a7a..5090e3d 100644
--- a/CORE/HDD/inc/wlan_hdd_main.h
+++ b/CORE/HDD/inc/wlan_hdd_main.h
@@ -1796,6 +1796,7 @@
     scan_reject_states last_scan_reject_reason;
     v_TIME_t last_scan_reject_timestamp;
     bool is_ap_mode_wow_supported;
+    bool is_fatal_event_log_sup;
 
     uint32_t track_arp_ip;
 };
diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c
index cf9cf6a..b74e059 100644
--- a/CORE/HDD/src/wlan_hdd_main.c
+++ b/CORE/HDD/src/wlan_hdd_main.c
@@ -12675,6 +12675,11 @@
    pHddCtx->is_ap_mode_wow_supported =
               sme_IsFeatureSupportedByFW(SAP_MODE_WOW);
 
+   pHddCtx->is_fatal_event_log_sup =
+      sme_IsFeatureSupportedByFW(FATAL_EVENT_LOGGING);
+   hddLog(VOS_TRACE_LEVEL_INFO, FL("FATAL_EVENT_LOGGING: %d"),
+          pHddCtx->is_fatal_event_log_sup);
+
    hdd_assoc_registerFwdEapolCB(pVosContext);
 
    goto success;
diff --git a/CORE/MAC/src/include/sirParams.h b/CORE/MAC/src/include/sirParams.h
index ecf6dc0..dca671d 100644
--- a/CORE/MAC/src/include/sirParams.h
+++ b/CORE/MAC/src/include/sirParams.h
@@ -155,7 +155,7 @@
    MAKE_BEFORE_BREAK = 67,
 #endif
    NUD_DEBUG = 68,
-   /*69 reserved for FATAL_EVENT_LOGGING */
+   FATAL_EVENT_LOGGING = 69,
    /*70 reserved for WIFI_DUAL_BAND_ENABLE */
    PROBE_RSP_TEMPLATE_VER1 = 71,
    //MAX_FEATURE_SUPPORTED = 128
diff --git a/CORE/SME/inc/csrInternal.h b/CORE/SME/inc/csrInternal.h
index 09a507b..3934fd9 100644
--- a/CORE/SME/inc/csrInternal.h
+++ b/CORE/SME/inc/csrInternal.h
@@ -1067,6 +1067,7 @@
     tANI_BOOLEAN   isWESModeEnabled;
 #endif
     tANI_U32 deauthRspStatus;
+    tANI_BOOLEAN pending_roam_disable;
 }tCsrRoamStruct;
 
 
diff --git a/CORE/SME/src/csr/csrApiRoam.c b/CORE/SME/src/csr/csrApiRoam.c
index 2d7af78..50a3924 100644
--- a/CORE/SME/src/csr/csrApiRoam.c
+++ b/CORE/SME/src/csr/csrApiRoam.c
@@ -17539,6 +17539,26 @@
     return ( desiredMask & ( 1 << pNeighborRoamInfo->lastSentCmd) );
 }
 
+eCsrBand GetCurrentBand(tANI_U8 channel)
+{
+    tSirRFBand Rfband;
+    eCsrBand band;
+
+    Rfband = GetRFBand(channel);
+
+    if (Rfband == SIR_BAND_5_GHZ)
+        band = eCSR_BAND_5G;
+    else if (Rfband == SIR_BAND_2_4_GHZ)
+         band = eCSR_BAND_24;
+    else if (Rfband == SIR_BAND_UNKNOWN)
+         band = eCSR_BAND_MAX;
+
+    VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
+              "channel %d Rfband %d band %d", channel, Rfband, band);
+
+    return band;
+}
+
 eHalStatus csrRoamOffloadScan(tpAniSirGlobal pMac, tANI_U8 command, tANI_U8 reason)
 {
    vos_msg_t msg;
@@ -17554,7 +17574,7 @@
    tpCsrChannelInfo    currChannelListInfo;
    tANI_U32 host_channels = 0;
    tANI_U8 ChannelCacheStr[128] = {0};
-   eCsrBand eBand;
+   eCsrBand eBand, Rfband = eCSR_BAND_ALL;
    tSirBssDescription *pBssDesc = NULL;
    tDot11fBeaconIEs *pIes = NULL;
    tANI_U8 minRate = 0, dataRate;
@@ -17629,6 +17649,10 @@
               "%s: pBssDesc not found for current session", __func__);
           return eHAL_STATUS_FAILURE;
       }
+
+       operationChannel = pSession->connectedProfile.operationChannel;
+       VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
+                 "operationChannel %d", operationChannel);
    }
    pRequestBuf = vos_mem_malloc(sizeof(tSirRoamOffloadScanReq));
    if (NULL == pRequestBuf)
@@ -17681,7 +17705,6 @@
     else
     {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "Calculate Adaptive Threshold");
-       operationChannel = pSession->connectedProfile.operationChannel;
 
        if (!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pBssDesc, &pIes)))
        {
@@ -17859,6 +17882,14 @@
              vos_mem_free(pRequestBuf);
              return eHAL_STATUS_FAILURE;
           }
+
+          if (pMac->roam.configParam.nRoamIntraBand)
+          {
+             eBand = GetCurrentBand(operationChannel);
+             VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
+                       "Current Band %d", eBand);
+          }
+
           for (i=0; i<pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels; i++)
           {
             if(((eCSR_BAND_24 == eBand) && CSR_IS_CHANNEL_24GHZ(*ChannelList)) ||
@@ -17881,15 +17912,32 @@
        else
        {
           ChannelList = pMac->scan.occupiedChannels.channelList;
+
+          if (pMac->roam.configParam.nRoamIntraBand)
+          {
+              Rfband = GetCurrentBand(operationChannel);
+              VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
+                        "Current Band %d", Rfband);
+          }
+
           for(i=0; i<pMac->scan.occupiedChannels.numChannels; i++)
           {
-             /*Allow DFS channels only if the DFS channel roam flag is enabled */
-             if(*ChannelList && ((pMac->roam.configParam.allowDFSChannelRoam) ||
-                (!CSR_IS_CHANNEL_DFS(*ChannelList))) &&
-                (num_channels < SIR_ROAM_MAX_CHANNELS))
-             {
-                pRequestBuf->ConnectedNetwork.ChannelCache[num_channels++] = *ChannelList;
-             }
+              if(((eCSR_BAND_24 == Rfband) &&
+                                          CSR_IS_CHANNEL_24GHZ(*ChannelList)) ||
+                 ((eCSR_BAND_5G == Rfband) && CSR_IS_CHANNEL_5GHZ(*ChannelList))
+                                          || (eCSR_BAND_ALL == Rfband))
+              {
+                  /* Allow DFS channels only if the DFS channel roam flag is
+                   * enabled
+                   */
+                 if(*ChannelList && ((pMac->roam.configParam.
+                    allowDFSChannelRoam) || (!CSR_IS_CHANNEL_DFS(*ChannelList)))
+                    && (num_channels < SIR_ROAM_MAX_CHANNELS))
+                 {
+                     pRequestBuf->ConnectedNetwork.ChannelCache[num_channels++]
+                                                                = *ChannelList;
+                 }
+              }
              ChannelList++;
           }
           pRequestBuf->ConnectedNetwork.ChannelCount = num_channels;
@@ -17899,10 +17947,13 @@
           if (reason == REASON_FLUSH_CHANNEL_LIST)
               pRequestBuf->ChannelCacheType = CHANNEL_LIST_DYNAMIC_FLUSH;
           else {
-                 if (csrNeighborRoamIsNewConnectedProfile(pMac))
-                     pRequestBuf->ChannelCacheType = CHANNEL_LIST_DYNAMIC_INIT;
+                 if ((csrNeighborRoamIsNewConnectedProfile(pMac)) ||
+                      (pMac->roam.configParam.nRoamIntraBand))
+                       pRequestBuf->ChannelCacheType =
+                                                   CHANNEL_LIST_DYNAMIC_INIT;
                  else
-                     pRequestBuf->ChannelCacheType = CHANNEL_LIST_DYNAMIC_UPDATE;
+                       pRequestBuf->ChannelCacheType =
+                                                   CHANNEL_LIST_DYNAMIC_UPDATE;
           }
        }
     }
@@ -17915,18 +17966,35 @@
        if (currChannelListInfo->numOfChannels != 0)
        {
           ChannelList = currChannelListInfo->ChannelList;
+
+          if (pMac->roam.configParam.nRoamIntraBand)
+          {
+              Rfband = GetCurrentBand(operationChannel);
+              VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
+                        "Current Band %d", Rfband);
+          }
+
           for (i=0;i<currChannelListInfo->numOfChannels;i++)
           {
-             if(*ChannelList && ((pMac->roam.configParam.allowDFSChannelRoam) ||
-                (!CSR_IS_CHANNEL_DFS(*ChannelList))))
-             {
-                pRequestBuf->ConnectedNetwork.ChannelCache[num_channels++] =
+              if(((eCSR_BAND_24 == Rfband) &&
+                                          CSR_IS_CHANNEL_24GHZ(*ChannelList)) ||
+                 ((eCSR_BAND_5G == Rfband) && CSR_IS_CHANNEL_5GHZ(*ChannelList))
+                                          || (eCSR_BAND_ALL == Rfband))
+              {
+                if(*ChannelList && ((pMac->roam.configParam.
+                   allowDFSChannelRoam) || (!CSR_IS_CHANNEL_DFS(*ChannelList))))
+                {
+                   pRequestBuf->ConnectedNetwork.ChannelCache[num_channels++] =
                                                                 *ChannelList;
-             }
+                }
+              }
              ChannelList++;
           }
           pRequestBuf->ConnectedNetwork.ChannelCount = num_channels;
-          pRequestBuf->ChannelCacheType = CHANNEL_LIST_DYNAMIC_UPDATE;
+          if (pMac->roam.configParam.nRoamIntraBand)
+              pRequestBuf->ChannelCacheType = CHANNEL_LIST_DYNAMIC_INIT;
+          else
+              pRequestBuf->ChannelCacheType = CHANNEL_LIST_DYNAMIC_UPDATE;
        }
      }
 #endif
@@ -17965,12 +18033,25 @@
         vos_mem_free(pRequestBuf);
         return eHAL_STATUS_FAILURE;
     }
+
+    if (pMac->roam.configParam.nRoamIntraBand)
+    {
+        Rfband = GetCurrentBand(operationChannel);
+        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "Current Band %d",
+                  Rfband);
+    }
+
     for(i=0; i<pMac->roam.numValidChannels; i++)
     {
-        if(*ChannelList && ((pMac->roam.configParam.allowDFSChannelRoam) ||
-            (!CSR_IS_CHANNEL_DFS(*ChannelList))))
+        if(((eCSR_BAND_24 == Rfband) && CSR_IS_CHANNEL_24GHZ(*ChannelList)) ||
+           ((eCSR_BAND_5G == Rfband) && CSR_IS_CHANNEL_5GHZ(*ChannelList)) ||
+            (eCSR_BAND_ALL == Rfband))
         {
-            pRequestBuf->ValidChannelList[num_channels++] = *ChannelList;
+           if(*ChannelList && ((pMac->roam.configParam.allowDFSChannelRoam) ||
+              (!CSR_IS_CHANNEL_DFS(*ChannelList))))
+           {
+               pRequestBuf->ValidChannelList[num_channels++] = *ChannelList;
+           }
         }
         ChannelList++;
     }
diff --git a/CORE/SME/src/csr/csrNeighborRoam.c b/CORE/SME/src/csr/csrNeighborRoam.c
index c9d6d42..72aec69 100644
--- a/CORE/SME/src/csr/csrNeighborRoam.c
+++ b/CORE/SME/src/csr/csrNeighborRoam.c
@@ -1253,6 +1253,17 @@
            goto abort_preauth;
         }
 
+        if (pMac->roam.pending_roam_disable)
+        {
+            smsLog(pMac, LOG1, FL("process pending roam disable"));
+            pMac->roam.configParam.isFastRoamIniFeatureEnabled = FALSE;
+            pMac->roam.pending_roam_disable = FALSE;
+            csrNeighborRoamUpdateFastRoamingEnabled(pMac, FALSE);
+            CSR_NEIGHBOR_ROAM_STATE_TRANSITION(
+                                   eCSR_NEIGHBOR_ROAM_STATE_CONNECTED);
+            goto DEQ_PREAUTH;
+        }
+
         /* Issue preauth request for the same/next entry */
         if (eHAL_STATUS_SUCCESS == csrNeighborRoamIssuePreauthReq(pMac))
         goto DEQ_PREAUTH; 
@@ -4691,6 +4702,13 @@
                             
 #endif
 
+            if (pMac->roam.pending_roam_disable)
+            {
+                smsLog(pMac, LOG1, FL("process pending roam disable"));
+                pMac->roam.configParam.isFastRoamIniFeatureEnabled = FALSE;
+                pMac->roam.pending_roam_disable = FALSE;
+            }
+
 #ifdef FEATURE_WLAN_LFR
             // If "Legacy Fast Roaming" is enabled 
             if (csrRoamIsFastRoamEnabled(pMac, sessionId))
diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c
index 9f836d3..91fd687 100644
--- a/CORE/SME/src/sme_common/sme_Api.c
+++ b/CORE/SME/src/sme_common/sme_Api.c
@@ -10425,6 +10425,16 @@
                       isFastRoamIniFeatureEnabled);
       return eHAL_STATUS_SUCCESS;
   }
+  if (smeNeighborMiddleOfRoaming(hHal))
+  {
+      VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
+                "%s: In middle of roaming isFastRoamIniFeatureEnabled %d",
+                __func__, isFastRoamIniFeatureEnabled);
+      if (!isFastRoamIniFeatureEnabled)
+          pMac->roam.pending_roam_disable = TRUE;
+
+      return eHAL_STATUS_SUCCESS;
+  }
 
   VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
                      "%s: FastRoamEnabled is changed from %d to %d", __func__,
diff --git a/CORE/VOSS/src/vos_api.c b/CORE/VOSS/src/vos_api.c
index 42e623e..8e048ba 100644
--- a/CORE/VOSS/src/vos_api.c
+++ b/CORE/VOSS/src/vos_api.c
@@ -1851,7 +1851,7 @@
         return VOS_STATUS_E_FAILURE;
     }
 
-    if(!pHddCtx->cfg_ini->enableFatalEvent)
+    if (!pHddCtx->cfg_ini->enableFatalEvent || !pHddCtx->is_fatal_event_log_sup)
     {
        VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
             "%s: Fatal event not enabled", __func__);