/* 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;
}
Exemple #8
0
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;  
}
Exemple #10
0
/*==========================================================================
   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 */