wlan: Add wait in STA disconnect path from hdd

In case of SAP down all STA are disconnected one by one and are
queued to serialization. serialization queue size is 30 while a
SAP can support 32 clients. So it there are more than 30 clients
the serialization cmd buffers are not assigned, which lead to assert.

Fix this by adding wait in STA disconnect path from HDD.

Change-Id: I2cf930335de64e6e6f6c1be43646d48594456937
CRs-Fixed: 2522514
diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h
index e8ab954..6ee9a85 100644
--- a/CORE/HDD/inc/wlan_hdd_main.h
+++ b/CORE/HDD/inc/wlan_hdd_main.h
@@ -863,6 +863,7 @@
     int bssState;
     vos_event_t vosEvent;
     VOS_STATUS vosStatus;
+    vos_event_t sta_discon_event;
     v_BOOL_t bCommit; 
 
 } hdd_hostapd_state_t;
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index 070bb34..efe8cff 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -19044,6 +19044,7 @@
     v_U8_t staId;
     v_CONTEXT_t pVosContext = NULL;
     ptSapContext pSapCtx = NULL;
+    hdd_hostapd_state_t *hostap_state;
 
     ENTER();
 
@@ -19068,6 +19069,7 @@
        || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
        )
     {
+        hostap_state =  WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
         pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
         pSapCtx = VOS_GET_SAP_CB(pVosContext);
         if(pSapCtx == NULL){
@@ -19098,9 +19100,19 @@
                             MAC_ADDRESS_STR,
                             __func__,
                             MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
+                    vos_event_reset(&hostap_state->sta_discon_event);
                     vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
                     if (VOS_IS_STATUS_SUCCESS(vos_status))
+                    {
                         pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
+                        vos_status =
+                            vos_wait_single_event(
+                                    &hostap_state->sta_discon_event,
+                                    WLAN_WAIT_TIME_DISCONNECT);
+                         if (!VOS_IS_STATUS_SUCCESS(vos_status))
+                                 hddLog(LOGE,"!!%s: ERROR: Deauth wait expired!!",
+                                        __func__);
+                    }
                 }
             }
         }
@@ -19135,6 +19147,7 @@
                                 __func__,
                                 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
 
+            vos_event_reset(&hostap_state->sta_discon_event);
             vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
             if (!VOS_IS_STATUS_SUCCESS(vos_status))
             {
@@ -19146,7 +19159,11 @@
                                 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
                 return -ENOENT;
             }
-
+            vos_status =
+                 vos_wait_single_event(&hostap_state->sta_discon_event,
+                                       WLAN_WAIT_TIME_DISCONNECT);
+            if (!VOS_IS_STATUS_SUCCESS(vos_status))
+                hddLog(LOGE,"!!%s: ERROR: Deauth wait expired!!", __func__);
         }
     }
 
diff --git a/CORE/HDD/src/wlan_hdd_hostapd.c b/CORE/HDD/src/wlan_hdd_hostapd.c
index 32a7ed7..29daf50 100644
--- a/CORE/HDD/src/wlan_hdd_hostapd.c
+++ b/CORE/HDD/src/wlan_hdd_hostapd.c
@@ -1497,6 +1497,8 @@
             memcpy(wrqu.addr.sa_data, &pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac,
                    sizeof(v_MACADDR_t));
             hddLog(LOG1, " disassociated "MAC_ADDRESS_STR, MAC_ADDR_ARRAY(wrqu.addr.sa_data));
+
+            vos_status = vos_event_set(&pHostapdState->sta_discon_event);
             if (pSapEvent->sapevt.sapStationDisassocCompleteEvent.reason == eSAP_USR_INITATED_DISASSOC)
                 hddLog(LOG1," User initiated disassociation");
             else
@@ -5536,6 +5538,12 @@
          VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: Hostapd HDD vos event init failed!!"));
          return status;
     }
+    status = vos_event_init(&phostapdBuf->sta_discon_event);
+    if (!VOS_IS_STATUS_SUCCESS(status))
+    {
+        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "ERROR: Hostapd HDD sta disassoc event init failed!!");
+        return status;
+    }
 #ifdef DHCP_SERVER_OFFLOAD
     status = vos_event_init(&dhcp_status->vos_event);
     if (!VOS_IS_STATUS_SUCCESS(status)) {