wlan: Fixed issue in handling of EAPOL keys

Due to the issue in handling of EAPOL keys
there was a race condition where EAPOL keys
were never getting exchanged in time and then
AP was cancelling authentation/association. Due
to this issue STA was not getting connected to
some APs (Belkin F5D7230-4). Other issues are
also fixed in handling of EAPOL such that EAPOL
effectively uses mgmt pool and is handled only in
connected state. Similarly, non-key data are only
handled in authenticated state.

Change-Id: I0ccd4cc8c81d2bb87352c122cd6e00f64224afdd
CRs-fixed: 442143
diff --git a/CORE/HDD/src/wlan_hdd_assoc.c b/CORE/HDD/src/wlan_hdd_assoc.c
index 201786b..633f69a 100755
--- a/CORE/HDD/src/wlan_hdd_assoc.c
+++ b/CORE/HDD/src/wlan_hdd_assoc.c
@@ -982,6 +982,7 @@
    staDesc.ucInitState = pRoamInfo->fAuthRequired ?
       WLANTL_STA_CONNECTED : WLANTL_STA_AUTHENTICATED;
    // Register the Station with TL...      
+   VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "%s: HDD register TL ucInitState=%d", __func__, staDesc.ucInitState );
    vosStatus = WLANTL_RegisterSTAClient( pHddCtx->pvosContext, 
                                          hdd_rx_packet_cbk, 
                                          hdd_tx_complete_cbk, 
@@ -1318,6 +1319,9 @@
             }
             else
             {
+                VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
+                          "%s: staId: %d Changing TL state to AUTHENTICATED",
+                          __func__, pHddStaCtx->conn_info.staId[ 0 ] );
                 vosStatus = WLANTL_ChangeSTAState( pHddCtx->pvosContext, pHddStaCtx->conn_info.staId[ 0 ], 
                         WLANTL_STA_AUTHENTICATED );
                 pHddStaCtx->conn_info.uIsAuthenticated = VOS_TRUE;
diff --git a/CORE/HDD/src/wlan_hdd_wext.c b/CORE/HDD/src/wlan_hdd_wext.c
index 1809d56..3672d12 100644
--- a/CORE/HDD/src/wlan_hdd_wext.c
+++ b/CORE/HDD/src/wlan_hdd_wext.c
@@ -846,8 +846,7 @@
         /*To avoid race condition between the set key and the last EAPOL
           packet, notify TL to finish upper layer authentication incase if the
           last EAPOL packet pending in the TL queue.*/
-        vos_status = WLANTL_Finish_ULA(wlan_hdd_ula_done_cb,pAdapter,
-                                       pHddStaCtx->conn_info.staId[0]);
+        vos_status = WLANTL_Finish_ULA(wlan_hdd_ula_done_cb, pAdapter);
 
         if ( vos_status != VOS_STATUS_SUCCESS )
         {
diff --git a/CORE/TL/inc/wlan_qct_tl.h b/CORE/TL/inc/wlan_qct_tl.h
index 75df0a2..cbf27ce 100644
--- a/CORE/TL/inc/wlan_qct_tl.h
+++ b/CORE/TL/inc/wlan_qct_tl.h
@@ -2521,7 +2521,7 @@
 ============================================================================*/
 
 VOS_STATUS WLANTL_Finish_ULA( void (*callbackRoutine) (void *callbackContext),
-                              void *callbackContext, uint8 staId);
+                              void *callbackContext);
 
 /*===============================================================================
   FUNCTION       WLANTL_UpdateRssiBmps
diff --git a/CORE/TL/src/wlan_qct_tl.c b/CORE/TL/src/wlan_qct_tl.c
index 72c32bc..5514f1d 100644
--- a/CORE/TL/src/wlan_qct_tl.c
+++ b/CORE/TL/src/wlan_qct_tl.c
@@ -1096,10 +1096,10 @@
 ============================================================================*/
 
 VOS_STATUS WLANTL_Finish_ULA( void (*callbackRoutine) (void *callbackContext),
-                              void *callbackContext, uint8 staId)
+                              void *callbackContext)
 {
 #if defined( FEATURE_WLAN_INTEGRATED_SOC )
-   return WDA_DS_FinishULA( callbackRoutine, callbackContext, staId); 
+   return WDA_DS_FinishULA( callbackRoutine, callbackContext);
 #else
    vos_msg_t  vosMsg;   
    VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
@@ -3748,6 +3748,7 @@
    vos_pkt_t*          vosDataBuff;
    v_U32_t             uTotalPktLen;
    v_U32_t             i=0;
+   v_U32_t             j=0;
    v_U32_t             ucResult = 0;
    VOS_STATUS          vosStatus;
    WLANTL_STAEventType   wSTAEvent;
@@ -3960,7 +3961,8 @@
            if ((NULL != pTLCb->atlSTAClients[i]) &&
                (pTLCb->atlSTAClients[i]->ucExists) &&
                (0 == pTLCb->atlSTAClients[i]->ucTxSuspended) &&
-               (pTLCb->atlSTAClients[i]->ucEapolPktPending)
+               (WLANTL_STA_CONNECTED == pTLCb->atlSTAClients[i]->tlState) &&
+               (pTLCb->atlSTAClients[i]->ucPktPending)
                )
                break;
         }
@@ -3973,6 +3975,15 @@
         /* Serve EAPOL frame with HI_FLOW_MASK */
         ucSTAId = i;
 
+        for (j = WLANTL_MAX_AC ; j > 0; j--)
+        {
+          if (0 != pTLCb->atlSTAClients[ucSTAId]->aucACMask[j-1])
+          {
+            pTLCb->atlSTAClients[ucSTAId]->ucCurrentAC = j-1;
+            pTLCb->uCurServedAC = j-1;
+          }
+        }
+
         pClientSTA = pTLCb->atlSTAClients[ucSTAId];
 
         wSTAEvent = WLANTL_TX_EVENT;
@@ -4012,24 +4023,6 @@
 
               vos_pkt_chain_packet( vosDataBuff, vosTempBuf, 1 /*true*/ );
 
-              //Check if EAPOL pkt is pending and ULA notification is pending 
-              //if both the condition are met then send the notification to ULA
-              if ( pClientSTA->ucEapolPktPending &&
-                   pClientSTA->ucULANotificationPending )
-              {
-                 //Error check if callback routine is not NULL
-                 if(pClientSTA->callbackRoutine != NULL )
-                 {
-                     pClientSTA->callbackRoutine(pClientSTA->callbackContext);
-                     pClientSTA->ucULANotificationPending = 0;
-                 }
-              }
-
-              pClientSTA->ucEapolPktPending = 0;
-              VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH,
-                "WLAN TL:GetFrames STA: %d EAPOLPktPending %d",
-                         ucSTAId, pClientSTA->ucEapolPktPending);
-
               /*EAPOL frame cannot be delayed*/
               pTLCb->bUrgent      = TRUE;
 
@@ -4047,11 +4040,18 @@
               pClientSTA->uBuffThresholdMax = (pClientSTA->uBuffThresholdMax >= uResLen) ?
                 (pClientSTA->uBuffThresholdMax - uResLen) : 0;
 #endif
+              pClientSTA->ucEapolPktPending = 0;
+              VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH,
+                "WLAN TL:GetFrames STA: %d EAPOLPktPending %d",
+                         ucSTAId, pClientSTA->ucEapolPktPending);
             }
          }
          else
          {  // no EAPOL frames exit Get frames
-            break;
+            TLLOG2(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH,
+                   "WLAN TL:GetFrames STA: %d, no EAPOL frame, continue.",
+                   ucSTAId));
+            continue;
          }
     }
 #endif /* FEATURE_WLAN_INTEGRATED_SOC */
@@ -8145,7 +8145,6 @@
    v_U8_t          ucSTAId; 
    v_U8_t          ucUcastSig;
    v_U8_t          ucBcastSig;
-   v_U8_t          staId;
 #ifdef WLAN_SOFTAP_FEATURE
    WLANTL_CbType*        pTLCb = NULL;
    WLANTL_STAClientType* pClientSTA = NULL;
@@ -8233,41 +8232,9 @@
       break;
 
   case WDA_DS_FINISH_ULA:
-    pTLCb = VOS_GET_TL_CB(pvosGCtx);
-    if ( NULL == pTLCb )
-    {
-        TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
-            "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_STAPktPending"));
-        return VOS_STATUS_E_FAULT;
-    }
-    staId = message->reserved; 
-    pClientSTA = pTLCb->atlSTAClients[staId];
-
-    if ( NULL == pClientSTA )
-    {
-        TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
-            "WLAN TL:Client Memory was not allocated on %s", __func__));
-        return VOS_STATUS_E_FAILURE;
-    }
-
-    //change for ULA 
-    if ( pClientSTA->ucEapolPktPending == 0  )
-    {
-      //ULA notification done bc no eapol pending 
-      callbackContext = (void *)message->bodyval;
-      callbackRoutine = message->bodyptr;
-      callbackRoutine(callbackContext);
-
-    }
-    else 
-    {
-      //ULA notification delayed bc eapol pending 
-       TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH,
-            "WLAN TL:EAPOL pkt pending. ULA notification has been delayed..."));
-       pClientSTA->ucULANotificationPending = 1;
-       pClientSTA->callbackRoutine = message->bodyptr;
-       pClientSTA->callbackContext = (void *)message->bodyval;
-    }
+    callbackContext = (void *)message->bodyval;
+    callbackRoutine = message->bodyptr;
+    callbackRoutine(callbackContext);
     break;
 #endif
 
@@ -9652,8 +9619,6 @@
   v_U8_t          uFlowMask; // TX FlowMask from WDA
   uint8           ucACMask; 
   uint8           i = 0; 
-  uint8           ucIndexSTA = 0;
-  uint8           j = 0; 
   /*------------------------------------------------------------------------
     Extract TL control block
   ------------------------------------------------------------------------*/
@@ -9674,41 +9639,6 @@
     return VOS_STATUS_E_FAULT;
   }
 
-  /* ! walk the STA table and check for :*/
-  for ( ucIndexSTA = 0; ucIndexSTA < WLAN_MAX_STA_COUNT; ucIndexSTA++ )
-  {
-      if (NULL == pTLCb->atlSTAClients[ucIndexSTA])
-      {
-          continue;
-      }
-      WLAN_TL_AC_ARRAY_2_MASK (pTLCb->atlSTAClients[ucIndexSTA], ucACMask, i);
-      if ( ( pTLCb->atlSTAClients[ucIndexSTA]->ucExists) &&
-            ( WLANTL_STA_CONNECTED ==  pTLCb->atlSTAClients[ucIndexSTA]->tlState) &&
-            ((pTLCb->atlSTAClients[ucIndexSTA]->ucPktPending) && !(ucACMask)) &&
-            (0 != (ucACMask & uFlowMask)) )
-      {
-          // Find a station. Weight is updated already.
-          *pucSTAId = ucNextSTA;
-          pTLCb->ucCurrentSTA = ucNextSTA;
-          if(NULL == pTLCb->atlSTAClients[*pucSTAId])
-          {
-              continue;
-          }
-          //walk array : aucACMask[i] and pick the 1st one with the highest priority that is non 0 
-          for( j = WLANTL_MAX_AC; j >= 0; j--)
-          {
-            if(  0!= pTLCb->atlSTAClients[*pucSTAId]->aucACMask[j] )
-               pTLCb->atlSTAClients[*pucSTAId]->ucCurrentAC = pTLCb->atlSTAClients[*pucSTAId]->aucACMask[i];
-          }
-  
-          TLLOG4(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,
-                   " TL serve one station AC: %d  W: %d StaId: %d",
-                   pTLCb->uCurServedAC, pTLCb->ucCurLeftWeight, pTLCb->ucCurrentSTA ));
-      
-          return VOS_STATUS_SUCCESS;
-      }
-   }
-
   ucNextSTA = pTLCb->ucCurrentSTA;
 
   ++ucNextSTA;
@@ -9768,7 +9698,15 @@
              (0 == (ucACMask & ucACFilter)) )
 
         {
-          //current statioin does not exist or have any packet to serve.
+          //current station does not exist or have any packet to serve.
+          continue;
+        }
+
+        if (WLANTL_STA_AUTHENTICATED != pTLCb->atlSTAClients[ucNextSTA]->tlState)
+        {
+          TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH,
+                 "%s Sta %d not in auth state so skipping it.",
+                 __func__, ucNextSTA));
           continue;
         }
 
@@ -9935,10 +9873,16 @@
     if (( pTLCb->atlSTAClients[ucNextSTA]->ucExists ) &&
         ( pTLCb->atlSTAClients[ucNextSTA]->ucPktPending ))
     {
-      TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH,
-      "STA ID: %d on WLAN_TLGetNextTxIds", *pucSTAId));
-      pTLCb->ucCurrentSTA = ucNextSTA; 
-      break;
+      if (WLANTL_STA_AUTHENTICATED == pTLCb->atlSTAClients[ucNextSTA]->tlState)
+      {
+        TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH,
+               "STA ID: %d on WLAN_TLGetNextTxIds", *pucSTAId));
+        pTLCb->ucCurrentSTA = ucNextSTA;
+        break;
+      } else
+        TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH,
+               "%s Sta %d is not in auth state, skipping this sta.",
+               __func__, ucNextSTA));
     }
   }
 
@@ -10094,11 +10038,18 @@
     if (( pTLCb->atlSTAClients[ucNextSTA]->ucExists ) &&
         ( pTLCb->atlSTAClients[ucNextSTA]->ucPktPending ))
     {
-      TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH,
-      "WLAN TL:No station registered with TL at this point or Mask 0"
-      "STA ID: %d on WLAN_TLGetNextTxIds", *pucSTAId));
-      pTLCb->ucCurrentSTA = ucNextSTA; 
-      break;
+      if (WLANTL_STA_AUTHENTICATED == pTLCb->atlSTAClients[ucNextSTA]->tlState)
+      {
+        TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH,
+               "WLAN TL:No station registered with TL at this point or Mask 0"
+               "STA ID: %d on WLAN_TLGetNextTxIds", *pucSTAId));
+        pTLCb->ucCurrentSTA = ucNextSTA;
+        break;
+      }
+      else
+        TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH,
+               "%s Sta %d is not in auth state, skipping this sta.",
+               __func__, ucNextSTA));
     }
   }
 
diff --git a/CORE/TL/src/wlan_qct_tli.h b/CORE/TL/src/wlan_qct_tli.h
index f8874a2..bbe9a7d 100644
--- a/CORE/TL/src/wlan_qct_tli.h
+++ b/CORE/TL/src/wlan_qct_tli.h
@@ -578,13 +578,6 @@
   /*Begining of the cached packets chain*/
   vos_pkt_t*                 vosEndCachedFrame;
 
-  /* ULA notfication is pending */
-  v_U8_t                ucULANotificationPending;
-
-  void (*callbackRoutine) (void *callbackContext);
-
-  void                 *callbackContext;
-
 #ifdef WLAN_SOFTAP_FEATURE
 
   /* LWM related fields */
diff --git a/CORE/WDA/inc/wlan_qct_wda.h b/CORE/WDA/inc/wlan_qct_wda.h
index f113fae..c681692 100644
--- a/CORE/WDA/inc/wlan_qct_wda.h
+++ b/CORE/WDA/inc/wlan_qct_wda.h
@@ -1551,8 +1551,7 @@
 WDA_DS_FinishULA
 (
  void (*callbackRoutine) (void *callbackContext),
- void  *callbackContext,
- v_U8_t staId
+ void  *callbackContext
 );
 
 /*==========================================================================
diff --git a/CORE/WDA/src/wlan_qct_wda_ds.c b/CORE/WDA/src/wlan_qct_wda_ds.c
index 9e744bc..7908c1d 100644
--- a/CORE/WDA/src/wlan_qct_wda_ds.c
+++ b/CORE/WDA/src/wlan_qct_wda_ds.c
@@ -654,8 +654,7 @@
 WDA_DS_FinishULA
 (
  void (*callbackRoutine) (void *callbackContext),
- void  *callbackContext,
- v_U8_t staId
+ void  *callbackContext
 )
 {
   vos_msg_t                    sMessage;
@@ -667,7 +666,6 @@
 
   vos_mem_zero( &sMessage, sizeof(vos_msg_t) );
 
-  sMessage.reserved = staId;
   sMessage.bodyval  = (v_U32_t)callbackContext;
   sMessage.bodyptr  = callbackRoutine;
   sMessage.type     = WDA_DS_FINISH_ULA;