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;