📄 zl5011xpacketloopback.c
字号:
/******************************************************************************
*
* 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 + -