/* DTS Tx packet complete function. * This function should be invoked by the transport device to indicate * transmit complete for a frame. * Parameters: * pContext:Cookie that should be passed back to the caller * pFrame:Refernce to PAL frame. * Return Value: SUCCESS Completed successfully. * FAILURE_XXX Request was rejected due XXX Reason. * */ wpt_status WDTS_TxPacketComplete(void *pContext, wpt_packet *pFrame, wpt_status status) { WDI_DS_ClientDataType *pClientData = (WDI_DS_ClientDataType*)(pContext); WDI_DS_TxMetaInfoType *pTxMetadata; void *pvBDHeader, *physBDHeader; wpt_uint8 staIndex; // Do Sanity checks if(NULL == pContext || NULL == pFrame){ return eWLAN_PAL_STATUS_E_FAILURE; } // extract metadata from PAL packet pTxMetadata = WDI_DS_ExtractTxMetaData(pFrame); pTxMetadata->txCompleteStatus = status; // Free BD header from pool WDI_GetBDPointers(pFrame, &pvBDHeader, &physBDHeader); 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 */ #ifdef FEATURE_WLAN_TDLS /* I utilizes TDLS mgmt frame always sent at BD_RATE2. (See limProcessTdls.c) Assumption here is data frame sent by WDA_TxPacket() <- HalTxFrame/HalTxFrameWithComplete() should take managment path. As of today, only TDLS feature has special data frame which needs to be treated as mgmt. */ if((!pTxMetadata->isEapol) && ((pTxMetadata->txFlags & WDI_USE_BD_RATE2_FOR_MANAGEMENT_FRAME) != WDI_USE_BD_RATE2_FOR_MANAGEMENT_FRAME)) #else if(!pTxMetadata->isEapol) #endif { /* 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; } WDI_SetBDPointers(pFrame, 0, 0); // Invoke Tx complete callback pClientData->txCompleteCB(pClientData->pCallbackContext, pFrame); return eWLAN_PAL_STATUS_SUCCESS; }
void WDI_DS_PrepareBDHeader (wpt_packet* palPacket, wpt_uint8 ucDisableHWFrmXtl, wpt_uint8 alignment) { void* pvBDHeader; wpt_uint8 ucHeaderOffset; wpt_uint8 ucHeaderLen; wpt_uint8 ucQosEnabled; wpt_uint8 ucWDSEnabled; wpt_uint32 ucMpduLen; wpt_uint32 ucPktLen; WDI_DS_TxMetaInfoType *pTxMetadata; pvBDHeader = WPAL_PACKET_GET_BD_POINTER(palPacket); pTxMetadata = WDI_DS_ExtractTxMetaData(palPacket); ucQosEnabled = pTxMetadata->qosEnabled; ucWDSEnabled = pTxMetadata->fenableWDS; WPAL_PACKET_SET_BD_LENGTH(palPacket, WDI_TX_BD_HEADER_SIZE); if ( ucDisableHWFrmXtl ) { ucHeaderOffset = WDI_TX_BD_HEADER_SIZE; ucHeaderLen = WDI_802_11_HEADER_LEN; if ( 0 != ucQosEnabled ) { ucHeaderLen += WDI_802_11_HEADER_QOS_CTL; } if ( 0 != ucWDSEnabled) { ucHeaderLen += WDI_802_11_HEADER_ADDR4_LEN; } } else { ucHeaderOffset = WDI_TX_BD_HEADER_SIZE+WDI_802_11_MAX_HEADER_LEN; ucHeaderLen = WDI_802_3_HEADER_LEN; } WDI_TX_BD_SET_MPDU_HEADER_LEN( pvBDHeader, ucHeaderLen); WDI_TX_BD_SET_MPDU_HEADER_OFFSET( pvBDHeader, ucHeaderOffset); WDI_TX_BD_SET_MPDU_DATA_OFFSET( pvBDHeader, ucHeaderOffset + ucHeaderLen + alignment); ucPktLen = wpalPacketGetLength( palPacket ); ucMpduLen = ucPktLen - WPAL_PACKET_GET_BD_LENGTH( palPacket ); WDI_TX_BD_SET_MPDU_LEN( pvBDHeader, ucMpduLen ); DTI_TRACE( DTI_TRACE_LEVEL_INFO, "WLAN DTI: VALUES ARE HLen=%x Hoff=%x doff=%x len=%x ex=%d", ucHeaderLen, ucHeaderOffset, (ucHeaderOffset + ucHeaderLen + alignment), pTxMetadata->fPktlen, alignment); }
/* DTS Tx packet function. * This function should be invoked by the DAL Dataservice to schedule transmit frame through DXE/SDIO. * Parameters: * pContext:Cookie that should be passed back to the caller along with the callback. * pFrame:Refernce to PAL frame. * Return Value: SUCCESS Completed successfully. * FAILURE_XXX Request was rejected due XXX Reason. * */ wpt_status WDTS_TxPacket(void *pContext, wpt_packet *pFrame) { void *pDTDriverContext = WDT_GetTransportDriverContext(pContext); WDI_DS_TxMetaInfoType *pTxMetadata; WDTS_ChannelType channel = WDTS_CHANNEL_TX_LOW_PRI; wpt_status status = eWLAN_PAL_STATUS_SUCCESS; // extract metadata from PAL packet pTxMetadata = WDI_DS_ExtractTxMetaData(pFrame); //Log the TX Stats if(gDsTrafficStats.running && pTxMetadata->staIdx < HAL_NUM_STA) { if(pTxMetadata->frmType & WDI_MAC_DATA_FRAME) { gDsTrafficStats.txStats[pTxMetadata->staIdx].txBytesPushed += pTxMetadata->fPktlen; gDsTrafficStats.txStats[pTxMetadata->staIdx].txPacketsPushed += 1; } } // assign MDPU to correct channel?? channel = (pTxMetadata->frmType & WDI_MAC_DATA_FRAME)? /* 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 */ #ifdef FEATURE_WLAN_TDLS /* I utilizes TDLS mgmt frame always sent at BD_RATE2. (See limProcessTdls.c) Assumption here is data frame sent by WDA_TxPacket() <- HalTxFrame/HalTxFrameWithComplete() should take managment path. As of today, only TDLS feature has special data frame which needs to be treated as mgmt. */ (((pTxMetadata->isEapol) || (pTxMetadata->txFlags & WDI_USE_BD_RATE2_FOR_MANAGEMENT_FRAME))? WDTS_CHANNEL_TX_HIGH_PRI : WDTS_CHANNEL_TX_LOW_PRI) : WDTS_CHANNEL_TX_HIGH_PRI; #else ((pTxMetadata->isEapol) ? WDTS_CHANNEL_TX_HIGH_PRI : WDTS_CHANNEL_TX_LOW_PRI) : WDTS_CHANNEL_TX_HIGH_PRI; #endif // Send packet to Transport Driver. status = gTransportDriver.xmit(pDTDriverContext, pFrame, channel); #ifdef DEBUG_ROAM_DELAY //Hack we need to send the frame type, so we are using bufflen as frametype vos_record_roam_event(e_DXE_FIRST_XMIT_TIME, (void *)pFrame, pTxMetadata->frmType); //Should we use the below check to avoid funciton calls /* if(gRoamDelayMetaInfo.dxe_monitor_tx) { } */ #endif return status; }
/* DTS Tx packet function. * This function should be invoked by the DAL Dataservice to schedule transmit frame through DXE/SDIO. * Parameters: * pContext:Cookie that should be passed back to the caller along with the callback. * pFrame:Refernce to PAL frame. * Return Value: SUCCESS Completed successfully. * FAILURE_XXX Request was rejected due XXX Reason. * */ wpt_status WDTS_TxPacket(void *pContext, wpt_packet *pFrame) { void *pDTDriverContext = WDT_GetTransportDriverContext(pContext); WDI_DS_TxMetaInfoType *pTxMetadata; WDTS_ChannelType channel = WDTS_CHANNEL_TX_LOW_PRI; wpt_status status = eWLAN_PAL_STATUS_SUCCESS; // extract metadata from PAL packet pTxMetadata = WDI_DS_ExtractTxMetaData(pFrame); // assign MDPU to correct channel?? channel = (pTxMetadata->frmType & WDI_MAC_DATA_FRAME)? WDTS_CHANNEL_TX_LOW_PRI : WDTS_CHANNEL_TX_HIGH_PRI; // Send packet to Transport Driver. status = gTransportDriver.xmit(pDTDriverContext, pFrame, channel); return status; }
v_VOID_t WDA_DS_TxCompleteCB ( v_PVOID_t pvosGCtx, v_PVOID_t pFrameDataBuff ) { tWDA_CbContext* wdaContext = NULL; WDI_DS_TxMetaInfoType* pTxMetadata; VOS_STATUS vosStatus; /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ /*------------------------------------------------------------------------ Sanity check ------------------------------------------------------------------------*/ if ( ( NULL == pvosGCtx ) || ( NULL == pFrameDataBuff ) ) { VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, "WDA: Invalid parameter sent on WDA_DS_TxCompleteCB" ); return; } wdaContext = (tWDA_CbContext *)vos_get_context( VOS_MODULE_ID_WDA, pvosGCtx ); if ( NULL == wdaContext ) { VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, "WDA: Invalid context on WDA_DS_TxCompleteCB" ); return; } // extract metadata from PAL packet pTxMetadata = WDI_DS_ExtractTxMetaData( (wpt_packet*)pFrameDataBuff ); if ( eWLAN_PAL_STATUS_SUCCESS == pTxMetadata->txCompleteStatus ) vosStatus = VOS_STATUS_SUCCESS; else vosStatus = VOS_STATUS_E_FAILURE; wdaContext->pfnTxCompleteCallback( pvosGCtx, pFrameDataBuff, vosStatus ); }
/* DTS Tx packet complete function. * This function should be invoked by the transport device to indicate * transmit complete for a frame. * Parameters: * pContext:Cookie that should be passed back to the caller * pFrame:Refernce to PAL frame. * Return Value: SUCCESS Completed successfully. * FAILURE_XXX Request was rejected due XXX Reason. * */ wpt_status WDTS_TxPacketComplete(void *pContext, wpt_packet *pFrame, wpt_status status) { WDI_DS_ClientDataType *pClientData = (WDI_DS_ClientDataType*)(pContext); WDI_DS_TxMetaInfoType *pTxMetadata; void *pvBDHeader, *physBDHeader; wpt_uint8 staIndex; // Do Sanity checks if(NULL == pContext || NULL == pFrame){ return eWLAN_PAL_STATUS_E_FAILURE; } // extract metadata from PAL packet pTxMetadata = WDI_DS_ExtractTxMetaData(pFrame); pTxMetadata->txCompleteStatus = status; // Free BD header from pool WDI_GetBDPointers(pFrame, &pvBDHeader, &physBDHeader); switch(pTxMetadata->frmType) { case WDI_MAC_DATA_FRAME: /* 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; case WDI_MAC_MGMT_FRAME: WDI_DS_MemPoolFree(&(pClientData->mgmtMemPool), pvBDHeader, physBDHeader); break; } WDI_SetBDPointers(pFrame, 0, 0); // Invoke Tx complete callback pClientData->txCompleteCB(pClientData->pCallbackContext, pFrame); return eWLAN_PAL_STATUS_SUCCESS; }
/*========================================================================== FUNCTION WDA_DS_BuildTxPacketInfo DESCRIPTION Build TX meta info for integrated SOC. Same function calls HAL for reserve BD header space into VOS packet and HAL function to fill it. DEPENDENCIES PARAMETERS IN pvosGCtx VOS context vosDataBuff vos data buffer pvDestMacAddr destination MAC address ponter ucDisableFrmXtl Is frame xtl disabled? ucQosEnabled Is QoS enabled? ucWDSEnabled Is WDS enabled? extraHeadSpace Extra head bytes. If it's not 0 due to 4 bytes align of BD header. typeSubtype typeSubtype from MAC header or TX metainfo/BD pAddr2 address 2 uTid tid txFlag timeStamp ucIsEapol ucUP OUT *pusPktLen Packet length RETURN VALUE VOS_STATUS_E_FAULT: pointer is NULL and other errors VOS_STATUS_SUCCESS: Everything is good :) SIDE EFFECTS ============================================================================*/ VOS_STATUS WDA_DS_BuildTxPacketInfo ( v_PVOID_t pvosGCtx, vos_pkt_t* vosDataBuff, v_MACADDR_t* pvDestMacAddr, v_U8_t ucDisableFrmXtl, v_U16_t* pusPktLen, v_U8_t ucQosEnabled, v_U8_t ucWDSEnabled, v_U8_t extraHeadSpace, v_U8_t typeSubtype, v_PVOID_t pAddr2, v_U8_t uTid, v_U32_t txFlag, v_U32_t timeStamp, v_U8_t ucIsEapol, v_U8_t ucUP ) { VOS_STATUS vosStatus; WDI_DS_TxMetaInfoType* pTxMetaInfo = NULL; v_SIZE_t usMacAddrSize; wpt_FrameCtrl *pFrameControl; /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ /*------------------------------------------------------------------------ Sanity check Extract TL control block ------------------------------------------------------------------------*/ if ( ( NULL == pvosGCtx ) || ( NULL == vosDataBuff ) || ( NULL == pvDestMacAddr ) ) { VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, "WDA:Invalid parameter sent on WDA_DS_BuildTxPacketInfo" ); return VOS_STATUS_E_FAULT; } /*------------------------------------------------------------------------ Extract TX Meta Info pointer from PAL packet ------------------------------------------------------------------------*/ pTxMetaInfo = WDI_DS_ExtractTxMetaData( VOS_TO_WPAL_PKT(vosDataBuff) ); if ( NULL == pTxMetaInfo ) { VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, "WLAN TL:Invalid RxMetaInfo pointer from PAL packet on WLANTL_RxFrames"); VOS_ASSERT( 0 ); return VOS_STATUS_E_FAULT; } /* Zero out memeory */ vos_mem_zero( pTxMetaInfo, sizeof( WDI_DS_TxMetaInfoType ) ); /* Fill the TX Meta info */ pTxMetaInfo->txFlags = txFlag; pTxMetaInfo->qosEnabled = ucQosEnabled; pTxMetaInfo->fenableWDS = ucWDSEnabled; pTxMetaInfo->ac = ucUP; pTxMetaInfo->fUP = uTid; pTxMetaInfo->isEapol = ucIsEapol; pTxMetaInfo->fdisableFrmXlt = ucDisableFrmXtl; pTxMetaInfo->frmType = ( ( typeSubtype & 0x30 ) >> 4 ); pTxMetaInfo->typeSubtype = typeSubtype; /* Length = MAC header + payload */ vos_pkt_get_packet_length( vosDataBuff, pusPktLen); pTxMetaInfo->fPktlen = *pusPktLen; /* For management frames, peek into Frame Control field to get value of Protected Frame bit */ pTxMetaInfo->fProtMgmtFrame = 0; if ( WDA_TLI_MGMT_FRAME_TYPE == pTxMetaInfo->frmType ) { if ( 1 == ucDisableFrmXtl ) /* should be 802.11, but check */ { vosStatus = vos_pkt_peek_data( vosDataBuff, 0, (v_PVOID_t)&pFrameControl, sizeof( wpt_FrameCtrl )); if ( VOS_STATUS_SUCCESS != vosStatus ) { VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, "WDA: Failed while attempting to extract Protect Bit in " "Frame Control, status %d", vosStatus ); VOS_ASSERT( 0 ); return VOS_STATUS_E_FAULT; } pTxMetaInfo->fProtMgmtFrame = pFrameControl->wep; VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW, "WLAN TL: fProtMgmtFrame:%d", pTxMetaInfo->fProtMgmtFrame ); } } // Dst address usMacAddrSize = VOS_MAC_ADDR_SIZE; vosStatus = vos_pkt_extract_data( vosDataBuff, WLANTL_MAC_ADDR_ALIGN( ucDisableFrmXtl ), (v_PVOID_t)pvDestMacAddr, &usMacAddrSize ); if ((VOS_STATUS_SUCCESS != vosStatus) || (usMacAddrSize != VOS_MAC_ADDR_SIZE)) { VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, "WDA:Failed while attempting to extract MAC Addr %d", vosStatus ); VOS_ASSERT( 0 ); return VOS_STATUS_E_FAULT; } vos_copy_macaddr( (v_MACADDR_t*)pTxMetaInfo->fSTAMACAddress, pvDestMacAddr ); // ADDR2 vos_copy_macaddr( (v_MACADDR_t*)pTxMetaInfo->addr2MACAddress, pAddr2 ); /* Dump TX meta infro for debugging */ VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW, "WLAN TL: Dump TX meta info: " "txFlags:%d, qosEnabled:%d, ac:%d, " "isEapol:%d, fdisableFrmXlt:%d, frmType:%d", pTxMetaInfo->txFlags, ucQosEnabled, pTxMetaInfo->ac, pTxMetaInfo->isEapol, pTxMetaInfo->fdisableFrmXlt, pTxMetaInfo->frmType ); return VOS_STATUS_SUCCESS; }
WDI_Status WDI_DS_TxPacket(void *pContext, wpt_packet *pFrame, wpt_boolean more) { WDI_DS_ClientDataType *pClientData; wpt_uint8 ucSwFrameTXXlation; wpt_uint8 ucUP; wpt_uint8 ucTypeSubtype; wpt_uint8 isEapol; wpt_uint8 alignment; wpt_uint8 ucTxFlag; wpt_uint8 ucProtMgmtFrame; wpt_uint8* pSTAMACAddress; wpt_uint8* pAddr2MACAddress; WDI_DS_TxMetaInfoType *pTxMetadata; void *physBDHeader, *pvBDHeader; wpt_uint8 ucType; WDI_DS_BdMemPoolType *pMemPool; wpt_uint8 ucBdPoolType; wpt_uint8 staId; WDI_Status wdiStatus; // Do Sanity checks if (NULL == pContext) { return WDI_STATUS_E_FAILURE; } pClientData = (WDI_DS_ClientDataType *) WDI_DS_GetDatapathContext(pContext); if (NULL == pClientData || pClientData->suspend) { return WDI_STATUS_E_FAILURE; } // extract metadata from PAL packet pTxMetadata = WDI_DS_ExtractTxMetaData(pFrame); ucSwFrameTXXlation = pTxMetadata->fdisableFrmXlt; ucTypeSubtype = pTxMetadata->typeSubtype; ucUP = pTxMetadata->fUP; isEapol = pTxMetadata->isEapol; ucTxFlag = pTxMetadata->txFlags; ucProtMgmtFrame = pTxMetadata->fProtMgmtFrame; pSTAMACAddress = &(pTxMetadata->fSTAMACAddress[0]); pAddr2MACAddress = &(pTxMetadata->addr2MACAddress[0]); /*------------------------------------------------------------------------ Get type and subtype of the frame first ------------------------------------------------------------------------*/ ucType = (ucTypeSubtype & WDI_FRAME_TYPE_MASK) >> WDI_FRAME_TYPE_OFFSET; switch(ucType) { case WDI_MAC_DATA_FRAME: #ifdef FEATURE_WLAN_TDLS /* I utilizes TDLS mgmt frame always sent at BD_RATE2. (See limProcessTdls.c) Assumption here is data frame sent by WDA_TxPacket() <- HalTxFrame/HalTxFrameWithComplete() should take managment path. As of today, only TDLS feature has special data frame which needs to be treated as mgmt. */ if((!pTxMetadata->isEapol) && ((pTxMetadata->txFlags & WDI_USE_BD_RATE2_FOR_MANAGEMENT_FRAME) != WDI_USE_BD_RATE2_FOR_MANAGEMENT_FRAME)) #else if(!pTxMetadata->isEapol) #endif { pMemPool = &(pClientData->dataMemPool); ucBdPoolType = WDI_DATA_POOL_ID; break; } // intentional fall-through to handle eapol packet as mgmt case WDI_MAC_MGMT_FRAME: pMemPool = &(pClientData->mgmtMemPool); ucBdPoolType = WDI_MGMT_POOL_ID; break; default: return WDI_STATUS_E_FAILURE; } // Allocate BD header from pool pvBDHeader = WDI_DS_MemPoolAlloc(pMemPool, &physBDHeader, ucBdPoolType); if(NULL == pvBDHeader) return WDI_STATUS_E_FAILURE; WDI_SetBDPointers(pFrame, pvBDHeader, physBDHeader); alignment = 0; WDI_DS_PrepareBDHeader(pFrame, ucSwFrameTXXlation, alignment); if (pTxMetadata->isEapol) { WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, "Packet Length is %d\n", pTxMetadata->fPktlen); } wdiStatus = WDI_FillTxBd(pContext, ucTypeSubtype, pSTAMACAddress, pAddr2MACAddress, &ucUP, 1, pvBDHeader, ucTxFlag /* No ACK */, ucProtMgmtFrame, 0, isEapol, &staId); if(WDI_STATUS_SUCCESS != wdiStatus) { WDI_DS_MemPoolFree(pMemPool, pvBDHeader, physBDHeader); return wdiStatus; } pTxMetadata->staIdx = staId; // Send packet to transport layer. if(eWLAN_PAL_STATUS_SUCCESS !=WDTS_TxPacket(pContext, pFrame)){ WDI_DS_MemPoolFree(pMemPool, pvBDHeader, physBDHeader); return WDI_STATUS_E_FAILURE; } /* resource count only for data packet */ // EAPOL packet doesn't use data mem pool if being treated as higher priority #ifdef FEATURE_WLAN_TDLS /* I utilizes TDLS mgmt frame always sent at BD_RATE2. (See limProcessTdls.c) Assumption here is data frame sent by WDA_TxPacket() <- HalTxFrame/HalTxFrameWithComplete() should take managment path. As of today, only TDLS feature has special data frame which needs to be treated as mgmt. */ if((WDI_MAC_DATA_FRAME == ucType) && (!pTxMetadata->isEapol) && ((pTxMetadata->txFlags & WDI_USE_BD_RATE2_FOR_MANAGEMENT_FRAME) != WDI_USE_BD_RATE2_FOR_MANAGEMENT_FRAME)) #else if(WDI_MAC_DATA_FRAME == ucType && (!pTxMetadata->isEapol)) #endif { WDI_DS_MemPoolIncreaseReserveCount(pMemPool, staId); } return WDI_STATUS_SUCCESS; }
WDI_Status WDI_DS_TxPacket(void *pContext, wpt_packet *pFrame, wpt_boolean more) { WDI_DS_ClientDataType *pClientData; wpt_uint8 ucSwFrameTXXlation; wpt_uint8 ucUP; wpt_uint8 ucTypeSubtype; wpt_uint8 isEapol; wpt_uint8 alignment; wpt_uint8 ucTxFlag; wpt_uint8 ucProtMgmtFrame; wpt_uint8* pSTAMACAddress; wpt_uint8* pAddr2MACAddress; WDI_DS_TxMetaInfoType *pTxMetadata; void *physBDHeader, *pvBDHeader; wpt_uint8 ucType; WDI_DS_BdMemPoolType *pMemPool; wpt_uint8 ucBdPoolType; wpt_uint8 staId; WDI_Status wdiStatus; // if (NULL == pContext) { return WDI_STATUS_E_FAILURE; } pClientData = (WDI_DS_ClientDataType *) WDI_DS_GetDatapathContext(pContext); if (NULL == pClientData || pClientData->suspend) { return WDI_STATUS_E_FAILURE; } // pTxMetadata = WDI_DS_ExtractTxMetaData(pFrame); ucSwFrameTXXlation = pTxMetadata->fdisableFrmXlt; ucTypeSubtype = pTxMetadata->typeSubtype; ucUP = pTxMetadata->fUP; isEapol = pTxMetadata->isEapol; ucTxFlag = pTxMetadata->txFlags; ucProtMgmtFrame = pTxMetadata->fProtMgmtFrame; pSTAMACAddress = &(pTxMetadata->fSTAMACAddress[0]); pAddr2MACAddress = &(pTxMetadata->addr2MACAddress[0]); /* */ ucType = (ucTypeSubtype & WDI_FRAME_TYPE_MASK) >> WDI_FRAME_TYPE_OFFSET; switch(ucType) { case WDI_MAC_DATA_FRAME: #ifdef FEATURE_WLAN_TDLS /* */ if((!pTxMetadata->isEapol) && ((pTxMetadata->txFlags & WDI_USE_BD_RATE2_FOR_MANAGEMENT_FRAME) != WDI_USE_BD_RATE2_FOR_MANAGEMENT_FRAME)) #else if(!pTxMetadata->isEapol) #endif { pMemPool = &(pClientData->dataMemPool); ucBdPoolType = WDI_DATA_POOL_ID; break; } // case WDI_MAC_MGMT_FRAME: pMemPool = &(pClientData->mgmtMemPool); ucBdPoolType = WDI_MGMT_POOL_ID; break; default: return WDI_STATUS_E_FAILURE; } // pvBDHeader = WDI_DS_MemPoolAlloc(pMemPool, &physBDHeader, ucBdPoolType); if(NULL == pvBDHeader) return WDI_STATUS_E_FAILURE; WDI_SetBDPointers(pFrame, pvBDHeader, physBDHeader); alignment = 0; WDI_DS_PrepareBDHeader(pFrame, ucSwFrameTXXlation, alignment); wdiStatus = WDI_FillTxBd(pContext, ucTypeSubtype, pSTAMACAddress, pAddr2MACAddress, &ucUP, 1, pvBDHeader, ucTxFlag /* */, ucProtMgmtFrame, 0, isEapol, &staId); if(WDI_STATUS_SUCCESS != wdiStatus) { WDI_DS_MemPoolFree(pMemPool, pvBDHeader, physBDHeader); return wdiStatus; } pTxMetadata->staIdx = staId; // if(eWLAN_PAL_STATUS_SUCCESS !=WDTS_TxPacket(pContext, pFrame)){ WDI_DS_MemPoolFree(pMemPool, pvBDHeader, physBDHeader); return WDI_STATUS_E_FAILURE; } /* */ // #ifdef FEATURE_WLAN_TDLS /* */ if((WDI_MAC_DATA_FRAME == ucType) && (!pTxMetadata->isEapol) && ((pTxMetadata->txFlags & WDI_USE_BD_RATE2_FOR_MANAGEMENT_FRAME) != WDI_USE_BD_RATE2_FOR_MANAGEMENT_FRAME)) #else if(WDI_MAC_DATA_FRAME == ucType && (!pTxMetadata->isEapol)) #endif { WDI_DS_MemPoolIncreaseReserveCount(pMemPool, staId); } return WDI_STATUS_SUCCESS; }
/*========================================================================== FUNCTION WDA_DS_BuildTxPacketInfo DESCRIPTION Build TX meta info for integrated SOC. Same function calls HAL for reserve BD header space into VOS packet and HAL function to fill it. DEPENDENCIES PARAMETERS IN pvosGCtx VOS context vosDataBuff vos data buffer pvDestMacAddr destination MAC address ponter ucDisableFrmXtl Is frame xtl disabled? ucQosEnabled Is QoS enabled? ucWDSEnabled Is WDS enabled? extraHeadSpace Extra head bytes. If it's not 0 due to 4 bytes align of BD header. typeSubtype typeSubtype from MAC header or TX metainfo/BD pAddr2 address 2 uTid tid txFlag timeStamp ucIsEapol ucUP OUT *pusPktLen Packet length RETURN VALUE VOS_STATUS_E_FAULT: pointer is NULL and other errors VOS_STATUS_SUCCESS: Everything is good :) SIDE EFFECTS ============================================================================*/ VOS_STATUS WDA_DS_BuildTxPacketInfo ( v_PVOID_t pvosGCtx, vos_pkt_t* vosDataBuff, v_MACADDR_t* pvDestMacAddr, v_U8_t ucDisableFrmXtl, v_U16_t* pusPktLen, v_U8_t ucQosEnabled, v_U8_t ucWDSEnabled, v_U8_t extraHeadSpace, v_U8_t typeSubtype, v_PVOID_t pAddr2, v_U8_t uTid, v_U8_t txFlag, v_U32_t timeStamp, v_U8_t ucIsEapol, v_U8_t ucUP ) { #if defined( FEATURE_WLAN_INTEGRATED_SOC ) VOS_STATUS vosStatus; WDI_DS_TxMetaInfoType* pTxMetaInfo = NULL; v_SIZE_t usMacAddrSize; /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ /*------------------------------------------------------------------------ Sanity check Extract TL control block ------------------------------------------------------------------------*/ if ( ( NULL == pvosGCtx ) || ( NULL == vosDataBuff ) || ( NULL == pvDestMacAddr ) ) { VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, "WDA:Invalid parameter sent on WDA_DS_BuildTxPacketInfo" ); return VOS_STATUS_E_FAULT; } /*------------------------------------------------------------------------ Extract TX Meta Info pointer from PAL packet ------------------------------------------------------------------------*/ pTxMetaInfo = WDI_DS_ExtractTxMetaData( VOS_TO_WPAL_PKT(vosDataBuff) ); if ( NULL == pTxMetaInfo ) { VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, "WLAN TL:Invalid RxMetaInfo pointer from PAL packet on WLANTL_RxFrames"); VOS_ASSERT( 0 ); return VOS_STATUS_E_FAULT; } /* Zero out memeory */ vos_mem_zero( pTxMetaInfo, sizeof( WDI_DS_TxMetaInfoType ) ); /* Fill the TX Meta info */ pTxMetaInfo->txFlags = txFlag; pTxMetaInfo->qosEnabled = ucQosEnabled; pTxMetaInfo->fenableWDS = ucWDSEnabled; pTxMetaInfo->ac = ucUP; pTxMetaInfo->fUP = uTid; pTxMetaInfo->isEapol = ucIsEapol; pTxMetaInfo->fdisableFrmXlt = ucDisableFrmXtl; pTxMetaInfo->frmType = ( ( typeSubtype & 0x30 ) >> 4 ); pTxMetaInfo->typeSubtype = typeSubtype; /* Length = MAC header + payload */ vos_pkt_get_packet_length( vosDataBuff, pusPktLen); pTxMetaInfo->fPktlen = *pusPktLen; // Dst address usMacAddrSize = VOS_MAC_ADDR_SIZE; vosStatus = vos_pkt_extract_data( vosDataBuff, WLANTL_MAC_ADDR_ALIGN( ucDisableFrmXtl ), (v_PVOID_t)pvDestMacAddr, &usMacAddrSize ); if ( VOS_STATUS_SUCCESS != vosStatus ) { VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, "WDA:Failed while attempting to extract MAC Addr %d", vosStatus ); VOS_ASSERT( 0 ); return VOS_STATUS_E_FAULT; } VOS_ASSERT(usMacAddrSize == VOS_MAC_ADDR_SIZE); vos_copy_macaddr( (v_MACADDR_t*)pTxMetaInfo->fSTAMACAddress, pvDestMacAddr ); // ADDR2 vos_copy_macaddr( (v_MACADDR_t*)pTxMetaInfo->addr2MACAddress, pAddr2 ); /* Dump TX meta infro for debugging */ VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW, "WLAN TL: Dump TX meta info: " "txFlags:%d, qosEnabled:%d, ac:%d, " "isEapol:%d, fdisableFrmXlt:%d" "frmType%d", pTxMetaInfo->txFlags, ucQosEnabled, pTxMetaInfo->ac, pTxMetaInfo->isEapol, pTxMetaInfo->fdisableFrmXlt, pTxMetaInfo->frmType ); return VOS_STATUS_SUCCESS; #else /* FEATURE_WLAN_INTEGRATED_SOC */ VOS_STATUS vosStatus; v_PVOID_t pvBDHeader; WDA_DS_PrepareBDHeader( vosDataBuff, &pvBDHeader, pvDestMacAddr, ucDisableFrmXtl, &vosStatus, pusPktLen, ucQosEnabled, ucWDSEnabled, extraHeadSpace ); if ( VOS_STATUS_SUCCESS != vosStatus ) { VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, "WLAN TL:Failed while attempting to prepare BD %d", vosStatus ); return vosStatus; } vosStatus = WLANHAL_FillTxBd( pvosGCtx, typeSubtype, pvDestMacAddr, pAddr2, &uTid, ucDisableFrmXtl, pvBDHeader, txFlag, timeStamp ); if ( VOS_STATUS_SUCCESS != vosStatus ) { VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, "WLAN TL:Failed while attempting to fill BD %d", vosStatus ); return vosStatus; } return VOS_STATUS_SUCCESS; #endif /* FEATURE_WLAN_INTEGRATED_SOC */ }
/*========================================================================== * FUNCTION WDI_DS_PrepareBDHeader DESCRIPTION function for preparing BD header before HAL processing. PARAMETERS IN palPacket: PAL packet pointer RETURN VALUE No return. SIDE EFFECTS ============================================================================*/ void WDI_DS_PrepareBDHeader (wpt_packet* palPacket, wpt_uint8 ucDisableHWFrmXtl, wpt_uint8 alignment) { void* pvBDHeader; wpt_uint8 ucHeaderOffset; wpt_uint8 ucHeaderLen; wpt_uint8 ucQosEnabled; wpt_uint8 ucWDSEnabled; wpt_uint32 ucMpduLen; wpt_uint32 ucPktLen; WDI_DS_TxMetaInfoType *pTxMetadata; /* Extract reuqired information from Metadata */ pvBDHeader = WPAL_PACKET_GET_BD_POINTER(palPacket); pTxMetadata = WDI_DS_ExtractTxMetaData(palPacket); ucQosEnabled = pTxMetadata->qosEnabled; ucWDSEnabled = pTxMetadata->fenableWDS; WPAL_PACKET_SET_BD_LENGTH(palPacket, WDI_TX_BD_HEADER_SIZE); /*--------------------------------------------------------------------- Fill MPDU info fields: - MPDU data start offset - MPDU header start offset - MPDU header length - MPDU length - this is a 16b field - needs swapping --------------------------------------------------------------------*/ if ( ucDisableHWFrmXtl ) { ucHeaderOffset = WDI_TX_BD_HEADER_SIZE; ucHeaderLen = WDI_802_11_HEADER_LEN; if ( 0 != ucQosEnabled ) { ucHeaderLen += WDI_802_11_HEADER_QOS_CTL; } if ( 0 != ucWDSEnabled) { ucHeaderLen += WDI_802_11_HEADER_ADDR4_LEN; } } else { ucHeaderOffset = WDI_TX_BD_HEADER_SIZE+WDI_802_11_MAX_HEADER_LEN; ucHeaderLen = WDI_802_3_HEADER_LEN; } WDI_TX_BD_SET_MPDU_HEADER_LEN( pvBDHeader, ucHeaderLen); WDI_TX_BD_SET_MPDU_HEADER_OFFSET( pvBDHeader, ucHeaderOffset); WDI_TX_BD_SET_MPDU_DATA_OFFSET( pvBDHeader, ucHeaderOffset + ucHeaderLen + alignment); // pkt length from PAL API. Need to change in case of HW FT used ucPktLen = wpalPacketGetLength( palPacket ); // This includes BD length /** This is the length (in number of bytes) of the entire MPDU (header and data). Note that the length INCLUDES FCS field. */ ucMpduLen = ucPktLen - WPAL_PACKET_GET_BD_LENGTH( palPacket ); WDI_TX_BD_SET_MPDU_LEN( pvBDHeader, ucMpduLen ); DTI_TRACE( DTI_TRACE_LEVEL_INFO, "WLAN DTI: VALUES ARE HLen=%x Hoff=%x doff=%x len=%x ex=%d", ucHeaderLen, ucHeaderOffset, (ucHeaderOffset + ucHeaderLen + alignment), pTxMetadata->fPktlen, alignment); }/* WDI_DS_PrepareBDHeader */