wlan: Ini Support for SAP Authentication Offload

Support SAP Auth Offload, create INI parameter to
enable/disable this feature. Enable/disable command
will be sent to target firmware when SAP start/end or unload
host driver.

Change-Id: I2fd622e1f32ce278d45bca6bde6392ea8747349c
CRs-Fixed: 753731
diff --git a/CORE/HDD/inc/wlan_hdd_cfg.h b/CORE/HDD/inc/wlan_hdd_cfg.h
index 9cc4f75..7d06c2e 100644
--- a/CORE/HDD/inc/wlan_hdd_cfg.h
+++ b/CORE/HDD/inc/wlan_hdd_cfg.h
@@ -50,6 +50,11 @@
 //Number of items that can be configured
 #define MAX_CFG_INI_ITEMS   512
 
+#ifdef SAP_AUTH_OFFLOAD
+/* 802.11 pre-share key length */
+#define WLAN_PSK_STRING_LENGTH   (64)
+#endif /* SAP_AUTH_OFFLOAD */
+
 // Defines for all of the things we read from the configuration (registry).
 
 #define CFG_RTS_THRESHOLD_NAME                 "RTSThreshold"
@@ -1656,6 +1661,29 @@
 #define CFG_ENABLE_TCP_DELACK_MAX            (1)
 #define CFG_ENABLE_TCP_DELACK_DEFAULT        (1)
 
+#ifdef SAP_AUTH_OFFLOAD
+/* Enable/Disable SAP Authentication offload
+ * Default: enable
+ */
+#define CFG_ENABLE_SAP_AUTH_OFL_NAME                   "gEnableSAPAuthOffload"
+#define CFG_ENABLE_SAP_AUTH_OFL_MIN                    ( 0 )
+#define CFG_ENABLE_SAP_AUTH_OFL_MAX                    ( 1 )
+#define CFG_ENABLE_SAP_AUTH_OFL_DEFAULT                ( 1 )
+
+/* SAP Authentication offload Security Type
+ *  0: None Security
+ *  1: WPA2-PSK CCMP
+ */
+#define CFG_SAP_AUTH_OFL_SECURITY_TYPE_NAME               "gSAPAuthOffloadSec"
+#define CFG_SAP_AUTH_OFL_SECURITY_TYPE_MIN                ( 0 )
+#define CFG_SAP_AUTH_OFL_SECURITY_TYPE_MAX                ( 1 )
+#define CFG_SAP_AUTH_OFL_SECURITY_TYPE_DEFAULT            ( 0 )
+
+/* SAP Authentication offload Security Key */
+#define CFG_SAP_AUTH_OFL_KEY_NAME     "gSAPAuthOffloadKey"
+#define CFG_SAP_AUTH_OFL_KEY_DEFAULT  ""
+#endif /* SAP_AUTH_OFFLOAD */
+
 /* In cfg.dat 1=1MBPS, 2=2MBPS, 3=5_5MBPS, 4=11MBPS, 5=6MBPS, 6=9MBPS,
  * 7=12MBPS, 8=18MBPS, 9=24MBPS. But 6=9MBPS and 8=18MBPS are not basic
  * 11g rates and should not be set by gDefaultRateIndex24Ghz. So instead
@@ -3453,6 +3481,11 @@
    v_BOOL_t                    sendMgmtPktViaWQ5;
    v_BOOL_t                    sap_probe_resp_offload;
    v_BOOL_t                    disable_scan_during_sco;
+#ifdef SAP_AUTH_OFFLOAD
+   bool                        enable_sap_auth_offload;
+   uint32_t                    sap_auth_offload_sec_type;
+   uint8_t                     sap_auth_offload_key[WLAN_PSK_STRING_LENGTH];
+#endif /* SAP_AUTH_OFFLOAD */
 } hdd_config_t;
 
 /*--------------------------------------------------------------------------- 
diff --git a/CORE/HDD/inc/wlan_hdd_hostapd.h b/CORE/HDD/inc/wlan_hdd_hostapd.h
index 0e16923..1a4c15a 100644
--- a/CORE/HDD/inc/wlan_hdd_hostapd.h
+++ b/CORE/HDD/inc/wlan_hdd_hostapd.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -96,4 +96,13 @@
 void hdd_hostapd_ch_avoid_cb(void *pAdapter, void *indParam);
 #endif /* FEATURE_WLAN_CH_AVOID */
 int hdd_del_all_sta(hdd_adapter_t *pAdapter);
+#ifdef SAP_AUTH_OFFLOAD
+void hdd_set_sap_auth_offload(hdd_adapter_t *pHostapdAdapter,
+        bool enabled);
+#else
+static inline void
+hdd_set_sap_auth_offload(hdd_adapter_t *pHostapdAdapter, bool enabled)
+{
+}
+#endif
 #endif    // end #if !defined( WLAN_HDD_HOSTAPD_H )
diff --git a/CORE/HDD/src/wlan_hdd_cfg.c b/CORE/HDD/src/wlan_hdd_cfg.c
index ce10a29..f2f7cf9 100644
--- a/CORE/HDD/src/wlan_hdd_cfg.c
+++ b/CORE/HDD/src/wlan_hdd_cfg.c
@@ -3755,6 +3755,26 @@
                CFG_DISABLE_SCAN_DURING_SCO_DEFAULT,
                CFG_DISABLE_SCAN_DURING_SCO_MIN,
                CFG_DISABLE_SCAN_DURING_SCO_MAX ),
+#ifdef SAP_AUTH_OFFLOAD
+  REG_VARIABLE(CFG_ENABLE_SAP_AUTH_OFL_NAME, WLAN_PARAM_Integer,
+               hdd_config_t, enable_sap_auth_offload,
+               VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+               CFG_ENABLE_SAP_AUTH_OFL_DEFAULT,
+               CFG_ENABLE_SAP_AUTH_OFL_MIN,
+               CFG_ENABLE_SAP_AUTH_OFL_MAX ),
+
+  REG_VARIABLE(CFG_SAP_AUTH_OFL_SECURITY_TYPE_NAME, WLAN_PARAM_Integer,
+               hdd_config_t, sap_auth_offload_sec_type,
+               VAR_FLAGS_OPTIONAL | CFG_SAP_AUTH_OFL_SECURITY_TYPE_DEFAULT,
+               CFG_SAP_AUTH_OFL_SECURITY_TYPE_DEFAULT,
+               CFG_SAP_AUTH_OFL_SECURITY_TYPE_MIN,
+               CFG_SAP_AUTH_OFL_SECURITY_TYPE_MAX ),
+
+  REG_VARIABLE_STRING(CFG_SAP_AUTH_OFL_KEY_NAME, WLAN_PARAM_String,
+                      hdd_config_t, sap_auth_offload_key,
+                      VAR_FLAGS_OPTIONAL,
+                      (void *) CFG_SAP_AUTH_OFL_KEY_DEFAULT ),
+#endif
 };
 
 /*
@@ -4319,7 +4339,11 @@
   VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
         "Name = [gDisableScanDuringSco] Value = [%u] ",
          pHddCtx->cfg_ini->disable_scan_during_sco);
-
+#endif
+#ifdef SAP_AUTH_OFFLOAD
+  VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
+          "Name = [gEnableSAPAuthOffload] Value = [%u] ",
+          pHddCtx->cfg_ini->enable_sap_auth_offload);
 #endif
 }
 
diff --git a/CORE/HDD/src/wlan_hdd_hostapd.c b/CORE/HDD/src/wlan_hdd_hostapd.c
index f2e8d13..67c8b92 100644
--- a/CORE/HDD/src/wlan_hdd_hostapd.c
+++ b/CORE/HDD/src/wlan_hdd_hostapd.c
@@ -80,6 +80,7 @@
 #include "cfgApi.h"
 #include "wniCfg.h"
 #include <wlan_hdd_wowl.h>
+#include "wlan_hdd_hostapd.h"
 
 #ifdef FEATURE_WLAN_CH_AVOID
 #include "wcnss_wlan.h"
@@ -786,6 +787,61 @@
     return (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
 }
 
+#ifdef SAP_AUTH_OFFLOAD
+void hdd_set_sap_auth_offload(hdd_adapter_t *pHostapdAdapter,
+        bool enabled)
+{
+    hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
+    struct tSirSapOffloadInfo *sap_offload_info = NULL;
+
+    /* Prepare the request to send to SME */
+    sap_offload_info = vos_mem_malloc(sizeof(*sap_offload_info));
+    if (NULL == sap_offload_info) {
+        hddLog(VOS_TRACE_LEVEL_ERROR,
+                "%s: could not allocate tSirSapOffloadInfo!", __func__);
+        return;
+    }
+
+    vos_mem_zero(sap_offload_info, sizeof(*sap_offload_info));
+    vos_mem_copy(sap_offload_info->macAddr,
+            pHostapdAdapter->macAddressCurrent.bytes, VOS_MAC_ADDR_SIZE);
+
+    sap_offload_info->sap_auth_offload_enable =
+        pHddCtx->cfg_ini->enable_sap_auth_offload && enabled;
+    sap_offload_info->sap_auth_offload_sec_type =
+        pHddCtx->cfg_ini->sap_auth_offload_sec_type;
+    sap_offload_info->key_len =
+        strlen(pHddCtx->cfg_ini->sap_auth_offload_key);
+
+    if (sap_offload_info->sap_auth_offload_enable) {
+        if (sap_offload_info->key_len < 8 ||
+                sap_offload_info->key_len > WLAN_PSK_STRING_LENGTH) {
+            hddLog(VOS_TRACE_LEVEL_ERROR,
+                    "%s: invalid key length(%d) of WPA security!", __func__,
+                    sap_offload_info->key_len);
+            goto end;
+        }
+    }
+
+    vos_mem_copy(sap_offload_info->key,
+            pHddCtx->cfg_ini->sap_auth_offload_key,
+            sap_offload_info->key_len);
+    if (eHAL_STATUS_SUCCESS !=
+            sme_set_sap_auth_offload(pHddCtx->hHal, sap_offload_info)) {
+        hddLog(VOS_TRACE_LEVEL_ERROR,
+                "%s: sme_set_sap_auth_offload fail!", __func__);
+        goto end;
+    }
+
+    hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
+            "%s: sme_set_sap_auth_offload successfully!", __func__);
+
+end:
+    vos_mem_free(sap_offload_info);
+    return;
+}
+#endif
+
 VOS_STATUS hdd_hostapd_SAPEventCB( tpSap_Event pSapEvent, v_PVOID_t usrDataForCallback)
 {
     hdd_adapter_t *pHostapdAdapter;
@@ -941,6 +997,11 @@
             hddLog(LOG1, FL("BSS stop status = %s"),pSapEvent->sapevt.sapStopBssCompleteEvent.status ?
                              "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
 
+#ifdef SAP_AUTH_OFFLOAD
+            if (cfg_param->enable_sap_auth_offload)
+                hdd_set_sap_auth_offload(pHostapdAdapter, FALSE);
+#endif
+
             //Free up Channel List incase if it is set
             sapCleanupChannelList();
 
@@ -4779,7 +4840,12 @@
     }
 
     ENTER();
-       // Allocate the Wireless Extensions state structure
+
+#ifdef SAP_AUTH_OFFLOAD
+    if (pHddCtx->cfg_ini->enable_sap_auth_offload)
+        hdd_set_sap_auth_offload(pAdapter, TRUE);
+#endif
+    // Allocate the Wireless Extensions state structure
     phostapdBuf = WLAN_HDD_GET_HOSTAP_STATE_PTR( pAdapter );
 
     spin_lock_init(&pAdapter->sta_hash_lock);
diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c
index 9207636..f356ded 100644
--- a/CORE/HDD/src/wlan_hdd_main.c
+++ b/CORE/HDD/src/wlan_hdd_main.c
@@ -9154,6 +9154,10 @@
 
             vos_flush_delayed_work(&pAdapter->roc_work);
          }
+#ifdef SAP_AUTH_OFFLOAD
+         if (pHddCtx->cfg_ini->enable_sap_auth_offload)
+             hdd_set_sap_auth_offload(pAdapter, FALSE);
+#endif
          mutex_lock(&pHddCtx->sap_lock);
          if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags)) 
          {
@@ -12238,6 +12242,13 @@
 
 #endif
 
+#ifdef SAP_AUTH_OFFLOAD
+   if (!sme_IsFeatureSupportedByFW(SAP_OFFLOADS))
+   {
+       hddLog(VOS_TRACE_LEVEL_INFO, FL(" SAP AUTH OFFLOAD not supp by FW"));
+       pHddCtx->cfg_ini->enable_sap_auth_offload = 0;
+   }
+#endif
 
    if (vos_is_multicast_logging())
        wlan_logging_set_log_level();
diff --git a/CORE/MAC/inc/aniGlobal.h b/CORE/MAC/inc/aniGlobal.h
index 1d50dbf..822cf1d 100644
--- a/CORE/MAC/inc/aniGlobal.h
+++ b/CORE/MAC/inc/aniGlobal.h
@@ -1086,6 +1086,10 @@
     v_U32_t PERroamTimeout;
     v_U32_t currentBssScore;
 #endif
+#ifdef SAP_AUTH_OFFLOAD
+    bool sap_auth_offload;
+    uint32_t sap_auth_offload_sec_type;
+#endif /* SAP_AUTH_OFFLOAD */
 } tAniSirGlobal;
 
 #ifdef FEATURE_WLAN_TDLS
diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h
index 3539665..26f8683 100644
--- a/CORE/MAC/inc/sirApi.h
+++ b/CORE/MAC/inc/sirApi.h
@@ -6063,5 +6063,39 @@
    tANI_U32  value;
 } tModifyRoamParamsReqParams, * tpModifyRoamParamsReqParams;
 
+#ifdef SAP_AUTH_OFFLOAD
+/* 80211 Pre-Share Key length */
+#define SIR_PSK_MAX_LEN   64
 
+/**
+ * enum tSirSecurityType - definition for Software AP Auth Offload
+ *                         Security Type
+ * @eSIR_OFFLOAD_NONE: None type security
+ * @eSIR_OFFLOAD_WPA2PSK_CCMP: WPA2-PSK
+ */
+enum tSirSecurityType
+{
+    eSIR_OFFLOAD_NONE,
+    eSIR_OFFLOAD_WPA2PSK_CCMP,
+};
+
+/**
+ * struct tSirSapOffloadInfo - Structure to store sap offload related params.
+ * @macAddr: Self mac address
+ * @sap_auth_offload_enable: tell if sap auth offload is enabled or not.
+ * @sap_auth_offload_sec_type: tells security type
+ *        0 - none
+ *        1 - WPA1-PSK
+ * @key_len: psk key length
+ * @key: psk key.
+ */
+struct tSirSapOffloadInfo
+{
+    tSirMacAddr macAddr;
+    bool sap_auth_offload_enable;
+    uint32_t sap_auth_offload_sec_type;
+    uint32_t key_len;
+    uint8_t key[SIR_PSK_MAX_LEN];
+};
+#endif /* SAP_AUTH_OFFLOAD */
 #endif /* __SIR_API_H */
diff --git a/CORE/MAC/src/include/sirParams.h b/CORE/MAC/src/include/sirParams.h
index 9e6f1b9..7e35c02 100644
--- a/CORE/MAC/src/include/sirParams.h
+++ b/CORE/MAC/src/include/sirParams.h
@@ -771,6 +771,13 @@
 #define SIR_HAL_PER_ROAM_SCAN_TRIGGER_RSP  (SIR_HAL_ITC_MSG_TYPES_BEGIN + 289)
 #endif
 #define SIR_HAL_UPDATE_CFG_INT_PARAM       (SIR_HAL_ITC_MSG_TYPES_BEGIN + 290)
+
+#ifdef SAP_AUTH_OFFLOAD
+#define SIR_HAL_SET_SAP_AUTH_OFL           (SIR_HAL_ITC_MSG_TYPES_BEGIN + 291)
+#define SIR_HAL_SAP_OFL_ADD_STA            (SIR_HAL_ITC_MSG_TYPES_BEGIN + 292)
+#define SIR_HAL_SAP_OFL_DEL_STA            (SIR_HAL_ITC_MSG_TYPES_BEGIN + 293)
+#endif
+
 #define SIR_HAL_MSG_TYPES_END              (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF)
 
 // CFG message types
diff --git a/CORE/SME/inc/sme_Api.h b/CORE/SME/inc/sme_Api.h
index 4d32fa8..e1e50db 100644
--- a/CORE/SME/inc/sme_Api.h
+++ b/CORE/SME/inc/sme_Api.h
@@ -3965,4 +3965,19 @@
 void sme_set_mgmt_frm_via_wq5(tHalHandle hHal,
         tANI_BOOLEAN sendMgmtPktViaWQ5);
 eHalStatus sme_update_cfg_int_param(tHalHandle hHal, tANI_U32 cfg_id);
+#ifdef SAP_AUTH_OFFLOAD
+/**
+ * sme_set_sap_auth_offload() enable/disable SAP Auth Offload
+ * @hHal: hal layer handler
+ * @sap_auth_offload_info: the information of  SAP Auth Offload
+ *
+ * This function provide enable/disable SAP authenticaiton offload
+ * feature on target firmware
+ *
+ * Return: eHalStatus.
+ */
+eHalStatus sme_set_sap_auth_offload(tHalHandle hHal,
+        struct tSirSapOffloadInfo *sap_auth_offload_info);
+
+#endif /* SAP_AUTH_OFFLOAD */
 #endif //#if !defined( __SME_API_H )
diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c
index 15ca4f7..ef14e99 100644
--- a/CORE/SME/src/sme_common/sme_Api.c
+++ b/CORE/SME/src/sme_common/sme_Api.c
@@ -14535,3 +14535,69 @@
     }
     return;
 }
+
+#ifdef SAP_AUTH_OFFLOAD
+/**
+ * sme_set_sap_auth_offload() enable/disable Software AP Auth Offload
+ * @hHal: hal layer handler
+ * @sap_auth_offload_info: the information of Software AP Auth offload
+ *
+ * This function provide enable/disable Software AP authenticaiton offload
+ * feature on target firmware
+ *
+ * Return: Return eHalStatus.
+ */
+eHalStatus sme_set_sap_auth_offload(tHalHandle hHal,
+        struct tSirSapOffloadInfo *sap_auth_offload_info)
+{
+    vos_msg_t vosMessage;
+    struct tSirSapOffloadInfo *sme_sap_auth_offload_info;
+    eHalStatus status = eHAL_STATUS_SUCCESS;
+    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+    pMac->sap_auth_offload_sec_type =
+        sap_auth_offload_info->sap_auth_offload_sec_type;
+    pMac->sap_auth_offload = sap_auth_offload_info->sap_auth_offload_enable;
+
+    sme_sap_auth_offload_info =
+        vos_mem_malloc(sizeof(*sme_sap_auth_offload_info));
+
+    if (!sme_sap_auth_offload_info)
+    {
+        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+                "%s: Not able to allocate memory for WDA_SET_SAP_AUTH_OFL",
+                __func__);
+        return eHAL_STATUS_E_MALLOC_FAILED;
+    }
+    vos_mem_copy(sme_sap_auth_offload_info, sap_auth_offload_info,
+           sizeof(*sap_auth_offload_info));
+
+    if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme)))
+    {
+        /* serialize the req through MC thread */
+        vosMessage.type     = WDA_SET_SAP_AUTH_OFL;
+        vosMessage.bodyptr  = sme_sap_auth_offload_info;
+
+        if (!VOS_IS_STATUS_SUCCESS(
+                 vos_mq_post_message(VOS_MODULE_ID_WDA, &vosMessage)))
+        {
+            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+                    "%s: Not able to post WDA_SET_SAP_AUTH_OFL to WDA!",
+                    __func__);
+            vos_mem_free(sme_sap_auth_offload_info);
+            status = eHAL_STATUS_FAILURE;
+        }
+        sme_ReleaseGlobalLock(&pMac->sme);
+    }
+    else
+    {
+        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+                "%s: sme_AcquireGlobalLock error!",
+                __func__);
+        vos_mem_free(sme_sap_auth_offload_info);
+        status = eHAL_STATUS_FAILURE;
+    }
+
+    return (status);
+}
+#endif
diff --git a/CORE/WDA/inc/wlan_qct_wda.h b/CORE/WDA/inc/wlan_qct_wda.h
index d058e45..40a8a00 100644
--- a/CORE/WDA/inc/wlan_qct_wda.h
+++ b/CORE/WDA/inc/wlan_qct_wda.h
@@ -1352,6 +1352,12 @@
 
 #define WDA_PAUSE_TL_IND                       SIR_HAL_PAUSE_TL_IND
 
+#ifdef SAP_AUTH_OFFLOAD
+#define WDA_SAP_OFL_ADD_STA                   SIR_HAL_SAP_OFL_ADD_STA
+#define WDA_SAP_OFL_DEL_STA                   SIR_HAL_SAP_OFL_DEL_STA
+#define WDA_SET_SAP_AUTH_OFL                  SIR_HAL_SET_SAP_AUTH_OFL
+#endif /* SAP_AUTH_OFFLOAD */
+
 #define HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME 0x40 // Bit 6 will be used to control BD rate for Management frames
 
 #define halTxFrame(hHal, pFrmBuf, frmLen, frmType, txDir, tid, pCompFunc, pData, txFlag) \
diff --git a/CORE/WDA/src/wlan_qct_wda.c b/CORE/WDA/src/wlan_qct_wda.c
index 751cf24..e799fdd 100644
--- a/CORE/WDA/src/wlan_qct_wda.c
+++ b/CORE/WDA/src/wlan_qct_wda.c
@@ -15291,6 +15291,74 @@
     return CONVERT_WDI2VOS_STATUS(status) ;
 }
 
+#ifdef SAP_AUTH_OFFLOAD
+VOS_STATUS wda_process_sap_auth_offload(tWDA_CbContext *pWDA,
+        struct tSirSapOffloadInfo *sap_auth_offload_info)
+{
+    WDI_Status status = WDI_STATUS_SUCCESS;
+    struct WDI_sap_ofl_enable_params *sap_ofl_enable_cmd;
+    v_U16_t psk_len, psk_len_padded;
+
+    VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+            "------> %s " ,__func__);
+
+    if(NULL == sap_auth_offload_info)
+    {
+        VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+                "%s: sap_auth_offload_info received NULL", __func__);
+        VOS_ASSERT(0) ;
+        return VOS_STATUS_E_FAULT;
+    }
+    psk_len = sap_auth_offload_info->key_len;
+    psk_len_padded = roundup(psk_len, sizeof(v_U32_t));
+
+    sap_ofl_enable_cmd = (struct WDI_sap_ofl_enable_params*)
+        vos_mem_malloc(sizeof
+                (*sap_ofl_enable_cmd));
+    if (!sap_ofl_enable_cmd) {
+        VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+                "%s: VOS MEM Alloc Failure", __func__);
+        vos_mem_free(sap_auth_offload_info);
+        return VOS_STATUS_E_NOMEM;
+    }
+    vos_mem_zero(sap_ofl_enable_cmd, sizeof(*sap_ofl_enable_cmd));
+    vos_mem_copy(sap_ofl_enable_cmd->macAddr,
+            sap_auth_offload_info->macAddr, VOS_MAC_ADDRESS_LEN);
+
+    sap_ofl_enable_cmd->enable = sap_auth_offload_info->sap_auth_offload_enable;
+    sap_ofl_enable_cmd->psk_len = psk_len;
+    switch (sap_auth_offload_info->sap_auth_offload_sec_type) {
+        case eSIR_OFFLOAD_WPA2PSK_CCMP:
+            sap_ofl_enable_cmd->rsn_authmode = WDI_AUTH_TYPE_RSN_PSK;
+            sap_ofl_enable_cmd->rsn_mcastcipherset = WDI_ED_CCMP;
+            sap_ofl_enable_cmd->rsn_ucastcipherset = WDI_ED_CCMP;
+            break;
+        case eSIR_OFFLOAD_NONE:
+        default:
+            VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+                  "Set SAP AP Auth offload with none support security type\n");
+            break;
+    }
+    vos_mem_copy(sap_ofl_enable_cmd->key, sap_auth_offload_info->key, psk_len);
+
+    status = WDI_process_sap_auth_offload(sap_ofl_enable_cmd);
+
+    if (WDI_STATUS_PENDING == status) {
+        VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+                FL("pending status received"));
+    } else if (WDI_STATUS_SUCCESS_SYNC != status &&
+            (WDI_STATUS_SUCCESS != status)) {
+        VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+                FL("Failure in process_sap_auth_offload API %d"), status);
+    }
+
+    vos_mem_free(sap_ofl_enable_cmd);
+    vos_mem_free(sap_auth_offload_info);
+    return CONVERT_WDI2VOS_STATUS(status) ;
+
+}
+#endif
+
 /*
  * FUNCTION: WDA_ProcessBcnMissPenaltyCount
  * Request to WDI.
@@ -16306,6 +16374,14 @@
          WDA_ProcessTLPauseInd(pWDA, pMsg->bodyval);
          break;
       }
+#ifdef SAP_AUTH_OFFLOAD
+      case WDA_SET_SAP_AUTH_OFL:
+      {
+          wda_process_sap_auth_offload(pWDA,
+                  (struct tSirSapOffloadInfo*)pMsg->bodyptr);
+          break;
+      }
+#endif
       default:
       {
          VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
diff --git a/CORE/WDI/CP/inc/wlan_qct_wdi.h b/CORE/WDI/CP/inc/wlan_qct_wdi.h
index 6f0864d..694f33c 100644
--- a/CORE/WDI/CP/inc/wlan_qct_wdi.h
+++ b/CORE/WDI/CP/inc/wlan_qct_wdi.h
@@ -6489,6 +6489,28 @@
    wpt_uint32 bitmask;
    wpt_uint32 reserved;
 };
+
+struct WDI_sap_ofl_enable_params{
+
+    wpt_macAddr macAddr;
+    /** enable/disable sap auth offload */
+    wpt_uint32 enable;
+    /** authentication mode (defined above) */
+    wpt_uint32 rsn_authmode;
+    /** unicast cipher set */
+    wpt_uint32 rsn_ucastcipherset;
+    /** mcast/group cipher set */
+    wpt_uint32 rsn_mcastcipherset;
+    /** mcast/group management frames cipher set */
+    wpt_uint32 rsn_mcastmgmtcipherset;
+    /** sap channel */
+    wpt_uint32 channel;
+    /** length of psk */
+    wpt_uint32 psk_len;
+    wpt_uint8 key[64];
+};
+
+
 /*----------------------------------------------------------------------------
  *   WDI callback types
  *--------------------------------------------------------------------------*/
@@ -12237,4 +12259,9 @@
 );
 
 void WDI_SetMgmtPktViaWQ5(wpt_boolean sendMgmtPktViaWQ5);
+WDI_Status
+WDI_process_sap_auth_offload(
+   struct WDI_sap_ofl_enable_params *sap_ofl_enable_cmd
+);
+
 #endif /* #ifndef WLAN_QCT_WDI_H */
diff --git a/CORE/WDI/CP/inc/wlan_qct_wdi_i.h b/CORE/WDI/CP/inc/wlan_qct_wdi_i.h
index 7debb41..81c80fa 100644
--- a/CORE/WDI/CP/inc/wlan_qct_wdi_i.h
+++ b/CORE/WDI/CP/inc/wlan_qct_wdi_i.h
@@ -557,8 +557,11 @@
   WDI_ANTENNA_DIVERSITY_SELECTION_REQ = WDI_MAX_REQ + 21,
   WDI_MODIFY_ROAM_PARAMS_IND = WDI_MAX_REQ + 22,
   WDI_SET_ALLOWED_ACTION_FRAMES_IND = WDI_MAX_REQ + 23,
+#ifdef SAP_AUTH_OFFLOAD
+  WDI_PROCESS_SAP_AUTH_OFFLOAD_IND = WDI_MAX_REQ +24,
+#endif
 
-  WDI_MAX_UMAC_IND = WDI_MAX_REQ + 24
+  WDI_MAX_UMAC_IND = WDI_MAX_REQ + 25
 
 }WDI_RequestEnumType;
 
@@ -6676,5 +6679,21 @@
   WDI_ControlBlockType*  pWDICtx,
   WDI_EventInfoType*     pEventData
 );
+#ifdef SAP_AUTH_OFFLOAD
+/**
+ *  WDI_ProcessSapAuthOffloadInd - Process Set sap offload enable
+ *                                         command
+ *
+ *  @pWDICtx: pointer to the WLAN DAL context
+ *  @pEventData: pointer to the event information structure
+ *
+ */
+WDI_Status
+WDI_ProcessSapAuthOffloadInd
+(
+  WDI_ControlBlockType*  pWDICtx,
+  WDI_EventInfoType*     pEventData
+ );
+#endif
 #endif /*WLAN_QCT_WDI_I_H*/
 
diff --git a/CORE/WDI/CP/src/wlan_qct_wdi.c b/CORE/WDI/CP/src/wlan_qct_wdi.c
index 18eb575..3c81622 100644
--- a/CORE/WDI/CP/src/wlan_qct_wdi.c
+++ b/CORE/WDI/CP/src/wlan_qct_wdi.c
@@ -578,6 +578,9 @@
   WDI_ProcessGetCurrentAntennaIndex,          /* WDI_ANTENNA_DIVERSITY_SELECTION_REQ  */
   WDI_ProcessBcnMissPenaltyCount,             /* WDI_MODIFY_ROAM_PARAMS_IND */
   WDI_ProcessSetAllowedActionFramesInd,  /* WDI_SET_ALLOWED_ACTION_FRAMES_IND */
+#ifdef SAP_AUTH_OFFLOAD
+  WDI_ProcessSapAuthOffloadInd,          /* WDI_PROCESS_SAP_AUTH_OFFLOAD_IND */
+#endif
 };
 
 
@@ -1299,6 +1302,9 @@
     CASE_RETURN_STRING( WDI_ANTENNA_DIVERSITY_SELECTION_REQ );
     CASE_RETURN_STRING( WDI_MODIFY_ROAM_PARAMS_IND );
     CASE_RETURN_STRING( WDI_SET_ALLOWED_ACTION_FRAMES_IND );
+#ifdef SAP_AUTH_OFFLOAD
+    CASE_RETURN_STRING( WDI_PROCESS_SAP_AUTH_OFFLOAD_IND);
+#endif
     default:
         return "Unknown WDI MessageId";
   }
@@ -24755,6 +24761,10 @@
   case WDI_PER_ROAM_SCAN_TRIGGER_REQ:
       return WLAN_HAL_PER_ROAM_SCAN_TRIGGER_REQ;
 #endif
+#ifdef SAP_AUTH_OFFLOAD
+  case WDI_PROCESS_SAP_AUTH_OFFLOAD_IND:
+      return WLAN_HAL_SAP_AUTH_OFFLOAD_IND;
+#endif
   default:
     return WLAN_HAL_MSG_MAX;
   }
@@ -38200,3 +38210,125 @@
 
     return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
 }
+#ifdef SAP_AUTH_OFFLOAD
+/**
+ *  WDI_ProcessSapAuthOffloadInd() - Process SAP AUTH ofload
+ *                                   Indication message and post it to HAL
+ *
+ *  @pWDICtx: pointer to the WLAN DAL context
+ *  @pEventData: pointer to the event information structure
+ *
+ *  Return: WDI_Status enumeration
+ */
+WDI_Status
+WDI_ProcessSapAuthOffloadInd
+(
+ WDI_ControlBlockType*  pWDICtx,
+ WDI_EventInfoType*     pEventData
+ )
+{
+    wpt_uint8*  pSendBuffer = NULL;
+    wpt_uint16  usDataOffset = 0;
+    wpt_uint16  usSendSize = 0;
+    tSapOffloadEnableMsg  *sapOffloadEnableIndParam;
+    struct  WDI_sap_ofl_enable_params *pwdiSapOflEnableParams;
+    WDI_Status wdiStatus = WDI_STATUS_SUCCESS;
+    int buffer_len = 0;
+
+    /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
+            "%s", __func__);
+
+    /*-------------------------------------------------------------------------
+      Sanity check
+      -------------------------------------------------------------------------*/
+    if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ))
+    {
+        WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
+                "%s: Invalid parameters", __func__);
+        WDI_ASSERT(0);
+        return WDI_STATUS_E_FAILURE;
+    }
+    /*-----------------------------------------------------------------------
+      Get message buffer
+      -----------------------------------------------------------------------*/
+    pwdiSapOflEnableParams =
+        (struct WDI_sap_ofl_enable_params*)pEventData->pEventData;
+
+    if (pwdiSapOflEnableParams->psk_len)
+        buffer_len = pwdiSapOflEnableParams->psk_len +
+                     sizeof(tSapOffloadEnableMsg) - sizeof(tANI_U8);
+    else
+        buffer_len = sizeof(tSapOffloadEnableMsg);
+
+    if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx,
+                    WDI_PROCESS_SAP_AUTH_OFFLOAD_IND,
+                    buffer_len,
+                    &pSendBuffer, &usDataOffset, &usSendSize))||
+            ( usSendSize < (usDataOffset + sizeof(tSapOffloadEnableMsg) )))
+    {
+        WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
+                "Unable to get send buffer in  SAP Auth offload Ind %p ",
+                pEventData);
+        WDI_ASSERT(0);
+        return WDI_STATUS_E_FAILURE;
+    }
+    pwdiSapOflEnableParams =
+        (struct WDI_sap_ofl_enable_params*)pEventData->pEventData;
+    sapOffloadEnableIndParam =
+        (tSapOffloadEnableMsg*)(pSendBuffer + usDataOffset);
+    wpalMemoryCopy(&sapOffloadEnableIndParam->selfMacAddr,
+            &pwdiSapOflEnableParams->macAddr, sizeof(wpt_macAddr));
+
+    sapOffloadEnableIndParam->enable = pwdiSapOflEnableParams->enable;
+    sapOffloadEnableIndParam->rsn_authmode =
+        pwdiSapOflEnableParams->rsn_authmode;
+    sapOffloadEnableIndParam->rsn_ucastcipherset =
+        pwdiSapOflEnableParams->rsn_ucastcipherset;
+    sapOffloadEnableIndParam->rsn_mcastcipherset =
+        pwdiSapOflEnableParams->rsn_mcastcipherset;
+    sapOffloadEnableIndParam->psk_len = pwdiSapOflEnableParams->psk_len;
+    wpalMemoryCopy(&sapOffloadEnableIndParam->psk, &pwdiSapOflEnableParams->key,
+            pwdiSapOflEnableParams->psk_len);
+    pWDICtx->pReqStatusUserData = NULL;
+    pWDICtx->pfncRspCB = NULL;
+    /*-------------------------------------------------------------------------
+      Send SAP_AUTH_OFFLOAD_IND Indication to HAL
+      -------------------------------------------------------------------------*/
+    wdiStatus =  WDI_SendIndication( pWDICtx, pSendBuffer, usSendSize);
+    return (wdiStatus != WDI_STATUS_SUCCESS) ?
+                                            wdiStatus:WDI_STATUS_SUCCESS_SYNC;
+
+}
+
+/**
+ *  WDI_process_sap_auth_offload() - Process SAP AUTH offload
+ *                                   Indication message and post it to HAL
+ *
+ *  @pWDICtx: pointer to the WLAN DAL context
+ *  @pEventData: pointer to the event information structure
+ *
+ *  Return: WDI_Status enumeration
+ */
+WDI_Status WDI_process_sap_auth_offload(
+        struct WDI_sap_ofl_enable_params  *params)
+{
+    WDI_EventInfoType wdiEventData;
+
+    if (eWLAN_PAL_FALSE == gWDIInitialized)
+    {
+        WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
+                "WDI API call before module is initialized - Fail req");
+        return WDI_STATUS_E_NOT_ALLOWED;
+    }
+
+    wdiEventData.wdiRequest = WDI_PROCESS_SAP_AUTH_OFFLOAD_IND;
+    wdiEventData.pEventData = params;
+    wdiEventData.uEventDataSize  = sizeof(*params);
+    wdiEventData.pCBfnc = NULL;
+    wdiEventData.pUserData = NULL;
+
+    return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
+}
+#endif
diff --git a/Kbuild b/Kbuild
index b7c1f72..06f553b 100644
--- a/Kbuild
+++ b/Kbuild
@@ -48,6 +48,9 @@
 
     endif
 
+# Flag to enable feature Software AP Authentication Offload
+SAP_AUTH_OFFLOAD := y
+
 # To enable CONFIG_QCOM_ESE_UPLOAD, dependent config
 # CONFIG_QCOM_ESE must be enabled.
 CONFIG_QCOM_ESE := n
@@ -658,6 +661,11 @@
 CDEFINES += -DCONFIG_ENABLE_LINUX_REG
 endif
 
+# Enable feature SAP Authentication Offload
+ifeq ($(SAP_AUTH_OFFLOAD), y)
+CDEFINES += -DSAP_AUTH_OFFLOAD
+endif
+
 CDEFINES += -DFEATURE_WLAN_CH_AVOID
 CDEFINES += -DWLAN_FEATURE_AP_HT40_24G