wlan: Fixed below issues due to which 2nd client is not associating to
GO

1. eWNI_SME_UPPER_LAYER_ASSOC_CNF msg is only processed in
eCSR_ROAMING_STATE_JOINED state . When STA/GO is scanning CSR is in
eCSR_ROAMING_STATE_SCANNING state currently driver is not processing
eWNI_SME_UPPER_LAYER_ASSOC_CNF msg . Fixed this by processing this msg
in CSR scanning state as well.

2. In driver fix was done  to not  allow DEL_STA events based on
pAdapter->aStaInfo[i].isUsed flag in HDD

3. If Driver received deauth from p2p client and at the same time if
driver gets DEL_STA from supplicant. In this case after processing  the
over-the-air deauth frame driver has to remove  any pending sme commands
with same session ID, same peer mac addr and with reason code
eCsrForcedDeauthSta  For this csrRoamRemoveDuplicateCommand function
is enhanced to take care of this

4. Introduced a new variable deauth_in_progress in HDD to avoid further
DEL_STA events to driver even if supplicant is buggy

5. Abort_scan when SAP_ASSOC_EVENT  is received on GO

6.Fix an issue(SCAN busy) because of race condition between  disconnect
request from the HDD and deauth from AP

CR-Fixed:  436439
Change-Id: If847ddf412529ae51a1b1c6038663b7c2d67eb19
diff --git a/CORE/HDD/inc/wlan_hdd_hostapd.h b/CORE/HDD/inc/wlan_hdd_hostapd.h
index 4a212db..53b8f5d 100644
--- a/CORE/HDD/inc/wlan_hdd_hostapd.h
+++ b/CORE/HDD/inc/wlan_hdd_hostapd.h
@@ -47,7 +47,7 @@
   \file  WLAN_HDD_HOSTAPD_H.h
   
   \brief Linux HDD HOSTAPD include file
-         Copyright 2008 (c) Qualcomm, Incorporated.
+         Copyright 2008-2013 (c) Qualcomm, Incorporated.
          All Rights Reserved.
          Qualcomm Confidential and Proprietary.
   
@@ -90,7 +90,7 @@
 eCsrEncryptionType 
 hdd_TranslateWPAToCsrEncryptionType(u_int8_t cipher_suite[4]);
 
-void hdd_softap_sta_deauth(hdd_adapter_t*,v_U8_t*);
+VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t*,v_U8_t*);
 void hdd_softap_sta_disassoc(hdd_adapter_t*,v_U8_t*);
 void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t*,v_BOOL_t);
 int hdd_softap_unpackIE( tHalHandle halHandle,
diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h
index 9cff240..e0dbda1 100644
--- a/CORE/HDD/inc/wlan_hdd_main.h
+++ b/CORE/HDD/inc/wlan_hdd_main.h
@@ -539,6 +539,8 @@
    /** Track QoS status of station */
    v_BOOL_t isQosEnabled;
 
+   /** The station entry for which Deauth is in progress  */
+   v_BOOL_t isDeauthInProgress;
 } hdd_station_info_t;
 
 struct hdd_ap_ctx_s
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index ca85655..da4fd77 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -6079,6 +6079,8 @@
                                          struct net_device *dev, u8 *mac)
 {
     hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
+    VOS_STATUS vos_status;
+    v_U8_t staId;
 
     ENTER();
     if ( NULL == pAdapter || NULL == pAdapter->pHddCtx)
@@ -6127,13 +6129,52 @@
         }
         else
         {
+
+            vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
+            if (!VOS_IS_STATUS_SUCCESS(vos_status))
+            {
+                hddLog(VOS_TRACE_LEVEL_INFO,
+                                "%s: Skip this DEL STA as this is not used::"
+                                "%02x:%02x:%02x:%02x:%02x:%02x",
+                                __func__,
+                                mac[0], mac[1], mac[2],
+                                mac[3], mac[4], mac[5]);
+                return -ENOENT;
+            }
+
+            if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
+            {
+                hddLog(VOS_TRACE_LEVEL_INFO,
+                                "%s: Skip this DEL STA as deauth is in progress::"
+                                "%02x:%02x:%02x:%02x:%02x:%02x",
+                                __func__,
+                                mac[0], mac[1], mac[2],
+                                mac[3], mac[4], mac[5]);
+                return -ENOENT;
+            }
+
+            pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
+
             hddLog(VOS_TRACE_LEVEL_INFO,
                                 "%s: Delete STA with MAC::"
                                 "%02x:%02x:%02x:%02x:%02x:%02x",
                                 __func__,
                                 mac[0], mac[1], mac[2],
                                 mac[3], mac[4], mac[5]);
-            hdd_softap_sta_deauth(pAdapter, mac);
+
+            vos_status = hdd_softap_sta_deauth(pAdapter, mac);
+            if (!VOS_IS_STATUS_SUCCESS(vos_status))
+            {
+                pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
+                hddLog(VOS_TRACE_LEVEL_INFO,
+                                "%s: STA removal failed for ::"
+                                "%02x:%02x:%02x:%02x:%02x:%02x",
+                                __func__,
+                                mac[0], mac[1], mac[2],
+                                mac[3], mac[4], mac[5]);
+                return -ENOENT;
+            }
+
         }
     }
 
diff --git a/CORE/HDD/src/wlan_hdd_hostapd.c b/CORE/HDD/src/wlan_hdd_hostapd.c
index afb6caf..f227194 100644
--- a/CORE/HDD/src/wlan_hdd_hostapd.c
+++ b/CORE/HDD/src/wlan_hdd_hostapd.c
@@ -456,6 +456,7 @@
     v_BYTE_t we_custom_start_event[64];
     char *startBssEvent; 
     hdd_context_t *pHddCtx;
+    hdd_scaninfo_t *pScanInfo  = NULL;
 
     dev = (struct net_device *)usrDataForCallback;
     pHostapdAdapter = netdev_priv(dev);
@@ -674,6 +675,12 @@
              }
 #endif
 #endif
+            pScanInfo =  &pHddCtx->scan_info;
+            // Lets do abort scan to ensure smooth authentication for client
+            if ((pScanInfo != NULL) && pScanInfo->mScanPending)
+            {
+                hdd_abort_mac_scan(pHddCtx);
+            }
 
             break;
         case eSAP_STA_DISASSOC_EVENT:
diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c
index f6ec662..7467c77 100644
--- a/CORE/HDD/src/wlan_hdd_main.c
+++ b/CORE/HDD/src/wlan_hdd_main.c
@@ -4483,9 +4483,10 @@
 
   --------------------------------------------------------------------------*/
 
-void hdd_softap_sta_deauth(hdd_adapter_t *pAdapter, v_U8_t *pDestMacAddress)
+VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter, v_U8_t *pDestMacAddress)
 {
     v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
+    VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
 #ifdef FEATURE_WLAN_NON_INTEGRATED_SOC
     tHalHandle hHalHandle;
 #endif
@@ -4496,12 +4497,12 @@
 
     //Ignore request to deauth bcmc station
     if( pDestMacAddress[0] & 0x1 )
-       return;
+       return vosStatus;
 
-    WLANSAP_DeauthSta(pVosContext,pDestMacAddress);
-
+    vosStatus = WLANSAP_DeauthSta(pVosContext,pDestMacAddress);
 
     EXIT();
+    return vosStatus;
 }
 
 /**---------------------------------------------------------------------------
diff --git a/CORE/HDD/src/wlan_hdd_softap_tx_rx.c b/CORE/HDD/src/wlan_hdd_softap_tx_rx.c
index ee06583..8df13d0 100644
--- a/CORE/HDD/src/wlan_hdd_softap_tx_rx.c
+++ b/CORE/HDD/src/wlan_hdd_softap_tx_rx.c
@@ -652,6 +652,7 @@
    }
 
    pAdapter->aStaInfo[STAId].isUsed = TRUE;
+   pAdapter->aStaInfo[STAId].isDeauthInProgress = FALSE;
    vos_copy_macaddr( &pAdapter->aStaInfo[STAId].macAddrSTA, pmacAddrSTA);
 
    spin_unlock_bh( &pAdapter->staInfo_lock );
@@ -690,6 +691,7 @@
    status = hdd_softap_flush_tx_queues_sta(pAdapter, STAId);
 
    pAdapter->aStaInfo[STAId].isUsed = FALSE;
+   pAdapter->aStaInfo[STAId].isDeauthInProgress = FALSE;
 
    /* if this STA had any of its WMM TX queues suspended, then the
       associated queue on the network interface was disabled.  check
diff --git a/CORE/MAC/src/pe/lim/limProcessDeauthFrame.c b/CORE/MAC/src/pe/lim/limProcessDeauthFrame.c
index 2b60c9c..1be3e0d 100644
--- a/CORE/MAC/src/pe/lim/limProcessDeauthFrame.c
+++ b/CORE/MAC/src/pe/lim/limProcessDeauthFrame.c
@@ -133,6 +133,15 @@
         limMlmStateStr(psessionEntry->limMlmState), reasonCode);
     limPrintMacAddr(pMac, pHdr->sa, LOGE);)
       
+    if (limCheckDisassocDeauthAckPending(pMac, (tANI_U8*)pHdr->sa))
+    {
+        PELOGW(limLog(pMac, LOGE, 
+                    FL("Ignore the Deauth received, while waiting for ack of disassoc/deauth\n"));)
+        limCleanUpDisassocDeauthReq(pMac,(tANI_U8*)pHdr->sa, 1);
+        return;
+    }
+
+  
     if ( (psessionEntry->limSystemRole == eLIM_AP_ROLE )||(psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE) )
     {
         switch (reasonCode)
diff --git a/CORE/SAP/src/sapModule.c b/CORE/SAP/src/sapModule.c
index b25b3f3..9777c95 100644
--- a/CORE/SAP/src/sapModule.c
+++ b/CORE/SAP/src/sapModule.c
@@ -1234,6 +1234,8 @@
     v_U8_t *pPeerStaMac
 )
 {
+    eHalStatus halStatus = eHAL_STATUS_FAILURE;
+    VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
     ptSapContext  pSapCtx = VOS_GET_SAP_CB(pvosGCtx);
 
     /*------------------------------------------------------------------------
@@ -1244,13 +1246,17 @@
     {
         VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
                    "%s: Invalid SAP pointer from pvosGCtx", __func__);
-        return VOS_STATUS_E_FAULT;
+        return vosStatus;
     }
 
-    sme_RoamDeauthSta(VOS_GET_HAL_CB(pSapCtx->pvosGCtx), pSapCtx->sessionId,
+    halStatus = sme_RoamDeauthSta(VOS_GET_HAL_CB(pSapCtx->pvosGCtx), pSapCtx->sessionId,
                             pPeerStaMac);
 
-    return VOS_STATUS_SUCCESS;
+    if (halStatus == eHAL_STATUS_SUCCESS)
+    {
+        vosStatus = VOS_STATUS_SUCCESS;
+    }
+    return vosStatus;
 }
 /*==========================================================================
   FUNCTION    WLANSAP_SetChannelRange
diff --git a/CORE/SME/src/csr/csrApiRoam.c b/CORE/SME/src/csr/csrApiRoam.c
index 20e5356..81f53e8 100644
--- a/CORE/SME/src/csr/csrApiRoam.c
+++ b/CORE/SME/src/csr/csrApiRoam.c
@@ -1867,6 +1867,11 @@
         if ( 
             (pCommand && ( pCommand->sessionId == pDupCommand->sessionId ) &&
                 ((pCommand->command == pDupCommand->command) &&
+                /* This peermac check is requried for Softap/GO scenarios
+                 * For STA scenario below OR check will suffice as pCommand will 
+                 * always be NULL for STA scenarios
+                 */
+                (vos_mem_compare(pDupCommand->u.roamCmd.peerMac, pCommand->u.roamCmd.peerMac, sizeof(v_MACADDR_t))) &&
                  (pCommand->u.roamCmd.roamReason == pDupCommand->u.roamCmd.roamReason ||
                     eCsrForcedDisassoc == pCommand->u.roamCmd.roamReason ||
                     eCsrHddIssued == pCommand->u.roamCmd.roamReason))) 
@@ -8211,6 +8216,9 @@
     tCsrRoamSession *pSession = NULL;
     tpSirSmeSwitchChannelInd pSwitchChnInd;
     tSmeMaxAssocInd *pSmeMaxAssocInd;
+#ifdef WLAN_SOFTAP_FEATURE
+    tSmeCmd pCommand;
+#endif
 #if defined ANI_PRODUCT_TYPE_AP
     pSirMsg->messageType = pal_be16_to_cpu(pSirMsg->messageType);
     pSirMsg->length = pal_be16_to_cpu(pSirMsg->length);
@@ -8366,6 +8374,16 @@
                     palCopyMemory(pMac->hHdd, &pRoamInfo->bssid, pDisassocInd->bssId, sizeof(tCsrBssid));
 
                     status = csrRoamCallCallback(pMac, sessionId, pRoamInfo, 0, eCSR_ROAM_INFRA_IND, eCSR_ROAM_RESULT_DISASSOC_IND);
+
+                    /*
+                    *  STA/P2P client got  disassociated so remove any pending deauth 
+                    *  commands in sme pending list
+                    */
+                    pCommand.command = eSmeCommandRoam;
+                    pCommand.sessionId = (tANI_U8)sessionId;
+                    pCommand.u.roamCmd.roamReason = eCsrForcedDeauthSta;
+                    vos_mem_copy(pCommand.u.roamCmd.peerMac, pDisassocInd->peerMacAddr, sizeof(tSirMacAddr));
+                    csrRoamRemoveDuplicateCommand(pMac, sessionId, &pCommand, eCsrForcedDeauthSta);
                 }
 #endif                
             }
@@ -9567,9 +9585,18 @@
             roamInfo.staId = (tANI_U8)pDeauthIndMsg->staId;
         }
         //Tell HDD about the lost link
-        csrRoamCallCallback(pMac, sessionId, &roamInfo, 0, eCSR_ROAM_LOSTLINK, result);
-       
-        /*No need to start idle scan in case of IBSS/SAP 
+#ifdef WLAN_SOFTAP_FEATURE
+       if(!CSR_IS_INFRA_AP(&pSession->connectedProfile))
+#endif
+        {
+           /* Dont call csrRoamCallCallback for GO/SoftAp case as this indication 
+            * was alredy given as part of eWNI_SME_DISASSOC_IND msg handling in 
+            * csrRoamCheckForLinkStatusChange API.
+           */ 
+            csrRoamCallCallback(pMac, sessionId, &roamInfo, 0, eCSR_ROAM_LOSTLINK, result);
+        }
+
+       /*No need to start idle scan in case of IBSS/SAP 
          Still enable idle scan for polling in case concurrent sessions are running */
         if(CSR_IS_INFRASTRUCTURE(&pSession->connectedProfile))
         {
diff --git a/CORE/SME/src/csr/csrApiScan.c b/CORE/SME/src/csr/csrApiScan.c
index ba8f4a3..b2a5cb9 100644
--- a/CORE/SME/src/csr/csrApiScan.c
+++ b/CORE/SME/src/csr/csrApiScan.c
@@ -2357,15 +2357,66 @@
     }
     else
     {
-        if( csrIsAnySessionInConnectState( pMac ) )
+#ifdef WLAN_SOFTAP_FEATURE
+        if(pMsg->type == eWNI_SME_UPPER_LAYER_ASSOC_CNF) 
         {
-            //In case of we are connected, we need to check whether connect status changes
-            //because scan may also run while connected.
-            csrRoamCheckForLinkStatusChange( pMac, ( tSirSmeRsp * )pMsgBuf );
+            tCsrRoamSession  *pSession;
+            tSirSmeAssocIndToUpperLayerCnf *pUpperLayerAssocCnf;
+            tCsrRoamInfo roamInfo;
+            tCsrRoamInfo *pRoamInfo = NULL;
+            tANI_U32 sessionId;
+            eHalStatus status;
+            smsLog( pMac, LOG1, FL("Scanning : ASSOCIATION confirmation can be given to upper layer \n"));
+            palZeroMemory(pMac->hHdd, &roamInfo, sizeof(tCsrRoamInfo));
+            pRoamInfo = &roamInfo;
+            pUpperLayerAssocCnf = (tSirSmeAssocIndToUpperLayerCnf *)pMsgBuf;
+            status = csrRoamGetSessionIdFromBSSID( pMac, (tCsrBssid *)pUpperLayerAssocCnf->bssId, &sessionId );
+            pSession = CSR_GET_SESSION(pMac, sessionId);
+
+            if(!pSession)
+            {
+                smsLog(pMac, LOGE, FL("  session %d not found "), sessionId);
+                return eHAL_STATUS_FAILURE;
+            }
+
+            pRoamInfo->statusCode = eSIR_SME_SUCCESS; //send the status code as Success 
+            pRoamInfo->u.pConnectedProfile = &pSession->connectedProfile;
+            pRoamInfo->staId = (tANI_U8)pUpperLayerAssocCnf->aid;
+            pRoamInfo->rsnIELen = (tANI_U8)pUpperLayerAssocCnf->rsnIE.length;
+            pRoamInfo->prsnIE = pUpperLayerAssocCnf->rsnIE.rsnIEdata;
+            pRoamInfo->addIELen = (tANI_U8)pUpperLayerAssocCnf->addIE.length;
+            pRoamInfo->paddIE = pUpperLayerAssocCnf->addIE.addIEdata;           
+            palCopyMemory(pMac->hHdd, pRoamInfo->peerMac, pUpperLayerAssocCnf->peerMacAddr, sizeof(tSirMacAddr));
+            palCopyMemory(pMac->hHdd, &pRoamInfo->bssid, pUpperLayerAssocCnf->bssId, sizeof(tCsrBssid));
+            pRoamInfo->wmmEnabledSta = pUpperLayerAssocCnf->wmmEnabledSta;
+            if(CSR_IS_INFRA_AP(pRoamInfo->u.pConnectedProfile) )
+            {
+                pMac->roam.roamSession[sessionId].connectState = eCSR_ASSOC_STATE_TYPE_INFRA_CONNECTED;
+                pRoamInfo->fReassocReq = pUpperLayerAssocCnf->reassocReq;
+                status = csrRoamCallCallback(pMac, sessionId, pRoamInfo, 0, eCSR_ROAM_INFRA_IND, eCSR_ROAM_RESULT_INFRA_ASSOCIATION_CNF);
+            }
+            if(CSR_IS_WDS_AP( pRoamInfo->u.pConnectedProfile))
+            {
+                vos_sleep( 100 );
+                pMac->roam.roamSession[sessionId].connectState = eCSR_ASSOC_STATE_TYPE_WDS_CONNECTED;//Sta
+                status = csrRoamCallCallback(pMac, sessionId, pRoamInfo, 0, eCSR_ROAM_WDS_IND, eCSR_ROAM_RESULT_WDS_ASSOCIATION_IND);//Sta
+            }
+
         }
         else
+#endif
         {
-            smsLog( pMac, LOGW, "Message [0x%04x] received in state, when expecting Scan Response\n", pMsg->type );
+
+            if( csrIsAnySessionInConnectState( pMac ) )
+            {
+                //In case of we are connected, we need to check whether connect status changes
+                //because scan may also run while connected.
+                csrRoamCheckForLinkStatusChange( pMac, ( tSirSmeRsp * )pMsgBuf );
+            }
+            else
+            {
+                smsLog( pMac, LOGW, "Message [0x%04x] received in state, when expecting Scan Response\n", pMsg->type );
+            }
         }
     }