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

📄 zl5011xpacketloopback.c

📁 Zalink50114----TDMoIP芯片驱动源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************
*
*  File name:              zl5011xPacketLoopback.c
*
*  Version:                6
*
*  Author:                 MRC
*
*  Date created:           21/02/2003
*
*  Copyright 2002, 2003, 2004, 2005, Zarlink Semiconductor Limited.
*  All rights reserved.
*
*  Module Description:
*
*  This module is used to setup packet loopback for the device. This is where
*  any unmatched packets received on the Lan interface are re-transmitted to
*  another destination for processing. This is to allow all control packets
*  from multiple Doningtons to be handled from a centralised location.
*
*  Revision History:
*
*  Rev:  Date:       Author:  Comments:
*  1     21/02/2003  MRC      Initial revision
*  2     05/06/2003  MRC      Fixed packet loopback function
*  3     29/07/2003  APL      Added support for devices with no TDM interface
*                             Renamed global wanLimits structure to devLimits
*  4     26/07/2004  MRC      Fixed some compiler warnings
*  5     29/07/2004  MRC      Fixed some compiler warnings
*  6     20/10/2004  APL      Replaced calloc with OS_CALLOC
*
******************************************************************************/

/*****************   INCLUDE FILES                ****************************/

#include "zl5011xApi.h"
#include "zl5011xMisc.h"
#include "zl5011xLan.h"
#include "zl5011xInit.h"
#include "zl5011xPacketLoopback.h"

/*****************   EXTERNAL FUNCTION DEFINITIONS   *************************/

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

 Function:
    zl5011xPacketTxLoopback

 Description:
    Sets up the required header for the loopback packets in the PTX.

 Inputs:
   zl5011xParams   Pointer to the structure for this device instance
    par           Pointer to the structure for configuration items. See below:

 Structure inputs:
   protocolType   what sort of header should be added to the loopback packets
   portNum        which port to use for packet Tx
   queueNum       which queue to use for packet Tx
   header         header data
   enableVlan     does the packet use a VLAN header
   ethernetSrcAddressFromMac add the source MAC address in the MAC itself

 Structure outputs:
   None

 Returns:
    zlStatusE

 Remarks:
    The PTX is being used to add the header for the re-directed packets. It is
    therefore not possible to support UDP checksum, so the field is set to 0.

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

zlStatusE zl5011xPacketTxLoopback(zl5011xParamsS *zl5011xParams,
      zl5011xPacketLoopbackConfigS *par)
{
   zlStatusE status = ZL5011X_OK;
   zl5011xLanTxSetLayer2and3HeaderS  *layer2and3Header = NULL;
   Uint8T udpChecksumPos = 0;
   Uint32T context;

   if (status == ZL5011X_OK)
   {
      ZL5011X_TRACE(ZL5011X_INIT_FN_ID,
            "zl5011xPacketTxLoopback: %d",
            par->protocolType, 0, 0, 0, 0, 0);
   }

   /* do some parameter checking */

   if (status == ZL5011X_OK)
   {
      if (par->portNum >= zl5011xParams->devLimits.lanNumLanPorts)
      {
         status = ZL5011X_PARAMETER_INVALID;
      }
   }

   if (status == ZL5011X_OK)
   {
     /* Allocate memory for the header structure */
      layer2and3Header = (zl5011xLanTxSetLayer2and3HeaderS *)OS_CALLOC(
            sizeof(zl5011xLanTxSetLayer2and3HeaderS), 1);

      if (layer2and3Header == NULL)
      {
         status = ZL5011X_RTOS_MEMORY_FAIL;
      }
   }

   if (status == ZL5011X_OK)
   {
      status = zl5011xLanTxSetLayer2and3HeaderStructInit(zl5011xParams, layer2and3Header);
   }

   /* Copy structure members across for the header construction functions */
   if (status == ZL5011X_OK)
   {
      context = ZL5011X_LOOPBACK_CONTEXT_NUMBER;  /* Use a fixed context */
      layer2and3Header->header.ethernetSrcAddressFromMac = par->ethernetSrcAddressFromMac;
   }

   /* set the Lan port and queue for this packet header */
   if (status == ZL5011X_OK)
   {
      status = zl5011xPkqSetMpidConnection(zl5011xParams, context,
            par->portNum, par->queueNum);
   }

   /* Layer 2: Ethernet header is present for all protocols */
   if (status == ZL5011X_OK)
   {
      layer2and3Header->header.txLowLength = ZL5011X_PKT_ETHERNET_HDR_LEN;

      /* If VLAN is turned on then the Ethernet header will be larger. */
      if (par->enableVlan == ZL5011X_TRUE)
      {
         layer2and3Header->header.txLowLength += ZL5011X_PKT_VLAN_HDR_LEN;
      }
   }

   /* Switch on the protocol stack, and populate the header structures as
     appropriate. */
   if (status == ZL5011X_OK)
   {
      switch (par->protocolType)
      {
         case ZL5011X_LOOPBACK_ETHERNET:
            /* only need to add the destination and source MAC addresses,
               since the ethertype will be preserved from the Rx packet */
            layer2and3Header->header.txLowLength -= ZL5011X_PKT_ETHERTYPE_LEN;
            break;

         case ZL5011X_LOOPBACK_IP_UDP:
            /* Layer 3 : setup IPv4 length */
            layer2and3Header->header.layer3LengthEnable = ZL5011X_TRUE;
            layer2and3Header->header.layer3LengthValue = ZL5011X_PKT_IPV4_HDR_LEN + ZL5011X_PKT_UDP_HDR_LEN;
            layer2and3Header->header.layer3LengthPos = (Uint8T)(layer2and3Header->header.txLowLength + ZL5011X_PKT_IPV4_LEN_POS);

            /* Layer 3 : setup IPv4 checksum */
            layer2and3Header->header.layer3ChecksumEnable = ZL5011X_TRUE;
            layer2and3Header->header.layer3ChecksumPos = (Uint8T)(layer2and3Header->header.txLowLength + ZL5011X_PKT_IPV4_CHKSUM_POS);

            layer2and3Header->header.txLowLength += ZL5011X_PKT_IPV4_HDR_LEN;

            /* Layer 4: UDP length */
            layer2and3Header->header.layer2LengthEnable = ZL5011X_TRUE;
            layer2and3Header->header.layer2LengthValue = ZL5011X_PKT_UDP_HDR_LEN;
            layer2and3Header->header.layer2LengthPos = (Uint8T)(layer2and3Header->header.txLowLength + ZL5011X_PKT_UDP_LEN_POS);
            udpChecksumPos = (Uint8T)(layer2and3Header->header.txLowLength + ZL5011X_PKT_UDP_CHKSUM_POS);

            layer2and3Header->header.txLowLength += ZL5011X_PKT_UDP_HDR_LEN;
            break;

         case ZL5011X_LOOPBACK_MPLS:
            /* Layer 3: MPLS  */
            layer2and3Header->header.txLowLength += ZL5011X_PKT_MPLS_HDR_LEN;
            break;

         default:
            status = ZL5011X_PARAMETER_INVALID;

            ZL5011X_TRACE(ZL5011X_INIT_FN_ID,
                  "zl5011xPacketTxLoopback: protocol type error %d",
                  par->protocolType, 0, 0, 0, 0, 0);
            break;
      }
   }

   if (status == ZL5011X_OK)
   {
      /* check that the header is not too long */
      if (layer2and3Header->header.txLowLength > ZL5011X_PTX_LOW_HEADER_MAX_LEN)
      {
         ZL5011X_TRACE(ZL5011X_INIT_FN_ID,
               "zl5011xPacketTxLoopback: ERROR - layer 2 & 3 header %2d, max %2d",
               layer2and3Header->header.txLowLength, ZL5011X_PTX_LOW_HEADER_MAX_LEN, 0, 0, 0, 0);

         status = ZL5011X_PKT_HEADER_SIZE_ERROR;
      }
   }

   if (status == ZL5011X_OK)
   {
      status = zl5011xLoopbackCopyHeaders(layer2and3Header, par);
   }

   if (status == ZL5011X_OK)
   {
      /* if the layer 3 checksum is enabled (IPv4) and the length field is
         enabled then need to update the checksum to take care of the fact
         that the length field needs to be 0 for the partial checksum.
         This will also impact on the UDP checksum if it is enabled. */
      if ((layer2and3Header->header.layer3ChecksumEnable == ZL5011X_TRUE) &&
         (layer2and3Header->header.layer3LengthEnable == ZL5011X_TRUE))
      {
         status = zl5011xLoopbackUpdateIPChecksum(layer2and3Header, par);
      }
   }

   if (status == ZL5011X_OK)
   {
      if (par->protocolType == ZL5011X_LOOPBACK_IP_UDP)
      {
         /* cannot support a UDP checksum on loopback packets, so force the
            checksum field to 0 */
         layer2and3Header->header.txLowData[udpChecksumPos] = 0;
         layer2and3Header->header.txLowData[udpChecksumPos + 1] = 0;
      }
   }

   /* set the header */
   if (status == ZL5011X_OK)
   {
      status = zl5011xPtxSetHeader(zl5011xParams, context, &(layer2and3Header->header));

   if (status == ZL5011X_OK)
      {

⌨️ 快捷键说明

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