wlan: MCC- EAPOL frame to use TX_HIGH_PRIO DXE channel and mgmt pool
EAPOL frames cannot be delayed even if DATA pool is full
MCC second session EAPOL failure under high data traffic in first
session
Change-Id: I702224d3873826aa3954bcb2a76868f1e25d08bd
CR-Fixed: 387009, 412052
diff --git a/CORE/TL/src/wlan_qct_tl.c b/CORE/TL/src/wlan_qct_tl.c
index 8aa0a5a..d70f1dd 100644
--- a/CORE/TL/src/wlan_qct_tl.c
+++ b/CORE/TL/src/wlan_qct_tl.c
@@ -1222,7 +1222,8 @@
pTLCb->atlSTAClients[pwSTADescType->ucSTAId].ucCurrentAC = WLANTL_AC_VO;
pTLCb->atlSTAClients[pwSTADescType->ucSTAId].ucCurrentWeight = 0;
pTLCb->atlSTAClients[pwSTADescType->ucSTAId].ucServicedAC = WLANTL_AC_BK;
-
+ pTLCb->atlSTAClients[pwSTADescType->ucSTAId].ucEapolPktPending = 0;
+
vos_mem_zero( pTLCb->atlSTAClients[pwSTADescType->ucSTAId].aucACMask,
sizeof(pTLCb->atlSTAClients[pwSTADescType->ucSTAId].aucACMask));
@@ -1699,9 +1700,15 @@
--------------------------------------------------------------------*/
pTLCb->ucRegisteredStaId = ucSTAId;
- if( WLANTL_STA_AUTHENTICATED != pTLCb->atlSTAClients[ucSTAId].tlState )
- {
- VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+ if( WLANTL_STA_CONNECTED == pTLCb->atlSTAClients[ucSTAId].tlState )
+ { /* EAPOL_HI_PRIORITY : need to find out whether EAPOL is pending before
+ WLANTL_FetchPacket()/WLANTL_TxConn() is called.
+ change STA_AUTHENTICATED != tlState to CONNECTED == tlState
+ to make sure TL is indeed waiting for EAPOL.
+ Just in the case when STA got disconnected shortly after connectection */
+ pTLCb->atlSTAClients[ucSTAId].ucEapolPktPending = 1;
+
+ VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH,
"WLAN TL:Packet pending indication for STA: %d AC: %d State: %d",
ucSTAId, ucAc, pTLCb->atlSTAClients[ucSTAId].tlState);
}
@@ -1713,7 +1720,8 @@
through WLANTL_TX_STAID_AC_IND message.
-----------------------------------------------------------------------*/
#ifdef WLAN_SOFTAP_FEATURE
- if (WLAN_STA_SOFTAP != pTLCb->atlSTAClients[ucSTAId].wSTADesc.wSTAType)
+ if ((WLAN_STA_SOFTAP != pTLCb->atlSTAClients[ucSTAId].wSTADesc.wSTAType) &&
+ !(vos_concurrent_sessions_running()))
{
#endif
@@ -2089,7 +2097,7 @@
ucWDSEnabled, extraHeadSpace, pMetaInfo->ucType,
&pTLCb->atlSTAClients[ucStaId].wSTADesc.vSelfMACAddress,
pMetaInfo->ucTID, 0 /* No ACK */, pMetaInfo->usTimeStamp,
- pMetaInfo->ucIsEapol, pMetaInfo->ucUP );
+ pMetaInfo->ucIsEapol || pMetaInfo->ucIsWai, pMetaInfo->ucUP );
if ( VOS_STATUS_SUCCESS != vosStatus )
{
@@ -3702,6 +3710,112 @@
break; /* Out of resources or reached max len */
}
}
+#if defined( FEATURE_WLAN_INTEGRATED_SOC )
+ /* note: this feature implemented only after WLAN_INGETRATED_SOC */
+ /* search 'EAPOL_HI_PRIORITY' will show EAPOL HI_PRIORITY change in TL and WDI
+ by default, EAPOL will be treated as higher priority, which means
+ use mgmt_pool and DXE_TX_HI prority channel.
+ this is introduced to address EAPOL failure under high background traffic
+ with multi-channel concurrent mode. But this change works in SCC or standalone, too.
+ see CR#387009 and WCNSOS-8
+ */
+ else if (( WDA_TLI_MIN_RES_MF <= pTLCb->uResCount )&&
+ ( 0 == pTLCb->ucTxSuspended ) &&
+ ( uFlowMask & ( 1 << WDA_TXFLOW_MGMT ) )
+ )
+ {
+ vosTempBuf = NULL;
+ /*---------------------------------------------------------------------
+ Check to see if there was any EAPOL packet is pending
+ *--------------------------------------------------------------------*/
+ for ( i = 0; i < WLAN_MAX_STA_COUNT; i++)
+ {
+ if ((pTLCb->atlSTAClients[i].ucExists) &&
+ (0 == pTLCb->atlSTAClients[i].ucTxSuspended) &&
+ (pTLCb->atlSTAClients[i].ucEapolPktPending)
+ )
+ break;
+ }
+
+ if (i >= WLAN_MAX_STA_COUNT)
+ {
+ /* No More to Serve Exit Get Frames */
+ break;
+ }
+ /* Serve EAPOL frame with HI_FLOW_MASK */
+ ucSTAId = i;
+
+ wSTAEvent = WLANTL_TX_EVENT;
+
+ pfnSTAFsm = tlSTAFsm[pTLCb->atlSTAClients[ucSTAId].tlState].
+ pfnSTATbl[wSTAEvent];
+
+ if ( NULL != pfnSTAFsm )
+ {
+ pTLCb->atlSTAClients[ucSTAId].ucNoMoreData = 0;
+ vosStatus = pfnSTAFsm( pvosGCtx, ucSTAId, &vosTempBuf);
+
+ if (( VOS_STATUS_SUCCESS != vosStatus ) &&
+ ( NULL != vosTempBuf ))
+ {
+ pTLCb->atlSTAClients[ucSTAId].pfnSTATxComp( pvosGCtx,
+ vosTempBuf,
+ vosStatus );
+ vosTempBuf = NULL;
+ break;
+ }/* status success*/
+ }
+
+ if (NULL != vosTempBuf)
+ {
+ WDA_TLI_PROCESS_FRAME_LEN( vosTempBuf, usPktLen, uResLen, uTotalPktLen);
+
+ VOS_ASSERT( usPktLen <= WLANTL_MAX_ALLOWED_LEN);
+
+ TLLOG4(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,
+ "WLAN TL:Resources needed by frame: %d", uResLen));
+
+ if ( ( pTLCb->uResCount >= (uResLen + WDA_TLI_MIN_RES_MF ) ) &&
+ ( uRemaining > uTotalPktLen )
+ )
+ {
+ TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH,
+ "WLAN TL:Chaining data frame on GetFrame"));
+
+ vos_pkt_chain_packet( vosDataBuff, vosTempBuf, 1 /*true*/ );
+
+ pTLCb->atlSTAClients[i].ucEapolPktPending = 0;
+
+ VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH,
+ "WLAN TL:GetFrames STA: %d EAPOLPktPending %d",
+ ucSTAId, pTLCb->atlSTAClients[ucSTAId].ucEapolPktPending);
+
+ /*EAPOL frame cannot be delayed*/
+ pTLCb->bUrgent = TRUE;
+
+ vosTempBuf = NULL;
+
+ /*Update remaining len from SSC */
+ uRemaining -= (usPktLen + WDA_DXE_HEADER_SIZE);
+
+ /*Update resource count */
+ pTLCb->uResCount -= uResLen;
+
+#ifdef WLAN_SOFTAP_FEATURE
+ //fow control update
+ pTLCb->atlSTAClients[ucSTAId].uIngress_length += uResLen;
+ pTLCb->atlSTAClients[ucSTAId].uBuffThresholdMax = (pTLCb->atlSTAClients[ucSTAId].uBuffThresholdMax >= uResLen) ?
+ (pTLCb->atlSTAClients[ucSTAId].uBuffThresholdMax - uResLen) : 0;
+#endif
+ }
+ }
+ else
+ { // no EAPOL frames exit Get frames
+ break;
+ }
+ }
+#endif /* FEATURE_WLAN_INTEGRATED_SOC */
+
else if (( WDA_TLI_MIN_RES_DATA <= pTLCb->uResCount )&&
( 0 == pTLCb->ucTxSuspended )
#if defined( FEATURE_WLAN_INTEGRATED_SOC )
@@ -5852,7 +5966,7 @@
extraHeadSpace,
ucTypeSubtype, &pTLCb->atlSTAClients[ucSTAId].wSTADesc.vSelfMACAddress,
ucTid, HAL_TX_NO_ENCRYPTION_MASK,
- tlMetaInfo.usTimeStamp, tlMetaInfo.ucIsEapol, tlMetaInfo.ucUP );
+ tlMetaInfo.usTimeStamp, tlMetaInfo.ucIsEapol || tlMetaInfo.ucIsWai, tlMetaInfo.ucUP );
if ( VOS_STATUS_SUCCESS != vosStatus )
{
diff --git a/CORE/TL/src/wlan_qct_tli.h b/CORE/TL/src/wlan_qct_tli.h
index 3089d95..3e953de 100644
--- a/CORE/TL/src/wlan_qct_tli.h
+++ b/CORE/TL/src/wlan_qct_tli.h
@@ -523,6 +523,9 @@
/*Packet pending flag - set if tx is pending for the station*/
v_U8_t ucPktPending;
+ /*EAPOL Packet pending flag - set if EAPOL packet is pending for the station*/
+ v_U8_t ucEapolPktPending;
+
/*used on tx packet to signal when there is no more data to tx for the
moment=> packets can be passed to BAL */
v_U8_t ucNoMoreData;
diff --git a/CORE/WDI/DP/src/wlan_qct_wdi_ds.c b/CORE/WDI/DP/src/wlan_qct_wdi_ds.c
index 8798d70..98d549b 100644
--- a/CORE/WDI/DP/src/wlan_qct_wdi_ds.c
+++ b/CORE/WDI/DP/src/wlan_qct_wdi_ds.c
@@ -161,9 +161,13 @@
switch(ucType)
{
case WDI_MAC_DATA_FRAME:
+ if(!pTxMetadata->isEapol)
+ {
pMemPool = &(pClientData->dataMemPool);
ucBdPoolType = WDI_DATA_POOL_ID;
- break;
+ break;
+ }
+ // intentional fall-through to handle eapol packet as mgmt
case WDI_MAC_MGMT_FRAME:
pMemPool = &(pClientData->mgmtMemPool);
ucBdPoolType = WDI_MGMT_POOL_ID;
@@ -195,7 +199,8 @@
}
/* resource count only for data packet */
- if(WDI_MAC_DATA_FRAME == ucType)
+ // EAPOL packet doesn't use data mem pool if being treated as higher priority
+ if(WDI_MAC_DATA_FRAME == ucType && (!pTxMetadata->isEapol))
{
WDI_DS_MemPoolIncreaseReserveCount(pMemPool, staId);
}
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 61741a4..9e388d8 100644
--- a/CORE/WDI/TRP/DTS/src/wlan_qct_wdi_dts.c
+++ b/CORE/WDI/TRP/DTS/src/wlan_qct_wdi_dts.c
@@ -90,12 +90,19 @@
switch(pTxMetadata->frmType)
{
case WDI_MAC_DATA_FRAME:
+ /* note that EAPOL frame hasn't incremented ReserveCount. see
+ WDI_DS_TxPacket() in wlan_qct_wdi_ds.c
+ */
+ if(!pTxMetadata->isEapol)
+ {
/* SWAP BD header to get STA index for completed frame */
WDI_SwapTxBd(pvBDHeader);
staIndex = (wpt_uint8)WDI_TX_BD_GET_STA_ID(pvBDHeader);
WDI_DS_MemPoolFree(&(pClientData->dataMemPool), pvBDHeader, physBDHeader);
WDI_DS_MemPoolDecreaseReserveCount(&(pClientData->dataMemPool), staIndex);
break;
+ }
+ // intentional fall-through to handle eapol packet as mgmt
case WDI_MAC_MGMT_FRAME:
WDI_DS_MemPoolFree(&(pClientData->mgmtMemPool), pvBDHeader, physBDHeader);
break;
@@ -487,8 +494,12 @@
// assign MDPU to correct channel??
channel = (pTxMetadata->frmType & WDI_MAC_DATA_FRAME)?
- WDTS_CHANNEL_TX_LOW_PRI : WDTS_CHANNEL_TX_HIGH_PRI;
-
+ /* EAPOL frame uses TX_HIGH_PRIORITY DXE channel
+ To make sure EAPOL (for second session) is pushed even if TX_LO channel
+ already reached to low resource condition
+ This can happen especially in MCC, high data traffic TX in first session
+ */
+ ((pTxMetadata->isEapol) ? WDTS_CHANNEL_TX_HIGH_PRI : WDTS_CHANNEL_TX_LOW_PRI) : WDTS_CHANNEL_TX_HIGH_PRI;
// Send packet to Transport Driver.
status = gTransportDriver.xmit(pDTDriverContext, pFrame, channel);
return status;