⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zl5011xdma.c

📁 Zalink50114----TDMoIP芯片驱动源码
💻 C
📖 第 1 页 / 共 5 页
字号:
   status = ZL5011X_CHECK_POINTERS(zl5011xParams, par);

   if (status == ZL5011X_OK)
   {
      status = ZL5011X_CHECK_RUNNING(zl5011xParams);
   }

   if (status == ZL5011X_OK)
   {
      ZL5011X_TRACE(ZL5011X_DMA_FN_ID,
            "zl5011xHostTxSendPacketStructInit:", 0, 0, 0, 0, 0, 0);

      par->buffer = NULL;
      par->pathType = ZL5011X_FLOW_CPU_PKT;
      par->packetLength = 0;
      /* Either the context or both the lanPort and lanPortQueue must be set.
         LanPort and lanPortQueue are used when pathType is ZL5011X_FLOW_CPU_PKT.
         Otherwise context is used. */
      par->context = (Uint32T)ZL5011X_INVALID;
      par->lanPort = (Uint32T)ZL5011X_INVALID;
      par->lanPortQueue = 0;
      par->sequenceNumber = 0;
      par->tstampChksum = 0;
   }

   return status;
}

/*******************************************************************************

 Function:
   zl5011xHostTxSendPacket

 Description:
   Send a packet to the required destination

 Inputs:
   zl5011xParams    Pointer to the structure for this device instance.
                   (Unused in this function)
   par             Pointer to the structure for configuration items. See below:

 Structure inputs:
   buffer          Location of data to transmit
   pathType        Desired destination for packet
                   Any of: ZL5011X_FLOW_CPU_WAN,
                           ZL5011X_FLOW_CPU_PKT,
                           ZL5011X_FLOW_CPU_PE_PKT
   packetLength    Length of packet in bytes (Excluding CRC field and PTH)
   context         Context number for use when the pathType is one of:
                     ZL5011X_FLOW_CPU_WAN    context range 0 to 127
                     ZL5011X_FLOW_CPU_PE_PKT context range 0 to 127
   lanPort         Output lan port to use (only valid when pathType
                     is ZL5011X_FLOW_CPU_PKT)
   lanPortQueue    Output queue to use on output lan port (only valid
                     when pathType is ZL5011X_FLOW_CPU_PKT)
   sequenceNumber  Sequence number for ZL5011X_FLOW_CPU_WAN mode only when
                   resequencing through the TFQ block is switched on. Otherwise
                   this parameter is ignored.

   tstampChksum    Test mode input, should be set to 0 under normal operation

 Structure outputs:
   None

 Outputs:
   None

 Returns:
   zlStatusE

 Remarks:
   This function will perform Endian conversions (if necessary) to the device
   which is little Endian

   This function does not set up the RTP block for the ZL5011X_FLOW_CPU_PE_PKT
   flow. This must be done elsewhere.

*******************************************************************************/

zlStatusE zl5011xHostTxSendPacket(zl5011xParamsS *zl5011xParams, zl5011xHostTxSendPacketS *par)
{
   zlStatusE status = ZL5011X_OK;

   Uint32T *buffer,newLsbByteCount;

   Uint32T sequenceNumber=0;
   Uint16T context;  /* The context to be used */

   Uint16T tstampChksum=0;

   status = ZL5011X_CHECK_POINTERS(zl5011xParams, par);

   if (status == ZL5011X_OK)
   {
      status = ZL5011X_CHECK_RUNNING(zl5011xParams);
   }

   /* Store the context in a local variable */
   context = par->context;

   if (status == ZL5011X_OK)
   {
      ZL5011X_TRACE(ZL5011X_DMA_FN_ID,"zl5011xHostTxSendPacket:", 0, 0, 0, 0, 0, 0);
   }

   ZL5011X_CHECK_FOR_INVALID_VALUE(par->buffer,NULL,ZL5011X_INVALID_POINTER)

   ZL5011X_CHECK_FOR_INVALID_VALUE(txQParams,NULL,ZL5011X_DMA_QUEUE_NOT_INIT)

         /* Check packet length does not exceed buffer capability                  */
   if (status == ZL5011X_OK)
   {
      if (par->packetLength >= (txQParams->dmaChannel.bufferSize*sizeof(Uint32T)))
      {
         status = ZL5011X_PARAMETER_INVALID;
      }
   }

   if (par->packetLength == 0)
   {
      /* Nothing to send, so do nothing */
   }
   else
   {  /* Valid packet length */
      if (status == ZL5011X_OK)
      {
         switch (par->pathType)
         {
            case ZL5011X_FLOW_CPU_WAN:
               /* check that the Wan Tx context is valid */
               status = zl5011xContextCheckTx(zl5011xParams, context,
                     ZL5011X_CHECK_CONTEXT_ACTIVE);
               if (status == ZL5011X_OK)
               {
                  sequenceNumber = par->sequenceNumber;
                  tstampChksum = (Uint16T)par->tstampChksum;
               }
               break;

            case ZL5011X_FLOW_CPU_PKT:
               if (status == ZL5011X_OK)
               {
                  /* Determine if the LAN port is configured */
                  status = zl5011xLanPortCheck(zl5011xParams,par->lanPort);
               }

               /* Check the supplied Lan queue number is valid */
               ZL5011X_CHECK_PARAMETER_RANGE(par->lanPortQueue,0,ZL5011X_PKQ_NUM_QUEUES,ZL5011X_PARAMETER_INVALID);

               /* Check the context is NOT specified when this pathType is specified */
               if (status == ZL5011X_OK)
               {
                  if (context != (Uint16T)ZL5011X_INVALID)
                  {
                     status = ZL5011X_PARAMETER_INVALID;
                  }
               }

               if (status == ZL5011X_OK)
               {
                  /* Convert port and queue to a special host context number */
                  /* First map the requested port number to the internal hardware port based on the device variant */
                  Uint8T internalPort;
                  status = zl5011xPkiExternalPortToInternal(zl5011xParams, &internalPort, (Uint8T)par->lanPort);

                  if (status == ZL5011X_OK)
                  {
                     /* Now deduce which context we should use */
                     context = zl5011xConvertPortAndQueueToHostContext(internalPort, par->lanPortQueue);
                  }
               }
               break;

            case ZL5011X_FLOW_CPU_PE_PKT:
               /* check that the Wan Tx context is valid */
                     status = zl5011xContextCheckTx(zl5011xParams, context, ZL5011X_CHECK_CONTEXT_NUMBER);
               if (status == ZL5011X_OK)
               {
                  /* calculate partial checksum for payload                          */
                  status =  zl5011xPacketCalculateChecksum(par->buffer,
                        (Uint16T)par->packetLength, &tstampChksum);
               }
               break;

            default:
               /* Invalid path                                                      */
               status = ZL5011X_INVALID_FLOW_TYPE;
               break;
         }
      }

      ZL5011X_DYNAMIC_MUTEX_TAKE(txQParams)
      if (status == ZL5011X_OK)
      {
         /* Determine if the descriptor chain is full                             */
         if ((status == ZL5011X_OK) &&
               (zl5011xDmaReadBufferStatus(&txQParams->dmaChannel,
               txQParams->dmaChannel.bufferIndex) == ZL5011X_DMA_BUFFER_FULL))
         {
            status = ZL5011X_DMA_BUFFERS_FULL;
         }

         if (status == ZL5011X_DMA_BUFFERS_FULL)
         {
            txQParams->packetsSentFail++;
         }
         else
         {
            /* Begin processing packet - starting with the PTH word 0              */
            buffer = (Uint32T *)zl5011xDmaReadSourceAddress(
                  &txQParams->dmaChannel,
                  txQParams->dmaChannel.bufferIndex);
            zl5011xCpuDmaPTHWrite((Uint32T)par->pathType, (Uint16T)par->packetLength,
                  context, ZL5011X_CPU_SOURCE_BLOCK_ID, ZL5011X_INT_DONE,
                  ZL5011X_LAST_PKT, (Uint16T)sequenceNumber, tstampChksum,
                  zl5011xDmaProps.transaction64Bit, buffer);

            /* Now add the data from the packet to the DMA buffer */
            (void)zl5011xCopyPacketToDmaBuffer(buffer+ZL5011X_PTH_WORDSIZE, par->buffer, par->packetLength);

            zl5011xDmaWriteLength(&txQParams->dmaChannel,
                  txQParams->dmaChannel.bufferIndex,
                  ZL5011X_ROUND_TO_INTEGER_WORDS(par->packetLength)
                  +ZL5011X_PTH_BYTESIZE);

            /* Set the valid bit on the descriptor                                 */
            zl5011xDmaFreeDescriptorBuffer(&txQParams->dmaChannel);

            /* Increment descriptor index                                          */
            txQParams->dmaChannel.bufferIndex++;
            txQParams->dmaChannel.bufferIndex = txQParams->dmaChannel.bufferIndex
                  % txQParams->dmaChannel.numberOfBuffers;

            newLsbByteCount = txQParams->bytesSentl +par->packetLength;
            if (newLsbByteCount < txQParams->bytesSentl)
            {
               /* LSB counter has wrapped                                           */
               txQParams->bytesSenth++;
            }

            txQParams->bytesSentl = newLsbByteCount;
            txQParams->packetsSent++;
         }
      }
      ZL5011X_MUTEX_GIVE(txQParams)

            /* Now look at the DMA status to determine if it needs restarting          */
      if ((status == ZL5011X_OK) || (status == ZL5011X_DMA_BUFFERS_FULL))
      {
         status = zl5011xStartDmaTx();
      }
   }

   return(status);
}

/*******************************************************************************

 Function:
   zl5011xHostTxGetStatsStructInit

 Description:
   This function will set default values for function zl5011xHostTxGetStats

 Inputs:
   zl5011xParams   Pointer to the structure for this device instance.
                      (Unused in this function)
   par            Pointer to the structure for configuration items.

 Outputs:
   None

 Returns:
   zlStatusE

 Remarks:
   None

*******************************************************************************/

zlStatusE zl5011xHostTxGetStatsStructInit(zl5011xParamsS *zl5011xParams, zl5011xHostTxGetStatsS *par)
{
   zlStatusE status = ZL5011X_OK;

   status = ZL5011X_CHECK_POINTERS(zl5011xParams, par);

   if (status == ZL5011X_OK)
   {
      status = ZL5011X_CHECK_RUNNING(zl5011xParams);
   }

   if (status == ZL5011X_OK)
   {
      ZL5011X_TRACE(ZL5011X_DMA_FN_ID,"zl5011xHostTxGetStatsStructInit:",0,0,0,0,0,0);

      par->packetsSent = 0;
      par->packetsSentFail = 0;
      par->packetsInQueue = 0;
      par->bytesSenth = 0;
      par->bytesSentl = 0;
   }

   return(status);
}

/*******************************************************************************

 Function:
   zl5011xHostTxGetStats

 Description:
   This function will return the stats for the transmit queue

 Inputs:
   zl5011xParams   Pointer to the structure for this device instance.
                      (Unused in this function)
   par            Pointer to the structure for configuration items.

 Structure inputs:
   None

 Structure outputs:
   packetsSent      Number of packets sent
   bytesSenth       The MSBs for the total number of bytes sent (excluding the
                    PTH)
   bytesSentl       The LSBs for the total number of bytes sent
   packetsSentFail  Number of packets that were failed to be sent because the
                    descriptor chain was full
   packetsInQueue   Number of packets waiting for transmission in the
                    descriptor chain

 Outputs:
   None

 Returns:
   zlStatusE

 Remarks:
   None

*******************************************************************************/

zlStatusE zl5011xHostTxGetStats(zl5011xParamsS *zl5011xParams, zl5011xHostTxGetStatsS *par)
{
   zlStatusE status = ZL5011X_OK;
   Uint32T n;

   status = ZL5011X_CHECK_POINTERS(zl5011xParams, par);

   if (status == ZL5011X_OK)
   {
      status = ZL5011X_CHECK_RUNNING(zl5011xParams);
   }

   if (status == ZL5011X_OK)
   {
      ZL5011X_TRACE(ZL5011X_DMA_FN_ID,"zl5011xHostTxGetStats:", 0, 0, 0, 0, 0, 0);
      ZL5011X_CHECK_FOR_INVALID_VALUE(txQParams,NULL,ZL5011X_DMA_QUEUE_NOT_INIT)

      ZL5011X_DYNAMIC_MUTEX_TAKE(txQParams);
      if (status == ZL5011X_OK)
      {
         par->packetsSent = txQParams->packetsSent;
         par->bytesSenth = txQParams->bytesSenth;
         par->bytesSentl = txQParams->bytesSentl;
         par->packetsSentFail = txQParams->packetsSentFail;
         par->packetsInQueue = 0;
         for (n=0;n<txQParams->dmaChannel.numberOfBuffers;n++)
         {
            if (zl5011xDmaReadBufferStatus(&txQParams->dmaChannel,n) ==
                  ZL5011X_DMA_BUFFER_FULL)
            {
               par->packetsInQueue++;
            }
         }

         ZL5011X_MUTEX_GIVE(txQParams)
      }
   }

   return status;
}

/*******************************************************************************
 Function:
    zl5011xHostRxInitialiseStructInit

 Description:
    Set up default parameters for the HostRxInitialise function

 Inputs:
   zl5011xParams   Pointer to the structure for this device instance.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -