?? zl5011xpacketloopback.c
字號(hào):
/* the header for the loopback Tx has now been set, so mark the
context as in use to prevent it from being changed */
zl5011xParams->wanIf.plaCurrent.context[context].state = ZL5011X_STATE_INIT;
}
}
/* free up the memory allocated for the headers */
if (layer2and3Header != NULL)
{
free(layer2and3Header);
}
return(status);
}
/******************************************************************************
Function:
zl5011xLoopbackUpdateIPChecksum
Description:
In IPv4 mode, the checksum needs to be presented to the device, based on the
length and the identification fields being zero for the partial checksum.
This function, amends the checksum based on these fields being zero.
Inputs:
layer2and3Header Pointer to the zl5011xLanTxSetLayer2and3HeaderS structure.
par Pointer to the zl5011xPacketLoopbackConfigS structure.
Outputs:
None
Returns:
zlStatusE
Remarks:
The PTX uses the length field from a seperate register in the control
header. The value in the header itself is as set by the calling function
- and as used for calculating the checksum. So, change this field to
zero and re-calculate the checksum.
******************************************************************************/
zlStatusE zl5011xLoopbackUpdateIPChecksum(zl5011xLanTxSetLayer2and3HeaderS *layer2and3Header,
zl5011xPacketLoopbackConfigS * par)
{
zlStatusE status = ZL5011X_OK;
Uint16T chkChange;
Uint8T tempArray[2];
ZL5011X_TRACE(ZL5011X_INIT_FN_ID,
"zl5011xLoopbackUpdateIPChecksum:",
0, 0, 0, 0, 0, 0);
chkChange = 0;
if (status == ZL5011X_OK)
{
/* change the length field to 0 */
status = zl5011xPacketChangeField(layer2and3Header->header.txLowData,
layer2and3Header->header.layer3LengthPos,
0, 0xffff, &chkChange);
}
if (status == ZL5011X_OK)
{
/* extract the identification fields, so that they can be reset to 0 for
the purpose of the checksum */
tempArray[0] = layer2and3Header->header.txLowData[layer2and3Header->header.layer3LengthPos +
(ZL5011X_PKT_IPV4_IDENT_POS - ZL5011X_PKT_IPV4_LEN_POS)];
tempArray[1] = layer2and3Header->header.txLowData[layer2and3Header->header.layer3LengthPos +
(ZL5011X_PKT_IPV4_IDENT_POS - ZL5011X_PKT_IPV4_LEN_POS) + 1];
/* change the identification field to 0 */
status = zl5011xPacketChangeField(tempArray, 0, 0, 0xffff, &chkChange);
}
/* update the IPv4 checksum in the header */
if (status == ZL5011X_OK)
{
status = zl5011xPacketUpdateChecksum(layer2and3Header->header.txLowData,
layer2and3Header->header.layer3ChecksumPos, chkChange);
}
/* invert the checksum in the header as required for the partial checksum */
if (status == ZL5011X_OK)
{
status = zl5011xPacketInvertChecksum(layer2and3Header->header.txLowData,
layer2and3Header->header.layer3ChecksumPos);
}
return(status);
}
/******************************************************************************
Function:
zl5011xLoopbackCopyHeaders
Description:
The primary intention of this function is to copy the header arrays across
from the array passed in, to the low headers as required to program
the device.
Inputs:
layer2and3Header Pointer to the zl5011xLanTxSetLayer2and3HeaderS structure.
par Pointer to the zl5011xPacketLoopbackConfigS structure.
Outputs:
None
Returns:
zlStatusE
Remarks:
******************************************************************************/
zlStatusE zl5011xLoopbackCopyHeaders(zl5011xLanTxSetLayer2and3HeaderS *layer2and3Header,
zl5011xPacketLoopbackConfigS * par)
{
zlStatusE status = ZL5011X_OK;
Uint32T n;
ZL5011X_TRACE(ZL5011X_INIT_FN_ID,
"zl5011xLoopbackCopyHeaders:",
0, 0, 0, 0, 0, 0);
for (n = 0; n < layer2and3Header->header.txLowLength; n++)
{
layer2and3Header->header.txLowData[n] = par->header[n];
}
return(status);
}
/******************************************************************************
Function:
zl5011xPacketRxLoopback
Description:
Sets up the packet Rx for unmatched packets.
Inputs:
zl5011xParams Pointer to the structure for this device instance
matchedProtocol enable loopback for packets passing the protocol match, but
failing to be classified.
unmatchedProtocol enable loopback for packets not passing the protocol match
Outputs:
None
Returns:
zlStatusE
Remarks:
******************************************************************************/
zlStatusE zl5011xPacketRxLoopback(zl5011xParamsS *zl5011xParams,
zl5011xPacketLoopbackConfigS *par, zl5011xBooleanE unmatchedProtocol)
{
zlStatusE status = ZL5011X_OK;
zl5011xLanRxSetProtocolMatchS protocolMatch;
zl5011xLanRxSetContextMatchS contextMatch;
Uint32T matchNum;
ZL5011X_TRACE(ZL5011X_INIT_FN_ID,
"zl5011xPacketRxLoopback: unmatched %d",
unmatchedProtocol, 0, 0, 0, 0, 0);
/* initialise the context match settings */
status = zl5011xLanRxSetContextMatchStructInit(zl5011xParams, &contextMatch);
if (status == ZL5011X_OK)
{
if (par->protocolType == ZL5011X_LOOPBACK_ETHERNET)
{
contextMatch.output.classifyHeaderOffset = ZL5011X_PKT_ETHERNET_HDR_LEN - ZL5011X_PKT_ETHERTYPE_LEN;
}
contextMatch.output.classifyFlow = ZL5011X_FLOW_PKT_PKT;
contextMatch.output.classifyMpid = ZL5011X_LOOPBACK_CONTEXT_NUMBER;
contextMatch.output.classifyLengthFromPacket = ZL5011X_TRUE;
}
if (unmatchedProtocol == ZL5011X_TRUE)
{
/* setup a classification entry for the last protocol match */
matchNum = ZL5011X_PKC_NUM_CLASSIFY_ENTRIES - 1;
contextMatch.match.protocolMatchNum = ZL5011X_PKC_NUM_PROTOCOL_ENTRIES - 1;
if (status == ZL5011X_OK)
{
/* reserve the classification entry - to mark it as in use */
status = zl5011xPkcClassifyGetFreeEntry(zl5011xParams, &matchNum);
}
if (status == ZL5011X_OK)
{
status = zl5011xPkcClassifySetContextMatch(zl5011xParams, ZL5011X_LOOPBACK_CONTEXT_NUMBER,
matchNum, &contextMatch.match, &contextMatch.output);
}
/* setup the last protocol match, in order to match any packets that do not
match any of the other protocol entries, to allow them to be sent back
out of the packet Tx */
if (status == ZL5011X_OK)
{
matchNum = ZL5011X_PKC_NUM_PROTOCOL_ENTRIES - 1;
status = zl5011xPkcProtocolGetFreeEntry(zl5011xParams, &matchNum);
}
if (status == ZL5011X_OK)
{
/* set up defaults for the protocol match settings */
status = zl5011xLanRxSetProtocolMatchStructInit(zl5011xParams, &protocolMatch);
}
if (status == ZL5011X_OK)
{
protocolMatch.output.discardUdpCheckFails = ZL5011X_FALSE;
protocolMatch.output.protocolIpv4 = ZL5011X_FALSE;
status = zl5011xPkcProtocolSetMatch(zl5011xParams, ZL5011X_PKC_NUM_PROTOCOL_ENTRIES - 1,
&protocolMatch.match, &protocolMatch.output);
}
if (status == ZL5011X_OK)
{
status = zl5011xPkcProtocolEnableEntry(zl5011xParams, ZL5011X_PKC_NUM_PROTOCOL_ENTRIES - 1);
}
}
return(status);
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -