wlan: Support SAP Auth Offload feature

For SAP Auth offload, station assoc and disassoc will happen
in firmware.
As soon driver is in waked up state, firmware
will send Assoc or disassoc indication to host.
In case of ADD STA indication, driver will parse all caps
of connected client and will register this client to TL and HDD.
In case of DEL STA indication, driver will remove entry for
this station and will start cleanup.

Change-Id: I8ab0cc906be97be6f1f61de3e2ac9359cb7d17b0
CRs-Fixed: 753731
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index 73aba2e..39e1b2c 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -9306,6 +9306,19 @@
 
     pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
                         WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
+#ifdef SAP_AUTH_OFFLOAD
+    /* In case of sap offload, hostapd.conf is configuted with open mode and
+     * security is configured from ini file. Due to open mode in hostapd.conf
+     * privacy bit is set to false which will result in not sending,
+     * data packets as encrypted.
+     * If enable_sap_auth_offload is enabled in ini and
+     * sap_auth_offload_sec_type is type of WPA2-PSK,
+     * driver will set privacy bit to 1.
+     */
+    if (pHddCtx->cfg_ini->enable_sap_auth_offload &&
+            pHddCtx->cfg_ini->sap_auth_offload_sec_type)
+        pConfig->privacy = VOS_TRUE;
+#endif
 
     (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
 
diff --git a/CORE/HDD/src/wlan_hdd_hostapd.c b/CORE/HDD/src/wlan_hdd_hostapd.c
index 67c8b92..5913fec 100644
--- a/CORE/HDD/src/wlan_hdd_hostapd.c
+++ b/CORE/HDD/src/wlan_hdd_hostapd.c
@@ -792,52 +792,45 @@
         bool enabled)
 {
     hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
-    struct tSirSapOffloadInfo *sap_offload_info = NULL;
+    struct tSirSapOffloadInfo sap_offload_info;
 
-    /* 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,
+    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 =
+    sap_offload_info.sap_auth_offload_enable = enabled;
+    sap_offload_info.sap_auth_offload_sec_type =
         pHddCtx->cfg_ini->sap_auth_offload_sec_type;
-    sap_offload_info->key_len =
+    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) {
+    if (sap_offload_info.sap_auth_offload_enable &&
+        sap_offload_info.sap_auth_offload_sec_type)
+    {
+        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;
+                    sap_offload_info.key_len);
+            return;
         }
     }
-
-    vos_mem_copy(sap_offload_info->key,
-            pHddCtx->cfg_ini->sap_auth_offload_key,
-            sap_offload_info->key_len);
+    if (sap_offload_info.key_len)
+    {
+        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)) {
+            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;
+        return;
     }
 
     hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
             "%s: sme_set_sap_auth_offload successfully!", __func__);
-
-end:
-    vos_mem_free(sap_offload_info);
     return;
 }
 #endif
@@ -4845,6 +4838,7 @@
     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 );
 
diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h
index 26f8683..74856ae 100644
--- a/CORE/MAC/inc/sirApi.h
+++ b/CORE/MAC/inc/sirApi.h
@@ -6097,5 +6097,85 @@
     uint32_t key_len;
     uint8_t key[SIR_PSK_MAX_LEN];
 };
+
+typedef PACKED_PRE struct PACKED_POST
+{
+    /** staId returned from firmware for each STA association to SAP */
+    tANI_U8 staIdx;
+    /** bssIdx on which the STA is added */
+    tANI_U8 bssIdx;
+    /** DPU desc index of this station */
+    tANI_U8 dpuIndex;
+    /** Bcast DPU index of this station */
+    tANI_U8 bcastDpuIndex;
+    /** Bcast DPU Management index of this station */
+    tANI_U8 bcastMgmtDpuIdx;
+
+    tANI_U8 ucUcastSig;
+
+    tANI_U8 ucBcastSig;
+
+    tANI_U8 ucMgmtSig;
+    /** aid (association id) of this station */
+    tANI_U32 assoc_id;
+    /** peer station's mac addr */
+    tSirMacAddr peer_macaddr;
+    /** length of association request frame */
+    tANI_U32 data_len;
+    /* Following this structure is the byte stream of a whole
+     * association request frame of length data_len
+     */
+    tANI_U8 bufp[1];
+} tSapOfldAddStaIndMsg, *tpSapOfldAddStaIndMsg;
+
+typedef enum
+{
+    SAP_OFL_DEL_STA_FLAG_NONE       = 0x00,
+    SAP_OFL_DEL_STA_FLAG_RECONNECT  = 0x01,
+} eSapOfldDelStaFlags;
+
+typedef PACKED_PRE struct PACKED_POST
+{
+    tANI_U32 staIdx;
+    /** bssIdx on which the STA is added */
+    tANI_U32 bssIdx;
+    /** aid (association id) of this station */
+    tANI_U32 assoc_id;
+    /** peer station's mac addr */
+    tSirMacAddr peer_macaddr;
+    /** disassociation reason */
+    tANI_U32 reason;
+    /** flags - wmi_sap_ofl_del_sta_flags */
+    tANI_U32 flags;
+} tSapOfldDelStaIndMsg, *tpSapOfldDelStaIndMsg;
+
+typedef enum
+{
+    SAP_OFFLOAD_ADD_STA_IND       = 0x00,
+    SAP_OFFLOAD_DEL_STA_IND       = 0x01,
+} eSapOfldIndType;
+
+typedef PACKED_PRE struct PACKED_POST
+{
+    /* indType will be from eSapOfldIndType */
+    tANI_U32 indType;
+    /* size of this array will be depend on the indication type.
+     * Indication type can be either ADD_STA_IND or DEL_STA_IND.
+     * If indication type is ADD_STA_IND, size of this indication
+     * array will be sizeof(tSapOfldDelStaIndMsg)
+     * and if indication type is DEL_STA_IND, size of this indication
+     * arrary will be sizeof(tSapOfldAddStaIndMsg)
+     */
+    tANI_U8         indication[1];
+} tSapOfldInd;
+
+typedef PACKED_PRE struct PACKED_POST
+{
+    tANI_U32 num_indications;
+    /* size of this array will be depend on the number of indications.*/
+    tSapOfldInd indications[1];
+}tSapOfldIndications;
+
 #endif /* SAP_AUTH_OFFLOAD */
+
 #endif /* __SIR_API_H */
diff --git a/CORE/MAC/src/cfg/cfgApi.c b/CORE/MAC/src/cfg/cfgApi.c
index 9047d3a..b4c260b 100644
--- a/CORE/MAC/src/cfg/cfgApi.c
+++ b/CORE/MAC/src/cfg/cfgApi.c
@@ -957,6 +957,17 @@
     if(systemRole == eLIM_AP_ROLE)
     {
         val = sessionEntry->privacy;
+#ifdef SAP_AUTH_OFFLOAD
+        /* Support SAP Authentication Offload feature,
+         * If Auth offload security Type is not disabled
+         * driver need to enable privacy bit in beacon
+         */
+        if (pMac->sap_auth_offload && pMac->sap_auth_offload_sec_type)
+        {
+            val = 1;
+        }
+#endif
+
     }
     else
     {
diff --git a/CORE/MAC/src/include/dphGlobal.h b/CORE/MAC/src/include/dphGlobal.h
index 3dac65a..7f057c0 100644
--- a/CORE/MAC/src/include/dphGlobal.h
+++ b/CORE/MAC/src/include/dphGlobal.h
@@ -639,6 +639,12 @@
      */
     tANI_U8 isDisassocDeauthInProgress;
     bool sta_deletion_in_progress;
+#ifdef SAP_AUTH_OFFLOAD
+    tANI_U8 dpuIndex;
+    tANI_U8 bcastDpuIndex;
+    tANI_U8 bcastMgmtDpuIdx;
+    tANI_U8 ucMgmtSig;
+#endif
     struct sDphHashNode  *next;
 
 
diff --git a/CORE/MAC/src/include/parserApi.h b/CORE/MAC/src/include/parserApi.h
index 8ab00e0..b37c877 100644
--- a/CORE/MAC/src/include/parserApi.h
+++ b/CORE/MAC/src/include/parserApi.h
@@ -995,3 +995,8 @@
                                     tANI_U8 *pMgmtFrame,
                                     tANI_U32 nFrameBytes,
                                     tANI_U32 *nMissingRsnBytes);
+#ifdef SAP_AUTH_OFFLOAD
+void
+sap_auth_offload_update_rsn_ie(tpAniSirGlobal pmac,
+        tDot11fIERSNOpaque *pdot11f);
+#endif /* SAP_AUTH_OFFLOAD */
diff --git a/CORE/MAC/src/pe/lim/limAssocUtils.c b/CORE/MAC/src/pe/lim/limAssocUtils.c
index 188f2e5..f3e3879 100644
--- a/CORE/MAC/src/pe/lim/limAssocUtils.c
+++ b/CORE/MAC/src/pe/lim/limAssocUtils.c
@@ -2421,7 +2421,15 @@
     }
     else
 #endif
-        pAddStaParams->staIdx = HAL_STA_INVALID_IDX;
+#ifdef SAP_AUTH_OFFLOAD
+        if (!pMac->sap_auth_offload)
+            pAddStaParams->staIdx = HAL_STA_INVALID_IDX;
+        else
+            pAddStaParams->staIdx = pStaDs->staIndex;
+#else
+            pAddStaParams->staIdx = HAL_STA_INVALID_IDX;
+#endif
+
     pAddStaParams->staType = pStaDs->staType;
 
     pAddStaParams->updateSta = updateEntry;
@@ -2593,11 +2601,29 @@
     "p2pCapableSta: %d"), pAddStaParams->htLdpcCapable,
     pAddStaParams->vhtLdpcCapable, pAddStaParams->p2pCapableSta);
 
+#ifdef SAP_AUTH_OFFLOAD
+    if (pMac->sap_auth_offload) {
+        pAddStaParams->dpuIndex =  pStaDs->dpuIndex;
+        pAddStaParams->bcastDpuIndex = pStaDs->bcastDpuIndex;
+        pAddStaParams->bcastMgmtDpuIdx = pStaDs->bcastMgmtDpuIdx;
+        pAddStaParams->ucUcastSig = pStaDs->ucUcastSig;
+        pAddStaParams->ucBcastSig = pStaDs->ucBcastSig;
+        pAddStaParams->ucMgmtSig = pStaDs->ucMgmtSig;
+    }
+#endif
+
     //we need to defer the message until we get the response back from HAL.
     if (pAddStaParams->respReqd)
         SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
 
-    msgQ.type = WDA_ADD_STA_REQ;
+#ifdef SAP_AUTH_OFFLOAD
+    if (pMac->sap_auth_offload)
+        msgQ.type = WDA_SAP_OFL_ADD_STA;
+    else
+        msgQ.type = WDA_ADD_STA_REQ;
+#else
+        msgQ.type = WDA_ADD_STA_REQ;
+#endif
 
     msgQ.reserved = 0;
     msgQ.bodyptr = pAddStaParams;
@@ -2723,7 +2749,14 @@
     pDelStaParams->sessionId = psessionEntry->peSessionId;
     
     pDelStaParams->status  = eHAL_STATUS_SUCCESS;
+#ifdef SAP_AUTH_OFFLOAD
+    if (pMac->sap_auth_offload)
+        msgQ.type = WDA_SAP_OFL_DEL_STA;
+    else
+        msgQ.type = WDA_DELETE_STA_REQ;
+#else
     msgQ.type = WDA_DELETE_STA_REQ;
+#endif
     msgQ.reserved = 0;
     msgQ.bodyptr = pDelStaParams;
     msgQ.bodyval = 0;
diff --git a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
index cb83c73..2e1d2af 100644
--- a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
+++ b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
@@ -679,6 +679,66 @@
 } /*** end limProcessEXTScanRealTimeData() ***/
 #endif /* WLAN_FEATURE_EXTSCAN */
 
+#ifdef SAP_AUTH_OFFLOAD
+/*
+ * lim_process_sap_offload_indication: function to process add sta/ del sta
+ *                   indication for SAP auth offload.
+ *
+ * @pMac: mac context
+ * @pRxPacketInfo: rx buffer
+ *
+ * This Function will go through buffer and if
+ * indication type is ADD_STA_IND, function will extract all data related to
+ * client and will call limAddSta
+ * and if indication type is DEL_STA_IND, function will call
+ * limSendSmeDisassocInd to do cleanup for station.
+ *
+ * Return : none
+ */
+static void lim_process_sap_offload_indication(tpAniSirGlobal pMac,
+        tANI_U8 *pRxPacketInfo)
+{
+    int i = 0;
+    tSapOfldIndications *sap_offload_indication_rx_buf =
+        (tSapOfldIndications *)WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
+    tSapOfldInd *sap_offload_ind =
+        (tSapOfldInd*)sap_offload_indication_rx_buf->indications;
+
+    limLog( pMac, LOG1,
+            FL("Notify SME with Sap Offload ind and indication type is %d  num_indication %d \n"),
+            sap_offload_ind->indType,
+            (tANI_U8) sap_offload_indication_rx_buf->num_indications);
+
+    for (i=1; i <= (tANI_U8)(sap_offload_indication_rx_buf->num_indications);
+            i++)
+    {
+        if (sap_offload_ind->indType == SAP_OFFLOAD_ADD_STA_IND)
+        {
+            tSapOfldAddStaIndMsg *add_sta;
+            add_sta = (tSapOfldAddStaIndMsg *)sap_offload_ind->indication;
+            lim_sap_offload_add_sta(pMac, add_sta);
+            if (sap_offload_indication_rx_buf->num_indications > 1)
+                sap_offload_ind =
+                    (tSapOfldInd *)((tANI_U8 *)sap_offload_ind +
+                            sizeof(tSapOfldAddStaIndMsg));
+        }
+        else if (sap_offload_ind->indType == SAP_OFFLOAD_DEL_STA_IND)
+        {
+            tSapOfldDelStaIndMsg *del_sta;
+            del_sta = (tSapOfldDelStaIndMsg *)sap_offload_ind->indication;
+            lim_sap_offload_del_sta(pMac, del_sta);
+            sap_offload_ind = (tSapOfldInd *)((tANI_U8 *)sap_offload_ind +
+                    sizeof(tSapOfldDelStaIndMsg));
+        }
+        else
+        {
+            limLog(pMac, LOGE, FL("No Valid indication for connected station"));
+        }
+    }
+
+}
+#endif
+
 /**
  * limHandle80211Frames()
  *
@@ -715,6 +775,15 @@
     *pDeferMsg= false;
     limGetBDfromRxPacket(pMac, limMsg->bodyptr, (tANI_U32 **)&pRxPacketInfo);
 
+#ifdef SAP_AUTH_OFFLOAD
+    if ((WDA_GET_SAP_AUTHOFFLOADIND(pRxPacketInfo)  == 1) &&
+         pMac->sap_auth_offload)
+    {
+        lim_process_sap_offload_indication(pMac, pRxPacketInfo);
+        goto end;
+    }
+#endif
+
 #ifdef WLAN_FEATURE_EXTSCAN
 
     if ( WDA_GET_EXTSCANFULLSCANRESIND(pRxPacketInfo))
@@ -2417,7 +2486,6 @@
          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/limProcessSmeReqMessages.c b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
index 72840ab..8c02628 100644
--- a/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
+++ b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
@@ -4063,7 +4063,94 @@
 
 } /*** end __limProcessSmeAssocCnfNew() ***/
 
+#ifdef SAP_AUTH_OFFLOAD
+/**
+ * __lim_process_sme_assoc_offload_cnf() station connection confirmation
+ *                          message from SME.
+ * @pMac: SirGlobal handler
+ * @msgType: message type
+ * @pMsgBuf: message body
+ *
+ * This function handles the station connect confirm of
+ * Software AP authentication offload feature
+ *
+ * Return: None
+ */
+    static void
+__lim_process_sme_assoc_offload_cnf(tpAniSirGlobal pmac,
+        tANI_U32 msg_type,
+        tANI_U32 *pmsg_buf)
+{
+    tSirSmeAssocCnf assoc_cnf;
+    tpDphHashNode sta_ds = NULL;
+    tpPESession psession_entry= NULL;
+    tANI_U8 session_id;
+    tANI_U16 aid=0;
 
+    if (pmsg_buf == NULL)
+    {
+        limLog(pmac, LOGE, FL("pmsg_buf is NULL "));
+        return;
+    }
+
+    if ((limAssocCnfSerDes(pmac, &assoc_cnf, (tANI_U8 *) pmsg_buf) ==
+                eSIR_FAILURE) || !__limIsSmeAssocCnfValid(&assoc_cnf))
+    {
+        limLog(pmac, LOGE, FL("Received invalid SME_RE(ASSOC)_CNF message "));
+        return;
+    }
+
+    if((psession_entry =
+               peFindSessionByBssid(pmac, assoc_cnf.bssId, &session_id))== NULL)
+    {
+        limLog(pmac, LOGE, FL("session does not exist for given bssId"));
+        goto end;
+    }
+
+    if ((!LIM_IS_AP_ROLE(psession_entry)) ||
+           ((psession_entry->limSmeState != eLIM_SME_NORMAL_STATE) &&
+           (psession_entry->limSmeState != eLIM_SME_NORMAL_CHANNEL_SCAN_STATE)))
+    {
+        limLog(pmac, LOGE,
+                FL("Received unexpected message %X in state %X, in role %X"),
+                msg_type, psession_entry->limSmeState,
+                GET_LIM_SYSTEM_ROLE(psession_entry));
+        goto end;
+    }
+    sta_ds = dphGetHashEntry(pmac,
+            assoc_cnf.aid,
+            &psession_entry->dph.dphHashTable);
+    if (sta_ds != NULL)
+    {
+        aid = sta_ds->assocId;
+        /* Deactivate/delete CNF_WAIT timer since ASSOC_CNF
+         * has been received */
+        limDeactivateAndChangePerStaIdTimer(pmac,
+                eLIM_CNF_WAIT_TIMER,
+                aid);
+    }
+
+end:
+    if((psession_entry != NULL) && (sta_ds != NULL))
+    {
+        if ( psession_entry->parsedAssocReq[aid] != NULL )
+        {
+            if ( ((tpSirAssocReq)
+                        (psession_entry->parsedAssocReq[aid]))->assocReqFrame)
+            {
+                vos_mem_free(((tpSirAssocReq)
+                         (psession_entry->parsedAssocReq[aid]))->assocReqFrame);
+                ((tpSirAssocReq)
+                 (psession_entry->parsedAssocReq[aid]))->assocReqFrame =
+                    NULL;
+            }
+            vos_mem_free(psession_entry->parsedAssocReq[aid]);
+            psession_entry->parsedAssocReq[aid] = NULL;
+        }
+    }
+
+} /*** end __lim_process_sme_assoc_offload_cnf() ***/
+#endif /* SAP_AUTH_OFFLOAD */
 
 
 static void
@@ -5713,7 +5800,14 @@
                 limLog(pMac, LOG1, FL("Received ASSOC_CNF message"));
             else
                 limLog(pMac, LOG1, FL("Received REASSOC_CNF message"));
+#ifdef SAP_AUTH_OFFLOAD
+            if (pMac->sap_auth_offload)
+                __lim_process_sme_assoc_offload_cnf(pMac, pMsg->type, pMsgBuf);
+            else
+                __limProcessSmeAssocCnfNew(pMac, pMsg->type, pMsgBuf);
+#else
             __limProcessSmeAssocCnfNew(pMac, pMsg->type, pMsgBuf);
+#endif /* SAP_AUTH_OFFLOAD */
             break;
 
         case eWNI_SME_ADDTS_REQ:
diff --git a/CORE/MAC/src/pe/lim/limUtils.c b/CORE/MAC/src/pe/lim/limUtils.c
index f8c315a..4c08388 100644
--- a/CORE/MAC/src/pe/lim/limUtils.c
+++ b/CORE/MAC/src/pe/lim/limUtils.c
@@ -59,6 +59,9 @@
 #ifdef WLAN_FEATURE_11W
 #include "wniCfg.h"
 #endif
+#ifdef SAP_AUTH_OFFLOAD
+#include "limAssocUtils.h"
+#endif
 
 /* Static global used to mark situations where pMac->lim.gLimTriggerBackgroundScanDuringQuietBss is SET
  * and limTriggerBackgroundScanDuringQuietBss() returned failure.  In this case, we will stop data
@@ -8617,3 +8620,513 @@
           limLog(mac_ctx, LOG1, FL("Clearing Immed Blk Ack:no AP support"));
     }
 }
+#ifdef SAP_AUTH_OFFLOAD
+/**
+ * _sap_offload_parse_assoc_req - Parse assoc request and store it.
+ *
+ * @pmac: mac context
+ * @assoc_req: Assoc request
+ * @add_sta_req: Add Sta request
+ *
+ * This function process recieved add sta message and store it as
+ * sta ds entry. This function will add this sta entry to DPH as well.
+ *
+ * Return: DPH hash node
+ */
+static tpDphHashNode
+_sap_offload_parse_assoc_req(tpAniSirGlobal pmac,
+        tpSirAssocReq assoc_req,
+        tSapOfldAddStaIndMsg *add_sta_req)
+{
+    tpSirMacAssocReqFrame mac_assoc_req = NULL;
+    tpSirAssocReq temp_assoc_req;
+    tSirRetStatus status;
+    tpDphHashNode sta_ds = NULL;
+    uint8_t *frame_body = NULL;
+
+    tpPESession session_entry = limIsApSessionActive(pmac);
+
+    if (session_entry == NULL)
+    {
+        PELOGE(limLog(pmac, LOGE, FL(" Session not found"));)
+            return NULL;
+    }
+
+    /* Update Attribute and Remove IE for
+     * Software AP Authentication Offload
+     */
+    frame_body = (tANI_U8 *)add_sta_req->bufp;
+    mac_assoc_req = (tpSirMacAssocReqFrame)frame_body;
+    mac_assoc_req->capabilityInfo.privacy = 0;
+
+    status = sirConvertAssocReqFrame2Struct(pmac,
+            frame_body,
+            add_sta_req->data_len,
+            assoc_req);
+    if (status != eSIR_SUCCESS)
+    {
+        limLog(pmac, LOGW, FL("sap_offload_add_sta_req parse error"));
+        goto error;
+    }
+    /* For software AP Auth Offload feature
+     * Host will take it as none security station
+     * Force change to none security
+     */
+    assoc_req->rsnPresent = 0;
+    assoc_req->wpaPresent = 0;
+
+    sta_ds = dphAddHashEntry(pmac,
+            add_sta_req->peer_macaddr,
+            add_sta_req->assoc_id,
+            &session_entry->dph.dphHashTable);
+    if (sta_ds == NULL)
+    {
+        /* Could not add hash table entry at DPH */
+        limLog(pmac, LOGE,
+                FL("could not add hash entry at DPH for aid=%d, MacAddr:"
+                    MAC_ADDRESS_STR),
+                add_sta_req->assoc_id,MAC_ADDR_ARRAY(add_sta_req->peer_macaddr));
+        goto error;
+    }
+
+    if (session_entry->parsedAssocReq != NULL)
+    {
+        temp_assoc_req = session_entry->parsedAssocReq[sta_ds->assocId];
+        if (temp_assoc_req != NULL)
+        {
+            if (temp_assoc_req->assocReqFrame)
+            {
+                vos_mem_free(temp_assoc_req->assocReqFrame);
+                temp_assoc_req->assocReqFrame = NULL;
+                temp_assoc_req->assocReqFrameLength = 0;
+            }
+            vos_mem_free(temp_assoc_req);
+            temp_assoc_req = NULL;
+        }
+        session_entry->parsedAssocReq[sta_ds->assocId] = assoc_req;
+    }
+error:
+    return sta_ds;
+}
+
+/**
+ * _sap_offload_parse_sta_capability - Parse sta caps from assoc request
+ *
+ * @sta_ds: STA state node
+ * @assoc_req: Assoc request
+ * @add_sta_req: Add Sta request
+ *
+ * This function process recieved add sta message and store station's caps
+ * in station ds entry.
+ *
+ * Return: none
+ */
+static void
+_sap_offload_parse_sta_capability(tpDphHashNode sta_ds,
+        tpSirAssocReq assoc_req,
+        tSapOfldAddStaIndMsg *add_sta_req)
+
+{
+
+    sta_ds->mlmStaContext.htCapability = assoc_req->HTCaps.present;
+#ifdef WLAN_FEATURE_11AC
+    sta_ds->mlmStaContext.vhtCapability = assoc_req->VHTCaps.present;
+#endif
+    sta_ds->qos.addtsPresent = (assoc_req->addtsPresent==0) ? false : true;
+    sta_ds->qos.addts        = assoc_req->addtsReq;
+    sta_ds->qos.capability   = assoc_req->qosCapability;
+    sta_ds->versionPresent   = 0;
+    /* short slot and short preamble should be
+     * updated before doing limaddsta
+     */
+    sta_ds->shortPreambleEnabled =
+        (tANI_U8)assoc_req->capabilityInfo.shortPreamble;
+    sta_ds->shortSlotTimeEnabled =
+        (tANI_U8)assoc_req->capabilityInfo.shortSlotTime;
+
+    sta_ds->valid = 0;
+    /* The Auth Type of Software AP Authentication Offload
+     * is always Open System is host side
+     */
+    sta_ds->mlmStaContext.authType = eSIR_OPEN_SYSTEM;
+    sta_ds->staType = STA_ENTRY_PEER;
+
+    /* Assoc Response frame to requesting STA */
+    sta_ds->mlmStaContext.subType = 0;
+
+    sta_ds->mlmStaContext.listenInterval = assoc_req->listenInterval;
+    sta_ds->mlmStaContext.capabilityInfo = assoc_req->capabilityInfo;
+
+    /* The following count will be used to knock-off the station
+     * if it doesn't come back to receive the buffered data.
+     * The AP will wait for numTimSent number of beacons after
+     * sending TIM information for the station, before assuming that
+     * the station is no more associated and disassociates it
+     */
+
+    /* timWaitCount is used by PMM for monitoring the STA's in PS for LINK*/
+    sta_ds->timWaitCount =
+        (tANI_U8)GET_TIM_WAIT_COUNT(assoc_req->listenInterval);
+
+    /* Initialise the Current successful
+     * MPDU's tranfered to this STA count as 0
+     */
+    sta_ds->curTxMpduCnt = 0;
+}
+
+/**
+ * _sap_offload_parse_sta_vht - Parse sta's HT/VHT caps from assoc request
+ *
+ * @pmac: mac context
+ * @sta_ds: STA state node
+ * @assoc_req: Assoc request
+ *
+ * This function process recieved add sta message and store station's HT and
+ * and VHT caps and store them in station ds entry.
+ *
+ * Return: tSirRetStatus
+ */
+static tSirRetStatus
+_sap_offload_parse_sta_vht(tpAniSirGlobal pmac,
+        tpDphHashNode sta_ds,
+        tpSirAssocReq assoc_req)
+{
+    tpPESession session_entry = limIsApSessionActive(pmac);
+
+    if (IS_DOT11_MODE_HT(session_entry->dot11mode) &&
+            assoc_req->HTCaps.present && assoc_req->wmeInfoPresent)
+    {
+        sta_ds->htGreenfield = (tANI_U8)assoc_req->HTCaps.greenField;
+        sta_ds->htAMpduDensity = assoc_req->HTCaps.mpduDensity;
+        sta_ds->htDsssCckRate40MHzSupport =
+            (tANI_U8)assoc_req->HTCaps.dsssCckMode40MHz;
+        sta_ds->htLsigTXOPProtection =
+            (tANI_U8)assoc_req->HTCaps.lsigTXOPProtection;
+        sta_ds->htMaxAmsduLength =
+            (tANI_U8)assoc_req->HTCaps.maximalAMSDUsize;
+        sta_ds->htMaxRxAMpduFactor = assoc_req->HTCaps.maxRxAMPDUFactor;
+        sta_ds->htMIMOPSState = assoc_req->HTCaps.mimoPowerSave;
+        sta_ds->htShortGI20Mhz = (tANI_U8)assoc_req->HTCaps.shortGI20MHz;
+        sta_ds->htShortGI40Mhz = (tANI_U8)assoc_req->HTCaps.shortGI40MHz;
+        sta_ds->htSupportedChannelWidthSet =
+            (tANI_U8)assoc_req->HTCaps.supportedChannelWidthSet;
+        /* peer just follows AP; so when we are softAP/GO,
+         * we just store our session entry's secondary channel offset here
+         * in peer INFRA STA. However, if peer's 40MHz channel width support
+         * is disabled then secondary channel will be zero
+         */
+        sta_ds->htSecondaryChannelOffset =
+            (sta_ds->htSupportedChannelWidthSet) ?
+            session_entry->htSecondaryChannelOffset : 0;
+#ifdef WLAN_FEATURE_11AC
+        if (assoc_req->operMode.present)
+        {
+            sta_ds->vhtSupportedChannelWidthSet =
+                (tANI_U8)((assoc_req->operMode.chanWidth ==
+                            eHT_CHANNEL_WIDTH_80MHZ) ?
+                        WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ :
+                        WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ);
+            sta_ds->htSupportedChannelWidthSet =
+                (tANI_U8)(assoc_req->operMode.chanWidth ?
+                        eHT_CHANNEL_WIDTH_40MHZ : eHT_CHANNEL_WIDTH_20MHZ);
+        }
+        else if (assoc_req->VHTCaps.present)
+        {
+            /* Check if STA has enabled it's channel bonding mode.
+             * If channel bonding mode is enabled, we decide based on
+             * SAP's current configuration else, we set it to VHT20.
+             */
+            sta_ds->vhtSupportedChannelWidthSet =
+                (tANI_U8)((sta_ds->htSupportedChannelWidthSet ==
+                            eHT_CHANNEL_WIDTH_20MHZ) ?
+                        WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ :
+                        session_entry->vhtTxChannelWidthSet );
+            sta_ds->htMaxRxAMpduFactor = assoc_req->VHTCaps.maxAMPDULenExp;
+        }
+
+        /* Lesser among the AP and STA bandwidth of operation. */
+        sta_ds->htSupportedChannelWidthSet =
+            (sta_ds->htSupportedChannelWidthSet <
+             session_entry->htSupportedChannelWidthSet) ?
+            sta_ds->htSupportedChannelWidthSet :
+            session_entry->htSupportedChannelWidthSet ;
+#endif
+        sta_ds->baPolicyFlag = 0xFF;
+        sta_ds->htLdpcCapable = (tANI_U8)assoc_req->HTCaps.advCodingCap;
+    }
+
+    if (assoc_req->VHTCaps.present && assoc_req->wmeInfoPresent)
+        sta_ds->vhtLdpcCapable = (tANI_U8)assoc_req->VHTCaps.ldpcCodingCap;
+
+    if (!assoc_req->wmeInfoPresent)
+    {
+        sta_ds->mlmStaContext.htCapability = 0;
+#ifdef WLAN_FEATURE_11AC
+        sta_ds->mlmStaContext.vhtCapability = 0;
+#endif
+    }
+#ifdef WLAN_FEATURE_11AC
+    if (limPopulateMatchingRateSet(pmac,
+                sta_ds,
+                &(assoc_req->supportedRates),
+                &(assoc_req->extendedRates),
+                assoc_req->HTCaps.supportedMCSSet,
+                &(assoc_req->propIEinfo.propRates),
+                session_entry , &assoc_req->VHTCaps)
+            != eSIR_SUCCESS)
+    {
+#else
+        if (limPopulateMatchingRateSet(pmac,
+                    sta_ds,
+                    &(assoc_req->supportedRates),
+                    &(assoc_req->extendedRates),
+                    assoc_req->HTCaps.supportedMCSSet,
+                    &(assoc_req->propIEinfo.propRates),
+                    session_entry) != eSIR_SUCCESS)
+        {
+#endif
+            limLog(pmac, LOGE,
+                    FL("Rate set mismatched for aid=%d, MacAddr: "
+                        MAC_ADDRESS_STR),
+                    sta_ds->assocId, MAC_ADDR_ARRAY(sta_ds->staAddr));
+            goto error;
+        }
+        return eSIR_SUCCESS;
+error:
+        return eSIR_FAILURE;
+}
+
+/**
+ * _sap_offload_parse_sta_qos - Parse sta's QOS caps from assoc request
+ *
+ * @pmac: mac context
+ * @sta_ds: STA state node
+ * @assoc_req: Assoc request
+ *
+ * This function process recieved add sta message and store station's QOS
+ * store them in station ds entry.
+ *
+ * Return: none
+ */
+static void
+ _sap_offload_parse_sta_qos(tpAniSirGlobal pmac,
+            tpDphHashNode sta_ds,
+            tpSirAssocReq assoc_req)
+{
+    tHalBitVal qos_mode;
+    tHalBitVal wsm_mode, wme_mode;
+    tpPESession session_entry = limIsApSessionActive(pmac);
+
+    limGetQosMode(session_entry, &qos_mode);
+    sta_ds->qosMode    = eANI_BOOLEAN_FALSE;
+    sta_ds->lleEnabled = eANI_BOOLEAN_FALSE;
+
+    if (assoc_req->capabilityInfo.qos && (qos_mode == eHAL_SET))
+    {
+        sta_ds->lleEnabled = eANI_BOOLEAN_TRUE;
+        sta_ds->qosMode    = eANI_BOOLEAN_TRUE;
+    }
+
+    sta_ds->wmeEnabled = eANI_BOOLEAN_FALSE;
+    sta_ds->wsmEnabled = eANI_BOOLEAN_FALSE;
+    limGetWmeMode(session_entry, &wme_mode);
+    if ((!sta_ds->lleEnabled) && assoc_req->wmeInfoPresent &&
+            (wme_mode == eHAL_SET))
+    {
+        sta_ds->wmeEnabled = eANI_BOOLEAN_TRUE;
+        sta_ds->qosMode = eANI_BOOLEAN_TRUE;
+        limGetWsmMode(session_entry, &wsm_mode);
+        /* WMM_APSD - WMM_SA related processing should be
+         * separate; WMM_SA and WMM_APSD can coexist
+         */
+        if (assoc_req->WMMInfoStation.present)
+        {
+            /* check whether AP supports or not */
+            if ((session_entry->limSystemRole == eLIM_AP_ROLE)
+                    && (session_entry->apUapsdEnable == 0) &&
+                    (assoc_req->WMMInfoStation.acbe_uapsd
+                     || assoc_req->WMMInfoStation.acbk_uapsd
+                     || assoc_req->WMMInfoStation.acvo_uapsd
+                     || assoc_req->WMMInfoStation.acvi_uapsd))
+            {
+                /*
+                 * Received Re/Association Request from
+                 * STA when UPASD is not supported
+                 */
+                limLog( pmac, LOGE, FL( "AP do not support UAPSD so reply "
+                            "to STA accordingly" ));
+                /* update UAPSD and send it to LIM to add STA */
+                sta_ds->qos.capability.qosInfo.acbe_uapsd = 0;
+                sta_ds->qos.capability.qosInfo.acbk_uapsd = 0;
+                sta_ds->qos.capability.qosInfo.acvo_uapsd = 0;
+                sta_ds->qos.capability.qosInfo.acvi_uapsd = 0;
+                sta_ds->qos.capability.qosInfo.maxSpLen =   0;
+            }
+            else
+            {
+                /* update UAPSD and send it to LIM to add STA */
+                sta_ds->qos.capability.qosInfo.acbe_uapsd =
+                    assoc_req->WMMInfoStation.acbe_uapsd;
+                sta_ds->qos.capability.qosInfo.acbk_uapsd =
+                    assoc_req->WMMInfoStation.acbk_uapsd;
+                sta_ds->qos.capability.qosInfo.acvo_uapsd =
+                    assoc_req->WMMInfoStation.acvo_uapsd;
+                sta_ds->qos.capability.qosInfo.acvi_uapsd =
+                    assoc_req->WMMInfoStation.acvi_uapsd;
+                sta_ds->qos.capability.qosInfo.maxSpLen =
+                    assoc_req->WMMInfoStation.max_sp_length;
+            }
+        }
+        if (assoc_req->wsmCapablePresent && (wsm_mode == eHAL_SET))
+            sta_ds->wsmEnabled = eANI_BOOLEAN_TRUE;
+    }
+}
+
+/**
+ * lim_sap_offload_add_sta - Parse Add sta request from firmware
+ *
+ * @pmac: mac context
+ * @lim_msgq: Add Sta indication buffer
+ *
+ * This function will recieve buffer from firmware. This buffer will store
+ * information about connected client. driver will process this buffer and
+ * will register this client with driver. Driver will call limAddSta
+ *
+ * Return: none
+ */
+void lim_sap_offload_add_sta(tpAniSirGlobal pmac,
+        tSapOfldAddStaIndMsg *lim_msgq)
+{
+    tpSirAssocReq assoc_req = NULL;
+    tpDphHashNode sta_ds = NULL;
+
+    tSapOfldAddStaIndMsg  *add_sta_req = NULL;
+    tpPESession session_entry = limIsApSessionActive(pmac);
+
+    if (session_entry == NULL)
+    {
+        PELOGE(limLog(pmac, LOGE, FL(" Session not found"));)
+            return;
+    }
+    add_sta_req = lim_msgq;
+    assoc_req = vos_mem_malloc(sizeof(*assoc_req));
+    if (NULL == assoc_req) {
+        limLog(pmac, LOGP, FL("Allocate Memory failed in AssocReq"));
+        return;
+    }
+    vos_mem_set(assoc_req , sizeof(*assoc_req), 0);
+
+    /* parse Assoc req frame for station information */
+    sta_ds = _sap_offload_parse_assoc_req(pmac, assoc_req, add_sta_req);
+    if (sta_ds == NULL)
+    {
+        PELOGE(limLog(pmac, LOGE, FL("could not add hash entry for"));)
+            limPrintMacAddr(pmac, add_sta_req->peer_macaddr, LOGE);
+        vos_mem_free(assoc_req);
+        goto error;
+    }
+
+    /* Parse Station Capability */
+    _sap_offload_parse_sta_capability(sta_ds, assoc_req, add_sta_req);
+
+    /* Parse Station HT/VHT information */
+    if (_sap_offload_parse_sta_vht(pmac, sta_ds, assoc_req)
+            == eSIR_FAILURE)
+    {
+        PELOGE(limLog(pmac, LOGE, FL("mismatch ht/vht information for "));)
+            limPrintMacAddr(pmac, add_sta_req->peer_macaddr, LOGE);
+            vos_mem_free(assoc_req);
+        goto error;
+
+    }
+
+    /* Parse Station QOS information */
+    _sap_offload_parse_sta_qos(pmac, sta_ds, assoc_req);
+
+    session_entry->parsedAssocReq[sta_ds->assocId] = assoc_req;
+    sta_ds->staIndex = add_sta_req->staIdx;
+    sta_ds->dpuIndex = add_sta_req->dpuIndex;
+    sta_ds->bcastDpuIndex = add_sta_req->bcastDpuIndex;
+    sta_ds->bcastMgmtDpuIdx = add_sta_req->bcastMgmtDpuIdx;
+    sta_ds->ucUcastSig = add_sta_req->ucUcastSig;
+    sta_ds->ucBcastSig = add_sta_req->ucBcastSig;
+    sta_ds->ucMgmtSig = add_sta_req->ucMgmtSig;
+
+
+    if (limAddSta(pmac, sta_ds, false, session_entry) != eSIR_SUCCESS) {
+        limLog(pmac, LOGE, FL("could not Add STA with assocId=%d"),
+                sta_ds->assocId);
+    }
+
+error:
+    return;
+}
+
+/**
+ * lim_sap_offload_del_sta - Parse Del sta request from firmware
+ *
+ * @pmac: mac context
+ * @lim_msgq: Del Sta indication buffer
+ *
+ * This function will recieve buffer from firmware. This buffer will
+ * have information about clinet to remove with reason code.
+ * This function will call limSendSmeDisassocInd to do cleanup
+ * for station entry
+ *
+ * Return: none
+ */
+void
+lim_sap_offload_del_sta(tpAniSirGlobal pmac, tSapOfldDelStaIndMsg *lim_msgq)
+{
+    tSapOfldDelStaIndMsg *del_sta_req = NULL;
+    tpDphHashNode sta_ds = NULL;
+    tANI_U16 assoc_id = 0;
+    tpPESession psession_entry = limIsApSessionActive(pmac);
+
+    if (psession_entry == NULL)
+    {
+        PELOGE(limLog(pmac, LOGE, FL(" Session not found"));)
+            goto error;
+    }
+
+    del_sta_req = lim_msgq;
+    sta_ds = dphLookupHashEntry(pmac,
+            del_sta_req->peer_macaddr,
+            &assoc_id,
+            &psession_entry->dph.dphHashTable);
+    if (sta_ds == NULL)
+    {
+        /*
+         * Disassociating STA is not associated.
+         * Log error
+         */
+        PELOGE(limLog(pmac, LOGE,
+                    FL("received del sta event that sta not exist in table "
+                        "reasonCode=%d, addr "MAC_ADDRESS_STR),
+                    del_sta_req->reason,
+                    MAC_ADDR_ARRAY(del_sta_req->peer_macaddr));)
+            goto error;
+    }
+
+    if (assoc_id != (tANI_U16)del_sta_req->assoc_id)
+    {
+        /*
+         * Associate Id mismatch
+         * Log error
+         */
+        PELOGE(limLog(pmac, LOGE,
+                    FL("received del sta event that sta assoc Id mismatch"));)
+            goto error;
+    }
+
+    sta_ds->mlmStaContext.cleanupTrigger = eLIM_PEER_ENTITY_DISASSOC;
+    sta_ds->mlmStaContext.disassocReason =
+        (tSirMacReasonCodes) del_sta_req->reason;
+    sta_ds->mlmStaContext.updateContext = 1;
+
+    limSendSmeDisassocInd(pmac, sta_ds, psession_entry);
+
+error:
+    return;
+}
+#endif /* SAP_AUTH_OFFLOAD */
diff --git a/CORE/MAC/src/pe/lim/limUtils.h b/CORE/MAC/src/pe/lim/limUtils.h
index 622774a..af21b05 100644
--- a/CORE/MAC/src/pe/lim/limUtils.h
+++ b/CORE/MAC/src/pe/lim/limUtils.h
@@ -577,5 +577,10 @@
 tANI_U8 lim_compute_ext_cap_ie_length (tDot11fIEExtCap *ext_cap);
 void lim_update_caps_info_for_bss(tpAniSirGlobal mac_ctx,
                              uint16_t *caps, uint16_t bss_caps);
-
+#ifdef SAP_AUTH_OFFLOAD
+void lim_sap_offload_add_sta(tpAniSirGlobal pmac,
+        tSapOfldAddStaIndMsg *lim_msgq);
+void lim_sap_offload_del_sta(tpAniSirGlobal pmac,
+        tSapOfldDelStaIndMsg *lim_msgq);
+#endif
 #endif /* __LIM_UTILS_H */
diff --git a/CORE/MAC/src/pe/sch/schBeaconGen.c b/CORE/MAC/src/pe/sch/schBeaconGen.c
index 0fc7989..15438a7 100644
--- a/CORE/MAC/src/pe/sch/schBeaconGen.c
+++ b/CORE/MAC/src/pe/sch/schBeaconGen.c
@@ -386,6 +386,13 @@
                        &pBcn2->WPA );
           PopulateDot11fRSNOpaque( pMac, &psessionEntry->pLimStartBssReq->rsnIE,
                        &pBcn2->RSNOpaque );
+#ifdef SAP_AUTH_OFFLOAD
+          /* Software AP Authentication Offload feature
+           * only support WPA2-PSK AES and we
+           * need to update RSNIE for beacon
+           */
+          sap_auth_offload_update_rsn_ie(pMac, &pBcn2->RSNOpaque);
+#endif
     }
 
     if(psessionEntry->limWmeEnabled)
diff --git a/CORE/SME/src/csr/csrApiRoam.c b/CORE/SME/src/csr/csrApiRoam.c
index 762ebb8..88d297b 100644
--- a/CORE/SME/src/csr/csrApiRoam.c
+++ b/CORE/SME/src/csr/csrApiRoam.c
@@ -9944,6 +9944,15 @@
                         status = csrRoamCallCallback(pMac, sessionId, pRoamInfo, 0, eCSR_ROAM_WDS_IND, eCSR_ROAM_RESULT_WDS_ASSOCIATION_IND);//Sta
                     if(CSR_IS_INFRA_AP(pRoamInfo->u.pConnectedProfile))
                     {
+#ifdef SAP_AUTH_OFFLOAD
+                        if (pMac->sap_auth_offload)
+                        {
+                            smsLog(pMac, LOGW, FL(" Auth is not required to set in Auth offload case \n"));
+                            pRoamInfo->fAuthRequired = FALSE;
+                        }
+                        else
+                        {
+#endif
                         if( CSR_IS_ENC_TYPE_STATIC( pSession->pCurRoamProfile->negotiatedUCEncryptionType ))
                         {
                             csrRoamIssueSetContextReq( pMac, sessionId, pSession->pCurRoamProfile->negotiatedUCEncryptionType, 
@@ -9956,6 +9965,9 @@
                         {
                             pRoamInfo->fAuthRequired = TRUE;
                         }
+#ifdef SAP_AUTH_OFFLOAD
+                        }
+#endif
                         status = csrRoamCallCallback(pMac, sessionId, pRoamInfo, 0, eCSR_ROAM_INFRA_IND, eCSR_ROAM_RESULT_INFRA_ASSOCIATION_IND);
                         if (!HAL_STATUS_SUCCESS(status))
                             pRoamInfo->statusCode = eSIR_SME_ASSOC_REFUSED;// Refused due to Mac filtering 
@@ -11683,7 +11695,13 @@
    }
 
     /* Incase of WEP Security encryption type is coming as part of add key. So while STart BSS dont have information */
-    if( (!CSR_IS_11n_ALLOWED(pProfile->EncryptionType.encryptionType[0] ) || ((pProfile->privacy == 1) && (pProfile->EncryptionType.encryptionType[0] == eCSR_ENCRYPT_TYPE_NONE))  ) &&
+   if (
+#ifdef SAP_AUTH_OFFLOAD
+      (!pMac->sap_auth_offload && !pMac->sap_auth_offload_sec_type) &&
+#endif
+      ((!CSR_IS_11n_ALLOWED(pProfile->EncryptionType.encryptionType[0] ) ||
+       ((pProfile->privacy == 1) &&
+       (pProfile->EncryptionType.encryptionType[0] == eCSR_ENCRYPT_TYPE_NONE)))) &&
         ((eCSR_CFG_DOT11_MODE_11N == cfgDot11Mode) ||
 #ifdef WLAN_FEATURE_11AC
         (eCSR_CFG_DOT11_MODE_11AC == cfgDot11Mode) ||
diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c
index ef14e99..2d9b957 100644
--- a/CORE/SME/src/sme_common/sme_Api.c
+++ b/CORE/SME/src/sme_common/sme_Api.c
@@ -5309,7 +5309,13 @@
       smsLog(pMac, LOGE, FL("Invalid key length %d"), pSetKey->keyLength);
       return eHAL_STATUS_FAILURE;
    }
-
+#ifdef SAP_AUTH_OFFLOAD
+   if (pMac->sap_auth_offload_sec_type)
+   {
+       smsLog(pMac, LOGW, FL("No set key is required in sap auth offload enable"));
+       return  eHAL_STATUS_SUCCESS;
+   }
+#endif
    status = sme_AcquireGlobalLock( &pMac->sme );
    if ( HAL_STATUS_SUCCESS( status ) )
    {
diff --git a/CORE/SYS/legacy/src/utils/src/parserApi.c b/CORE/SYS/legacy/src/utils/src/parserApi.c
index d408f16..d0cb17f 100644
--- a/CORE/SYS/legacy/src/utils/src/parserApi.c
+++ b/CORE/SYS/legacy/src/utils/src/parserApi.c
@@ -50,6 +50,30 @@
 #include "rrmApi.h"
 #endif
 
+#define DOT11F_RSN_VERSION 1    /* current supported version */
+#define DOT11F_RSN_OUI_SIZE 4
+#define DOT11F_RSN_CSE_NULL 0x00
+#define DOT11F_RSN_CSE_WEP40 0x01
+#define DOT11F_RSN_CSE_TKIP 0x02
+#define DOT11F_RSN_CSE_WRAP 0x03
+#define DOT11F_RSN_CSE_CCMP 0x04
+#define DOT11F_RSN_CSE_WEP104 0x05
+#define DOT11F_RSN_CSE_AES_CMAC 0x06
+
+static const tANI_U8 sirRSNOui[][ DOT11F_RSN_OUI_SIZE ] = {
+    { 0x00, 0x0F, 0xAC, 0x00 }, /* group cipher */
+    { 0x00, 0x0F, 0xAC, 0x01 }, /* WEP-40 or RSN */
+    { 0x00, 0x0F, 0xAC, 0x02 }, /* TKIP or RSN-PSK */
+    { 0x00, 0x0F, 0xAC, 0x03 }, /* Reserved */
+    { 0x00, 0x0F, 0xAC, 0x04 }, /* AES-CCMP */
+    { 0x00, 0x0F, 0xAC, 0x05 }, /* WEP-104 */
+    { 0x00, 0x40, 0x96, 0x00 }, /* CCKM */
+    /* BIP (encryption type) or RSN-PSK-SHA256 (authentication type) */
+    { 0x00, 0x0F, 0xAC, 0x06 },
+    /* RSN-8021X-SHA256 (authentication type) */
+    { 0x00, 0x0F, 0xAC, 0x05 }
+};
+
 
 
 ////////////////////////////////////////////////////////////////////////
@@ -5468,4 +5492,115 @@
    pDot11f->timeoutType = type;
    pDot11f->timeoutValue = value;
 }
+#ifdef SAP_AUTH_OFFLOAD
+tSirRetStatus
+sap_auth_offload_construct_rsn_opaque( tDot11fIERSN *pdot11f_rsn,
+        tDot11fIERSNOpaque *pdot11f)
+{
+    tANI_U32 data_len=0;
+    tANI_U8 *ptr;
+    tANI_U32 element_len=0;
+    tANI_U32 count=0;
+    ptr = (tANI_U8 *)pdot11f->data;
+    if (pdot11f_rsn->present)
+    {
+        pdot11f->present = pdot11f_rsn->present;
+        element_len = sizeof(pdot11f_rsn->version);
+        vos_mem_copy(ptr, &pdot11f_rsn->version, element_len);
+        ptr += element_len;
+        data_len += element_len;
+        element_len = sizeof(pdot11f_rsn->gp_cipher_suite);
+        vos_mem_copy(ptr, pdot11f_rsn->gp_cipher_suite, element_len);
+        ptr += element_len;
+        data_len += element_len;
+
+        if (pdot11f_rsn->pwise_cipher_suite_count)
+        {
+            element_len = sizeof(pdot11f_rsn->pwise_cipher_suite_count);
+            vos_mem_copy(ptr,
+                    &pdot11f_rsn->pwise_cipher_suite_count,
+                    element_len);
+            ptr += element_len;
+            data_len += element_len;
+            for (count = 0; count < pdot11f_rsn->pwise_cipher_suite_count;
+                    count++)
+            {
+                element_len = DOT11F_RSN_OUI_SIZE;
+                vos_mem_copy(ptr,
+                        &pdot11f_rsn->pwise_cipher_suites[count][0],
+                        element_len);
+                ptr += element_len;
+                data_len += element_len;
+            }
+        }
+
+        if (pdot11f_rsn->akm_suite_count)
+        {
+            element_len = sizeof(pdot11f_rsn->akm_suite_count);
+            vos_mem_copy(ptr, &pdot11f_rsn->akm_suite_count, element_len);
+            ptr += element_len;
+            data_len += element_len;
+            for (count = 0; count < pdot11f_rsn->akm_suite_count; count++)
+            {
+                element_len = DOT11F_RSN_OUI_SIZE;
+                vos_mem_copy(ptr,
+                        &pdot11f_rsn->akm_suites[count][0],
+                        element_len);
+                ptr += element_len;
+                data_len += element_len;
+            }
+        }
+
+        element_len = sizeof(pdot11f_rsn->RSN_Cap);
+        vos_mem_copy(ptr, pdot11f_rsn->RSN_Cap, element_len);
+        ptr += element_len;
+        data_len += element_len;
+    }
+    pdot11f->num_data = data_len;
+    return eSIR_SUCCESS;
+}
+
+void
+sap_auth_offload_update_rsn_ie( tpAniSirGlobal pmac,
+        tDot11fIERSNOpaque *pdot11f)
+{
+    tDot11fIERSN *pdot11f_rsn;
+    pdot11f_rsn = vos_mem_malloc(sizeof(tDot11fIERSN));
+    vos_mem_set(pdot11f_rsn, sizeof(tDot11fIERSN), 0);
+    /* Assign RSN IE for Software AP Authentication offload security */
+    if (pmac->sap_auth_offload && pmac->sap_auth_offload_sec_type)
+    {
+        switch (pmac->sap_auth_offload_sec_type)
+        {
+            case eSIR_OFFLOAD_WPA2PSK_CCMP:
+                /* Only Support one kind of Cipher Suit for
+                 * Software AP authentication offload
+                 */
+                pdot11f_rsn->present = 1;
+                pdot11f_rsn->version = 1;
+                vos_mem_copy(pdot11f_rsn->gp_cipher_suite,
+                        &sirRSNOui[DOT11F_RSN_CSE_CCMP][0],
+                        DOT11F_RSN_OUI_SIZE);
+                pdot11f_rsn->pwise_cipher_suite_count = 1;
+                vos_mem_copy(&(pdot11f_rsn->pwise_cipher_suites[0][0]),
+                        &sirRSNOui[DOT11F_RSN_CSE_CCMP][0],
+                        DOT11F_RSN_OUI_SIZE);
+                pdot11f_rsn->akm_suite_count = 1;
+                vos_mem_copy(&(pdot11f_rsn->akm_suites[0][0]),
+                        &sirRSNOui[DOT11F_RSN_CSE_TKIP][0],
+                        DOT11F_RSN_OUI_SIZE);
+                pdot11f_rsn->pmkid_count = 0;
+                /* Construct RSN IE into RSNOpaque*/
+                sap_auth_offload_construct_rsn_opaque(pdot11f_rsn, pdot11f);
+                break;
+            default:
+                dot11fLog( pmac, LOGE,
+                        FL("The security type is not definied for "
+                            "Software AP authentication offload!\n"));
+                break;
+        }
+    }
+}
+#endif /* SAP_AUTH_OFFLOAD */
+
 // parserApi.c ends here.
diff --git a/CORE/WDA/inc/legacy/halMsgApi.h b/CORE/WDA/inc/legacy/halMsgApi.h
index 2711451..83d0267 100644
--- a/CORE/WDA/inc/legacy/halMsgApi.h
+++ b/CORE/WDA/inc/legacy/halMsgApi.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -73,6 +73,10 @@
 //invalid channel id.
 #define HAL_INVALID_CHANNEL_ID 0
 
+#ifdef SAP_AUTH_OFFLOAD
+#define MAX_CONNECT_REQ_LENGTH 512
+#endif
+
 /* BSS index used when no BSS is associated with the station. For example,
  * driver creates only one self station without valid BSS while scanning.
  * Then this index is used to tell softmac that BSS is not valid.
@@ -288,6 +292,13 @@
 
     tANI_U8    htLdpcCapable;
     tANI_U8    vhtLdpcCapable;
+#ifdef SAP_AUTH_OFFLOAD
+    tANI_U8    dpuIndex;
+    tANI_U8    bcastDpuIndex;
+    tANI_U8    bcastMgmtDpuIdx;
+    tANI_U8    ucMgmtSig;
+#endif
+
 } tAddStaParams, *tpAddStaParams;
 
 
@@ -1417,5 +1428,22 @@
     tANI_U8  request_data[1];
 } tNanRequest, *tpNanRequest;
 
+
+#ifdef SAP_AUTH_OFFLOAD
+struct sap_offload_add_sta_req
+{
+    tANI_U32 assoc_id;
+    tANI_U32 conn_req_len;
+    tANI_U8 conn_req[MAX_CONNECT_REQ_LENGTH];
+};
+struct sap_offload_del_sta_req
+{
+    tANI_U32 assoc_id;
+    tANI_U32 reason_code;
+    tANI_U32 flags;
+    tSirMacAddr sta_mac;
+};
+#endif /* SAP_AUTH_OFFLOAD */
+
 #endif /* _HALMSGAPI_H_ */
 
diff --git a/CORE/WDA/inc/wlan_qct_wda.h b/CORE/WDA/inc/wlan_qct_wda.h
index 40a8a00..503f460 100644
--- a/CORE/WDA/inc/wlan_qct_wda.h
+++ b/CORE/WDA/inc/wlan_qct_wda.h
@@ -816,6 +816,11 @@
 #ifdef WLAN_FEATURE_EXTSCAN
 #define WDA_GET_EXTSCANFULLSCANRESIND(pRxMeta) (((WDI_DS_RxMetaInfoType*)(pRxMeta))->extscanBuffer)
 #endif
+
+#ifdef SAP_AUTH_OFFLOAD
+#define WDA_GET_SAP_AUTHOFFLOADIND(pRxMeta)  (((WDI_DS_RxMetaInfoType*)(pRxMeta))->indType)
+#endif
+
 /* WDA_GET_RX_RSSI_DB ********************************************************/
 // Volans RF
 #  define WDA_RSSI_OFFSET             100
diff --git a/CORE/WDA/src/wlan_qct_wda.c b/CORE/WDA/src/wlan_qct_wda.c
index e799fdd..6cb743b 100644
--- a/CORE/WDA/src/wlan_qct_wda.c
+++ b/CORE/WDA/src/wlan_qct_wda.c
@@ -4382,7 +4382,90 @@
    }
    return CONVERT_WDI2VOS_STATUS(status) ;
 }
+#ifdef SAP_AUTH_OFFLOAD
 
+/**
+ * WDA_ProcessSapAuthOffloadAddStaReq():  process add sta command.
+ *
+ * @pWDA: WDA Call back context
+ * @addStaReqParam: Add sta request params
+ *
+ * This function process sta params and store them to WDA layer.
+ * It will register station entry to mempool as well.
+ * As station is already in associated state in firmware this
+ * function doesnt send any request to firmware and wait for response,
+ * instead of that this function will send response from here.
+ *
+ * Return: Return VOS_STATUS
+ */
+VOS_STATUS WDA_ProcessSapAuthOffloadAddStaReq(tWDA_CbContext *pWDA,
+                                    tAddStaParams *addStaReqParam)
+{
+    WDI_Status status = WDI_STATUS_SUCCESS ;
+    WDI_AddStaParams   wdiAddSTAParam = {0};
+    WDI_ConfigSTAReqParamsType *wdiConfigStaReqParam =
+        (WDI_ConfigSTAReqParamsType *)vos_mem_malloc(
+                sizeof(WDI_ConfigSTAReqParamsType)) ;
+
+    VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+            "------> %s " ,__func__);
+
+    if (NULL == wdiConfigStaReqParam)
+    {
+        VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+                "%s: VOS MEM Alloc Failure", __func__);
+        VOS_ASSERT(0);
+        return VOS_STATUS_E_NOMEM;
+    }
+
+    vos_mem_set(wdiConfigStaReqParam, sizeof(WDI_ConfigSTAReqParamsType), 0);
+    /* update STA params into WDI structure */
+    WDA_UpdateSTAParams(pWDA, &wdiConfigStaReqParam->wdiReqInfo,
+            addStaReqParam);
+    wdiAddSTAParam.ucSTAIdx = wdiConfigStaReqParam->wdiReqInfo.staIdx;
+    wdiAddSTAParam.ucStaType    = WDI_STA_ENTRY_PEER;
+    /* MAC Address of STA */
+    wpalMemoryCopy(wdiAddSTAParam.staMacAddr,
+            wdiConfigStaReqParam->wdiReqInfo.macSTA,
+            WDI_MAC_ADDR_LEN);
+
+    wpalMemoryCopy(wdiAddSTAParam.macBSSID,
+            wdiConfigStaReqParam->wdiReqInfo.macBSSID,
+            WDI_MAC_ADDR_LEN);
+
+    wdiAddSTAParam.dpuIndex = addStaReqParam->dpuIndex;
+    wdiAddSTAParam.dpuSig   = addStaReqParam->ucUcastSig;
+    wdiAddSTAParam.bcastDpuIndex     = addStaReqParam->bcastDpuIndex;
+    wdiAddSTAParam.bcastDpuSignature = addStaReqParam->ucBcastSig;
+    wdiAddSTAParam.bcastMgmtDpuIndex         = addStaReqParam->bcastMgmtDpuIdx;
+    wdiAddSTAParam.bcastMgmtDpuSignature     = addStaReqParam->ucMgmtSig;
+
+    WDI_STATableAddSta(pWDA->pWdiContext, &wdiAddSTAParam);
+    pWDA->wdaStaInfo[wdiConfigStaReqParam->wdiReqInfo.staIdx].ucValidStaIndex =
+        WDA_VALID_STA_INDEX;
+    pWDA->wdaStaInfo[wdiConfigStaReqParam->wdiReqInfo.staIdx].currentOperChan =
+        addStaReqParam->currentOperChan;
+
+    if (WDI_STATUS_SUCCESS !=
+            WDI_STATableFindStaidByAddr(pWDA->pWdiContext,
+                wdiConfigStaReqParam->wdiReqInfo.macSTA,
+                (wpt_uint8 *)&wdiConfigStaReqParam->wdiReqInfo.staIdx))
+    {
+        VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+                "%s: Failed to get selfStaIdx!", __func__);
+    }
+    if (WDI_DS_AddSTAMemPool(pWDA->pWdiContext,
+                wdiConfigStaReqParam->wdiReqInfo.staIdx))
+    {
+        VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+                "%s: add STA into mempool fail", __func__);
+        VOS_ASSERT(0) ;
+    }
+    vos_mem_free(wdiConfigStaReqParam);
+    WDA_SendMsg(pWDA, WDA_ADD_STA_RSP, (void *)addStaReqParam, 0) ;
+    return status;
+}
+#endif
 /*
  * FUNCTION: WDA_DelBSSRspCallback
  * Dens DEL BSS RSP back to PE
@@ -4648,6 +4731,43 @@
    return ;
 }
 
+#ifdef SAP_AUTH_OFFLOAD
+/**
+ * WDA_ProcessSapAuthOffloadDelStaReq():  process del sta command.
+ *
+ * @pWDA: WDA Call back context
+ * @delStaParam: Del sta request params
+ *
+ * This function process sta params and remove entry from WDA layer.
+ * It will unregister station entry from mempool as well.
+ * As station is already in disassociated state in firmware this
+ * function doesn't send any request to firmware and wait for response,
+ * instead of that this function will send response from here.
+ *
+ * Return: Return VOS_STATUS
+ */
+void WDA_ProcessSapAuthOffloadDelStaReq(tWDA_CbContext *pWDA,
+        tDeleteStaParams *delStaParam)
+
+{
+    VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+            "------> %s " ,__func__);
+
+    if (WDI_DS_DelSTAMemPool(pWDA->pWdiContext, delStaParam->staIdx))
+    {
+        VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+                "%s: DEL STA from MemPool Fail", __func__);
+        //   VOS_ASSERT(0) ;
+    }
+    WDI_STATableDelSta(pWDA->pWdiContext, delStaParam->staIdx);
+    pWDA->wdaStaInfo[delStaParam->staIdx].ucValidStaIndex =
+        WDA_INVALID_STA_INDEX;
+    pWDA->wdaStaInfo[delStaParam->staIdx].currentOperChan = 0;
+    WDA_SendMsg(pWDA, WDA_DELETE_STA_RSP, (void *)delStaParam, 0);
+    return ;
+}
+#endif
+
 /*
  * FUNCTION: WDA_ProcessDelStaReq
  * Init DEL STA req with WDI
@@ -16381,6 +16501,18 @@
                   (struct tSirSapOffloadInfo*)pMsg->bodyptr);
           break;
       }
+      case WDA_SAP_OFL_ADD_STA:
+      {
+          WDA_ProcessSapAuthOffloadAddStaReq(pWDA,
+                  (tAddStaParams *)pMsg->bodyptr);
+          break;
+      }
+      case WDA_SAP_OFL_DEL_STA:
+      {
+          WDA_ProcessSapAuthOffloadDelStaReq(pWDA,
+                  (tDeleteStaParams *)pMsg->bodyptr);
+          break;
+      }
 #endif
       default:
       {
diff --git a/CORE/WDI/CP/inc/wlan_qct_wdi_bd.h b/CORE/WDI/CP/inc/wlan_qct_wdi_bd.h
index e42c183..0e9faa6 100644
--- a/CORE/WDI/CP/inc/wlan_qct_wdi_bd.h
+++ b/CORE/WDI/CP/inc/wlan_qct_wdi_bd.h
@@ -325,9 +325,16 @@
         this field is set to zero. */
         wpt_uint32 tid:4;
 
-        wpt_uint32 reserved4:8;
+        wpt_uint32 indType:2;
+        wpt_uint32 reserved4:4;
+        wpt_uint32 htt_t2h_msg:1;
+        wpt_uint32 fc:1;
+
 #else
-        wpt_uint32 reserved4:8;
+        wpt_uint32 fc:1;
+        wpt_uint32 htt_t2h_msg:1;
+        wpt_uint32 reserved4:4;
+        wpt_uint32 indType:2;
         wpt_uint32 tid:4;
 #ifdef WCN_PRONTO
         wpt_uint32 rxDXEPriorityRouting:1;
diff --git a/CORE/WDI/CP/inc/wlan_qct_wdi_dp.h b/CORE/WDI/CP/inc/wlan_qct_wdi_dp.h
index 465946e..5729672 100644
--- a/CORE/WDI/CP/inc/wlan_qct_wdi_dp.h
+++ b/CORE/WDI/CP/inc/wlan_qct_wdi_dp.h
@@ -226,6 +226,8 @@
 
 #endif
 
+#define WDI_RXBD_MLME_STA_STATUS 0x1
+#define WDI_RXBD_SAP_TX_COMPL_STATS  0x2
 /*--------------------------------------------------------------------------
    BD header macros - used by the data path to get or set various values
    inside the packet BD 
@@ -312,6 +314,8 @@
 #define WDI_RX_BD_GET_EXTSCANFULLSCANRESIND( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->extscanBuffer)
 #endif
 
+#define WDI_RX_BD_GET_PER_SAPOFFLOAD( _pvBDHeader )     (((WDI_RxBdType*)_pvBDHeader)->indType)
+
 /*------------ RSSI and SNR Information extraction -------------*/
 #define WDI_RX_BD_GET_RSSI0( _pvBDHeader )  \
     (((((WDI_RxBdType*)_pvBDHeader)->phyStats0) >> 24) & 0xff)
diff --git a/CORE/WDI/CP/inc/wlan_qct_wdi_sta.h b/CORE/WDI/CP/inc/wlan_qct_wdi_sta.h
index 44cd97d..f62bbff 100644
--- a/CORE/WDI/CP/inc/wlan_qct_wdi_sta.h
+++ b/CORE/WDI/CP/inc/wlan_qct_wdi_sta.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014, 2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -71,45 +71,6 @@
 #define WDI_STA_INVALID_IDX 0xFF
 
 /*----------------------------------------------------------------------------
-  WDI_AddStaParams
-  -------------------------------------------------------------------------*/
-typedef struct 
-{
-  wpt_uint8    ucSTAIdx; 
-  wpt_uint8    ucWmmEnabled;
-  wpt_uint8    ucHTCapable; 
-
-  /* MAC Address of STA */
-  wpt_macAddr staMacAddr;
-
-  /*MAC Address of the BSS*/
-  wpt_macAddr  macBSSID;
-
-  /* Field to indicate if this is sta entry for itself STA adding entry for itself
-     or remote (AP adding STA after successful association.
-     This may or may not be required in production driver.
-     0 - Self, 1 other/remote, 2 - bssid */
-  wpt_uint8   ucStaType;       
-
-
-  /*DPU Information*/
-  wpt_uint8   dpuIndex;                      // DPU table index
-  wpt_uint8   dpuSig;                        // DPU signature
-  wpt_uint8   bcastDpuIndex;
-  wpt_uint8   bcastDpuSignature;
-  wpt_uint8   bcastMgmtDpuIndex;
-  wpt_uint8   bcastMgmtDpuSignature;
-
-
-  /*RMF enabled/disabled*/
-  wpt_uint8   ucRmfEnabled;
-
-  /* Index into the BSS Session table */
-  wpt_uint8   ucBSSIdx;
-
-}WDI_AddStaParams; 
-
-/*----------------------------------------------------------------------------
   WDI_StaStruct
   -------------------------------------------------------------------------*/
 typedef struct
@@ -206,41 +167,6 @@
   WDI_ControlBlockType*  pWDICtx
 );
 
-
-/**
- @brief WDI_STATableAddSta - Function to Add Station
-
- 
- @param  pWDICtx:     pointer to the WLAN DAL context 
-         pwdiParam:   station parameters  
-  
- @see
- @return Result of the function call
-*/
-WDI_Status
-WDI_STATableAddSta
-(
-    WDI_ControlBlockType*  pWDICtx,
-    WDI_AddStaParams*      pwdiParam
-);
-
-/**
- @brief WDI_STATableDelSta - Function to Delete a Station
-
- 
- @param  pWDICtx:         pointer to the WLAN DAL context 
-         ucSTAIdx:        station to be deleted
-  
- @see
- @return Result of the function call
-*/
-WDI_Status
-WDI_STATableDelSta
-(
-    WDI_ControlBlockType*  pWDICtx,
-    wpt_uint8              ucSTAIdx
-);
-
 /**
  @brief WDI_STATableBSSDelSta - Function to Delete Stations in this BSS
 
@@ -356,25 +282,6 @@
 
 
 /**
- @brief WDI_STATableFindStaidByAddr - Given a station mac address, search
-        for the corresponding station index from the Station Table.
- 
- @param  pWDICtx:  WDI Context pointer
-         staAddr:  station address
-         pucStaId: output station id 
-  
- @see
- @return Result of the function call
-*/
-WDI_Status
-WDI_STATableFindStaidByAddr
-(
-    WDI_ControlBlockType*  pWDICtx, 
-    wpt_macAddr            staAddr, 
-    wpt_uint8*             pucStaId
-);
-
-/**
  @brief WDI_STATableGetStaAddr - get station address
  
  @param  pWDICtx:  WDI Context pointer
diff --git a/CORE/WDI/CP/src/wlan_qct_wdi_sta.c b/CORE/WDI/CP/src/wlan_qct_wdi_sta.c
index 9b8aa78..0038a7b 100644
--- a/CORE/WDI/CP/src/wlan_qct_wdi_sta.c
+++ b/CORE/WDI/CP/src/wlan_qct_wdi_sta.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014, 2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -206,7 +206,7 @@
  @brief WDI_STATableAddSta - Function to Add Station
 
  
- @param  pWDICtx:     pointer to the WLAN DAL context 
+ @param  pWDICtx:     pointer to the WLAN DAL context
          pwdiParam:   station parameters  
   
  @see
@@ -215,11 +215,12 @@
 WDI_Status
 WDI_STATableAddSta
 (
-    WDI_ControlBlockType*  pWDICtx,
+    void*  ctx,
     WDI_AddStaParams*      pwdiParam
 )
 {
     wpt_uint8        ucSTAIdx  = 0;
+    WDI_ControlBlockType*  pWDICtx = ctx;
     WDI_StaStruct*   pSTATable = (WDI_StaStruct*) pWDICtx->staTable;
     /*- - - -  - - - - - - - - - - - -  - - - - - - - - - - - -  - - - - - */
 
@@ -302,7 +303,7 @@
  @brief WDI_STATableDelSta - Function to Delete a Station
 
  
- @param  pWDICtx:         pointer to the WLAN DAL context 
+ @param  void:            pointer to the WLAN DAL context
          ucSTAIdx:        station to be deleted
   
  @see
@@ -311,10 +312,11 @@
 WDI_Status
 WDI_STATableDelSta
 (
-    WDI_ControlBlockType*  pWDICtx,
+    void*  ctx,
     wpt_uint8              ucSTAIdx
 )
 {
+    WDI_ControlBlockType*  pWDICtx = ctx;
     WDI_StaStruct*   pSTATable = (WDI_StaStruct*) pWDICtx->staTable;
     /*- - - -  - - - - - - - - - - - -  - - - - - - - - - - - -  - - - - - */
 
@@ -341,7 +343,7 @@
  @brief WDI_STATableBSSDelSta - Function to Delete Stations in this BSS
 
  
- @param  pWDICtx:         pointer to the WLAN DAL context 
+ @param  pWDICtx:         pointer to the WLAN DAL context
          ucBSSIdx:        BSS index 
   
  @see
@@ -584,12 +586,13 @@
 WDI_Status
 WDI_STATableFindStaidByAddr
 (
-    WDI_ControlBlockType*  pWDICtx, 
+    void * context,
     wpt_macAddr            staAddr, 
     wpt_uint8*             pucStaId
 )
 {
     WDI_Status wdiStatus = WDI_STATUS_E_FAILURE;
+    WDI_ControlBlockType*  pWDICtx = context;
     wpt_uint8 i;
     WDI_StaStruct* pSTATable = (WDI_StaStruct*) pWDICtx->staTable;
 
diff --git a/CORE/WDI/DP/inc/wlan_qct_wdi_ds.h b/CORE/WDI/DP/inc/wlan_qct_wdi_ds.h
index 483ad65..e3be91a 100644
--- a/CORE/WDI/DP/inc/wlan_qct_wdi_ds.h
+++ b/CORE/WDI/DP/inc/wlan_qct_wdi_ds.h
@@ -174,6 +174,7 @@
    wpt_uint32 extscanBuffer;
 #endif
    wpt_uint32 loggingData;
+   wpt_uint32 indType;
 } WDI_DS_RxMetaInfoType;
 
 typedef struct sPktMetaInfo
@@ -198,6 +199,48 @@
    wpt_uint16 reasonCode;
 } WDI_DS_LoggingSessionType;
 
+
+/*----------------------------------------------------------------------------
+ *   WDI_AddStaParams
+ *     -------------------------------------------------------------------------*/
+typedef struct
+{
+    wpt_uint8    ucSTAIdx;
+    wpt_uint8    ucWmmEnabled;
+    wpt_uint8    ucHTCapable;
+
+    /* MAC Address of STA */
+    wpt_macAddr staMacAddr;
+
+    /*MAC Address of the BSS*/
+    wpt_macAddr  macBSSID;
+
+    /* Field to indicate if this is sta entry for itself STA adding entry for itself
+     * or remote (AP adding STA after successful association.
+     * This may or may not be required in production driver.
+     * 0 - Self, 1 other/remote, 2 - bssid
+     */
+    wpt_uint8   ucStaType;
+
+
+    /*DPU Information*/
+    wpt_uint8   dpuIndex;                      // DPU table index
+    wpt_uint8   dpuSig;                        // DPU signature
+    wpt_uint8   bcastDpuIndex;
+    wpt_uint8   bcastDpuSignature;
+    wpt_uint8   bcastMgmtDpuIndex;
+    wpt_uint8   bcastMgmtDpuSignature;
+
+
+    /*RMF enabled/disabled*/
+    wpt_uint8   ucRmfEnabled;
+
+    /* Index into the BSS Session table */
+    wpt_uint8   ucBSSIdx;
+
+}WDI_AddStaParams;
+
+
 WPT_STATIC WPT_INLINE WDI_DS_RxMetaInfoType* WDI_DS_ExtractRxMetaData (wpt_packet *pFrame)
 {
   WDI_DS_RxMetaInfoType * pRxMetadata =
@@ -316,6 +359,59 @@
  *
  */
 WDI_Status WDI_DS_AddSTAMemPool(void *pContext, wpt_uint8 staIndex);
+/**
+ @brief WDI_STATableFindStaidByAddr - Given a station mac address, search
+ for the corresponding station index from the Station Table.
+
+ @param  pWDICtx:   Context pointer
+staAddr:  station address
+pucStaId: output station id
+
+@see
+@return Result of the function call
+*/
+WDI_Status
+WDI_STATableFindStaidByAddr
+(
+ void*  pWDICtx,
+ wpt_macAddr            staAddr,
+ wpt_uint8*             pucStaId
+ );
+
+/**
+ *  @brief WDI_STATableAddSta - Function to Add Station
+ *
+ *
+ *  @param  pWDICtx:     pointer to the WLAN DAL context
+ *  pwdiParam:   station parameters
+ *
+ *  @see
+ *  @return Result of the function call
+ *                 */
+WDI_Status
+WDI_STATableAddSta
+(
+ void*  pWDICtx,
+ WDI_AddStaParams*      pwdiParam
+ );
+
+
+/**
+ * @brief WDI_STATableDelSta - Function to Delete a Station
+ *
+ *
+ * @param  pWDICtx:         pointer to the WLAN DAL context
+ *         ucSTAIdx:        station to be deleted
+ *
+ * @see
+ * @return Result of the function call
+ */
+WDI_Status
+WDI_STATableDelSta
+(
+ void*  pWDICtx,
+ wpt_uint8              ucSTAIdx
+ );
 
 /* DAL Remove STA from memPool
  * Parameters:
diff --git a/CORE/WDI/TRP/DTS/src/wlan_qct_wdi_dts.c b/CORE/WDI/TRP/DTS/src/wlan_qct_wdi_dts.c
index 018b8be..3dfb38b 100644
--- a/CORE/WDI/TRP/DTS/src/wlan_qct_wdi_dts.c
+++ b/CORE/WDI/TRP/DTS/src/wlan_qct_wdi_dts.c
@@ -668,6 +668,7 @@
   wpt_uint8                  isFcBd = 0;
   WDI_DS_LoggingSessionType *pLoggingSession;
   tPerPacketStats             rxStats = {0};
+  wpt_uint32 indType =0;
 
   tpSirMacFrameCtl  pMacFrameCtl;
   // Do Sanity checks
@@ -733,45 +734,52 @@
 
   pRxMetadata = WDI_DS_ExtractRxMetaData(pFrame);
 
-  // Special handling for frames which contain logging information
   if (WDTS_CHANNEL_RX_LOG == channel)
   {
-      if (VPKT_SIZE_BUFFER_ALIGNED < (usMPDULen+ucMPDUHOffset))
+      indType       = (wpt_uint32)WDI_RX_BD_GET_PER_SAPOFFLOAD(pBDHeader);
+      if(indType) {
+          DTI_TRACE(DTI_TRACE_LEVEL_INFO, "indtype is %d size of pacekt is %lu",
+                  indType, sizeof(WDI_RxBdType));
+      }
+      else
       {
-          /* Size of the packet tranferred by the DMA engine is
-           * greater than the the memory allocated for the skb
-           * Recover the SKB  case of length is in same memory page
-           */
-          WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
-                   "Invalid Frame size, might memory corrupted(%d+%d/%d)",
-                   usMPDULen, ucMPDUHOffset, VPKT_SIZE_BUFFER_ALIGNED);
-
-          // Store RXBD,  skb head, tail and skb lenght in circular buffer
-          WDTS_StoreMetaInfo(pFrame, pBDHeader);
-
-          if ((usMPDULen+ucMPDUHOffset) <= WDTS_MAX_PAGE_SIZE)
+          if (VPKT_SIZE_BUFFER_ALIGNED < (usMPDULen+ucMPDUHOffset))
           {
-              wpalRecoverTail(pFrame);
-              wpalPacketFree(pFrame);
-          } else {
-              //Recovery may cause adjoining buffer corruption
-              WPAL_BUG(0);
+              /* Size of the packet tranferred by the DMA engine is
+               * greater than the the memory allocated for the skb
+               * Recover the SKB  case of length is in same memory page
+               */
+              WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
+                      "Invalid Frame size, might memory corrupted(%d+%d/%d)",
+                      usMPDULen, ucMPDUHOffset, VPKT_SIZE_BUFFER_ALIGNED);
+
+              // Store RXBD,  skb head, tail and skb lenght in circular buffer
+              WDTS_StoreMetaInfo(pFrame, pBDHeader);
+
+              if ((usMPDULen+ucMPDUHOffset) <= WDTS_MAX_PAGE_SIZE)
+              {
+                  wpalRecoverTail(pFrame);
+                  wpalPacketFree(pFrame);
+              } else {
+                  //Recovery may cause adjoining buffer corruption
+                  WPAL_BUG(0);
+              }
+
+              return eWLAN_PAL_STATUS_SUCCESS;
           }
 
+          /* Firmware should send the Header offset as length
+           * of RxBd and data length should be populated to
+           * the length of total data being sent
+           */
+          wpalPacketSetRxLength(pFrame, usMPDULen+ucMPDUHOffset);
+          wpalPacketRawTrimHead(pFrame, ucMPDUHOffset);
+
+          // Invoke Rx complete callback
+          wpalLogPktSerialize(pFrame);
+
           return eWLAN_PAL_STATUS_SUCCESS;
       }
-
-      /* Firmware should send the Header offset as length
-       * of RxBd and data length should be populated to
-       * the length of total data being sent
-       */
-      wpalPacketSetRxLength(pFrame, usMPDULen+ucMPDUHOffset);
-      wpalPacketRawTrimHead(pFrame, ucMPDUHOffset);
-
-      // Invoke Rx complete callback
-      wpalLogPktSerialize(pFrame);
-
-      return eWLAN_PAL_STATUS_SUCCESS;
   }
   else
   {
@@ -780,7 +788,9 @@
 
   if(!isFcBd)
   {
-      if(usMPDUDOffset <= ucMPDUHOffset || usMPDULen < ucMPDUHLen) {
+      /* When channel is WDTS_CHANNEL_RX_LOG firmware doesn't send MPDU header*/
+      if ((usMPDUDOffset <= ucMPDUHOffset || usMPDULen < ucMPDUHLen) &&
+              (WDTS_CHANNEL_RX_LOG != channel)) {
         DTI_TRACE( DTI_TRACE_LEVEL_ERROR,
             "WLAN TL:BD header corrupted - dropping packet");
         /* Drop packet ???? */ 
@@ -866,6 +876,30 @@
       pRxMetadata->roamCandidateInd = WDI_RX_BD_GET_ROAMCANDIDATEIND(pBDHeader);
       pRxMetadata->perRoamCndInd = WDI_RX_BD_GET_PER_ROAMCANDIDATEIND(pBDHeader);
 #endif
+#ifdef SAP_AUTH_OFFLOAD
+      /* Currently firmware use WDTS_CHANNEL_RX_LOG channel for two purpose.
+       * 1) For firmare logging information: driver will do special handling
+       * for those message.
+       * 2) When SAP offload is enabled: In this case, indication type is stored
+       * in pRxMetadata which will be used by LIM later.
+       */
+      if (WDTS_CHANNEL_RX_LOG == channel)
+      {
+          pRxMetadata->indType =
+              (wpt_uint32)WDI_RX_BD_GET_PER_SAPOFFLOAD(pBDHeader);
+          if (pRxMetadata->indType == WDI_RXBD_MLME_STA_STATUS)
+          {
+              DTI_TRACE( DTI_TRACE_LEVEL_INFO, "%s: Indtype is %d\n",
+                      __func__, pRxMetadata->indType);
+              pRxMetadata->type    = WDI_MAC_MGMT_FRAME;
+          }
+      }
+      else
+      {
+          pRxMetadata->indType = 0;
+      }
+#endif
+
 #ifdef WLAN_FEATURE_EXTSCAN
       pRxMetadata->extscanBuffer = WDI_RX_BD_GET_EXTSCANFULLSCANRESIND(pBDHeader);
 #endif