Merge 475bbc7207a52028bb464093c90bb04aab2f522c on remote branch

Change-Id: If5adb67e5c13002ab31db629076267583816a8c2
diff --git a/CORE/HDD/inc/wlan_hdd_cfg.h b/CORE/HDD/inc/wlan_hdd_cfg.h
index e62dbe9..7d63f0c 100644
--- a/CORE/HDD/inc/wlan_hdd_cfg.h
+++ b/CORE/HDD/inc/wlan_hdd_cfg.h
@@ -3271,6 +3271,29 @@
 #define CFG_ENABLE_DEFAULT_SAP           "gEnabledefaultSAP"
 #define CFG_ENABLE_DEFAULT_SAP_DEFAULT   ""
 
+/*
+ * <ini>
+ * sae_enabled - Enable/Disable SAE support in driver
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to enable/disable SAE support in driver
+ * Driver will update config to supplicant based on this config.
+ *
+ * Related: None
+ *
+ * Supported Feature: SAE
+ * Usage: External
+ *
+ * </ini>
+ */
+
+#define CFG_IS_SAE_ENABLED_NAME    "sae_enabled"
+#define CFG_IS_SAE_ENABLED_DEFAULT (1)
+#define CFG_IS_SAE_ENABLED_MIN     (0)
+#define CFG_IS_SAE_ENABLED_MAX     (1)
+
 /*--------------------------------------------------------------------------- 
   Type declarations
   -------------------------------------------------------------------------*/ 
@@ -3888,6 +3911,9 @@
    bool                        indoor_channel_support;
    bool                        force_rsne_override;
    char enabledefaultSAP[CFG_CONCURRENT_IFACE_MAX_LEN];
+#ifdef WLAN_FEATURE_SAE
+   bool                        is_sae_enabled;
+#endif
 } hdd_config_t;
 
 /*--------------------------------------------------------------------------- 
diff --git a/CORE/HDD/inc/wlan_hdd_cfg80211.h b/CORE/HDD/inc/wlan_hdd_cfg80211.h
index 9ef5a8c..0eec5af 100644
--- a/CORE/HDD/inc/wlan_hdd_cfg80211.h
+++ b/CORE/HDD/inc/wlan_hdd_cfg80211.h
@@ -143,6 +143,15 @@
 }__attribute__((packed)) qcom_ie_age ;
 #endif
 
+#ifndef WLAN_AKM_SUITE_SAE
+#define WLAN_AKM_SUITE_SAE 0x000FAC08
+#endif
+
+#ifndef WLAN_AKM_SUITE_OWE_1
+#define WLAN_AKM_SUITE_OWE_1 0x000FAC12
+#endif
+
+
 enum qca_nl80211_vendor_subcmds {
     QCA_NL80211_VENDOR_SUBCMD_UNSPEC = 0,
     QCA_NL80211_VENDOR_SUBCMD_TEST = 1,
diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h
index e8ab954..6ee9a85 100644
--- a/CORE/HDD/inc/wlan_hdd_main.h
+++ b/CORE/HDD/inc/wlan_hdd_main.h
@@ -863,6 +863,7 @@
     int bssState;
     vos_event_t vosEvent;
     VOS_STATUS vosStatus;
+    vos_event_t sta_discon_event;
     v_BOOL_t bCommit; 
 
 } hdd_hostapd_state_t;
diff --git a/CORE/HDD/inc/wlan_hdd_wext.h b/CORE/HDD/inc/wlan_hdd_wext.h
index 9e577bf..4d2ebb8 100644
--- a/CORE/HDD/inc/wlan_hdd_wext.h
+++ b/CORE/HDD/inc/wlan_hdd_wext.h
@@ -402,10 +402,6 @@
 extern int iw_get_auth(struct net_device *dev,struct iw_request_info *info,
                        union iwreq_data *wrqu,char *extra);
 
-VOS_STATUS iw_set_pno(struct net_device *dev, struct iw_request_info *info,
-                      union iwreq_data *wrqu, char *extra, int nOffset);
-
-
 VOS_STATUS iw_set_rssi_filter(struct net_device *dev, struct iw_request_info *info,
                               union iwreq_data *wrqu, char *extra, int nOffset);
 
diff --git a/CORE/HDD/src/wlan_hdd_assoc.c b/CORE/HDD/src/wlan_hdd_assoc.c
index 766e227..fa27193 100644
--- a/CORE/HDD/src/wlan_hdd_assoc.c
+++ b/CORE/HDD/src/wlan_hdd_assoc.c
@@ -152,6 +152,13 @@
 v_U8_t ccpRSNOui08[ HDD_RSN_OUI_SIZE ] = { 0x00, 0x0F, 0xAC, 0x05 };
 #endif
 
+#ifdef WLAN_FEATURE_SAE
+v_U8_t ccp_rsn_oui_80[HDD_RSN_OUI_SIZE] = {0x00, 0x0F, 0xAC, 0x08};
+v_U8_t ccp_rsn_oui_90[HDD_RSN_OUI_SIZE] = {0x00, 0x0F, 0xAC, 0x09};
+#endif
+/* OWE https://tools.ietf.org/html/rfc8110 */
+uint8_t ccp_rsn_oui_18[HDD_RSN_OUI_SIZE] = {0x00, 0x0F, 0xAC, 0x12};
+
 #if defined(WLAN_FEATURE_VOWIFI_11R)
 // Offset where the EID-Len-IE, start.
 #define FT_ASSOC_RSP_IES_OFFSET 6 /* Capability(2) + AID(2) + Status Code(2)*/
@@ -192,6 +199,53 @@
                                                 eRoamCmdStatus roamStatus,
                                                 eCsrRoamResult roamResult );
 
+#if defined(WLAN_FEATURE_SAE) && \
+	defined(CFG80211_EXTERNAL_AUTH_SUPPORT)
+/**
+ * wlan_hdd_sae_callback() - Sends SAE info to supplicant
+ * @adapter: pointer adapter context
+ * @roam_info: pointer to roam info
+ *
+ * This API is used to send required SAE info to trigger SAE in supplicant.
+ *
+ * Return: None
+ */
+static void wlan_hdd_sae_callback(hdd_adapter_t *adapter,
+                                  tCsrRoamInfo *roam_info)
+{
+   hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+   int flags;
+   struct sir_sae_info *sae_info = roam_info->sae_info;
+   struct cfg80211_external_auth_params params = {0};
+
+   if (wlan_hdd_validate_context(hdd_ctx))
+       return;
+   if (!sae_info) {
+       hddLog(LOGE, FL("SAE info in NULL"));
+       return;
+   }
+   flags = vos_get_gfp_flags();
+
+   params.key_mgmt_suite = 0x00;
+   params.key_mgmt_suite |= 0x0F << 8;
+   params.key_mgmt_suite |= 0xAC << 16;
+   params.key_mgmt_suite |= 0x8 << 24;
+
+   params.action = NL80211_EXTERNAL_AUTH_START;
+   vos_mem_copy(params.bssid, sae_info->peer_mac_addr.bytes,
+                VOS_MAC_ADDR_SIZE);
+   vos_mem_copy(params.ssid.ssid, sae_info->ssid.ssId, sae_info->ssid.length);
+   params.ssid.ssid_len = sae_info->ssid.length;
+
+   cfg80211_external_auth_request(adapter->dev, &params, flags);
+   hddLog(LOG1, FL("SAE: sent cmd"));
+}
+#else
+static void wlan_hdd_sae_callback(hdd_adapter_t *adapter,
+                                  tCsrRoamInfo *roam_info)
+{ }
+#endif
+
 v_VOID_t hdd_connSetConnectionState( hdd_station_ctx_t *pHddStaCtx,
                                         eConnectionState connState )
 {
@@ -2427,55 +2481,61 @@
                 }
                 return eHAL_STATUS_FAILURE;
             }
+
+            //Association Response
+            pFTAssocRsp = (u8 *)(pRoamInfo->pbFrames +
+                                 pRoamInfo->nBeaconLength +
+                                 pRoamInfo->nAssocReqLength);
+            if (pFTAssocRsp != NULL)
+            {
+                // pFTAssocRsp needs to point to the IEs
+                pFTAssocRsp += FT_ASSOC_RSP_IES_OFFSET;
+                hddLog(LOG1, "%s: AssocRsp is now at %02x%02x", __func__,
+                       (unsigned int)pFTAssocRsp[0],
+                       (unsigned int)pFTAssocRsp[1]);
+                assocRsplen =
+                         pRoamInfo->nAssocRspLength - FT_ASSOC_RSP_IES_OFFSET;
+            }
+            else
+            {
+                hddLog(LOGE, "%s:AssocRsp is NULL", __func__);
+                assocRsplen = 0;
+            }
+
+            //Association Request
+            pFTAssocReq = (u8 *)(pRoamInfo->pbFrames +
+                                 pRoamInfo->nBeaconLength);
+            if (pFTAssocReq != NULL)
+            {
+                 if(!ft_carrier_on)
+                 {
+                    // pFTAssocReq needs to point to the IEs
+                    pFTAssocReq += FT_ASSOC_REQ_IES_OFFSET;
+                    hddLog(LOG1, "%s: pFTAssocReq is now at %02x%02x", __func__,
+                           (unsigned int)pFTAssocReq[0],
+                           (unsigned int)pFTAssocReq[1]);
+                     assocReqlen =
+                          pRoamInfo->nAssocReqLength - FT_ASSOC_REQ_IES_OFFSET;
+                 }
+                 else
+                 {
+                     /* This should contain only the FTIEs */
+                     assocReqlen = pRoamInfo->nAssocReqLength;
+                 }
+            }
+            else
+            {
+                hddLog(LOGE, "%s:AssocReq is NULL", __func__);
+                assocReqlen = 0;
+            }
+
+            hddLog(LOG1, "assocReqlen %d assocRsplen %d", assocReqlen,
+                   assocRsplen);
+
 #ifdef WLAN_FEATURE_VOWIFI_11R
             if(pRoamInfo->u.pConnectedProfile->AuthType == eCSR_AUTH_TYPE_FT_RSN ||
                 pRoamInfo->u.pConnectedProfile->AuthType == eCSR_AUTH_TYPE_FT_RSN_PSK )
             {
-
-                //Association Response
-                pFTAssocRsp = (u8 *)(pRoamInfo->pbFrames + pRoamInfo->nBeaconLength +
-                                    pRoamInfo->nAssocReqLength);
-                if (pFTAssocRsp != NULL)
-                {
-                    // pFTAssocRsp needs to point to the IEs
-                    pFTAssocRsp += FT_ASSOC_RSP_IES_OFFSET;
-                    hddLog(LOG1, "%s: AssocRsp is now at %02x%02x", __func__,
-                                        (unsigned int)pFTAssocRsp[0],
-                                        (unsigned int)pFTAssocRsp[1]);
-                    assocRsplen = pRoamInfo->nAssocRspLength - FT_ASSOC_RSP_IES_OFFSET;
-                }
-                else
-                {
-                    hddLog(LOGE, "%s:AssocRsp is NULL", __func__);
-                    assocRsplen = 0;
-                }
-
-                //Association Request
-                pFTAssocReq = (u8 *)(pRoamInfo->pbFrames +
-                                     pRoamInfo->nBeaconLength);
-                if (pFTAssocReq != NULL)
-                {
-                    if(!ft_carrier_on)
-                    {
-                         // pFTAssocReq needs to point to the IEs
-                        pFTAssocReq += FT_ASSOC_REQ_IES_OFFSET;
-                        hddLog(LOG1, "%s: pFTAssocReq is now at %02x%02x", __func__,
-                                              (unsigned int)pFTAssocReq[0],
-                                              (unsigned int)pFTAssocReq[1]);
-                        assocReqlen = pRoamInfo->nAssocReqLength - FT_ASSOC_REQ_IES_OFFSET;
-                    }
-                    else
-                    {
-                        /* This should contain only the FTIEs */
-                        assocReqlen = pRoamInfo->nAssocReqLength;
-                    }
-                }
-                else
-                {
-                    hddLog(LOGE, "%s:AssocReq is NULL", __func__);
-                    assocReqlen = 0;
-                }
-
                 if(ft_carrier_on)
                 {
                     if ( !hddDisconInProgress )
@@ -2486,8 +2546,6 @@
                                  "indication", __FUNCTION__, ft_carrier_on);
                         chan = ieee80211_get_channel(pAdapter->wdev.wiphy,
                                          (int)pRoamInfo->pBssDesc->channelId);
-                        hddLog(LOG1, "assocReqlen %d assocRsplen %d", assocReqlen,
-                                         assocRsplen);
                         if (pHddCtx->cfg_ini &&
                             pHddCtx->cfg_ini->gEnableRoamDelayStats)
                         {
@@ -2566,8 +2624,8 @@
                          /* inform connect result to nl80211 */
                          hdd_connect_result(dev, pRoamInfo->bssid,
                                 pRoamInfo,
-                                reqRsnIe, reqRsnLength,
-                                rspRsnIe, rspRsnLength,
+                                pFTAssocReq, assocReqlen,
+                                pFTAssocRsp, assocRsplen,
                                 WLAN_STATUS_SUCCESS,
                                 GFP_KERNEL);
                     }
@@ -4328,6 +4386,12 @@
               else
                   hddLog(LOG1, FL("UPDATE_SCAN_RESULT returned NULL"));
          }
+
+       case eCSR_ROAM_SAE_COMPUTE:
+         if (pRoamInfo)
+             wlan_hdd_sae_callback(pAdapter, pRoamInfo);
+         break;
+
        case eCSR_ROAM_STA_CHANNEL_SWITCH:
          {
              hdd_adapter_t *pHostapdAdapter = NULL;
@@ -4374,9 +4438,32 @@
     }
     return( halStatus );
 }
+
+#ifdef WLAN_FEATURE_SAE
+/**
+ * hdd_translate_sae_rsn_to_csr_auth() - Translate SAE RSN to CSR auth type
+ * @auth_suite: auth suite
+ * @auth_type: pointer to eCsrAuthType
+ *
+ * Return: None
+ */
+static void hdd_translate_sae_rsn_to_csr_auth(int8_t auth_suite[4],
+                                              eCsrAuthType *auth_type)
+{
+        if (!memcmp(auth_suite, ccp_rsn_oui_80, 4))
+                *auth_type = eCSR_AUTH_TYPE_SAE;
+}
+#else
+static inline
+void hdd_translate_sae_rsn_to_csr_auth(int8_t auth_suite[4],
+                                       eCsrAuthType *auth_type)
+{
+}
+#endif
+
 eCsrAuthType hdd_TranslateRSNToCsrAuthType( u_int8_t auth_suite[4])
 {
-    eCsrAuthType auth_type;
+    eCsrAuthType auth_type = eCSR_AUTH_TYPE_UNKNOWN;
     // is the auth type supported?
     if ( memcmp(auth_suite , ccpRSNOui01, 4) == 0)
     {
@@ -4414,9 +4501,20 @@
         auth_type = eCSR_AUTH_TYPE_RSN_8021X_SHA256;
     } else
 #endif
+    if (!memcmp(auth_suite, ccp_rsn_oui_18, 4))
     {
-        auth_type = eCSR_AUTH_TYPE_UNKNOWN;
-    }
+       auth_type = eCSR_AUTH_TYPE_OWE;
+    } else
+
+    {
+    /* If auth suite is of SAE, auth_type will be
+     * overwritten in hdd_translate_sae_rsn_to_csr_auth
+     */
+     hdd_translate_sae_rsn_to_csr_auth(auth_suite, &auth_type);
+     }
+
+    hddLog(LOG1, FL("auth_type : %d"), auth_type);
+
     return auth_type;
 }
 
@@ -4820,7 +4918,10 @@
     ENTER();
 
     pRoamProfile->AuthType.numEntries = 1;
-    hddLog( LOG1, "%s: pHddStaCtx->conn_info.authType = %d", __func__, pHddStaCtx->conn_info.authType);
+    hddLog( LOG1,
+           "%s: authType = %d RSNAuthType %d wpa_versions %d key_mgmt : 0x%x",
+           __func__, pHddStaCtx->conn_info.authType, RSNAuthType,
+           pWextState->wpaVersion, pWextState->authKeyMgmt);
 
     switch( pHddStaCtx->conn_info.authType)
     {
@@ -4895,7 +4996,22 @@
                                             eCSR_AUTH_TYPE_RSN_8021X_SHA256;
             } else
 #endif
-
+            if ((RSNAuthType == eCSR_AUTH_TYPE_SAE) &&
+                ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
+                 == IW_AUTH_KEY_MGMT_802_1X)) {
+                 /* SAE case */
+                 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_SAE;
+            } else
+            if ((RSNAuthType == eCSR_AUTH_TYPE_OWE) &&
+                ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
+                 == IW_AUTH_KEY_MGMT_802_1X)) {
+                /* OWE case */
+                pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_OWE;
+            } else
+            if (RSNAuthType == eCSR_AUTH_TYPE_SAE) {
+               /* SAE with open authentication case */
+               pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_SAE;
+            } else
             if( (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
                     == IW_AUTH_KEY_MGMT_802_1X) {
                pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_RSN;
@@ -4903,7 +5019,8 @@
             if ( (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_PSK)
                     == IW_AUTH_KEY_MGMT_PSK) {
                pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_RSN_PSK;
-            } else {
+            } else
+            {
                pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_UNKNOWN;
             }
         }
@@ -4913,6 +5030,10 @@
 
           pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_SHARED_KEY;
           break;
+       case eCSR_AUTH_TYPE_SAE:
+          pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_SAE;
+          break;
+
         default:
 
 #ifdef FEATURE_WLAN_ESE
diff --git a/CORE/HDD/src/wlan_hdd_cfg.c b/CORE/HDD/src/wlan_hdd_cfg.c
index 050d9b8..c6581af 100644
--- a/CORE/HDD/src/wlan_hdd_cfg.c
+++ b/CORE/HDD/src/wlan_hdd_cfg.c
@@ -4040,6 +4040,14 @@
                       VAR_FLAGS_NONE,
                       (void *)CFG_ENABLE_DEFAULT_SAP_DEFAULT),
 
+#ifdef WLAN_FEATURE_SAE
+  REG_VARIABLE(CFG_IS_SAE_ENABLED_NAME, WLAN_PARAM_Integer,
+               hdd_config_t, is_sae_enabled,
+               VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+               CFG_IS_SAE_ENABLED_DEFAULT,
+               CFG_IS_SAE_ENABLED_MIN,
+               CFG_IS_SAE_ENABLED_MAX),
+#endif
 };
 
 /*
@@ -4256,6 +4264,17 @@
    return vos_status;
 }
 
+#ifdef WLAN_FEATURE_SAE
+static void hdd_cfg_print_sae(hdd_context_t *hdd_ctx)
+{
+   hddLog(LOG2, "Name = [%s] value = [%u]", CFG_IS_SAE_ENABLED_NAME,
+          hdd_ctx->cfg_ini->is_sae_enabled);
+}
+#else
+static void hdd_cfg_print_sae(hdd_context_t *hdd_ctx)
+{
+}
+#endif
 
 static void print_hdd_cfg(hdd_context_t *pHddCtx)
 {
@@ -4717,6 +4736,7 @@
             "Name = [%s] Value = [%s] ",
             CFG_ENABLE_DEFAULT_SAP,
             pHddCtx->cfg_ini->enabledefaultSAP);
+    hdd_cfg_print_sae(pHddCtx);
 }
 
 
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index 166217e..513add9 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -347,6 +347,7 @@
     [NL80211_IFTYPE_STATION] = {
         .tx = 0xffff,
         .rx = BIT(SIR_MAC_MGMT_ACTION) |
+            BIT(SIR_MAC_MGMT_AUTH) |
             BIT(SIR_MAC_MGMT_PROBE_REQ),
     },
     [NL80211_IFTYPE_AP] = {
@@ -1682,7 +1683,8 @@
 			  MAC_ADDR_ARRAY(mac_addr.bytes));
 		return -EINVAL;
 	}
-	if (sap_ctx->aStaInfo[stainfo->ucSTAId].isUsed == TRUE) {
+	if (sap_ctx->aStaInfo[stainfo->ucSTAId].isUsed == TRUE &&
+		!sap_ctx->aStaInfo[stainfo->ucSTAId].isDeauthInProgress) {
 		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
 			  "peer " MAC_ADDRESS_STR " is in connected state",
 			  MAC_ADDR_ARRAY(mac_addr.bytes));
@@ -9139,6 +9141,32 @@
 }
 #endif
 
+#if defined(WLAN_FEATURE_SAE) && \
+        defined(CFG80211_EXTERNAL_AUTH_SUPPORT)
+/**
+ * wlan_hdd_cfg80211_set_wiphy_sae_feature() - Indicates support of SAE feature
+ * @wiphy: Pointer to wiphy
+ * @config: pointer to config
+ *
+ * This function is used to indicate the support of SAE
+ *
+ * Return: None
+ */
+static
+void wlan_hdd_cfg80211_set_wiphy_sae_feature(struct wiphy *wiphy,
+                                             hdd_config_t *config)
+{
+    if (config->is_sae_enabled)
+             wiphy->features |= NL80211_FEATURE_SAE;
+}
+#else
+static
+void wlan_hdd_cfg80211_set_wiphy_sae_feature(struct wiphy *wiphy,
+                                             hdd_config_t *config)
+{
+}
+#endif
+
 /*
  * FUNCTION: wlan_hdd_cfg80211_init
  * This function is called by hdd_wlan_startup()
@@ -9378,6 +9406,7 @@
     wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
 
     hdd_config_sched_scan_plans_to_wiphy(wiphy, pCfg);
+    wlan_hdd_cfg80211_set_wiphy_sae_feature(wiphy, pCfg);
 
     EXIT();
     return 0;
@@ -16296,7 +16325,10 @@
             pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
             break;
 #endif
-
+        case NL80211_AUTHTYPE_SAE:
+             hddLog(LOG1, "set authentication type to SAE");
+             pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SAE;
+             break;
 
         default:
             hddLog(VOS_TRACE_LEVEL_ERROR,
@@ -16368,9 +16400,18 @@
             pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
             break;
 #endif
+        case WLAN_AKM_SUITE_SAE:
+             hddLog(LOG1, "setting key mgmt type to SAE");
+             pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
+             break;
+
+        case WLAN_AKM_SUITE_OWE_1:
+             hddLog(LOG1, "setting key mgmt type to OWE");
+             pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
+             break;
 
         default:
-            hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
+            hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %x",
                     __func__, key_mgmt);
             return -EINVAL;
 
@@ -16844,6 +16885,32 @@
                 }
                 break;
 #endif
+            case SIR_MAC_REQUEST_EID_MAX:
+                 if (genie[0] == SIR_DH_PARAMETER_ELEMENT_EXT_EID)
+                 {
+                    v_U16_t curAddIELen = pWextState->assocAddIE.length;
+                    if (SIR_MAC_MAX_ADD_IE_LENGTH <
+                        (pWextState->assocAddIE.length + eLen))
+                    {
+                       hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
+                              "Need bigger buffer space");
+                       VOS_ASSERT(0);
+                       return -ENOMEM;
+                    }
+                 hddLog(VOS_TRACE_LEVEL_INFO, "Set DH EXT IE(len %d)",
+                        eLen + 2);
+                 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen,
+                         genie - 2, eLen + 2);
+                 pWextState->assocAddIE.length += eLen + 2;
+                 pWextState->roamProfile.pAddIEAssoc =
+                                            pWextState->assocAddIE.addIEdata;
+                 pWextState->roamProfile.nAddIEAssocLength =
+                                            pWextState->assocAddIE.length;
+                }else {
+                hddLog(VOS_TRACE_LEVEL_FATAL, "UNKNOWN EID: %X", genie[0]);
+                }
+                break;
+
             default:
                 hddLog (VOS_TRACE_LEVEL_ERROR,
                         "%s Set UNKNOWN IE %X", __func__, elementId);
@@ -18360,7 +18427,6 @@
 {
     hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
     hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
-    int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
     tANI_U32 rate_flags;
 
     hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
@@ -18399,11 +18465,9 @@
     if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
         return wlan_hdd_get_sap_stats(pAdapter, mac, sinfo);
 
-    if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
-            (0 == ssidlen))
+    if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState))
     {
-        hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
-                    " Invalid ssidlen, %d", __func__, ssidlen);
+        hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated", __func__);
         /*To keep GUI happy*/
         return 0;
     }
@@ -19043,6 +19107,7 @@
     v_U8_t staId;
     v_CONTEXT_t pVosContext = NULL;
     ptSapContext pSapCtx = NULL;
+    hdd_hostapd_state_t *hostap_state;
 
     ENTER();
 
@@ -19067,6 +19132,7 @@
        || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
        )
     {
+        hostap_state =  WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
         pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
         pSapCtx = VOS_GET_SAP_CB(pVosContext);
         if(pSapCtx == NULL){
@@ -19097,9 +19163,19 @@
                             MAC_ADDRESS_STR,
                             __func__,
                             MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
+                    vos_event_reset(&hostap_state->sta_discon_event);
                     vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
                     if (VOS_IS_STATUS_SUCCESS(vos_status))
+                    {
                         pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
+                        vos_status =
+                            vos_wait_single_event(
+                                    &hostap_state->sta_discon_event,
+                                    WLAN_WAIT_TIME_DISCONNECT);
+                         if (!VOS_IS_STATUS_SUCCESS(vos_status))
+                                 hddLog(LOGE,"!!%s: ERROR: Deauth wait expired!!",
+                                        __func__);
+                    }
                 }
             }
         }
@@ -19134,6 +19210,7 @@
                                 __func__,
                                 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
 
+            vos_event_reset(&hostap_state->sta_discon_event);
             vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
             if (!VOS_IS_STATUS_SUCCESS(vos_status))
             {
@@ -19145,7 +19222,11 @@
                                 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
                 return -ENOENT;
             }
-
+            vos_status =
+                 vos_wait_single_event(&hostap_state->sta_discon_event,
+                                       WLAN_WAIT_TIME_DISCONNECT);
+            if (!VOS_IS_STATUS_SUCCESS(vos_status))
+                hddLog(LOGE,"!!%s: ERROR: Deauth wait expired!!", __func__);
         }
     }
 
@@ -19263,6 +19344,92 @@
 
     return ret;
 }
+
+#if defined(WLAN_FEATURE_SAE) && \
+		defined(CFG80211_EXTERNAL_AUTH_SUPPORT)
+/*
+ * wlan_hdd_is_pmksa_valid: API to validate pmksa
+ * @pmksa: pointer to cfg80211_pmksa structure
+ *
+ * Return: True if valid else false
+ */
+static inline bool wlan_hdd_is_pmksa_valid(struct cfg80211_pmksa *pmksa)
+{
+    if (pmksa->bssid){
+        return true;
+    }
+    else
+    {
+        hddLog(LOGE, FL(" Either of  bssid (%p) is NULL"), pmksa->bssid);
+        return false;
+    }
+}
+
+/*
+ * hdd_update_pmksa_info: API to update tPmkidCacheInfo from cfg80211_pmksa
+ * @pmk_cache: pmksa from supplicant
+ * @pmk_cache: pmk needs to be updated
+ *
+ * Return: None
+ */
+static void hdd_update_pmksa_info(tPmkidCacheInfo *pmk_cache,
+        struct cfg80211_pmksa *pmksa, bool is_delete)
+{
+    if (pmksa->bssid) {
+        hddLog(VOS_TRACE_LEVEL_DEBUG,"set PMKSA for " MAC_ADDRESS_STR,
+                MAC_ADDR_ARRAY(pmksa->bssid));
+        vos_mem_copy(pmk_cache->BSSID,
+               pmksa->bssid, VOS_MAC_ADDR_SIZE);
+    }
+
+    if (is_delete)
+        return;
+
+    vos_mem_copy(pmk_cache->PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
+    if (pmksa->pmk_len && (pmksa->pmk_len <= CSR_RSN_MAX_PMK_LEN)) {
+        vos_mem_copy(pmk_cache->pmk, pmksa->pmk, pmksa->pmk_len);
+        pmk_cache->pmk_len = pmksa->pmk_len;
+    } else
+        hddLog(VOS_TRACE_LEVEL_INFO, "pmk len is %zu", pmksa->pmk_len);
+}
+#else
+/*
+ * wlan_hdd_is_pmksa_valid: API to validate pmksa
+ * @pmksa: pointer to cfg80211_pmksa structure
+ *
+ * Return: True if valid else false
+ */
+static inline bool wlan_hdd_is_pmksa_valid(struct cfg80211_pmksa *pmksa)
+{
+    if (!pmksa->bssid) {
+        hddLog(LOGE,FL("both bssid is NULL %p"), pmksa->bssid);
+        return false;
+    }
+    return true;
+}
+
+/*
+ * hdd_update_pmksa_info: API to update tPmkidCacheInfo from cfg80211_pmksa
+ * @pmk_cache: pmksa from supplicant
+ * @pmk_cache: pmk needs to be updated
+ *
+ * Return: None
+ */
+static void hdd_update_pmksa_info(tPmkidCacheInfo *pmk_cache,
+        struct cfg80211_pmksa *pmksa, bool is_delete)
+{
+    hddLog(VOS_TRACE_LEVEL_INFO,"set PMKSA for " MAC_ADDRESS_STR,
+            MAC_ADDR_ARRAY(pmksa->bssid));
+    vos_mem_copy(pmk_cache->BSSID,
+            pmksa->bssid, VOS_MAC_ADDR_SIZE);
+
+    if (is_delete)
+        return;
+
+    vos_mem_copy(pmk_cache->PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
+}
+#endif
+
 #ifdef FEATURE_WLAN_LFR
 
 static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
@@ -19273,7 +19440,7 @@
     eHalStatus result;
     int status;
     hdd_context_t *pHddCtx;
-    tPmkidCacheInfo pmk_id;
+    tPmkidCacheInfo pmk_cache;
 
     ENTER();
 
@@ -19289,14 +19456,13 @@
         return -EINVAL;
     }
 
-    if (!pmksa->bssid || !pmksa->pmkid) {
-       hddLog(LOGE, FL("pmksa->bssid(%pK) or pmksa->pmkid(%pK) is NULL"),
-              pmksa->bssid, pmksa->pmkid);
+    if (!pmksa->pmkid) {
+       hddLog(LOGE, FL("pmksa->pmkid(%p) is NULL"), pmksa->pmkid);
        return -EINVAL;
     }
 
-    hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
-           __func__, MAC_ADDR_ARRAY(pmksa->bssid));
+    if (!wlan_hdd_is_pmksa_valid(pmksa))
+        return -EINVAL;
 
     pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
     status = wlan_hdd_validate_context(pHddCtx);
@@ -19308,12 +19474,19 @@
     // Retrieve halHandle
     halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
 
-    vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
-    vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
+    vos_mem_zero(&pmk_cache, sizeof(pmk_cache));
 
-    /* Add to the PMKSA ID Cache in CSR */
-    result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
-                                   &pmk_id, 1, FALSE);
+    hdd_update_pmksa_info(&pmk_cache, pmksa, false);
+
+
+    /* Add to the PMKSA ID Cache in CSR
+     * PMKSA cache will be having following
+     * 1. pmkid id
+     * 2. pmk 15733
+     * 3. bssid or cache identifier
+     */
+     result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
+                                   &pmk_cache, 1, FALSE);
 
     MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                      TRACE_CODE_HDD_CFG80211_SET_PMKSA,
@@ -19343,6 +19516,7 @@
     tHalHandle halHandle;
     hdd_context_t *pHddCtx;
     int status = 0;
+    tPmkidCacheInfo pmk_cache;
 
     ENTER();
 
@@ -19358,13 +19532,9 @@
         return -EINVAL;
     }
 
-    if (!pmksa->bssid) {
-       hddLog(LOGE, FL("pmksa->bssid is NULL"));
-       return -EINVAL;
-    }
+    if (!wlan_hdd_is_pmksa_valid(pmksa))
+        return -EINVAL;
 
-    hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
-           __func__, MAC_ADDR_ARRAY(pmksa->bssid));
 
     pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
     status = wlan_hdd_validate_context(pHddCtx);
@@ -19379,10 +19549,15 @@
     MTRACE(vos_trace(VOS_MODULE_ID_HDD,
                      TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
                      pAdapter->sessionId, 0));
+
+     vos_mem_zero(&pmk_cache, sizeof(pmk_cache));
+
+     hdd_update_pmksa_info(&pmk_cache, pmksa, true);
+
     /* Delete the PMKID CSR cache */
     if (eHAL_STATUS_SUCCESS !=
         sme_RoamDelPMKIDfromCache(halHandle,
-                                  pAdapter->sessionId, pmksa->bssid, FALSE)) {
+                                  pAdapter->sessionId, &pmk_cache, FALSE)) {
         hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
                      MAC_ADDR_ARRAY(pmksa->bssid));
         status = -EINVAL;
@@ -19455,6 +19630,64 @@
 }
 #endif
 
+#if defined(WLAN_FEATURE_SAE) && \
+         defined(CFG80211_EXTERNAL_AUTH_SUPPORT)
+/**
+ * __wlan_hdd_cfg80211_external_auth() - Handle external auth
+ * @wiphy: Pointer to wireless phy
+ * @dev: net device
+ * @params: Pointer to external auth params
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+static int
+__wlan_hdd_cfg80211_external_auth(struct wiphy *wiphy, struct net_device *dev,
+                                  struct cfg80211_external_auth_params *params)
+{
+   hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
+   hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+   int ret;
+
+   if (hdd_get_conparam() == VOS_FTM_MODE) {
+       hddLog(VOS_TRACE_LEVEL_ERROR, FL("Command not allowed in FTM mode"));
+       return -EPERM;
+   }
+
+   ret = wlan_hdd_validate_context(hdd_ctx);
+   if (ret)
+       return ret;
+
+   hddLog(VOS_TRACE_LEVEL_DEBUG, FL("external_auth status: %d"),
+          params->status);
+
+   sme_handle_sae_msg(hdd_ctx->hHal, adapter->sessionId, params->status);
+
+   return ret;
+}
+
+/**
+ * wlan_hdd_cfg80211_external_auth() - Handle external auth
+ * @wiphy: Pointer to wireless phy
+ * @dev: net device
+ * @params: Pointer to external auth params
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+static int
+wlan_hdd_cfg80211_external_auth(struct wiphy *wiphy,
+                                struct net_device *dev,
+                                struct cfg80211_external_auth_params *params)
+{
+   int ret;
+
+   vos_ssr_protect(__func__);
+   ret = __wlan_hdd_cfg80211_external_auth(wiphy, dev, params);
+   vos_ssr_unprotect(__func__);
+
+   return ret;
+}
+#endif
+
 #if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
 static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
                                              struct net_device *dev,
@@ -22496,5 +22729,9 @@
 	.channel_switch = wlan_hdd_cfg80211_channel_switch,
 #endif
 
+#if defined(WLAN_FEATURE_SAE) && \
+      defined(CFG80211_EXTERNAL_AUTH_SUPPORT)
+      .external_auth = wlan_hdd_cfg80211_external_auth,
+#endif
 };
 
diff --git a/CORE/HDD/src/wlan_hdd_early_suspend.c b/CORE/HDD/src/wlan_hdd_early_suspend.c
index f8f0da2..e68aa7a 100644
--- a/CORE/HDD/src/wlan_hdd_early_suspend.c
+++ b/CORE/HDD/src/wlan_hdd_early_suspend.c
@@ -1677,6 +1677,7 @@
            pAdapterNode = pNext;
            continue;
        }
+       dev_hold(pAdapter->dev);
        /* Avoid multiple enter/exit BMPS in this while loop using
         * hdd_enter_bmps flag
         */
@@ -1721,6 +1722,7 @@
                  __func__, ret);
        }
        status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
+       dev_put(pAdapter->dev);
        pAdapterNode = pNext;
    }
 
diff --git a/CORE/HDD/src/wlan_hdd_hostapd.c b/CORE/HDD/src/wlan_hdd_hostapd.c
index 32a7ed7..29daf50 100644
--- a/CORE/HDD/src/wlan_hdd_hostapd.c
+++ b/CORE/HDD/src/wlan_hdd_hostapd.c
@@ -1497,6 +1497,8 @@
             memcpy(wrqu.addr.sa_data, &pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac,
                    sizeof(v_MACADDR_t));
             hddLog(LOG1, " disassociated "MAC_ADDRESS_STR, MAC_ADDR_ARRAY(wrqu.addr.sa_data));
+
+            vos_status = vos_event_set(&pHostapdState->sta_discon_event);
             if (pSapEvent->sapevt.sapStationDisassocCompleteEvent.reason == eSAP_USR_INITATED_DISASSOC)
                 hddLog(LOG1," User initiated disassociation");
             else
@@ -5536,6 +5538,12 @@
          VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: Hostapd HDD vos event init failed!!"));
          return status;
     }
+    status = vos_event_init(&phostapdBuf->sta_discon_event);
+    if (!VOS_IS_STATUS_SUCCESS(status))
+    {
+        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "ERROR: Hostapd HDD sta disassoc event init failed!!");
+        return status;
+    }
 #ifdef DHCP_SERVER_OFFLOAD
     status = vos_event_init(&dhcp_status->vos_event);
     if (!VOS_IS_STATUS_SUCCESS(status)) {
diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c
index 776c208..517f3bc 100644
--- a/CORE/HDD/src/wlan_hdd_main.c
+++ b/CORE/HDD/src/wlan_hdd_main.c
@@ -307,7 +307,12 @@
                                          unsigned long state,
                                          void *ndev)
 {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
+   struct netdev_notifier_info *info = ndev;
+   struct net_device *dev = info->dev;
+#else
    struct net_device *dev = ndev;
+#endif
    hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_context_t *pHddCtx;
 #ifdef WLAN_BTAMP_FEATURE
diff --git a/CORE/HDD/src/wlan_hdd_p2p.c b/CORE/HDD/src/wlan_hdd_p2p.c
index dfb9083..3b1b38f 100644
--- a/CORE/HDD/src/wlan_hdd_p2p.c
+++ b/CORE/HDD/src/wlan_hdd_p2p.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -1289,6 +1289,7 @@
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
     uint8_t home_ch = 0;
 #endif
+    eHalStatus hal_status;
 
     ENTER();
 
@@ -1313,6 +1314,18 @@
     hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d type: %d",
                             __func__, pAdapter->device_mode, type);
 
+    /* When frame to be transmitted is auth mgmt, then trigger
+     * sme_send_mgmt_tx to send auth frame.
+     */
+    if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
+        (type == SIR_MAC_MGMT_FRAME && subType == SIR_MAC_MGMT_AUTH)) {
+         hal_status = sme_send_mgmt_tx(WLAN_HDD_GET_HAL_CTX(pAdapter),
+                                       pAdapter->sessionId, buf, len);
+         if (HAL_STATUS_SUCCESS(hal_status))
+              return 0;
+         else
+              return -EINVAL;
+    }
 
     if ((type == SIR_MAC_MGMT_FRAME) &&
             (subType == SIR_MAC_MGMT_ACTION) &&
@@ -2547,6 +2560,7 @@
 {
 	wlan_hdd_release_intf_addr(hdd_ctx, adapter->macAddressCurrent.bytes);
 	hdd_stop_adapter(hdd_ctx, adapter, VOS_TRUE);
+	hdd_deinit_adapter(hdd_ctx, adapter, TRUE);
 	hdd_close_adapter(hdd_ctx, adapter, rtnl_held);
 }
 
@@ -2762,6 +2776,7 @@
     /* Get pAdapter from Destination mac address of the frame */
     if ((type == SIR_MAC_MGMT_FRAME) &&
         (subType != SIR_MAC_MGMT_PROBE_REQ) &&
+        (nFrameLength > WLAN_HDD_80211_FRM_DA_OFFSET + VOS_MAC_ADDR_SIZE) &&
         !vos_is_macaddr_broadcast(
          (v_MACADDR_t *)&pbFrames[WLAN_HDD_80211_FRM_DA_OFFSET]))
     {
@@ -2832,12 +2847,16 @@
     cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
 
     if ((type == SIR_MAC_MGMT_FRAME) &&
-        (subType == SIR_MAC_MGMT_ACTION))
+        (subType == SIR_MAC_MGMT_ACTION) &&
+        (nFrameLength > WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET + 1))
     {
         if(pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET] == WLAN_HDD_PUBLIC_ACTION_FRAME)
         {
             // public action frame
-            if((pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET+1] == SIR_MAC_ACTION_VENDOR_SPECIFIC) &&
+            if((WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET + SIR_MAC_P2P_OUI_SIZE + 2 <
+                nFrameLength) &&
+               (pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET+1] ==
+                SIR_MAC_ACTION_VENDOR_SPECIFIC) &&
                 vos_mem_compare(&pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET+2], SIR_MAC_P2P_OUI, SIR_MAC_P2P_OUI_SIZE))
             // P2P action frames
             {
diff --git a/CORE/HDD/src/wlan_hdd_wext.c b/CORE/HDD/src/wlan_hdd_wext.c
index a8f6818..5d8582f 100644
--- a/CORE/HDD/src/wlan_hdd_wext.c
+++ b/CORE/HDD/src/wlan_hdd_wext.c
@@ -4137,13 +4137,6 @@
         hddLog( VOS_TRACE_LEVEL_INFO, "pnoforce");
         /*TODO: support pnoforce*/
     }
-    else if( strncasecmp(cmd, "pno",3) == 0 ) {
-
-        hddLog( VOS_TRACE_LEVEL_INFO, "pno");
-        vos_status = iw_set_pno(dev, info, wrqu, cmd, 3);
-        kfree(cmd);
-        return (vos_status == VOS_STATUS_SUCCESS) ? 0 : -EINVAL;
-    }
     else if( strncasecmp(cmd, "rssifilter",10) == 0 ) {
         hddLog( VOS_TRACE_LEVEL_INFO, "rssifilter");
         vos_status = iw_set_rssi_filter(dev, info, wrqu, cmd, 10);
@@ -9738,426 +9731,6 @@
    return ret;
 }
 #ifdef FEATURE_WLAN_SCAN_PNO
-
-/*Max Len for PNO notification*/
-#define MAX_PNO_NOTIFY_LEN 100
-void found_pref_network_cb (void *callbackContext,
-                              tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
-{
-  hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
-  union iwreq_data wrqu;
-  char buf[MAX_PNO_NOTIFY_LEN+1];
-
-  hddLog(VOS_TRACE_LEVEL_WARN, "A preferred network was found: %s with rssi: -%d",
-         pPrefNetworkFoundInd->ssId.ssId, pPrefNetworkFoundInd->rssi);
-
-  // create the event
-  memset(&wrqu, 0, sizeof(wrqu));
-  memset(buf, 0, sizeof(buf));
-
-  snprintf(buf, MAX_PNO_NOTIFY_LEN, "QCOM: Found preferred network: %s with RSSI of -%u",
-           pPrefNetworkFoundInd->ssId.ssId,
-          (unsigned int)pPrefNetworkFoundInd->rssi);
-
-  wrqu.data.pointer = buf;
-  wrqu.data.length = strlen(buf);
-
-  // send the event
-
-  wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
-
-}
-
-
-/*string based input*/
-VOS_STATUS iw_set_pno(struct net_device *dev, struct iw_request_info *info,
-                      union iwreq_data *wrqu, char *extra, int nOffset)
-{
-  hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
-  hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
-  /* pnoRequest is a large struct, so we make it static to avoid stack
-     overflow.  This API is only invoked via ioctl, so it is
-     serialized by the kernel rtnl_lock and hence does not need to be
-     reentrant */
-  tSirPNOScanReq pnoRequest = {0};
-  char *ptr, *data;
-  v_U8_t i,j, ucParams, ucMode;
-  size_t len;
-  eHalStatus status = eHAL_STATUS_FAILURE;
-  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-  VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
-            "PNO data len %d data %s",
-            wrqu->data.length,
-            extra);
-
-  if (wrqu->data.length <= nOffset )
-  {
-    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, "PNO input is not correct");
-    return VOS_STATUS_E_FAILURE;
-  }
-
-  pnoRequest.enable = 0;
-  pnoRequest.ucNetworksCount = 0;
-  /*-----------------------------------------------------------------------
-    Input is string based and expected to be like this:
-
-    <enabled> <netw_count>
-    for each network:
-    <ssid_len> <ssid> <authentication> <encryption>
-    <ch_num> <channel_list optional> <bcast_type> <rssi_threshold>
-    <scan_timers> <scan_time> <scan_repeat> <scan_time> <scan_repeat>
-
-    e.g:
-    1 2 4 test 0 0 3 1 6 11 2 40 5 test2 4 4 6 1 2 3 4 5 6 1 0 2 5 2 300 0
-
-    this translates into:
-    -----------------------------
-    enable PNO
-    look for 2 networks:
-    test - with authentication type 0 and encryption type 0,
-    that can be found on 3 channels: 1 6 and 11 ,
-    SSID bcast type is unknown (directed probe will be sent if AP not found)
-    and must meet -40dBm RSSI
-
-    test2 - with auth and enrytption type 4/4
-    that can be found on 6 channels 1, 2, 3, 4, 5 and 6
-    bcast type is non-bcast (directed probe will be sent)
-    and must not meet any RSSI threshold
-
-    scan every 5 seconds 2 times, scan every 300 seconds until stopped
-  -----------------------------------------------------------------------*/
-
-  /* making sure argument string ends with '\0' */
-  len = (wrqu->data.length-nOffset) + 1;
-  data = vos_mem_malloc(len);
-  if (NULL == data) {
-      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
-                FL("fail to allocate memory %zu"), len);
-      return -EINVAL;
-  }
-  vos_mem_zero(data, len);
-  vos_mem_copy(data, &extra[nOffset], (len-1));
-  ptr = data;
-
-  if (1 != sscanf(ptr," %hhu%n", &(pnoRequest.enable), &nOffset))
-  {
-      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
-                "PNO enable input is not valid %s",ptr);
-      vos_mem_free(data);
-      return VOS_STATUS_E_FAILURE;
-  }
-
-  if ( 0 == pnoRequest.enable )
-  {
-    /*Disable PNO*/
-    memset(&pnoRequest, 0, sizeof(pnoRequest));
-    status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
-                                &pnoRequest,
-                                pAdapter->sessionId,
-                                found_pref_network_cb, pAdapter);
-    if (eHAL_STATUS_SUCCESS != status)
-    {
-        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
-                  "%s: failed to disable PNO", __func__);
-        vos_mem_free(data);
-        return VOS_STATUS_E_FAILURE;
-    }
-    pHddCtx->isPnoEnable = FALSE;
-    vos_mem_free(data);
-    return VOS_STATUS_SUCCESS;
-  }
-
-  if (TRUE == pHddCtx->isPnoEnable)
-  {
-     VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
-               FL("already PNO is enabled"));
-     vos_mem_free(data);
-     return -EBUSY;
-  }
-  pHddCtx->isPnoEnable = TRUE;
-
-  ptr += nOffset;
-
-  if (1 != sscanf(ptr," %hhu %n", &(pnoRequest.ucNetworksCount), &nOffset))
-  {
-      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
-                "PNO count input not valid %s",ptr);
-      goto error;
-  }
-
-  VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
-            "PNO enable %d networks count %d offset %d",
-            pnoRequest.enable,
-            pnoRequest.ucNetworksCount,
-            nOffset);
-
-  /* Parameters checking:
-      ucNetworksCount has to be larger than 0*/
-  if (( 0 == pnoRequest.ucNetworksCount ) ||
-      ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
-  {
-      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, "Network input is not correct");
-      goto error;
-  }
-
-  ptr += nOffset;
-
-  pnoRequest.aNetworks =
-           vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
-  if (pnoRequest.aNetworks == NULL)
-  {
-       VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
-           FL("failed to allocate memory aNetworks %u"),
-               (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
-       goto error;
-  }
-  vos_mem_zero(pnoRequest.aNetworks,
-               sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
-
-  for ( i = 0; i < pnoRequest.ucNetworksCount; i++ )
-  {
-
-    pnoRequest.aNetworks[i].ssId.length = 0;
-
-    ucParams = sscanf(ptr," %hhu %n",
-                      &(pnoRequest.aNetworks[i].ssId.length),&nOffset);
-
-    if (1 != ucParams)
-    {
-        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
-                  "PNO ssid length input is not valid %s",ptr);
-        goto error;
-    }
-
-    if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
-        ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
-    {
-      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
-                "SSID Len %d is not correct for network %d",
-                pnoRequest.aNetworks[i].ssId.length, i);
-      goto error;
-    }
-
-    /*Advance to SSID*/
-    ptr += nOffset;
-
-    memcpy(pnoRequest.aNetworks[i].ssId.ssId, ptr,
-           pnoRequest.aNetworks[i].ssId.length);
-    ptr += pnoRequest.aNetworks[i].ssId.length;
-
-    ucParams = sscanf(ptr," %u %u %hhu %n",
-                      &(pnoRequest.aNetworks[i].authentication),
-                      &(pnoRequest.aNetworks[i].encryption),
-                      &(pnoRequest.aNetworks[i].ucChannelCount),
-                      &nOffset);
-
-    if ( 3 != ucParams )
-    {
-      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
-                "Incorrect cmd %s",ptr);
-      goto error;
-    }
-
-    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
-              "PNO len %d ssid 0x%08x%08x%08x%08x%08x%08x%08x%08x"
-              "auth %d encry %d channel count %d offset %d",
-              pnoRequest.aNetworks[i].ssId.length,
-              *((v_U32_t *) &pnoRequest.aNetworks[i].ssId.ssId[0]),
-              *((v_U32_t *) &pnoRequest.aNetworks[i].ssId.ssId[4]),
-              *((v_U32_t *) &pnoRequest.aNetworks[i].ssId.ssId[8]),
-              *((v_U32_t *) &pnoRequest.aNetworks[i].ssId.ssId[12]),
-              *((v_U32_t *) &pnoRequest.aNetworks[i].ssId.ssId[16]),
-              *((v_U32_t *) &pnoRequest.aNetworks[i].ssId.ssId[20]),
-              *((v_U32_t *) &pnoRequest.aNetworks[i].ssId.ssId[24]),
-              *((v_U32_t *) &pnoRequest.aNetworks[i].ssId.ssId[28]),
-              pnoRequest.aNetworks[i].authentication,
-              pnoRequest.aNetworks[i].encryption,
-              pnoRequest.aNetworks[i].ucChannelCount,
-              nOffset );
-
-    /*Advance to channel list*/
-    ptr += nOffset;
-
-    if (SIR_PNO_MAX_NETW_CHANNELS < pnoRequest.aNetworks[i].ucChannelCount)
-    {
-      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
-                "Incorrect number of channels");
-      goto error;
-    }
-
-    if ( 0 !=  pnoRequest.aNetworks[i].ucChannelCount)
-    {
-      for ( j = 0; j < pnoRequest.aNetworks[i].ucChannelCount; j++)
-      {
-           if (1 != sscanf(ptr," %hhu %n",
-                           &(pnoRequest.aNetworks[i].aChannels[j]),
-                           &nOffset))
-            {    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
-                           "PNO network channel input is not valid %s",ptr);
-                 goto error;
-            }
-            if (!IS_CHANNEL_VALID(pnoRequest.aNetworks[i].aChannels[j])) {
-                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
-                          FL("invalid channel: %hhu"),
-                             pnoRequest.aNetworks[i].aChannels[j]);
-                goto error;
-            }
-
-            /*Advance to next channel number*/
-            ptr += nOffset;
-      }
-    }
-
-    if (1 != sscanf(ptr," %u %n",
-                    &(pnoRequest.aNetworks[i].bcastNetwType),
-                    &nOffset))
-    {
-        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
-                  "PNO broadcast network type input is not valid %s",ptr);
-        goto error;
-    }
-    if (pnoRequest.aNetworks[i].bcastNetwType > 2) {
-        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
-                  FL("invalid bcast nw type: %u"),
-                      pnoRequest.aNetworks[i].bcastNetwType);
-         goto error;
-    }
-
-    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
-            "PNO bcastNetwType %d offset %d",
-            pnoRequest.aNetworks[i].bcastNetwType,
-            nOffset );
-
-    /*Advance to rssi Threshold*/
-    ptr += nOffset;
-
-    if (1 != sscanf(ptr," %hhu %n",
-                    &(pnoRequest.aNetworks[i].rssiThreshold),
-                    &nOffset))
-    {
-        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
-                  "PNO rssi threshold input is not valid %s",ptr);
-        goto error;
-    }
-
-    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
-            "PNO rssi %d offset %d",
-            pnoRequest.aNetworks[i].rssiThreshold,
-            nOffset );
-    /*Advance to next network*/
-    ptr += nOffset;
-  }/*For ucNetworkCount*/
-
-  ucParams = sscanf(ptr," %hhu %n",
-                    &(pnoRequest.scanTimers.ucScanTimersCount),
-                    &nOffset);
-
-  /*Read the scan timers*/
-  if (( 1 == ucParams ) && ( pnoRequest.scanTimers.ucScanTimersCount > 0 ))
-  {
-     ptr += nOffset;
-
-     VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
-        "Scan timer count %d offset %d",
-        pnoRequest.scanTimers.ucScanTimersCount,
-        nOffset );
-
-     if ( SIR_PNO_MAX_SCAN_TIMERS < pnoRequest.scanTimers.ucScanTimersCount )
-     {
-       VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
-                    "Incorrect cmd - too many scan timers");
-       goto error;
-     }
-
-     for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++ )
-     {
-        ucParams = sscanf(ptr," %u %u %n",
-           &(pnoRequest.scanTimers.aTimerValues[i].uTimerValue),
-           &( pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat),
-           &nOffset);
-
-        if (2 != ucParams)
-        {
-            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
-                    "Incorrect cmd - diff params then expected %d", ucParams);
-            goto error;
-        }
-
-        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
-            "PNO Timer value %d Timer repeat %d offset %d",
-            pnoRequest.scanTimers.aTimerValues[i].uTimerValue,
-            pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat,
-            nOffset );
-
-        ptr += nOffset;
-     }
-
-  }
-  else
-  {
-    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
-       "No scan timers provided param count %d scan timers %d",
-        ucParams,  pnoRequest.scanTimers.ucScanTimersCount );
-
-    /*Scan timers defaults to 5 minutes*/
-    pnoRequest.scanTimers.ucScanTimersCount = 1;
-    pnoRequest.scanTimers.aTimerValues[0].uTimerValue  = 60;
-    pnoRequest.scanTimers.aTimerValues[0].uTimerRepeat = 0;
-  }
-
-  ucParams = sscanf(ptr," %hhu %n",&(ucMode), &nOffset);
-
-  pnoRequest.modePNO = ucMode;
-  /*for LA we just expose suspend option*/
-  if (( 1 != ucParams )||(  ucMode >= SIR_PNO_MODE_MAX ))
-  {
-     pnoRequest.modePNO = SIR_PNO_MODE_ON_SUSPEND;
-  }
-  pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
-  if (pnoRequest.p24GProbeTemplate == NULL){
-      VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
-          FL("failed to allocate memory p24GProbeTemplate %u"),
-              SIR_PNO_MAX_PB_REQ_SIZE);
-      goto error;
-  }
-
-  pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
-  if (pnoRequest.p5GProbeTemplate == NULL){
-      VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
-          FL("failed to allocate memory p5GProbeTemplate %u"),
-              SIR_PNO_MAX_PB_REQ_SIZE);
-      goto error;
-  }
-
-  vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
-  vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
-
-  status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter), &pnoRequest,
-                                pAdapter->sessionId,
-                                found_pref_network_cb, pAdapter);
-  if (eHAL_STATUS_SUCCESS == status)
-  {
-      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
-                  "%s: PNO enabled", __func__);
-      vos_mem_free(data);
-      return VOS_STATUS_SUCCESS;
-  }
-error:
-    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
-                "%s: Failed to enable PNO", __func__);
-    pHddCtx->isPnoEnable = FALSE;
-    if (pnoRequest.aNetworks)
-        vos_mem_free(pnoRequest.aNetworks);
-    if (pnoRequest.p24GProbeTemplate)
-        vos_mem_free(pnoRequest.p24GProbeTemplate);
-    if (pnoRequest.p5GProbeTemplate)
-        vos_mem_free(pnoRequest.p5GProbeTemplate);
-
-    vos_mem_free(data);
-    return VOS_STATUS_E_FAILURE;
-}/*iw_set_pno*/
-
 VOS_STATUS iw_set_rssi_filter(struct net_device *dev, struct iw_request_info *info,
         union iwreq_data *wrqu, char *extra, int nOffset)
 {
@@ -10178,55 +9751,6 @@
     sme_SetRSSIFilter(WLAN_HDD_GET_HAL_CTX(pAdapter), rssiThreshold);
     return VOS_STATUS_SUCCESS;
 }
-
-
-static int __iw_set_pno_priv(struct net_device *dev,
-                           struct iw_request_info *info,
-                           union iwreq_data *wrqu, char *extra)
-{
-    hdd_adapter_t *pAdapter;
-    hdd_context_t *pHddCtx;
-    int ret = 0;
-    VOS_STATUS status;
-
-    ENTER();
-    pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
-    if (NULL == pAdapter)
-    {
-        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
-                  "%s: Adapter is NULL",__func__);
-        return -EINVAL;
-    }
-
-    pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
-    ret = wlan_hdd_validate_context(pHddCtx);
-    if (0 != ret)
-    {
-        return ret;
-    }
-
-
-    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
-                "Set PNO Private");
-
-    status = iw_set_pno(dev,info,wrqu,extra,0);
-
-    EXIT();
-    return status;
-}
-
-static int iw_set_pno_priv(struct net_device *dev,
-                           struct iw_request_info *info,
-                           union iwreq_data *wrqu, char *extra)
-{
-    int ret;
-
-    vos_ssr_protect(__func__);
-    ret = __iw_set_pno_priv(dev, info, wrqu, extra);
-    vos_ssr_unprotect(__func__);
-
-    return ret;
-}
 #endif /*FEATURE_WLAN_SCAN_PNO*/
 
 //Common function to SetBand
@@ -11019,10 +10543,6 @@
    ,
    [WLAN_SET_PACKET_FILTER_PARAMS       - SIOCIWFIRSTPRIV]   = iw_set_packet_filter_params
 #endif
-#ifdef FEATURE_WLAN_SCAN_PNO
-   ,
-   [WLAN_SET_PNO                        - SIOCIWFIRSTPRIV]   = iw_set_pno_priv
-#endif
    ,
    [WLAN_SET_BAND_CONFIG                - SIOCIWFIRSTPRIV]   = iw_set_band_config,
    [WLAN_PRIV_SET_MCBC_FILTER           - SIOCIWFIRSTPRIV]   = iw_set_dynamic_mcbc_filter,
diff --git a/CORE/MAC/inc/aniGlobal.h b/CORE/MAC/inc/aniGlobal.h
index db919d5..8715388 100644
--- a/CORE/MAC/inc/aniGlobal.h
+++ b/CORE/MAC/inc/aniGlobal.h
@@ -244,6 +244,8 @@
      */
     TX_TIMER           gLimActiveToPassiveChannelTimer;
     TX_TIMER           g_lim_ap_ecsa_timer;
+    /* SAE authentication related timer */
+    TX_TIMER           sae_auth_timer;
 //********************TIMER SECTION ENDS**************************************************
 // ALL THE FIELDS BELOW THIS CAN BE ZEROED OUT in limInitialize
 //****************************************************************************************
diff --git a/CORE/MAC/inc/aniSystemDefs.h b/CORE/MAC/inc/aniSystemDefs.h
index 0eb1cce..3594ef3 100644
--- a/CORE/MAC/inc/aniSystemDefs.h
+++ b/CORE/MAC/inc/aniSystemDefs.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2014, 2019  The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -84,6 +84,8 @@
 #if defined WLAN_FEATURE_VOWIFI_11R
     eSIR_FT_AUTH,
 #endif
+    eSIR_AUTH_TYPE_SAE = 3,
+    eSIR_AUTH_TYPE_OWE = 4,
 #if defined FEATURE_WLAN_ESE
     eSIR_LEAP_AUTH = 0x80,
 #endif
diff --git a/CORE/MAC/inc/qwlan_version.h b/CORE/MAC/inc/qwlan_version.h
index 07a6af7..848bf42 100644
--- a/CORE/MAC/inc/qwlan_version.h
+++ b/CORE/MAC/inc/qwlan_version.h
@@ -46,6 +46,6 @@
 
 #define QWLAN_VERSION_BUILD            85
 
-#define QWLAN_VERSIONSTR               "3.0.11.85"
+#define QWLAN_VERSIONSTR               "3.0.11.85.9"
 
 #endif /* QWLAN_VERSION_H */
diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h
index 4f7e7db..768c989 100644
--- a/CORE/MAC/inc/sirApi.h
+++ b/CORE/MAC/inc/sirApi.h
@@ -149,6 +149,8 @@
 #define PERIODIC_TX_PTRN_MAX_SIZE 1536
 #define MAXNUM_PERIODIC_TX_PTRNS 6
 
+/* Cache ID length */
+#define CACHE_ID_LEN 2
 
 #ifdef WLAN_FEATURE_EXTSCAN
 
@@ -1077,6 +1079,7 @@
     tSirBssType         bsstype;                // add new type for BT -AMP STA and AP Modules
     tANI_U8             dot11mode;              // to support BT-AMP     
     tVOS_CON_MODE       staPersona;             //Persona
+    bool                sae_pmk_cached;
     tANI_BOOLEAN        bOSENAssociation;       //HS2.0
     tANI_BOOLEAN        bWPSAssociation;       //WPS
     ePhyChanBondState   cbMode;                 // Pass CB mode value in Join.
@@ -6449,4 +6452,33 @@
 	void *user_data;
 };
 
+/**
+ * struct sae_info - SAE info used for commit/confirm messages
+ * @msg_type: Message type
+ * @msg_len: length of message
+ * @vdev_id: vdev id
+ * @peer_mac_addr: peer MAC address
+ * @ssid: SSID
+ */
+struct sir_sae_info {
+    uint16_t msg_type;
+    uint16_t msg_len;
+    uint32_t vdev_id;
+    v_MACADDR_t peer_mac_addr;
+    tSirMacSSid ssid;
+};
+
+/**
+ * struct sir_sae_msg - SAE msg used for message posting
+ * @message_type: message type
+ * @length: message length
+ * @session_id: SME session id
+ * @sae_status: SAE status, 0: Success, Non-zero: Failure.
+ */
+struct sir_sae_msg {
+    uint16_t message_type;
+    uint16_t length;
+    uint16_t session_id;
+    uint8_t sae_status;
+};
 #endif /* __SIR_API_H */
diff --git a/CORE/MAC/inc/sirMacProtDef.h b/CORE/MAC/inc/sirMacProtDef.h
index 930f29d..b7e4ce9 100644
--- a/CORE/MAC/inc/sirMacProtDef.h
+++ b/CORE/MAC/inc/sirMacProtDef.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2016, 2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2016, 2017, 2019 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -463,6 +463,9 @@
 
 #define SIR_MAC_OUI_VERSION_1         1
 
+/* OWE DH Parameter element https://tools.ietf.org/html/rfc8110 */
+#define SIR_DH_PARAMETER_ELEMENT_EXT_EID 32
+
 // OUI and type definition for WPA IE in network byte order
 #define SIR_MAC_WPA_OUI             0x01F25000
 #define SIR_MAC_WME_OUI             0x02F25000
diff --git a/CORE/MAC/inc/wniApi.h b/CORE/MAC/inc/wniApi.h
index 0ea1e5c..67839eb 100644
--- a/CORE/MAC/inc/wniApi.h
+++ b/CORE/MAC/inc/wniApi.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2013, 2016-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, 2016-2017, 2019 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -401,6 +401,9 @@
     eWNI_SME_ECSA_CHAN_CHANGE_REQ,
     eWNI_SME_ECSA_CHAN_CHANGE_RSP,
     eWNI_SME_STA_DEL_BA_REQ,
+    eWNI_SME_TRIGGER_SAE,
+    eWNI_SME_SEND_MGMT_FRAME_TX,
+    eWNI_SME_SEND_SAE_MSG,
     eWNI_SME_MSG_TYPES_END
 };
 
diff --git a/CORE/MAC/src/cfg/cfgUtil/dot11f.frms b/CORE/MAC/src/cfg/cfgUtil/dot11f.frms
index 179b95c..394ef88 100644
--- a/CORE/MAC/src/cfg/cfgUtil/dot11f.frms
+++ b/CORE/MAC/src/cfg/cfgUtil/dot11f.frms
@@ -120,6 +120,22 @@
 const EID_OPERATING_MODE             =  199;
 const EID_WIDER_BW_CHANNEL_SWITCH_ANN=  194;
 const EID_VENDOR_SPECIFIC            = 221;
+/**
+ * Extended Element ID
+ *
+ * As part of IEEE-802.11-2016 spec, extended element ID is introduced(9.4.2.1)
+ * Elements are defined to have a common general format consisting of a 1 octet
+ * Element ID field, a 1 octet Length field, an optional 1 octet Element ID
+ * Extension field, and a variable-length element-specific Information field.
+ * Each element is identified by the contents of the Element ID and, when
+ * present, Element ID Extension fields as defined in this standard. An Extended
+ * Element ID is a combination of an Element ID and an Element ID Extension for
+ * those elements that have a defined Element ID Extension. The Length field
+ * specifies the number of octets following the Length field. The presence of
+ * the Element ID Extension field is determined by the Element ID field having
+ * value of 255
+ */
+const EID_EXTN_ID_ELEMENT            = 255;
 
 const SIR_MAC_PROP_EXT_RATES_TYPE    =   0;
 const SIR_MAC_PROP_AP_NAME_TYPE      =   1;
@@ -2890,6 +2906,11 @@
   OPTIE  WMMSchedule;
 }
 
+IE dh_parameter_element (EID_EXTN_ID_ELEMENT) OUI ( 0x20 )
+{
+  group[2];
+  public_key[0..255];
+}
 /////////////////////////////////////////////////////////////////////////////
 //                                MULTIIEs                                 //
 /////////////////////////////////////////////////////////////////////////////
@@ -3539,6 +3560,7 @@
     OPTIE  QOSCapsStation;
     OPTIE  RRMEnabledCap;
     OPTIE  MobilityDomain;
+    OPTIE  dh_parameter_element;
     OPTIE  WPAOpaque;
     OPTIE  HTCaps;
     OPTIE  WMMCaps;
diff --git a/CORE/MAC/src/include/dot11f.h b/CORE/MAC/src/include/dot11f.h
index 25085dd..81d072c 100644
--- a/CORE/MAC/src/include/dot11f.h
+++ b/CORE/MAC/src/include/dot11f.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -32,7 +32,7 @@
   * \brief Structures, function prototypes & definitions
   * for working with 802.11 Frames
   * This file was automatically generated by 'framesc'
-  * Tue Aug 28 09:50:49 2018 from the following file(s):
+  * Mon Jul 22 17:48:28 2019 from the following file(s):
   *
   * dot11f.frms
   *
@@ -6191,6 +6191,33 @@
 #ifdef __cplusplus
 }; /* End extern "C". */
 #endif /* C++ */
+// EID 255 (0xff) Extended EID 32 (0x20)
+typedef struct sDot11fIEdh_parameter_element {
+    tANI_U8      present;
+    tANI_U8      group[2];
+    tANI_U8      num_public_key;
+    tANI_U8      public_key[255];
+} tDot11fIEdh_parameter_element;
+
+#define DOT11F_EID_DH_PARAMETER_ELEMENT ( 255 )
+
+// N.B. These #defines do *not* include the EID & length
+#define DOT11F_IE_DH_PARAMETER_ELEMENT_MIN_LEN ( 2 )
+
+#define DOT11F_IE_DH_PARAMETER_ELEMENT_MAX_LEN ( 257 )
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+tANI_U32 dot11fUnpackIedh_parameter_element(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEdh_parameter_element*);
+
+tANI_U32 dot11fPackIedh_parameter_element(tpAniSirGlobal, tDot11fIEdh_parameter_element*, tANI_U8*, tANI_U32, tANI_U32*);
+
+tANI_U32 dot11fGetPackedIEdh_parameter_element(tpAniSirGlobal, tDot11fIEdh_parameter_element*, tANI_U32*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
 // EID 60 (0x3c)
 typedef struct sDot11fIEext_chan_switch_ann {
     tANI_U8      present;
@@ -6397,33 +6424,34 @@
 #endif /* C++ */
 
 typedef struct sDot11fAssocRequest{
-    tDot11fFfCapabilities   Capabilities;
-    tDot11fFfListenInterval ListenInterval;
-    tDot11fIESSID           SSID;
-    tDot11fIESuppRates      SuppRates;
-    tDot11fIEExtSuppRates   ExtSuppRates;
-    tDot11fIEPowerCaps      PowerCaps;
-    tDot11fIESuppChannels   SuppChannels;
-    tDot11fIERSNOpaque      RSNOpaque;
-    tDot11fIEQOSCapsStation QOSCapsStation;
-    tDot11fIERRMEnabledCap  RRMEnabledCap;
-    tDot11fIEMobilityDomain MobilityDomain;
-    tDot11fIEWPAOpaque      WPAOpaque;
-    tDot11fIEHTCaps         HTCaps;
-    tDot11fIEWMMCaps        WMMCaps;
-    tDot11fIEWMMInfoStation WMMInfoStation;
-    tDot11fIEAirgo          Airgo;
-    tDot11fIEWscIEOpaque    WscIEOpaque;
-    tDot11fIEWAPIOpaque     WAPIOpaque;
-    tDot11fIEESERadMgmtCap  ESERadMgmtCap;
-    tDot11fIEESEVersion     ESEVersion;
-    tDot11fIEP2PIEOpaque    P2PIEOpaque;
-    tDot11fIEWFDIEOpaque    WFDIEOpaque;
-    tDot11fIEVHTCaps        VHTCaps;
-    tDot11fIEExtCap         ExtCap;
-    tDot11fIEOperatingMode  OperatingMode;
-    tDot11fIEQosMapSet      QosMapSet;
-    tDot11fIEhs20vendor_ie  hs20vendor_ie;
+    tDot11fFfCapabilities         Capabilities;
+    tDot11fFfListenInterval       ListenInterval;
+    tDot11fIESSID                 SSID;
+    tDot11fIESuppRates            SuppRates;
+    tDot11fIEExtSuppRates         ExtSuppRates;
+    tDot11fIEPowerCaps            PowerCaps;
+    tDot11fIESuppChannels         SuppChannels;
+    tDot11fIERSNOpaque            RSNOpaque;
+    tDot11fIEQOSCapsStation       QOSCapsStation;
+    tDot11fIERRMEnabledCap        RRMEnabledCap;
+    tDot11fIEMobilityDomain       MobilityDomain;
+    tDot11fIEdh_parameter_element dh_parameter_element;
+    tDot11fIEWPAOpaque            WPAOpaque;
+    tDot11fIEHTCaps               HTCaps;
+    tDot11fIEWMMCaps              WMMCaps;
+    tDot11fIEWMMInfoStation       WMMInfoStation;
+    tDot11fIEAirgo                Airgo;
+    tDot11fIEWscIEOpaque          WscIEOpaque;
+    tDot11fIEWAPIOpaque           WAPIOpaque;
+    tDot11fIEESERadMgmtCap        ESERadMgmtCap;
+    tDot11fIEESEVersion           ESEVersion;
+    tDot11fIEP2PIEOpaque          P2PIEOpaque;
+    tDot11fIEWFDIEOpaque          WFDIEOpaque;
+    tDot11fIEVHTCaps              VHTCaps;
+    tDot11fIEExtCap               ExtCap;
+    tDot11fIEOperatingMode        OperatingMode;
+    tDot11fIEQosMapSet            QosMapSet;
+    tDot11fIEhs20vendor_ie        hs20vendor_ie;
 } tDot11fAssocRequest;
 
 #define DOT11F_ASSOCREQUEST ( 5 )
diff --git a/CORE/MAC/src/include/sirParams.h b/CORE/MAC/src/include/sirParams.h
index e834dc8..552cdd7 100644
--- a/CORE/MAC/src/include/sirParams.h
+++ b/CORE/MAC/src/include/sirParams.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017, 2019 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -266,6 +266,20 @@
     tANI_U32 data[1];
 } tSirMbMsgP2p, *tpSirMbMsgP2p;
 
+/**
+ * struct sir_mgmt_msg - Structure used to send auth frame from CSR to LIM
+ * @type: Message type
+ * @msg_len: Message length
+ * @session_id: session id
+ * @data: Pointer to data tobe transmitted
+ */
+struct sir_mgmt_msg {
+    uint16_t type;
+    uint16_t msg_len;
+    uint8_t session_id;
+    uint8_t *data;
+};
+
 /// Message queue definitions
 //  msgtype(2bytes) reserved(2bytes) bodyptr(4bytes) bodyval(4bytes)
 //  NOTE tSirMsgQ should be always multiples of WORD(4Bytes)
@@ -913,6 +927,7 @@
 #define SIR_LIM_REASSOC_MBB_RSP_TIMEOUT   (SIR_LIM_TIMEOUT_MSG_START + 0x2A)
 #endif
 
+#define SIR_LIM_AUTH_SAE_TIMEOUT            (SIR_LIM_TIMEOUT_MSG_START + 0x2B)
 #define SIR_LIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE (SIR_LIM_TIMEOUT_MSG_START + 0x2C)
 #define SIR_LIM_AUTH_RETRY_TIMEOUT            (SIR_LIM_TIMEOUT_MSG_START + 0x2D)
 #define SIR_LIM_SAP_ECSA_TIMEOUT            (SIR_LIM_TIMEOUT_MSG_START + 0x2E)
diff --git a/CORE/MAC/src/pe/include/limGlobal.h b/CORE/MAC/src/pe/include/limGlobal.h
index 150184d..31ecfbb 100644
--- a/CORE/MAC/src/pe/include/limGlobal.h
+++ b/CORE/MAC/src/pe/include/limGlobal.h
@@ -184,6 +184,7 @@
     eLIM_MLM_WT_FT_REASSOC_RSP_STATE,
 #endif
     eLIM_MLM_P2P_LISTEN_STATE,
+    eLIM_MLM_WT_SAE_AUTH_STATE,
 } tLimMlmStates;
 
 // 11h channel quiet states
diff --git a/CORE/MAC/src/pe/include/limSession.h b/CORE/MAC/src/pe/include/limSession.h
index 75ff4f4..49e99e0 100644
--- a/CORE/MAC/src/pe/include/limSession.h
+++ b/CORE/MAC/src/pe/include/limSession.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017, 2019 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -372,6 +372,7 @@
     tDot11fIEVHTOperation vht_operation;
     bool force_24ghz_in_ht20;
     int8_t def_max_tx_pwr;
+    bool sae_pmk_cached;
 }tPESession, *tpPESession;
 
 #define LIM_MAX_ACTIVE_SESSIONS 4
@@ -480,9 +481,19 @@
 
 --------------------------------------------------------------------------*/
  tpPESession peFindSessionByStaId(tpAniSirGlobal pMac,  tANI_U8  staid,    tANI_U8* sessionId);
- 
 
-
+/**
+ * pe_find_session_by_sme_session_id() - looks up the PE session for given sme
+ * session id
+ * @mac_ctx: pointer to global adapter context
+ * @sme_session_id: sme session id
+ *
+ * Looks up the PE session for given sme session id
+ *
+ * Return: pe session entry for given sme session if found else NULL
+ */
+tpPESession pe_find_session_by_sme_session_id(tpAniSirGlobal mac_ctx,
+                                              uint8_t sme_session_id);
 
 
 /*--------------------------------------------------------------------------
diff --git a/CORE/MAC/src/pe/lim/limProcessAuthFrame.c b/CORE/MAC/src/pe/lim/limProcessAuthFrame.c
index 894549f..0abfed6 100644
--- a/CORE/MAC/src/pe/lim/limProcessAuthFrame.c
+++ b/CORE/MAC/src/pe/lim/limProcessAuthFrame.c
@@ -101,6 +101,41 @@
     return valid;
 }
 
+#ifdef WLAN_FEATURE_SAE
+/**
+ * lim_process_sae_auth_frame()-Process SAE authentication frame
+ * @mac_ctx: MAC context
+ * @rx_pkt_info: Rx packet
+ * @pe_session: PE session
+ *
+ * Return: None
+ */
+static void lim_process_sae_auth_frame(tpAniSirGlobal mac_ctx,
+                                       uint8_t *rx_pkt_info,
+                                       tpPESession pe_session)
+{
+    tpSirMacMgmtHdr mac_hdr;
+
+    mac_hdr = WDA_GET_RX_MAC_HEADER(rx_pkt_info);
+
+    limLog(mac_ctx, LOG1, FL("Received SAE Auth frame type %d subtype %d"),
+           mac_hdr->fc.type, mac_hdr->fc.subType);
+
+    if (pe_session->limMlmState != eLIM_MLM_WT_SAE_AUTH_STATE)
+        limLog(mac_ctx, LOGE,
+               FL("received SAE auth response in unexpected state %x"),
+               pe_session->limMlmState);
+
+    limSendSmeMgmtFrameInd(mac_ctx, pe_session->peSessionId,
+                           rx_pkt_info, pe_session,
+                           WDA_GET_RX_RSSI_DB(rx_pkt_info));
+}
+#else
+static void lim_process_sae_auth_frame(tpAniSirGlobal mac_ctx,
+                                       uint8_t *rx_pkt_info,
+                                       tpPESession pe_session)
+{}
+#endif
 
 /**
  * limProcessAuthFrame
@@ -162,6 +197,7 @@
     tpDphHashNode           pStaDs = NULL;
     tANI_U16                assocId = 0;
     tANI_U16                currSeqNo = 0;
+    tANI_U16                auth_alg = 0;
     /* Added For BT -AMP support */
     // Get pointer to Authentication frame header and body
  
@@ -199,6 +235,9 @@
 
     pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
 
+    auth_alg = *(uint16_t *)pBody;
+    limLog(pMac, LOG1, FL("auth_alg %d "), auth_alg);
+
     //PELOG3(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG3, (tANI_U8*)pBd, ((tpHalBufDesc) pBd)->mpduDataOffset + frameLen);)
 
     //Restore default failure timeout
@@ -588,6 +627,10 @@
 
             goto free;
         } // else if (wlan_cfgGetInt(CFG_PRIVACY_OPTION_IMPLEMENTED))
+    } else if ((auth_alg ==
+        eSIR_AUTH_TYPE_SAE) && (LIM_IS_STA_ROLE(psessionEntry))) {
+        lim_process_sae_auth_frame(pMac, pRxPacketInfo, psessionEntry);
+        goto free;
     } // if (fc.wep)
     else
     {
@@ -683,13 +726,22 @@
                    )
                 {
                     limLog(pMac, LOGE,
-                            FL("STA is already connected but received auth frame"
-                                "Send the Deauth and lim Delete Station Context"
-                                "(staId: %d, assocId: %d) "),
+                            FL("Auth frame received in mlm state: %d(staId: %d, assocId: %d)"),
+                            pStaDs->mlmStaContext.mlmState,
                             pStaDs->staIndex, assocId);
-                    limSendDeauthMgmtFrame(pMac, eSIR_MAC_UNSPEC_FAILURE_REASON,
-                            (tANI_U8 *) pHdr->sa, psessionEntry, FALSE);
-                    limTriggerSTAdeletion(pMac, pStaDs, psessionEntry);
+                    if (pStaDs->mlmStaContext.mlmState ==
+                        eLIM_MLM_LINK_ESTABLISHED_STATE) {
+                        limLog(pMac, LOGE,
+                               FL("STA is already connected but received auth frame"
+                                  "Send the Deauth and lim Delete Station Context"
+                                  "(staId: %d, assocId: %d) "),
+                               pStaDs->staIndex, assocId);
+                        limSendDeauthMgmtFrame(pMac,
+                                               eSIR_MAC_UNSPEC_FAILURE_REASON,
+                                               (tANI_U8 *) pHdr->sa,
+                                               psessionEntry, FALSE);
+                        limTriggerSTAdeletion(pMac, pStaDs, psessionEntry);
+                    }
                     goto free;
                 }
             }
@@ -1153,19 +1205,29 @@
             if (pRxAuthFrameBody->authAlgoNumber !=
                 pMac->lim.gpLimMlmAuthReq->authType)
             {
-                /**
-                 * Received Authentication frame with an auth
-                 * algorithm other than one requested.
-                 * Wait until Authentication Failure Timeout.
+                /*
+                 * Auth algo is open in rx auth frame when auth type is SAE and
+                 * PMK is cached as driver sent auth algo as open in tx frame
+                 * as well.
                  */
-
-                // Log error
-                PELOGW(limLog(pMac, LOGW,
-                       FL("received Auth frame2 for unexpected auth algo number %d "
-                       MAC_ADDRESS_STR), pRxAuthFrameBody->authAlgoNumber,
-                       MAC_ADDR_ARRAY(pHdr->sa));)
-
-                break;
+                if ((pMac->lim.gpLimMlmAuthReq->authType ==
+                     eSIR_AUTH_TYPE_SAE) && psessionEntry->sae_pmk_cached) {
+                     limLog(pMac, LOGW,
+                            FL("rx Auth frame2 auth algo %d in SAE PMK case"),
+                            pRxAuthFrameBody->authAlgoNumber);
+                } else {
+                    /**
+                     * Received Authentication frame with an auth
+                     * algorithm other than one requested.
+                     * Wait until Authentication Failure Timeout.
+                     */
+                    // Log error
+                    PELOGW(limLog(pMac, LOGW,
+                           FL("received Auth frame2 for unexpected auth algo num %d "
+                           MAC_ADDRESS_STR), pRxAuthFrameBody->authAlgoNumber,
+                           MAC_ADDR_ARRAY(pHdr->sa));)
+                    break;
+                }
             }
 
             if (pRxAuthFrameBody->authStatusCode ==
diff --git a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
index 6c8e41b..eb2c931 100644
--- a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
+++ b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2017, 2019 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -82,6 +82,7 @@
 #include "vos_types.h"
 #include "vos_packet.h"
 #include "vos_memory.h"
+#include "limSecurityUtils.h"
 
 /* This value corresponds to 500 ms */
 #define MAX_PROBEREQ_TIME 50
@@ -92,8 +93,69 @@
 
 #define CHECK_BIT(value, mask)    ((value) & (1 << (mask)))
 
+#define IEEE80211_STATUS_SUCCESS            0
+
 void limLogSessionStates(tpAniSirGlobal pMac);
 
+#ifdef WLAN_FEATURE_SAE
+/**
+ * lim_process_sae_msg() - Process SAE message
+ * @mac: Global MAC pointer
+ * @body: Buffer pointer
+ *
+ * Return: None
+ */
+static void lim_process_sae_msg(tpAniSirGlobal mac, struct sir_sae_msg *body)
+{
+    struct sir_sae_msg *sae_msg = body;
+    tpPESession session;
+
+    if (!sae_msg) {
+        limLog(mac, LOGE, FL("SAE msg is NULL"));
+        return;
+    }
+
+    session = pe_find_session_by_sme_session_id(mac, sae_msg->session_id);
+    if (session == NULL) {
+        limLog(mac, LOGE, FL("SAE:Unable to find session"));
+        return;
+    }
+
+    if (session->pePersona != VOS_STA_MODE) {
+        limLog(mac, LOGE, FL("SAE:Not supported in this mode %d"),
+               session->pePersona);
+        return;
+    }
+
+    limLog(mac, LOG1, FL("SAE:status %d limMlmState %d pePersona %d"),
+           sae_msg->sae_status, session->limMlmState,
+           session->pePersona);
+    switch (session->limMlmState) {
+    case eLIM_MLM_WT_SAE_AUTH_STATE:
+        /* SAE authentication is completed. Restore from auth state */
+        if (tx_timer_running(&mac->lim.limTimers.sae_auth_timer))
+            limDeactivateAndChangeTimer(mac, eLIM_AUTH_SAE_TIMER);
+        /* success */
+        if (sae_msg->sae_status == IEEE80211_STATUS_SUCCESS)
+            limRestoreFromAuthState(mac, eSIR_SME_SUCCESS,
+                                    eSIR_MAC_SUCCESS_STATUS, session);
+        else
+            limRestoreFromAuthState(mac, eSIR_SME_AUTH_REFUSED,
+                                    eSIR_MAC_UNSPEC_FAILURE_STATUS, session);
+       break;
+    default:
+       /* SAE msg is received in unexpected state */
+       limLog(mac, LOGE, FL("received SAE msg in state %X"),
+              session->limMlmState);
+       limPrintMlmState(mac, LOGE, session->limMlmState);
+       break;
+    }
+}
+#else
+static void lim_process_sae_msg(tpAniSirGlobal mac, struct sir_sae_msg *body)
+{}
+#endif
+
 /** -------------------------------------------------------------
 \fn defMsgDecision
 \brief The function decides whether to defer a message or not in limProcessMessage function
@@ -1769,6 +1831,12 @@
             limMsg->bodyptr = NULL;
             break;
 
+        case eWNI_SME_SEND_MGMT_FRAME_TX:
+            lim_send_mgmt_frame_tx(pMac, limMsg);
+            vos_mem_free(limMsg->bodyptr);
+            limMsg->bodyptr = NULL;
+            break;
+
 #ifdef WLAN_FEATURE_RMC
         case eWNI_SME_ENABLE_RMC_REQ:
         case eWNI_SME_DISABLE_RMC_REQ:
@@ -2022,6 +2090,7 @@
 #ifdef WLAN_FEATURE_LFR_MBB
         case SIR_LIM_PREAUTH_MBB_RSP_TIMEOUT:
         case SIR_LIM_REASSOC_MBB_RSP_TIMEOUT:
+        case SIR_LIM_AUTH_SAE_TIMEOUT:
 #endif
             // These timeout messages are handled by MLM sub module
 
@@ -2553,6 +2622,11 @@
     case eWNI_SME_STA_DEL_BA_REQ:
         limStaDelBASession(pMac);
         break;
+    case eWNI_SME_SEND_SAE_MSG:
+        lim_process_sae_msg(pMac, limMsg->bodyptr);
+        vos_mem_free((v_VOID_t*)limMsg->bodyptr);
+        limMsg->bodyptr = NULL;
+        break;
     default:
         vos_mem_free((v_VOID_t*)limMsg->bodyptr);
         limMsg->bodyptr = NULL;
diff --git a/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c b/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c
index b55954a..774812b 100644
--- a/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c
+++ b/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c
@@ -100,6 +100,49 @@
 #define IS_MLM_SCAN_REQ_BACKGROUND_SCAN_AGGRESSIVE(pMac)    (pMac->lim.gpLimMlmScanReq->backgroundScanMode == eSIR_AGGRESSIVE_BACKGROUND_SCAN)
 #define IS_MLM_SCAN_REQ_BACKGROUND_SCAN_NORMAL(pMac)        (pMac->lim.gpLimMlmScanReq->backgroundScanMode == eSIR_NORMAL_BACKGROUND_SCAN)
 
+ /**
+ * lim_process_sae_auth_timeout() - This function is called to process sae
+ * auth timeout
+ * @mac_ctx: Pointer to Global MAC structure
+ *
+ * @Return: None
+ */
+static void lim_process_sae_auth_timeout(tpAniSirGlobal mac_ctx)
+{
+    tpPESession session;
+
+    session = peFindSessionBySessionId(mac_ctx,
+                            mac_ctx->lim.limTimers.sae_auth_timer.sessionId);
+    if (session == NULL) {
+        limLog(mac_ctx, LOGE,
+               FL("Session does not exist for given session id"));
+        return;
+    }
+
+    limLog(mac_ctx, LOG1,
+           FL("SAE auth timeout sessionid %d mlmstate %X SmeState %X"),
+           session->peSessionId, session->limMlmState, session->limSmeState);
+
+    switch (session->limMlmState) {
+    case eLIM_MLM_WT_SAE_AUTH_STATE:
+        /*
+         * SAE authentication is not completed. Restore from
+         * auth state.
+         */
+        if (session->pePersona == VOS_STA_MODE)
+            limRestoreFromAuthState(mac_ctx, eSIR_SME_AUTH_TIMEOUT_RESULT_CODE,
+                                    eSIR_MAC_UNSPEC_FAILURE_REASON, session);
+        break;
+    default:
+        /* SAE authentication is timed out in unexpected state */
+        limLog(mac_ctx, LOGE,
+               FL("received unexpected SAE auth timeout in state %X"),
+                  session->limMlmState);
+        limPrintMlmState(mac_ctx, LOGE, session->limMlmState);
+	break;
+     }
+}
+
 /**
  * limProcessMlmReqMessages()
  *
@@ -180,6 +223,9 @@
         case LIM_MLM_ADDBA_REQ:             limProcessMlmAddBAReq( pMac, Msg->bodyptr ); break;
         case LIM_MLM_ADDBA_RSP:             limProcessMlmAddBARsp( pMac, Msg->bodyptr ); break;
         case LIM_MLM_DELBA_REQ:             limProcessMlmDelBAReq( pMac, Msg->bodyptr ); break;
+        case SIR_LIM_AUTH_SAE_TIMEOUT:
+            lim_process_sae_auth_timeout(pMac);
+            break;
         case LIM_MLM_TSPEC_REQ:                 
         default:
             break;
@@ -818,9 +864,15 @@
 {
         tSirMacAuthFrameBody    authFrameBody;
 
+        /* Mark auth algo as open when auth type is SAE and PMK is cached */
+        if ((pMac->lim.gpLimMlmAuthReq->authType == eSIR_AUTH_TYPE_SAE) &&
+             psessionEntry->sae_pmk_cached) {
+             authFrameBody.authAlgoNumber = eSIR_OPEN_SYSTEM;
+         } else {
+             authFrameBody.authAlgoNumber =
+                             (tANI_U8) pMac->lim.gpLimMlmAuthReq->authType;
+         }
         //Prepare & send Authentication frame
-        authFrameBody.authAlgoNumber =
-                        (tANI_U8) pMac->lim.gpLimMlmAuthReq->authType;
         authFrameBody.authTransactionSeqNumber = SIR_MAC_AUTH_FRAME_1;
         authFrameBody.authStatusCode = 0;
         pMac->authAckStatus = LIM_AUTH_ACK_NOT_RCD;
@@ -2462,7 +2514,79 @@
     limPostSmeMessage(pMac, LIM_MLM_JOIN_CNF, (tANI_U32 *) &mlmJoinCnf);
 } /*** limProcessMlmJoinReq() ***/
 
+#ifdef WLAN_FEATURE_SAE
+/**
+ * lim_process_mlm_auth_req_sae() - Handle SAE authentication
+ * @mac_ctx: global MAC context
+ * @session: PE session entry
+ *
+ * This function is called by lim_process_mlm_auth_req to handle SAE
+ * authentication.
+ *
+ * Return: tSirRetStatus
+ */
+static VOS_STATUS lim_process_mlm_auth_req_sae(tpAniSirGlobal mac_ctx,
+                                               tpPESession session)
+{
+        VOS_STATUS status = VOS_STATUS_SUCCESS;
+        struct sir_sae_info *sae_info;
+        vos_msg_t  msg;
 
+        sae_info = vos_mem_malloc(sizeof(*sae_info));
+        if (sae_info == NULL) {
+                limLog(mac_ctx, LOGP, FL("Memory allocation failed"));
+                return VOS_STATUS_E_FAILURE;
+        }
+
+        sae_info->msg_type = eWNI_SME_TRIGGER_SAE;
+        sae_info->msg_len = sizeof(*sae_info);
+        sae_info->vdev_id = session->smeSessionId;
+
+        vos_mem_copy(sae_info->peer_mac_addr.bytes, session->bssId,
+                     VOS_MAC_ADDR_SIZE);
+
+        sae_info->ssid.length = session->ssId.length;
+        vos_mem_copy(sae_info->ssid.ssId, session->ssId.ssId,
+                     session->ssId.length);
+        limLog(mac_ctx, LOG1, FL("vdev_id %d ssid %.*s "MAC_ADDRESS_STR""),
+               sae_info->vdev_id, sae_info->ssid.length,sae_info->ssid.ssId,
+               MAC_ADDR_ARRAY(sae_info->peer_mac_addr.bytes));
+
+        msg.type = eWNI_SME_TRIGGER_SAE;
+        msg.bodyptr = sae_info;
+        msg.bodyval = 0;
+
+        if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MQ_ID_SME, &msg))
+        {
+                limLog(mac_ctx, LOGE, FL("%s failed to post msg to self "),
+                       __func__);
+                vos_mem_free((void *)sae_info);
+                status = VOS_STATUS_E_FAILURE;
+        }
+
+        session->limMlmState = eLIM_MLM_WT_SAE_AUTH_STATE;
+
+        MTRACE(macTrace(mac_ctx, TRACE_CODE_MLM_STATE, session->peSessionId,
+                        session->limMlmState));
+
+        mac_ctx->lim.limTimers.sae_auth_timer.sessionId = session->peSessionId;
+        /* Activate SAE auth timer */
+        MTRACE(macTrace(mac_ctx, TRACE_CODE_TIMER_ACTIVATE,
+                        session->peSessionId, eLIM_AUTH_SAE_TIMER));
+        if (tx_timer_activate(&mac_ctx->lim.limTimers.sae_auth_timer)
+            != TX_SUCCESS) {
+            limLog(mac_ctx, LOGE, FL("could not start Auth SAE timer"));
+        }
+
+        return status;
+}
+#else
+static VOS_STATUS lim_process_mlm_auth_req_sae(tpAniSirGlobal mac_ctx,
+                                               tpPESession session)
+{
+        return VOS_STATUS_E_NOSUPPORT;
+}
+#endif
 
 /**
  * limProcessMlmAuthReq()
@@ -2610,7 +2734,21 @@
                                  pMac->lim.gpLimMlmAuthReq->peerMacAddr);
 
         psessionEntry->limPrevMlmState = psessionEntry->limMlmState;
-        psessionEntry->limMlmState = eLIM_MLM_WT_AUTH_FRAME2_STATE;
+        if ((pMac->lim.gpLimMlmAuthReq->authType == eSIR_AUTH_TYPE_SAE) &&
+             !psessionEntry->sae_pmk_cached) {
+            if (lim_process_mlm_auth_req_sae(pMac, psessionEntry) !=
+                VOS_STATUS_SUCCESS) {
+                mlmAuthCnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
+                goto end;
+            } else {
+                limLog(pMac, LOG1,
+                       FL("lim_process_mlm_auth_req_sae is successful"));
+                return;
+            }
+        } else {
+            psessionEntry->limMlmState = eLIM_MLM_WT_AUTH_FRAME2_STATE;
+        }
+
         MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState));
 
         //assign appropriate sessionId to the timer object
diff --git a/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
index b224b6a..371e27f 100644
--- a/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
+++ b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
@@ -1685,6 +1685,31 @@
                   sizeof(tSirDFSChannelList), 0);
 }
 
+#ifdef WLAN_FEATURE_SAE
+/**
+ * lim_update_sae_config()- This API update SAE session info to csr config
+ * from join request.
+ * @session: PE session
+ * @sme_join_req: pointer to join request
+ *
+ * Return: None
+ */
+static void lim_update_sae_config(tpPESession session,
+                                  tpSirSmeJoinReq sme_join_req)
+{
+    session->sae_pmk_cached = sme_join_req->sae_pmk_cached;
+
+    VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_DEBUG,
+              FL("pmk_cached %d for BSSID=" MAC_ADDRESS_STR),
+              session->sae_pmk_cached,
+              MAC_ADDR_ARRAY(sme_join_req->bssDescription.bssId));
+}
+#else
+static inline void lim_update_sae_config(tpPESession session,
+                                         tpSirSmeJoinReq sme_join_req)
+{}
+#endif
+
 /**
  * __limProcessSmeJoinReq()
  *
@@ -2003,6 +2028,8 @@
 #endif
         psessionEntry->txLdpcIniFeatureEnabled = pSmeJoinReq->txLdpcIniFeatureEnabled;
 
+        lim_update_sae_config(psessionEntry, pSmeJoinReq);
+
         if (psessionEntry->bssType == eSIR_INFRASTRUCTURE_MODE)
         {
             psessionEntry->limSystemRole = eLIM_STA_ROLE;
diff --git a/CORE/MAC/src/pe/lim/limSecurityUtils.c b/CORE/MAC/src/pe/lim/limSecurityUtils.c
index bffffb0..e364e73 100644
--- a/CORE/MAC/src/pe/lim/limSecurityUtils.c
+++ b/CORE/MAC/src/pe/lim/limSecurityUtils.c
@@ -518,10 +518,14 @@
      * retry is needed also cancel the auth rety timer
      */
     pMac->authAckStatus = LIM_AUTH_ACK_RCD_SUCCESS;
-    // 'Change' timer for future activations
-    limDeactivateAndChangeTimer(pMac, eLIM_AUTH_RETRY_TIMER);
-    // 'Change' timer for future activations
-    limDeactivateAndChangeTimer(pMac, eLIM_AUTH_FAIL_TIMER);
+    /* Auth retry and AUth failure timers are not started for SAE
+     * Change' timer for future activations
+     */
+    if (tx_timer_running(&pMac->lim.limTimers.gLimPeriodicAuthRetryTimer))
+        limDeactivateAndChangeTimer(pMac, eLIM_AUTH_RETRY_TIMER);
+    /* Change' timer for future activations */
+    if (tx_timer_running(&pMac->lim.limTimers.gLimAuthFailureTimer))
+        limDeactivateAndChangeTimer(pMac, eLIM_AUTH_FAIL_TIMER);
 
     #if 0
     if (wlan_cfgGetStr(pMac, WNI_CFG_BSSID, currentBssId, &cfg) != eSIR_SUCCESS)
diff --git a/CORE/MAC/src/pe/lim/limSendManagementFrames.c b/CORE/MAC/src/pe/lim/limSendManagementFrames.c
index c47fa71..c776cfb 100644
--- a/CORE/MAC/src/pe/lim/limSendManagementFrames.c
+++ b/CORE/MAC/src/pe/lim/limSendManagementFrames.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -7333,3 +7333,77 @@
 } // End limSendRMCActionFrame.
 
 #endif /* WLAN_FEATURE_RMC */
+
+/**
+ * lim_tx_mgmt_frame() - Transmits Auth mgmt frame
+ * @mac_ctx Pointer to Global MAC structure
+ * @mb_msg: Received message info
+ * @msg_len: Received message length
+ * @packet: Packet to be transmitted
+ * @frame: Received frame
+ *
+ * Return: None
+ */
+static void lim_tx_mgmt_frame(tpAniSirGlobal mac_ctx,
+                              struct sir_mgmt_msg *mb_msg, uint32_t msg_len,
+                              void *packet, uint8_t *frame)
+{
+    tpSirMacFrameCtl fc = (tpSirMacFrameCtl)mb_msg->data;
+    eHalStatus hal_status;
+    uint8_t sme_session_id = 0;
+    tpPESession session;
+
+    sme_session_id = mb_msg->session_id;
+    session = pe_find_session_by_sme_session_id(mac_ctx, sme_session_id);
+    if (session == NULL) {
+            limLog(mac_ctx, LOGP,
+                   FL("session not found for given sme session"));
+            return;
+    }
+    MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
+           session->peSessionId, fc->subType));
+    mac_ctx->authAckStatus = LIM_AUTH_ACK_NOT_RCD;
+    hal_status =
+           halTxFrameWithTxComplete(mac_ctx, packet, (uint16_t)msg_len,
+                                    HAL_TXRX_FRM_802_11_MGMT,
+                                    ANI_TXDIR_TODS,
+                                    7, limTxComplete, frame,
+                                    limAuthTxCompleteCnf,
+                                    0, mac_ctx->lim.txBdToken);
+    MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
+           session->peSessionId, hal_status));
+    if (!HAL_STATUS_SUCCESS(hal_status)) {
+        limLog(mac_ctx, LOGP,
+               FL("*** Could not send Auth frame, retCode=%X ***"),
+               hal_status);
+        mac_ctx->authAckStatus = LIM_AUTH_ACK_RCD_FAILURE;
+        limDiagEventReport(mac_ctx, WLAN_PE_DIAG_AUTH_REQ_EVENT,
+                           session, eSIR_FAILURE, eSIR_FAILURE);
+        /* Pkt will be freed up by the callback */
+    }
+}
+
+void lim_send_mgmt_frame_tx(tpAniSirGlobal mac_ctx, tpSirMsgQ msg)
+{
+    struct sir_mgmt_msg *mb_msg = (struct sir_mgmt_msg *)msg->bodyptr;
+    uint32_t msg_len;
+    tpSirMacFrameCtl fc = (tpSirMacFrameCtl)mb_msg->data;
+    uint8_t sme_session_id;
+    eHalStatus halstatus;
+    uint8_t *frame;
+    void *packet;
+
+    msg_len = mb_msg->msg_len - sizeof(*mb_msg);
+    limLog(mac_ctx, LOG1, FL("sending fc->type: %d fc->subType: %d"),
+           fc->type, fc->subType);
+    sme_session_id = mb_msg->session_id;
+    halstatus = palPktAlloc(mac_ctx->hHdd, HAL_TXRX_FRM_802_11_MGMT,
+                            (uint16_t)msg_len, (void **)&frame,
+                            (void **)&packet);
+    if (!HAL_STATUS_SUCCESS(halstatus)) {
+        limLog(mac_ctx, LOGP, FL("call to bufAlloc failed for AUTH frame"));
+        return;
+    }
+    vos_mem_copy(frame, mb_msg->data, msg_len);
+    lim_tx_mgmt_frame(mac_ctx, mb_msg, msg_len, packet, frame);
+}
diff --git a/CORE/MAC/src/pe/lim/limSerDesUtils.c b/CORE/MAC/src/pe/lim/limSerDesUtils.c
index 6e14ba5..ea0ebf4 100644
--- a/CORE/MAC/src/pe/lim/limSerDesUtils.c
+++ b/CORE/MAC/src/pe/lim/limSerDesUtils.c
@@ -992,6 +992,13 @@
         limLog(pMac, LOGE, FL("remaining len %d is too short"), len);
         return eSIR_FAILURE;
     }
+    pJoinReq->sae_pmk_cached = *pBuf++;
+    len--;
+    if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+    {
+        limLog(pMac, LOGE, FL("remaining len %d is too short"), len);
+        return eSIR_FAILURE;
+    }
 
     pJoinReq->bOSENAssociation = *pBuf++;
     len--;
diff --git a/CORE/MAC/src/pe/lim/limSession.c b/CORE/MAC/src/pe/lim/limSession.c
index 23c53bd..667032d 100644
--- a/CORE/MAC/src/pe/lim/limSession.c
+++ b/CORE/MAC/src/pe/lim/limSession.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2014, 2016-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2014, 2016-2017, 2019 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -276,6 +276,22 @@
     return NULL;
 }
 
+tpPESession pe_find_session_by_sme_session_id(tpAniSirGlobal mac_ctx,
+                                              tANI_U8 sme_session_id)
+{
+   uint8_t i;
+
+   for (i = 0; i < mac_ctx->lim.maxBssId; i++) {
+       if ((mac_ctx->lim.gpSession[i].valid) &&
+           (mac_ctx->lim.gpSession[i].smeSessionId == sme_session_id))
+           return &mac_ctx->lim.gpSession[i];
+   }
+   limLog(mac_ctx, LOG4, FL("Session lookup fails for smeSessionID: %d"),
+          sme_session_id);
+
+   return NULL;
+}
+
 /*--------------------------------------------------------------------------
   \brief peFindSessionBySessionId() - looks up the PE session given the session ID.
 
diff --git a/CORE/MAC/src/pe/lim/limTimerUtils.c b/CORE/MAC/src/pe/lim/limTimerUtils.c
index 5a5163a..f5bb4d3 100644
--- a/CORE/MAC/src/pe/lim/limTimerUtils.c
+++ b/CORE/MAC/src/pe/lim/limTimerUtils.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017, 2019 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -56,6 +56,11 @@
 #define LIM_JOIN_PROBE_REQ_TIMER_MS              200
 #define LIM_AUTH_RETRY_TIMER_MS              60
 
+/*
+ * SAE auth timer of 5secs. This is required for duration of entire SAE
+ * authentication.
+ */
+#define LIM_AUTH_SAE_TIMER_MS 5000
 
 //default beacon interval value used in HB timer interval calculation
 #define LIM_HB_TIMER_BEACON_INTERVAL             100
@@ -431,6 +436,18 @@
             goto err_timer;
         }
 
+       /*
+        * SAE auth timer of 5secs. This is required for duration of entire SAE
+        * authentication.
+        */
+       if ((tx_timer_create(&pMac->lim.limTimers.sae_auth_timer,
+             "SAE AUTH Timer", limTimerHandler, SIR_LIM_AUTH_SAE_TIMEOUT,
+             SYS_MS_TO_TICKS(LIM_AUTH_SAE_TIMER_MS), 0, TX_NO_ACTIVATE)) !=
+             TX_SUCCESS) {
+           limLog(pMac, LOGP, FL("could not create SAE AUTH Timer"));
+           goto err_timer;
+       }
+
         if (wlan_cfgGetInt(pMac, WNI_CFG_BACKGROUND_SCAN_PERIOD,
                       &cfgValue) != eSIR_SUCCESS)
         {
@@ -784,6 +801,7 @@
         tx_timer_delete(&pMac->lim.limTimers.gLimP2pSingleShotNoaInsertTimer);
         tx_timer_delete(&pMac->lim.limTimers.gLimActiveToPassiveChannelTimer);
         tx_timer_delete(&pMac->lim.limTimers.g_lim_ap_ecsa_timer);
+        tx_timer_delete(&pMac->lim.limTimers.sae_auth_timer);
 
         if(NULL != pMac->lim.gLimPreAuthTimerTable.pTable)
         {
@@ -1935,6 +1953,21 @@
                 limLog(pMac, LOGE, FL("Unable to change g_lim_ap_ecsa_timer timer"));
         }
 
+    case eLIM_AUTH_SAE_TIMER:
+        if (tx_timer_deactivate(&pMac->lim.limTimers.sae_auth_timer)
+            != TX_SUCCESS) {
+            limLog(pMac, LOGP, FL("Unable to deactivate SAE auth timer"));
+            return;
+        }
+        /* Change timer to reactivate it in future */
+        val = SYS_MS_TO_TICKS(LIM_AUTH_SAE_TIMER_MS);
+        if (tx_timer_change(&pMac->lim.limTimers.sae_auth_timer,
+            val, 0) != TX_SUCCESS) {
+            limLog(pMac, LOGP, FL("unable to change SAE auth timer"));
+            return;
+        }
+        break;
+
         break;
      default:
             // Invalid timerId. Log error
diff --git a/CORE/MAC/src/pe/lim/limTimerUtils.h b/CORE/MAC/src/pe/lim/limTimerUtils.h
index 2b10fdc..eb4e284 100644
--- a/CORE/MAC/src/pe/lim/limTimerUtils.h
+++ b/CORE/MAC/src/pe/lim/limTimerUtils.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2015, 2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2015, 2017, 2019 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -81,7 +81,8 @@
     eLIM_AP_ECSA_TIMER,
 #ifdef WLAN_FEATURE_LFR_MBB
     eLIM_PREAUTH_MBB_RSP_TIMER,
-    eLIM_REASSOC_MBB_RSP_TIMER
+    eLIM_REASSOC_MBB_RSP_TIMER,
+    eLIM_AUTH_SAE_TIMER
 #endif
 };
 
diff --git a/CORE/MAC/src/pe/lim/limTypes.h b/CORE/MAC/src/pe/lim/limTypes.h
index 6d0ca49..aaffe0c 100644
--- a/CORE/MAC/src/pe/lim/limTypes.h
+++ b/CORE/MAC/src/pe/lim/limTypes.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017, 2019 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -1142,6 +1142,14 @@
 void lim_send_chan_switch_action_frame(tpAniSirGlobal mac_ctx,
      uint16_t new_channel, tpPESession session_entry);
 
+/**
+ * lim_send_mgmt_frame_tx() - Sends mgmt frame
+ * @mac_ctx Pointer to Global MAC structure
+ * @msg: Received message info
+ *
+ * Return: None
+ */
+void lim_send_mgmt_frame_tx(tpAniSirGlobal mac_ctx, tpSirMsgQ msg);
 
 #endif /* __LIM_TYPES_H */
 
diff --git a/CORE/MAC/src/pe/lim/limUtils.c b/CORE/MAC/src/pe/lim/limUtils.c
index e0f4560..a35cff5 100644
--- a/CORE/MAC/src/pe/lim/limUtils.c
+++ b/CORE/MAC/src/pe/lim/limUtils.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -1141,6 +1141,9 @@
         tx_timer_deactivate(&pMac->lim.limTimers.g_lim_ap_ecsa_timer);
         tx_timer_delete(&pMac->lim.limTimers.g_lim_ap_ecsa_timer);
 
+        tx_timer_deactivate(&pMac->lim.limTimers.sae_auth_timer);
+        tx_timer_delete(&pMac->lim.limTimers.sae_auth_timer);
+
         pMac->lim.gLimTimersCreated = 0;
     }
 
diff --git a/CORE/SME/inc/csrApi.h b/CORE/SME/inc/csrApi.h
index 59eb8eb..9fdc24d 100644
--- a/CORE/SME/inc/csrApi.h
+++ b/CORE/SME/inc/csrApi.h
@@ -46,6 +46,7 @@
     // MAC layer authentication types
     eCSR_AUTH_TYPE_OPEN_SYSTEM,
     eCSR_AUTH_TYPE_SHARED_KEY,
+    eCSR_AUTH_TYPE_SAE,
     eCSR_AUTH_TYPE_AUTOSWITCH,
 
     // Upper layer authentication types
@@ -71,6 +72,7 @@
     eCSR_AUTH_TYPE_RSN_PSK_SHA256,
     eCSR_AUTH_TYPE_RSN_8021X_SHA256,
 #endif
+    eCSR_AUTH_TYPE_OWE,
     eCSR_NUM_OF_SUPPORT_AUTH_TYPE,
     eCSR_AUTH_TYPE_FAILED = 0xff,
     eCSR_AUTH_TYPE_UNKNOWN = eCSR_AUTH_TYPE_FAILED,
@@ -218,6 +220,7 @@
 #define CSR_SCAN_TIME_DEFAULT       0
 #define CSR_VALUE_IGNORED           0xFFFFFFFF
 #define CSR_RSN_PMKID_SIZE          16
+#define CSR_RSN_MAX_PMK_LEN         48
 #define CSR_MAX_PMKID_ALLOWED       32
 #define CSR_WEP40_KEY_LEN       5
 #define CSR_WEP104_KEY_LEN      13
@@ -526,6 +529,7 @@
     eCSR_ROAM_ECSA_BCN_TX_IND,
     eCSR_ROAM_ECSA_CHAN_CHANGE_RSP,
     eCSR_ROAM_STA_CHANNEL_SWITCH,
+    eCSR_ROAM_SAE_COMPUTE,
 }eRoamCmdStatus;
 
 
@@ -845,6 +849,11 @@
 {
     tCsrBssid BSSID;
     tANI_U8 PMKID[CSR_RSN_PMKID_SIZE];
+    uint8_t pmk[CSR_RSN_MAX_PMK_LEN];
+    uint8_t pmk_len;
+    uint8_t ssid_len;
+    uint8_t ssid[SIR_MAC_MAX_SSID_LENGTH];
+    uint8_t cache_id[CACHE_ID_LEN];
 }tPmkidCacheInfo;
 
 #ifdef FEATURE_WLAN_WAPI
@@ -1357,6 +1366,9 @@
     struct sir_channel_chanege_rsp *ap_chan_change_rsp;
     tSirSmeChanInfo chan_info;
     tSirMacHTChannelWidth ch_width;
+#ifdef WLAN_FEATURE_SAE
+    struct sir_sae_info *sae_info;
+#endif
 }tCsrRoamInfo;
 
 typedef struct tagCsrFreqScanInfo
@@ -1656,6 +1668,12 @@
 
 ///////////////////////////////////////////Common Roam ends
 
+#ifdef WLAN_FEATURE_SAE
+#define CSR_IS_AUTH_TYPE_SAE(auth_type) \
+   (eCSR_AUTH_TYPE_SAE == auth_type)
+#else
+#define CSR_IS_AUTH_TYPE_SAE(auth_type) (false)
+#endif
 
 /* ---------------------------------------------------------------------------
     \fn csrSetChannels
diff --git a/CORE/SME/inc/sme_Api.h b/CORE/SME/inc/sme_Api.h
index 51c9425..0acded1 100644
--- a/CORE/SME/inc/sme_Api.h
+++ b/CORE/SME/inc/sme_Api.h
@@ -3731,9 +3731,9 @@
 
 eHalStatus sme_RoamDelPMKIDfromCache( tHalHandle hHal, tANI_U8 sessionId,
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
-                                      const tANI_U8 *pBSSId,
+                                      tPmkidCacheInfo *pmksa,
 #else
-                                      tANI_U8 *pBSSId,
+                                      tPmkidCacheInfo *pmksa,
 #endif
                                       tANI_BOOLEAN flush_cache );
 
@@ -4115,4 +4115,35 @@
  */
 VOS_STATUS sme_process_msg_callback(tHalHandle hal, vos_msg_t *msg);
 
+/**
+ * sme_send_mgmt_tx() - Sends mgmt frame from CSR to LIM
+ * @hal: The handle returned by mac_open
+ * @session_id: session id
+ * @buf: pointer to frame
+ * @len: frame length
+ *
+ * Return: eHalStatus
+ */
+eHalStatus sme_send_mgmt_tx(tHalHandle hal, uint8_t session_id,
+                                const uint8_t *buf, uint32_t len);
+
+#ifdef WLAN_FEATURE_SAE
+/**
+ * sme_handle_sae_msg() - Sends SAE message received from supplicant
+ * @hal: The handle returned by mac_open
+ * @session_id: session id
+ * @sae_status: status of SAE authentication
+ *
+ * Return: HAL_STATUS
+ */
+eHalStatus sme_handle_sae_msg(tHalHandle hal, uint8_t session_id,
+                              uint8_t sae_status);
+#else
+static inline eHalStatus sme_handle_sae_msg(tHalHandle hal, uint8_t session_id,
+                                            uint8_t sae_status)
+{
+	return eHAL_STATUS_SUCCESS;
+}
+#endif
+
 #endif //#if !defined( __SME_API_H )
diff --git a/CORE/SME/inc/sme_Trace.h b/CORE/SME/inc/sme_Trace.h
index 77ff1d6..9fd4495 100644
--- a/CORE/SME/inc/sme_Trace.h
+++ b/CORE/SME/inc/sme_Trace.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2017, 2019 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -146,6 +146,7 @@
     TRACE_CODE_SME_RX_HDD_LPHB_CONFIG_REQ,
 #endif /* FEATURE_WLAN_LPHB */
     TRACE_CODE_SME_RX_HDD_ROAM_DEL_PMKIDCACHE,
+    TRACE_CODE_SME_RX_HDD_SEND_MGMT_TX,
     TRACE_CODE_SME_TX_HDD_CAP_TSF_REQ,
     TRACE_CODE_SME_TX_HDD_GET_TSF_REQ,
     TRACE_CODE_SME_DEL_STA_BA_SESSION_REQ,
diff --git a/CORE/SME/src/csr/csrApiRoam.c b/CORE/SME/src/csr/csrApiRoam.c
index 058915b..64500d7 100644
--- a/CORE/SME/src/csr/csrApiRoam.c
+++ b/CORE/SME/src/csr/csrApiRoam.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -121,6 +121,51 @@
 /*-------------------------------------------------------------------------- 
   Type declarations
   ------------------------------------------------------------------------*/
+
+#ifdef WLAN_FEATURE_SAE
+/**
+ * csr_sae_callback - Update SAE info to CSR roam session
+ * @mac_ctx: MAC context
+ * @msg_ptr: pointer to SAE message
+ *
+ * API to update SAE info to roam csr session
+ *
+ * Return: QDF_STATUS
+ */
+static VOS_STATUS csr_sae_callback(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr)
+{
+        tCsrRoamInfo roam_info;
+        uint32_t session_id;
+        struct sir_sae_info *sae_info;
+
+        sae_info = (struct sir_sae_info *) msg_ptr;
+        if (!sae_info) {
+                smsLog(mac_ctx, LOGE, "SAE info is NULL");
+                return VOS_STATUS_E_FAILURE;
+        }
+
+        smsLog(mac_ctx, LOG1, FL("vdev_id %d "MAC_ADDRESS_STR""),
+               sae_info->vdev_id,
+               MAC_ADDR_ARRAY(sae_info->peer_mac_addr.bytes));
+
+        session_id = sae_info->vdev_id;
+        if (session_id == CSR_SESSION_ID_INVALID)
+               return VOS_STATUS_E_FAILURE;
+
+        roam_info.sae_info = sae_info;
+        csrRoamCallCallback(mac_ctx, session_id, &roam_info, 0,
+                            eCSR_ROAM_SAE_COMPUTE, eCSR_ROAM_RESULT_NONE);
+
+        return VOS_STATUS_SUCCESS;
+}
+#else
+static inline VOS_STATUS csr_sae_callback(tpAniSirGlobal mac_ctx,
+                                          tSirSmeRsp *msg_ptr)
+{
+        return VOS_STATUS_SUCCESS;
+}
+#endif
+
 #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
 int diagAuthTypeFromCSRType(eCsrAuthType authType)
 {
@@ -3322,8 +3367,11 @@
                 pBssConfig->uCfgDot11Mode = eCSR_CFG_DOT11_MODE_11A;
             }
         }
-        smsLog(pMac, LOG1, FL("phyMode %d uCfgDot11Mode %d"),
-                              pProfile->phyMode, pBssConfig->uCfgDot11Mode);
+        smsLog(pMac, LOG1,
+               FL("phyMode %d uCfgDot11Mode %d negotiatedAuthType %d"),
+               pProfile->phyMode, pBssConfig->uCfgDot11Mode,
+               pProfile->negotiatedAuthType);
+
         //Qos
         if ((pBssConfig->uCfgDot11Mode != eCSR_CFG_DOT11_MODE_11N) &&
                 (pMac->roam.configParam.WMMSupportMode == eCsrRoamWmmNoQos))
@@ -3360,6 +3408,10 @@
             case eCSR_AUTH_TYPE_AUTOSWITCH:
                 pBssConfig->authType = eSIR_AUTO_SWITCH;
                 break;
+            case eCSR_AUTH_TYPE_SAE:
+                pBssConfig->authType = eSIR_AUTH_TYPE_SAE;
+                break;
+
         }
         //short slot time
         if( eCSR_CFG_DOT11_MODE_11B != cfgDot11Mode )
@@ -3502,6 +3554,10 @@
         case eCSR_AUTH_TYPE_AUTOSWITCH:
             pBssConfig->authType = eSIR_AUTO_SWITCH;
             break;
+        case eCSR_AUTH_TYPE_SAE:
+            pBssConfig->authType = eSIR_AUTH_TYPE_SAE;
+            break;
+
     }
     //short slot time
     if( WNI_CFG_PHY_MODE_11B != pBssConfig->uCfgDot11Mode )
@@ -4554,6 +4610,11 @@
         case eCSR_AUTH_TYPE_AUTOSWITCH:
              pCommand->u.roamCmd.roamProfile.negotiatedAuthType = eCSR_AUTH_TYPE_AUTOSWITCH;
              break;
+        case eCSR_AUTH_TYPE_SAE:
+             pCommand->u.roamCmd.roamProfile.negotiatedAuthType =
+                                    eCSR_AUTH_TYPE_SAE;
+             break;
+
     }
     pCommand->u.roamCmd.roamProfile.negotiatedUCEncryptionType = 
     pCommand->u.roamCmd.roamProfile.EncryptionType.encryptionType[0]; 
@@ -5291,7 +5352,7 @@
        (eCSR_AUTH_TYPE_RSN_PSK_SHA256 == authType) ||
        (eCSR_AUTH_TYPE_RSN_8021X_SHA256 == authType)
 #endif /* FEATURE_WLAN_WAPI */
-        )
+      || (eCSR_AUTH_TYPE_SAE == authType))
     {
         if( !pIesLocal && (!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSirBssDesc, &pIesLocal))) )
         {
@@ -9007,6 +9068,11 @@
                                pRoamInfo, 0, eCSR_ROAM_LOST_LINK_PARAMS_IND, result);
                 break;
             }
+        case eWNI_SME_TRIGGER_SAE:
+             smsLog(pMac, LOG1, FL("Invoke SAE callback"));
+             csr_sae_callback(pMac, pSmeRsp);
+             break;
+
         default:
             smsLog(pMac, LOG1,
                    FL("Unexpected message type = %d[0x%X] received in substate %s"),
@@ -12808,6 +12874,48 @@
    return (pMac->roam.roamSession[sessionId].NumBkidCache);
 }
 #endif /* FEATURE_WLAN_WAPI */
+
+static void csr_update_pmk_cache(tCsrRoamSession *pSession,
+        tPmkidCacheInfo *pmksa)
+{
+    uint16_t cache_idx = pSession->CurCacheIndex;
+
+    /* Add entry to the cache */
+    pSession->PmkidCacheInfo[cache_idx].ssid_len = 0;
+    if (!pmksa->ssid_len) {
+        vos_mem_copy(pSession->PmkidCacheInfo[cache_idx].ssid,
+                pmksa->ssid, pmksa->ssid_len);
+        pSession->PmkidCacheInfo[cache_idx].ssid_len =
+            pmksa->ssid_len;
+    }
+
+    vos_copy_macaddr(
+            (v_MACADDR_t *)pSession->PmkidCacheInfo[cache_idx].BSSID,
+            (v_MACADDR_t *)pmksa->BSSID);
+    vos_mem_copy(pSession->PmkidCacheInfo[cache_idx].cache_id,
+            pmksa->cache_id, CACHE_ID_LEN);
+
+    vos_mem_copy(
+            pSession->PmkidCacheInfo[cache_idx].PMKID,
+            pmksa->PMKID, CSR_RSN_PMKID_SIZE);
+
+    if (pmksa->pmk_len)
+        vos_mem_copy(pSession->PmkidCacheInfo[cache_idx].pmk,
+                pmksa->pmk, pmksa->pmk_len);
+
+    pSession->PmkidCacheInfo[cache_idx].pmk_len = pmksa->pmk_len;
+
+    /* Increment the CSR local cache index */
+    if (cache_idx < (CSR_MAX_PMKID_ALLOWED - 1))
+        pSession->CurCacheIndex++;
+    else
+        pSession->CurCacheIndex = 0;
+
+    pSession->NumPmkidCache++;
+    if (pSession->NumPmkidCache > CSR_MAX_PMKID_ALLOWED)
+        pSession->NumPmkidCache = CSR_MAX_PMKID_ALLOWED;
+}
+
 eHalStatus csrRoamSetPMKIDCache( tpAniSirGlobal pMac, tANI_U32 sessionId,
                                  tPmkidCacheInfo *pPMKIDCache,
                                  tANI_U32 numItems,
@@ -12859,25 +12967,10 @@
                 pmksa = &pPMKIDCache[i];
 
                 /* Delete the entry if present */
-                csrRoamDelPMKIDfromCache(pMac,sessionId,pmksa->BSSID,FALSE);
+                csrRoamDelPMKIDfromCache(pMac,sessionId,pmksa,FALSE);
 
-                /* Add entry to the cache */
-                vos_mem_copy(
-                   pSession->PmkidCacheInfo[pSession->CurCacheIndex].BSSID,
-                   pmksa->BSSID, VOS_MAC_ADDR_SIZE);
-                vos_mem_copy(
-                   pSession->PmkidCacheInfo[pSession->CurCacheIndex].PMKID,
-                   pmksa->PMKID, CSR_RSN_PMKID_SIZE);
+                csr_update_pmk_cache(pSession, pmksa);
 
-                /* Increment the CSR local cache index */
-                if (pSession->CurCacheIndex < (CSR_MAX_PMKID_ALLOWED - 1))
-                    pSession->CurCacheIndex++;
-                else
-                    pSession->CurCacheIndex = 0;
-
-                pSession->NumPmkidCache++;
-                if(pSession->NumPmkidCache > CSR_MAX_PMKID_ALLOWED)
-                    pSession->NumPmkidCache = CSR_MAX_PMKID_ALLOWED;
             }
         }
     }
@@ -12886,9 +12979,9 @@
 
 eHalStatus csrRoamDelPMKIDfromCache( tpAniSirGlobal pMac, tANI_U32 sessionId,
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
-                                     const tANI_U8 *pBSSId,
+                                     tPmkidCacheInfo *pmksa,
 #else
-                                     tANI_U8 *pBSSId,
+                                     tPmkidCacheInfo *pmksa,
 #endif
                                      tANI_BOOLEAN flush_cache )
 {
@@ -12897,6 +12990,7 @@
     tANI_U32 Index;
     tANI_U32 CurIndex;
     tANI_U32 i;
+    tPmkidCacheInfo *cached_pmksa;
 
     if(!pSession)
     {
@@ -12912,20 +13006,28 @@
 
     if (!flush_cache) {
         for (Index = 0; Index < CSR_MAX_PMKID_ALLOWED; Index++) {
-            if (vos_mem_compare(pSession->PmkidCacheInfo[Index].BSSID,
-                pBSSId, VOS_MAC_ADDR_SIZE)) {
-                fMatchFound = 1;
+             cached_pmksa = &pSession->PmkidCacheInfo[Index];
+             if (((!cached_pmksa->ssid_len) &&
+                  vos_is_macaddr_equal((v_MACADDR_t *)cached_pmksa->BSSID,
+                                       (v_MACADDR_t *)pmksa->BSSID))) {
+                  fMatchFound = 1;
 
+             } else if ((!vos_mem_compare(cached_pmksa->ssid,
+                         pmksa->ssid, pmksa->ssid_len)) &&
+                         (!vos_mem_compare(cached_pmksa->cache_id,
+                         pmksa->cache_id, CACHE_ID_LEN)))
+                 fMatchFound = 1;
+
+            if(fMatchFound) {
                 /* Clear this - the matched entry */
-                vos_mem_zero(&pSession->PmkidCacheInfo[Index],
-                             sizeof(tPmkidCacheInfo));
+                vos_mem_zero(cached_pmksa, sizeof(tPmkidCacheInfo));
                 break;
             }
         }
 
         if (Index == CSR_MAX_PMKID_ALLOWED && !fMatchFound) {
-            smsLog(pMac, LOG1, FL("No such PMKSA entry exists "MAC_ADDRESS_STR),
-                   MAC_ADDR_ARRAY(pBSSId));
+            smsLog(pMac, LOG1, FL("No such PMKSA entry exists "));
+
         }
         else {
             /* Match Found */
@@ -13327,6 +13429,40 @@
     return( status );
 }
 
+#ifdef WLAN_FEATURE_SAE
+/*
+ * csr_update_sae_config: Copy SAE info to join request
+ * @profile: pointer to profile
+ * @csr_join_req: csr join request
+ *
+ * Return: None
+ */
+static bool csr_update_sae_config(tSirMacAddr bssid, tpAniSirGlobal mac,
+                                  tCsrRoamSession *session)
+{
+    tPmkidCacheInfo pmkid_cache;
+    uint32_t index;
+    bool sae_pmk_cached;
+
+    vos_mem_copy(pmkid_cache.BSSID, bssid, VOS_MAC_ADDR_SIZE);
+
+    sae_pmk_cached =
+              csr_lookup_pmkid_using_bssid(mac, session, &pmkid_cache, &index);
+
+    VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG,
+              "pmk_cached %d for BSSID=" MAC_ADDRESS_STR, sae_pmk_cached,
+              MAC_ADDR_ARRAY(bssid));
+
+    return sae_pmk_cached;
+}
+#else
+static bool csr_update_sae_config(tSirMacAddr bssid, tpAniSirGlobal mac,
+                                  tCsrRoamSession *session)
+{
+    return false;
+}
+#endif
+
 ////////////////////Mail box
 
 //pBuf is caller allocated memory point to &(tSirSmeJoinReq->rsnIE.rsnIEdata[ 0 ]) + pMsg->rsnIE.length;
@@ -13526,6 +13662,8 @@
         //Persona
         *pBuf = (tANI_U8)pProfile->csrPersona;
         pBuf++;
+        *pBuf = csr_update_sae_config(pBssDescription->bssId, pMac, pSession);
+        pBuf++;
         *pBuf = (tANI_U8)pProfile->bOSENAssociation;
         pBuf++;
         *pBuf = (tANI_U8)pProfile->bWPSAssociation;
@@ -15652,7 +15790,7 @@
         //Persona
         *pBuf = (tANI_U8)pParam->bssPersona;
         pBuf++;
-        
+
         //txLdpcIniFeatureEnabled
         *pBuf = (tANI_U8)(tANI_U8)pMac->roam.configParam.txLdpcEnable;
         pBuf++;
@@ -17651,6 +17789,13 @@
 
    currChannelListInfo = &pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo;
 
+   pSession = CSR_GET_SESSION( pMac, sessionId );
+   if (!pSession) {
+       VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+                 "%s:pSession is null", __func__);
+       return eHAL_STATUS_FAILURE;
+   }
+
    if (0 == csrRoamIsRoamOffloadScanEnabled(pMac))
    {
       smsLog( pMac, LOGE,"isRoamOffloadScanEnabled not set");
@@ -17663,6 +17808,21 @@
         return eHAL_STATUS_FAILURE;
    }
 
+   /* Roaming is not supported currently for SAE authentication */
+   if (pSession->pCurRoamProfile &&
+       CSR_IS_AUTH_TYPE_SAE(pSession->pCurRoamProfile->AuthType.authType[0])) {
+     smsLog(pMac, LOGE, "Roaming not suppprted for SAE connection");
+     return eHAL_STATUS_SUCCESS;
+   }
+
+   /* Roaming is not supported currently for OWE akm */
+   if (pSession->pCurRoamProfile &&
+       (pSession->pCurRoamProfile->AuthType.authType[0] == eCSR_AUTH_TYPE_OWE))
+   {
+        smsLog(pMac, LOGE, "Roaming not suppprted for OWE connection");
+        return eHAL_STATUS_SUCCESS;
+   }
+
    /*The Dynamic Config Items Update may happen even if the state is in INIT.
     * It is important to ensure that the command is passed down to the FW only
     * if the Infra Station is in a connected state.A connected station could also be
@@ -17704,13 +17864,6 @@
             "%s: Not able to find the sessionId for Roam Offload scan request", __func__);
           return eHAL_STATUS_FAILURE;
       }
-      pSession = CSR_GET_SESSION( pMac, sessionId );
-      if (NULL == pSession)
-      {
-          VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
-                 "%s:pSession is null", __func__);
-          return eHAL_STATUS_FAILURE;
-      }
       pBssDesc = pSession->pConnectBssDesc;
       if (pBssDesc == NULL)
       {
diff --git a/CORE/SME/src/csr/csrInsideApi.h b/CORE/SME/src/csr/csrInsideApi.h
index 81c3f16..7d80c89 100644
--- a/CORE/SME/src/csr/csrInsideApi.h
+++ b/CORE/SME/src/csr/csrInsideApi.h
@@ -1112,9 +1112,9 @@
 eHalStatus csrUpdateChannelList(tpAniSirGlobal pMac);
 eHalStatus csrRoamDelPMKIDfromCache( tpAniSirGlobal pMac, tANI_U32 sessionId,
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
-                                     const tANI_U8 *pBSSId,
+                                     tPmkidCacheInfo *pmksa,
 #else
-                                     tANI_U8 *pBSSId,
+                                     tPmkidCacheInfo *pmksa,
 #endif
                                      tANI_BOOLEAN flush_cache );
 tANI_BOOLEAN csrElectedCountryInfo(tpAniSirGlobal pMac);
@@ -1123,6 +1123,18 @@
 void csr_remove_bssid_from_scan_list(tpAniSirGlobal pMac,
        tSirMacAddr bssid);
 
+/**
+ * csr_lookup_pmkid_using_bssid() - lookup pmkid using bssid
+ * @mac: pointer to mac
+ * @session: sme session pointer
+ * @pmk_cache: pointer to pmk cache
+ * @index: index value needs to be seached
+ *
+ * Return: true if pmkid is found else false
+ */
+bool csr_lookup_pmkid_using_bssid(tpAniSirGlobal mac, tCsrRoamSession *session,
+                                  tPmkidCacheInfo *pmk_cache, uint32_t *index);
+
 #ifdef WLAN_FEATURE_AP_HT40_24G
 eHalStatus csrSetHT2040Mode(tpAniSirGlobal pMac, tANI_U32 sessionId, tANI_U8 cbMode);
 #endif
diff --git a/CORE/SME/src/csr/csrUtil.c b/CORE/SME/src/csr/csrUtil.c
index 3d23fa5..fa00158 100644
--- a/CORE/SME/src/csr/csrUtil.c
+++ b/CORE/SME/src/csr/csrUtil.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2017, 2019 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -70,7 +70,22 @@
     { 0x00, 0x40, 0x96, 0x00 }, // CCKM
     { 0x00, 0x0F, 0xAC, 0x06 },  // BIP (encryption type) or RSN-PSK-SHA256 (authentication type)
     /* RSN-8021X-SHA256 (authentication type) */
-    { 0x00, 0x0F, 0xAC, 0x05 }
+    { 0x00, 0x0F, 0xAC, 0x05 },
+#ifdef WLAN_FEATURE_SAE
+#define ENUM_SAE 9
+    /* SAE */
+    {0x00, 0x0F, 0xAC, 0x08},
+#define ENUM_FT_SAE 10
+    /* FT SAE */
+    {0x00, 0x0F, 0xAC, 0x09},
+#else
+    {0x00, 0x00, 0x00, 0x00},
+    {0x00, 0x00, 0x00, 0x00},
+ #endif
+    /* define new oui here */
+#define ENUM_OWE 11
+    /* OWE https://tools.ietf.org/html/rfc8110 */
+    {0x00, 0x0F, 0xAC, 0x12},
 };
 
 #ifdef FEATURE_WLAN_WAPI
@@ -1306,6 +1321,7 @@
         CASE_RETURN_STR(eCSR_ROAM_LOST_LINK_PARAMS_IND);
         CASE_RETURN_STR(eCSR_ROAM_ECSA_BCN_TX_IND);
         CASE_RETURN_STR(eCSR_ROAM_ECSA_CHAN_CHANGE_RSP);
+        CASE_RETURN_STR(eCSR_ROAM_SAE_COMPUTE);
     default:
         return "unknown";
     }
@@ -2845,7 +2861,14 @@
         case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
         case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
 #endif
-            fRSNProfile = TRUE;
+            fRSNProfile = true;
+            break;
+        case eCSR_AUTH_TYPE_SAE:
+            fRSNProfile = true;
+            break;
+
+        case eCSR_AUTH_TYPE_OWE:
+            fRSNProfile = true;
             break;
 
         default:
@@ -3591,6 +3614,42 @@
 }
 #endif
 
+#ifdef WLAN_FEATURE_SAE
+/**
+ * csr_is_auth_wpa_sae() - check whether oui is SAE
+ * @mac: Global MAC context
+ * @all_suites: pointer to all supported akm suites
+ * @suite_count: all supported akm suites count
+ * @oui: Oui needs to be matched
+ *
+ * Return: True if OUI is SAE, false otherwise
+ */
+static bool csr_is_auth_wpa_sae(tpAniSirGlobal mac,
+                                uint8_t all_suites[][CSR_RSN_OUI_SIZE],
+                                uint8_t suite_count, uint8_t oui[])
+{
+        return csrIsOuiMatch(mac, all_suites, suite_count, csrRSNOui[ENUM_SAE],
+                             oui);
+}
+#endif
+
+/**
+ * csr_is_auth_wpa_sae() - check whether oui is OWE
+ * @mac: Global MAC context
+ * @all_suites: pointer to all supported akm suites
+ * @suite_count: all supported akm suites count
+ * @oui: Oui needs to be matched
+ *
+ * Return: True if OUI is SAE, false otherwise
+ */
+static bool csr_is_auth_wpa_owe(tpAniSirGlobal mac,
+                                uint8_t all_suites[][CSR_RSN_OUI_SIZE],
+                                uint8_t suite_count, uint8_t oui[])
+{
+    return csrIsOuiMatch
+            (mac, all_suites, suite_count, csrRSNOui[ENUM_OWE], oui);
+}
+
 static tANI_BOOLEAN csrIsAuthWpa( tpAniSirGlobal pMac, tANI_U8 AllSuites[][CSR_WPA_OUI_SIZE],
                                 tANI_U8 cAllSuites,
                                 tANI_U8 Oui[] )
@@ -3708,6 +3767,48 @@
         return OUIIndex;
 }
 
+#ifdef WLAN_FEATURE_SAE
+/**
+ * csr_check_sae_auth() - update negotiated auth if matches to SAE auth type
+ * @mac_ctx: pointer to mac context
+ * @authsuites: auth suites
+ * @c_auth_suites: auth suites count
+ * @authentication: authentication
+ * @auth_type: authentication type list
+ * @index: current counter
+ * @neg_authtype: pointer to negotiated auth
+ *
+ * Return: None
+ */
+static void csr_check_sae_auth(tpAniSirGlobal mac_ctx,
+                               uint8_t authsuites[][CSR_RSN_OUI_SIZE],
+                               uint8_t c_auth_suites,
+                               uint8_t authentication[],
+                               tCsrAuthList *auth_type,
+                               uint8_t index, eCsrAuthType *neg_authtype)
+{
+        if ((*neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) &&
+            csr_is_auth_wpa_sae(mac_ctx, authsuites, c_auth_suites,
+                                authentication)) {
+                if (eCSR_AUTH_TYPE_SAE == auth_type->authType[index])
+                        *neg_authtype = eCSR_AUTH_TYPE_SAE;
+                if (eCSR_AUTH_TYPE_OPEN_SYSTEM == auth_type->authType[index])
+                        *neg_authtype = eCSR_AUTH_TYPE_OPEN_SYSTEM;
+        }
+        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+                  FL("negotiated auth type is %d"), *neg_authtype);
+}
+#else
+static void csr_check_sae_auth(tpAniSirGlobal mac_ctx,
+                               uint8_t authsuites[][CSR_RSN_OUI_SIZE],
+                               uint8_t c_auth_suites,
+                               uint8_t authentication[],
+                               tCsrAuthList *auth_type,
+                               uint8_t index, eCsrAuthType *neg_authtype)
+{
+}
+#endif
+
 tANI_BOOLEAN csrGetRSNInformation( tHalHandle hHal, tCsrAuthList *pAuthType, eCsrEncryptionType enType, tCsrEncryptionList *pMCEncryption,
                                    tDot11fIERSN *pRSNIe,
                            tANI_U8 *UnicastCypher,
@@ -3770,6 +3871,11 @@
             for (i = 0 ; i < pAuthType->numEntries; i++)
             {
                 //Ciphers are supported, Match authentication algorithm and pick first matching authtype.
+
+                /* Set SAE as first preference */
+                csr_check_sae_auth(pMac, AuthSuites, cAuthSuites,
+                                   Authentication, pAuthType, i, &negAuthType);
+
  #ifdef WLAN_FEATURE_VOWIFI_11R
                 /* Changed the AKM suites according to order of preference */
                 if ( csrIsFTAuthRSN( pMac, AuthSuites, cAuthSuites, Authentication ) )
@@ -3815,6 +3921,12 @@
                         negAuthType = eCSR_AUTH_TYPE_RSN_8021X_SHA256;
                 }
 #endif
+                if ((negAuthType == eCSR_AUTH_TYPE_UNKNOWN) &&
+                    csr_is_auth_wpa_owe(pMac, AuthSuites,
+                    cAuthSuites, Authentication)) {
+                         if (eCSR_AUTH_TYPE_OWE == pAuthType->authType[i])
+                              negAuthType = eCSR_AUTH_TYPE_OWE;
+                }
 
                 // The 1st auth type in the APs RSN IE, to match stations connecting
                 // profiles auth type will cause us to exit this loop
@@ -3983,8 +4095,63 @@
     return( fRSNMatch );
 }
 
+/**
+ * csr_lookup_pmkid_using_ssid() - lookup pmkid using ssid and cache_id
+ * @mac: pointer to mac
+ * @session: sme session pointer
+ * @pmk_cache: pointer to pmk cache
+ * @index: index value needs to be seached
+ *
+ * Return: true if pmkid is found else false
+ */
+static bool csr_lookup_pmkid_using_ssid(tpAniSirGlobal mac,
+                    tCsrRoamSession *session,
+                    tPmkidCacheInfo *pmk_cache,
+                    uint32_t *index)
+{
+    uint32_t i;
+    tPmkidCacheInfo *session_pmk;
 
-tANI_BOOLEAN csrLookupPMKID( tpAniSirGlobal pMac, tANI_U32 sessionId, tANI_U8 *pBSSId, tANI_U8 *pPMKId )
+    for (i = 0; i < session->NumPmkidCache; i++) {
+        session_pmk = &session->PmkidCacheInfo[i];
+
+        if ((!vos_mem_compare(pmk_cache->ssid, session_pmk->ssid,
+                  pmk_cache->ssid_len)) &&
+            (!vos_mem_compare(session_pmk->cache_id,
+                  pmk_cache->cache_id, CACHE_ID_LEN))) {
+            /* match found */
+            *index = i;
+            return true;
+        }
+    }
+
+    return false;
+}
+
+bool csr_lookup_pmkid_using_bssid(tpAniSirGlobal mac,
+                    tCsrRoamSession *session,
+                    tPmkidCacheInfo *pmk_cache,
+                    uint32_t *index)
+{
+    uint32_t i;
+    tPmkidCacheInfo *session_pmk;
+
+    for (i = 0; i < session->NumPmkidCache; i++) {
+        session_pmk = &session->PmkidCacheInfo[i];
+        if (vos_is_macaddr_equal((v_MACADDR_t *)pmk_cache->BSSID,
+                     (v_MACADDR_t *)session_pmk->BSSID)) {
+            /* match found */
+            *index = i;
+            return true;
+        }
+    }
+
+    return false;
+}
+
+tANI_BOOLEAN csrLookupPMKID(tpAniSirGlobal pMac, tANI_U32 sessionId,
+                                tPmkidCacheInfo *pmk_cache)
+
 {
     tANI_BOOLEAN fRC = FALSE, fMatchFound = FALSE;
     tANI_U32 Index;
@@ -4005,25 +4172,30 @@
         return fRC;
     }
     
-    do
-    {
-        for( Index=0; Index < CSR_MAX_PMKID_ALLOWED; Index++ )
-        {
-            if( vos_mem_compare(pBSSId, pSession->PmkidCacheInfo[Index].BSSID, sizeof(tCsrBssid)) )
-            {
-                // match found
-                fMatchFound = TRUE;
-                break;
-            }
-        }
+   if (pmk_cache->ssid_len) {
+       /* Try to find based on cache_id and ssid first */
+       fMatchFound = csr_lookup_pmkid_using_ssid(pMac, pSession, pmk_cache,
+                                                 &Index);
+   }
 
-        if( !fMatchFound ) break;
+    /* If not able to find using cache id or ssid_len is not present */
+    if (!fMatchFound)
+        fMatchFound = csr_lookup_pmkid_using_bssid(pMac, pSession, pmk_cache,
+                                                   &Index);
 
-        vos_mem_copy(pPMKId, pSession->PmkidCacheInfo[Index].PMKID, CSR_RSN_PMKID_SIZE);
+   if (!fMatchFound) {
+       smsLog(pMac, LOG2, "No PMKID Match Found");
+       return false;
 
-        fRC = TRUE;
-    }
-    while( 0 );
+   }
+
+   vos_mem_copy(pmk_cache->PMKID, pSession->PmkidCacheInfo[Index].PMKID, CSR_RSN_PMKID_SIZE);
+   vos_mem_copy(pmk_cache->pmk, pSession->PmkidCacheInfo[Index].pmk,
+                pSession->PmkidCacheInfo[Index].pmk_len);
+   pmk_cache->pmk_len = pSession->PmkidCacheInfo[Index].pmk_len;
+
+   fRC = TRUE;
+
     smsLog(pMac, LOG1, "csrLookupPMKID called return match = %d pMac->roam.NumPmkidCache = %d",
         fRC, pSession->NumPmkidCache);
 
@@ -4043,7 +4215,7 @@
     tCsrRSNAuthIe *pAuthSuite;
     tCsrRSNCapabilities RSNCapabilities;
     tCsrRSNPMKIe        *pPMK;
-    tANI_U8 PMKId[CSR_RSN_PMKID_SIZE];
+    tPmkidCacheInfo pmkid_cache;
     uint32_t ret;
 #ifdef WLAN_FEATURE_11W
     tANI_U8 *pGroupMgmtCipherSuite;
@@ -4111,16 +4283,19 @@
         *(tANI_U16 *)( &pAuthSuite->AuthOui[ 1 ] ) = *((tANI_U16 *)(&RSNCapabilities));
 
         pPMK = (tCsrRSNPMKIe *)( ((tANI_U8 *)(&pAuthSuite->AuthOui[ 1 ])) + sizeof(tANI_U16) );
+        vos_mem_copy((v_MACADDR_t *)pmkid_cache.BSSID,
+                     (v_MACADDR_t *)pSirBssDesc->bssId, VOS_MAC_ADDR_SIZE);
 
         if (
 #ifdef FEATURE_WLAN_ESE
         (eCSR_AUTH_TYPE_CCKM_RSN != negAuthType) &&
 #endif
-        csrLookupPMKID( pMac, sessionId, pSirBssDesc->bssId, &(PMKId[0]) ) )
+        csrLookupPMKID( pMac, sessionId, &pmkid_cache))
         {
             pPMK->cPMKIDs = 1;
 
-            vos_mem_copy(pPMK->PMKIDList[0].PMKID, PMKId, CSR_RSN_PMKID_SIZE);
+            vos_mem_copy(pPMK->PMKIDList[0].PMKID, pmkid_cache.PMKID,
+                         CSR_RSN_PMKID_SIZE);
         }
         else
         {
diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c
index 7b19327..a62bcec 100644
--- a/CORE/SME/src/sme_common/sme_Api.c
+++ b/CORE/SME/src/sme_common/sme_Api.c
@@ -4487,9 +4487,9 @@
 
 eHalStatus sme_RoamDelPMKIDfromCache( tHalHandle hHal, tANI_U8 sessionId,
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
-                                      const tANI_U8 *pBSSId,
+                                      tPmkidCacheInfo *pmksa,
 #else
-                                      tANI_U8 *pBSSId,
+                                      tPmkidCacheInfo *pmksa,
 #endif
                                       tANI_BOOLEAN flush_cache )
 {
@@ -4504,7 +4504,7 @@
       if( CSR_IS_SESSION_VALID( pMac, sessionId ) )
       {
          status = csrRoamDelPMKIDfromCache( pMac, sessionId,
-                                            pBSSId, flush_cache );
+                                            pmksa, flush_cache );
       }
       else
       {
@@ -15387,3 +15387,104 @@
 
          return dot11fUnpackIeRSN(mac_ctx, buf, buf_len, rsn_ie);
 }
+
+/**
+ * sme_prepare_mgmt_tx() - Prepares mgmt frame
+ * @hal: The handle returned by mac_open
+ * @session_id: session id
+ * @buf: pointer to frame
+ * @len: frame length
+ *
+ * Return: eHalStatus
+ */
+static eHalStatus sme_prepare_mgmt_tx(tHalHandle hal, uint8_t session_id,
+                                      const uint8_t *buf, uint32_t len)
+{
+    eHalStatus status = eHAL_STATUS_SUCCESS;
+    VOS_STATUS vos_status = VOS_STATUS_SUCCESS;
+    vos_msg_t vos_message;
+    struct sir_mgmt_msg *msg;
+    uint16_t msg_len;
+
+    VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG,
+              ("prepares auth frame"));
+
+    msg_len = sizeof(*msg) + len;
+    msg = vos_mem_malloc(msg_len);
+    if (msg == NULL) {
+        status = eHAL_STATUS_FAILED_ALLOC;
+    } else {
+        msg->type = eWNI_SME_SEND_MGMT_FRAME_TX;
+        msg->msg_len = msg_len;
+        msg->session_id = session_id;
+        msg->data = (uint8_t *)msg + sizeof(*msg);
+        vos_mem_copy(msg->data, buf, len);
+        vos_message.bodyptr = msg;
+        vos_message.type =  eWNI_SME_SEND_MGMT_FRAME_TX;
+        vos_status = vos_mq_post_message(VOS_MQ_ID_PE, &vos_message);
+        if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
+            vos_mem_free(msg);
+            status = eHAL_STATUS_FAILURE;
+        }
+    }
+    return status;
+}
+
+eHalStatus sme_send_mgmt_tx(tHalHandle hal, uint8_t session_id,
+                            const uint8_t *buf, uint32_t len)
+{
+    eHalStatus status = eHAL_STATUS_SUCCESS;
+    tpAniSirGlobal mac = PMAC_STRUCT(hal);
+
+    MTRACE(vos_trace(VOS_MODULE_ID_SME,
+           TRACE_CODE_SME_RX_HDD_SEND_MGMT_TX, session_id, 0));
+
+    status = sme_AcquireGlobalLock(&mac->sme);
+    if (HAL_STATUS_SUCCESS(status)) {
+        status = sme_prepare_mgmt_tx(hal, session_id, buf, len);
+        sme_ReleaseGlobalLock(&mac->sme);
+    }
+
+    return status;
+}
+
+#ifdef WLAN_FEATURE_SAE
+eHalStatus sme_handle_sae_msg(tHalHandle hal, uint8_t session_id,
+                              uint8_t sae_status)
+{
+    eHalStatus hal_status = eHAL_STATUS_SUCCESS;
+    tpAniSirGlobal mac = PMAC_STRUCT(hal);
+    struct sir_sae_msg *sae_msg;
+    vos_msg_t vos_message;
+    VOS_STATUS vos_status = VOS_STATUS_SUCCESS;
+
+    hal_status = sme_AcquireGlobalLock(&mac->sme);
+    if (HAL_STATUS_SUCCESS(hal_status)) {
+        sae_msg = vos_mem_malloc(sizeof(*sae_msg));
+        if (!sae_msg) {
+            hal_status = eHAL_STATUS_FAILED_ALLOC;
+            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+                      "SAE: memory allocation failed");
+        } else {
+            sae_msg->message_type = eWNI_SME_SEND_SAE_MSG;
+            sae_msg->length = sizeof(*sae_msg);
+            sae_msg->session_id = session_id;
+            sae_msg->sae_status = sae_status;
+            vos_message.bodyptr = sae_msg;
+            vos_message.type =  eWNI_SME_SEND_SAE_MSG;
+            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG,
+                      "SAE: sae_status %d session_id %d", sae_msg->sae_status,
+                      sae_msg->session_id);
+
+            vos_status = vos_mq_post_message(VOS_MQ_ID_PE, &vos_message);
+            if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
+                vos_mem_free(sae_msg);
+                hal_status = eHAL_STATUS_FAILURE;
+            }
+       }
+       sme_ReleaseGlobalLock(&mac->sme);
+}
+
+return hal_status;
+}
+#endif
diff --git a/CORE/SYS/legacy/src/utils/src/dot11f.c b/CORE/SYS/legacy/src/utils/src/dot11f.c
index a47bbc1..d22f1f8 100644
--- a/CORE/SYS/legacy/src/utils/src/dot11f.c
+++ b/CORE/SYS/legacy/src/utils/src/dot11f.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -30,7 +30,7 @@
   * \brief Structures, functions & definitions for
   * working with 802.11 Frames
   * This file was automatically generated by 'framesc'
-  * Tue Aug 28 09:50:49 2018 from the following file(s):
+  * Mon Jul 22 17:48:28 2019 from the following file(s):
   *
   * dot11f.frms
   *
@@ -7770,6 +7770,29 @@
 #define SigIeWscReassocRes ( 0x008e )
 
 
+tANI_U32 dot11fUnpackIedh_parameter_element(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEdh_parameter_element *pDst)
+{
+    tANI_U32 status = DOT11F_PARSE_SUCCESS;
+    (void) pBuf; (void)ielen; /* Shutup the compiler */
+    if (pDst->present) status = DOT11F_DUPLICATE_IE;
+    pDst->present = 1;
+    if (unlikely(ielen < 2)) {
+        pDst->present = 0;
+        return DOT11F_INCOMPLETE_IE;
+    }
+
+    DOT11F_MEMCPY(pCtx, pDst->group, pBuf, 2);
+    pBuf += 2;
+    ielen -= (tANI_U8)2;
+    pDst->num_public_key = (tANI_U8)( ielen );
+    DOT11F_MEMCPY(pCtx, pDst->public_key, pBuf, ( ielen ) );
+    (void)pCtx;
+    return status;
+} /* End dot11fUnpackIedh_parameter_element. */
+
+#define SigIedh_parameter_element ( 0x008f )
+
+
 tANI_U32 dot11fUnpackIeext_chan_switch_ann(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEext_chan_switch_ann *pDst)
 {
     tANI_U32 status = DOT11F_PARSE_SUCCESS;
@@ -7810,7 +7833,7 @@
     return status;
 } /* End dot11fUnpackIeext_chan_switch_ann. */
 
-#define SigIeext_chan_switch_ann ( 0x008f )
+#define SigIeext_chan_switch_ann ( 0x0090 )
 
 
 tANI_U32 dot11fUnpackIehs20vendor_ie(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEhs20vendor_ie *pDst)
@@ -7866,7 +7889,7 @@
     return status;
 } /* End dot11fUnpackIehs20vendor_ie. */
 
-#define SigIehs20vendor_ie ( 0x0090 )
+#define SigIehs20vendor_ie ( 0x0091 )
 
 
 tANI_U32 dot11fUnpackIesec_chan_offset(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEsec_chan_offset *pDst)
@@ -7885,7 +7908,7 @@
     return status;
 } /* End dot11fUnpackIesec_chan_offset. */
 
-#define SigIesec_chan_offset ( 0x0091 )
+#define SigIesec_chan_offset ( 0x0092 )
 
 
     static const tFFDefn FFS_AddBAReq[] = {
@@ -8530,6 +8553,7 @@
         {offsetof(tDot11fAssocRequest, QOSCapsStation), offsetof(tDot11fIEQOSCapsStation, present), 0, "QOSCapsStation" , 0, 3, 3, SigIeQOSCapsStation, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QOSCAPSSTATION, 0, 0, },
         {offsetof(tDot11fAssocRequest, RRMEnabledCap), offsetof(tDot11fIERRMEnabledCap, present), 0, "RRMEnabledCap" , 0, 7, 7, SigIeRRMEnabledCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RRMENABLEDCAP, 0, 0, },
         {offsetof(tDot11fAssocRequest, MobilityDomain), offsetof(tDot11fIEMobilityDomain, present), 0, "MobilityDomain" , 0, 5, 5, SigIeMobilityDomain, {0, 0, 0, 0, 0}, 0, DOT11F_EID_MOBILITYDOMAIN, 0, 0, },
+        {offsetof(tDot11fAssocRequest, dh_parameter_element), offsetof(tDot11fIEdh_parameter_element, present), 0, "dh_parameter_element" , 0, 4, 259, SigIedh_parameter_element, {0, 0, 0, 0, 0}, 0, DOT11F_EID_DH_PARAMETER_ELEMENT, 32, 0, },
         {offsetof(tDot11fAssocRequest, WPAOpaque), offsetof(tDot11fIEWPAOpaque, present), 0, "WPAOpaque" , 0, 8, 255, SigIeWPAOpaque, {0, 80, 242, 1, 0}, 4, DOT11F_EID_WPAOPAQUE, 0, 0, },
         {offsetof(tDot11fAssocRequest, HTCaps), offsetof(tDot11fIEHTCaps, present), 0, "HTCaps" , 0, 28, 60, SigIeHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HTCAPS, 0, 0, },
         {offsetof(tDot11fAssocRequest, WMMCaps), offsetof(tDot11fIEWMMCaps, present), 0, "WMMCaps" , 0, 9, 9, SigIeWMMCaps, {0, 80, 242, 2, 5}, 5, DOT11F_EID_WMMCAPS, 0, 0, },
@@ -8704,6 +8728,17 @@
             FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("resourceReqCap (1): %d\n"), pFrm->MobilityDomain.resourceReqCap);
             FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved (6): %d\n"), pFrm->MobilityDomain.reserved);
         }
+        FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("dh_parameter_element:\n"));
+        if (!pFrm->dh_parameter_element.present)
+        {
+            FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n"));
+        }
+        else
+        {
+            FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->dh_parameter_element.group, 2);
+            FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_public_key: %d.\n"), pFrm->dh_parameter_element.num_public_key);
+            FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->dh_parameter_element.public_key, pFrm->dh_parameter_element.num_public_key);
+        }
         FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("WPAOpaque:\n"));
         if (!pFrm->WPAOpaque.present)
         {
@@ -23207,6 +23242,9 @@
                 case SigIeWscReassocRes:
                         status |= dot11fUnpackIeWscReassocRes(pCtx, pBufRemaining, len, ( tDot11fIEWscReassocRes* )(pFrm + pIe->offset + sizeof(tDot11fIEWscReassocRes)*countOffset) );
                             break;
+                case SigIedh_parameter_element:
+                        status |= dot11fUnpackIedh_parameter_element(pCtx, pBufRemaining, len, ( tDot11fIEdh_parameter_element* )(pFrm + pIe->offset + sizeof(tDot11fIEdh_parameter_element)*countOffset) );
+                            break;
                 case SigIeext_chan_switch_ann:
                         status |= dot11fUnpackIeext_chan_switch_ann(pCtx, pBufRemaining, len, ( tDot11fIEext_chan_switch_ann* )(pFrm + pIe->offset + sizeof(tDot11fIEext_chan_switch_ann)*countOffset) );
                             break;
@@ -25580,6 +25618,11 @@
                             offset = sizeof(tDot11fIEWscReassocRes);
                             status |= dot11fGetPackedIEWscReassocRes(pCtx, ( tDot11fIEWscReassocRes* )(pFrm + pIe->offset + offset * i ), pnNeeded);
                             break;
+                case SigIedh_parameter_element:
+                            offset = sizeof(tDot11fIEdh_parameter_element);
+                            byteCount = ((tDot11fIEdh_parameter_element* )(pFrm + pIe->offset + sizeof(tDot11fIEdh_parameter_element) * i ))->num_public_key + 2;
+                            pIePresent = ( (tDot11fIEdh_parameter_element* )(pFrm + pIe->offset + offset * i  ))->present;
+                            break;
                 case SigIeext_chan_switch_ann:
                             offset = sizeof(tDot11fIEext_chan_switch_ann);
                             byteCount = 4;
@@ -34234,6 +34277,41 @@
     return status;
 } /* End dot11fPackIeWscReassocRes. */
 
+tANI_U32 dot11fPackIedh_parameter_element(tpAniSirGlobal pCtx,
+                                          tDot11fIEdh_parameter_element *pSrc,
+                                          tANI_U8 *pBuf,
+                                          tANI_U32 nBuf,
+                                          tANI_U32 *pnConsumed)
+{
+    tANI_U8* pIeLen = 0;
+    tANI_U32 nConsumedOnEntry = *pnConsumed;
+    tANI_U32 nNeeded = 0U;
+    nNeeded  +=  (pSrc->num_public_key + 2);
+    while ( pSrc->present )
+    {
+        if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW;
+        *pBuf = 255;
+        ++pBuf; ++(*pnConsumed);
+        pIeLen = pBuf;
+        ++pBuf; ++(*pnConsumed);
+        *pBuf = 32;
+        ++pBuf; ++(*pnConsumed);
+        DOT11F_MEMCPY(pCtx, pBuf, pSrc->group, 2);
+        *pnConsumed += 2;
+        pBuf += 2;
+        DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->public_key ), pSrc->num_public_key);
+        *pnConsumed += pSrc->num_public_key;
+        // fieldsEndFlag = 1
+        break;
+    }
+    (void)pCtx;
+    if (pIeLen)
+    {
+        *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+    }
+    return DOT11F_PARSE_SUCCESS;
+} /* End dot11fPackIedh_parameter_element. */
+
 tANI_U32 dot11fPackIeext_chan_switch_ann(tpAniSirGlobal pCtx,
                                          tDot11fIEext_chan_switch_ann *pSrc,
                                          tANI_U8 *pBuf,
@@ -35089,6 +35167,17 @@
             FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("resourceReqCap (1): %d\n"), pFrm->MobilityDomain.resourceReqCap);
             FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved (6): %d\n"), pFrm->MobilityDomain.reserved);
         }
+        FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("dh_parameter_element:\n"));
+        if (!pFrm->dh_parameter_element.present)
+        {
+            FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n"));
+        }
+        else
+        {
+            FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->dh_parameter_element.group, 2);
+            FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_public_key: %d.\n"), pFrm->dh_parameter_element.num_public_key);
+            FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->dh_parameter_element.public_key, pFrm->dh_parameter_element.num_public_key);
+        }
         FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("WPAOpaque:\n"));
         if (!pFrm->WPAOpaque.present)
         {
@@ -48559,6 +48648,9 @@
                     case SigIeWscReassocRes:
                         status |= dot11fPackIeWscReassocRes(pCtx, ( tDot11fIEWscReassocRes* )(pSrc + pIe->offset + sizeof(tDot11fIEWscReassocRes) * i ),  pBufRemaining, nBufRemaining, &len);
                         break;
+                    case SigIedh_parameter_element:
+                        status |= dot11fPackIedh_parameter_element(pCtx, ( tDot11fIEdh_parameter_element* )(pSrc + pIe->offset + sizeof(tDot11fIEdh_parameter_element) * i ),  pBufRemaining, nBufRemaining, &len);
+                        break;
                     case SigIeext_chan_switch_ann:
                         status |= dot11fPackIeext_chan_switch_ann(pCtx, ( tDot11fIEext_chan_switch_ann* )(pSrc + pIe->offset + sizeof(tDot11fIEext_chan_switch_ann) * i ),  pBufRemaining, nBufRemaining, &len);
                         break;
diff --git a/CORE/SYS/legacy/src/utils/src/macTrace.c b/CORE/SYS/legacy/src/utils/src/macTrace.c
index c90dbaf..981dd2d 100644
--- a/CORE/SYS/legacy/src/utils/src/macTrace.c
+++ b/CORE/SYS/legacy/src/utils/src/macTrace.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017, 2019 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -586,6 +586,9 @@
         CASE_RETURN_STRING(eWNI_SME_ECSA_IE_BEACON_COMP_IND);
         CASE_RETURN_STRING(eWNI_SME_ECSA_CHAN_CHANGE_REQ);
         CASE_RETURN_STRING(eWNI_SME_ECSA_CHAN_CHANGE_RSP);
+        CASE_RETURN_STRING(eWNI_SME_TRIGGER_SAE);
+        CASE_RETURN_STRING(eWNI_SME_SEND_MGMT_FRAME_TX);
+        CASE_RETURN_STRING(eWNI_SME_SEND_SAE_MSG);
         default:
             return( (tANI_U8*)"UNKNOWN" );
             break;
@@ -999,6 +1002,7 @@
 
 #endif
 
+        CASE_RETURN_STRING(SIR_LIM_AUTH_SAE_TIMEOUT);
         CASE_RETURN_STRING(SIR_LIM_AUTH_RETRY_TIMEOUT);
         CASE_RETURN_STRING(SIR_LIM_SAP_ECSA_TIMEOUT);
 
diff --git a/CORE/SYS/legacy/src/utils/src/utilsParser.c b/CORE/SYS/legacy/src/utils/src/utilsParser.c
index 32f1992..c5f27a8 100644
--- a/CORE/SYS/legacy/src/utils/src/utilsParser.c
+++ b/CORE/SYS/legacy/src/utils/src/utilsParser.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2015, 2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2015, 2017-2019 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -136,7 +136,7 @@
 {
     // This is awful, I know, but the old code just rammed the IE into
     // an opaque array.  Note that we need to explicitly add the vendorIE and OUI !
-    tANI_U8 curAddIELen = pOld->length; 
+    tANI_U16 curAddIELen = pOld->length;
 
     pOld->length    = curAddIELen + pNew->num_data + 6;
     pOld->addIEdata[ curAddIELen++ ] = 0xdd;
@@ -156,7 +156,7 @@
 {
     // This is awful, I know, but the old code just rammed the IE into
     // an opaque array.  Note that we need to explicitly add the vendorIE and OUI !
-    tANI_U8 curAddIELen = pOld->length; 
+    tANI_U16 curAddIELen = pOld->length;
 
     pOld->length    = curAddIELen + pNew->num_data + 6;
     pOld->addIEdata[ curAddIELen++ ] = 0xdd;
@@ -177,7 +177,7 @@
 {
     // This is awful, I know, but the old code just rammed the IE into
     // an opaque array.  Note that we need to explicitly add the vendorIE and OUI !
-    tANI_U8 curAddIELen = pOld->length; 
+    tANI_U16 curAddIELen = pOld->length;
 
     pOld->length    = curAddIELen + pNew->num_data + 6;
     pOld->addIEdata[ curAddIELen++ ] = 0xdd;
diff --git a/CORE/VOSS/src/vos_sched.c b/CORE/VOSS/src/vos_sched.c
index 19d6f0b..2fa2b6a 100644
--- a/CORE/VOSS/src/vos_sched.c
+++ b/CORE/VOSS/src/vos_sched.c
@@ -2226,3 +2226,13 @@
    vos_dump_stack(TX_Thread);
    vos_dump_stack(RX_Thread);
 }
+
+int vos_get_gfp_flags(void)
+{
+   int flags = GFP_KERNEL;
+
+   if (in_interrupt() || in_atomic() || irqs_disabled())
+      flags = GFP_ATOMIC;
+
+   return flags;
+}
diff --git a/CORE/VOSS/src/vos_sched.h b/CORE/VOSS/src/vos_sched.h
index 3a92a65..8d75a8b 100644
--- a/CORE/VOSS/src/vos_sched.h
+++ b/CORE/VOSS/src/vos_sched.h
@@ -550,5 +550,11 @@
 bool vos_is_wd_thread(int threadId);
 void vos_dump_stack(uint8_t value);
 void vos_dump_thread_stacks(int threadId);
-
+/**
+ * vos_get_gfp_flags(): get GFP flags
+ *
+ * Based on the scheduled context, return GFP flags
+ * Return: gfp flags
+ */
+int vos_get_gfp_flags(void);
 #endif // #if !defined __VOSS_SCHED_H
diff --git a/Kbuild b/Kbuild
index d822f0f..c085b36 100644
--- a/Kbuild
+++ b/Kbuild
@@ -23,6 +23,12 @@
 #Flag to enable Legacy Fast Roaming(LFR)
     CONFIG_PRIMA_WLAN_LFR := y
 
+#Flag to enable SAE
+    CONFIG_WLAN_FEATURE_SAE := y
+
+#Flag to enable OWE
+    CONFIG_WLAN_AKM_SUITE_OWE := y
+
 #Flag to enable Legacy Fast Roaming(LFR) Make Before Break
     CONFIG_PRIMA_WLAN_LFR_MBB := y
 
@@ -677,6 +683,14 @@
 CDEFINES += -DFEATURE_WLAN_LFR
 endif
 
+ifeq ($(CONFIG_WLAN_FEATURE_SAE),y)
+CDEFINES += -DWLAN_FEATURE_SAE
+endif
+
+ifeq ($(CONFIG_WLAN_AKM_SUITE_OWE),y)
+CDEFINES += -DWLAN_AKM_SUITE_OWE
+endif
+
 ifeq ($(CONFIG_PRIMA_WLAN_LFR_MBB),y)
 CDEFINES += -DWLAN_FEATURE_LFR_MBB
 endif