📄 zl5011xmisc.c
字号:
*******************************************************************************/
zlStatusE zl5011xContextCheckRx(zl5011xParamsS *zl5011xParams, Uint32T context,
zl5011xCheckContextStateE check)
{
zlStatusE status = ZL5011X_OK;
ZL5011X_TRACE(ZL5011X_MISC_FN_ID,
"zl5011xContextCheckRx: ctxt %d, check %d",
context, check, 0, 0, 0, 0);
/* check that the context number does not exceed the maximum allowed */
if (context >= ZL5011X_MAX_NUMBER_CONTEXTS)
{
status = ZL5011X_CONTEXTID_RANGE;
}
else
{
/* if the context is currently in use then it's number must be valid. If it is
not in use then check it */
if (zl5011xParams->wanIf.plaCurrent.context[context].state == ZL5011X_STATE_NOT_IN_USE)
{
/* For TDM (wan) contexts when the mode is unframed then there is a one-to-one mapping between
contexts and streams. For Lan-to-Lan contexts any context number can be used */
if ((zl5011xParams->packetIf.lanLanContext[context] == ZL5011X_FALSE) &&
(zl5011xParams->wanIf.wanConnectionMode == ZL5011X_WAN_CONNECTION_UNFRAMED))
{
if (context >= zl5011xParams->wanIf.wanNumStreams)
{
if (zl5011xParams->devLimits.cesAvailable == ZL5011X_FALSE)
{
/* non CES part, so auxilliary clock is a valid option */
if (context != zl5011xParams->devLimits.wanAuxClockNum)
{
status = ZL5011X_CONTEXTID_RANGE;
}
}
else
{
status = ZL5011X_CONTEXTID_RANGE;
}
}
}
else
{
if (context >= zl5011xParams->devLimits.numContexts)
{
status = ZL5011X_CONTEXTID_RANGE;
}
}
}
}
if (status == ZL5011X_OK)
{
switch (check)
{
case ZL5011X_CHECK_CONTEXT_NUMBER:
break;
case ZL5011X_CHECK_CONTEXT_INIT:
if (zl5011xParams->wanIf.plaCurrent.context[context].state != ZL5011X_STATE_INIT)
{
status = ZL5011X_CONTEXT_NOT_IN_INIT;
}
break;
case ZL5011X_CHECK_CONTEXT_MODIFY:
if ((zl5011xParams->wanIf.plaCurrent.context[context].state != ZL5011X_STATE_INIT) &&
(zl5011xParams->wanIf.plaCurrent.context[context].state != ZL5011X_STATE_TAKEN))
{
status = ZL5011X_CONTEXT_NOT_TAKEN;
}
break;
case ZL5011X_CHECK_CONTEXT_ACTIVE:
if ((zl5011xParams->wanIf.plaCurrent.context[context].state != ZL5011X_STATE_TAKEN) &&
(zl5011xParams->wanIf.plaCurrent.context[context].state != ZL5011X_STATE_ACTIVE) &&
(zl5011xParams->wanIf.plaCurrent.context[context].state != ZL5011X_STATE_UPDATING))
{
status = ZL5011X_CONTEXT_NOT_ACTIVE;
}
break;
case ZL5011X_CHECK_CONTEXT_IN_USE:
if ((zl5011xParams->wanIf.plaCurrent.context[context].state != ZL5011X_STATE_INIT) &&
(zl5011xParams->wanIf.plaCurrent.context[context].state != ZL5011X_STATE_TAKEN) &&
(zl5011xParams->wanIf.plaCurrent.context[context].state != ZL5011X_STATE_ACTIVE) &&
(zl5011xParams->wanIf.plaCurrent.context[context].state != ZL5011X_STATE_UPDATING))
{
status = ZL5011X_CONTEXT_NOT_IN_USE;
}
break;
default:
status = ZL5011X_PARAMETER_INVALID;
}
}
return status;
}
/*******************************************************************************
Function:
zl5011xContextCheckTx
Description:
Used to check that a Wan Tx context number is valid. Can also check that
the context is in a valid state for modification - i.e. taken or init
Inputs:
zl5011xParams Pointer to the structure for this device instance
check which check to perform on the context
Outputs:
None
Returns:
zlStatusE
Remarks:
None
*******************************************************************************/
zlStatusE zl5011xContextCheckTx(zl5011xParamsS *zl5011xParams, Uint32T context,
zl5011xCheckContextStateE check)
{
zlStatusE status = ZL5011X_OK;
ZL5011X_TRACE(ZL5011X_MISC_FN_ID,
"zl5011xContextCheckTx: ctxt %d, check %d",
context, check, 0, 0, 0, 0);
/* check that the context number does not exceed the maximum allowed */
if (context >= ZL5011X_MAX_NUMBER_CONTEXTS)
{
status = ZL5011X_CONTEXTID_RANGE;
}
else
{
/* if the context is currently in use then it's number must be valid. If it is
not in use then check it */
if (zl5011xParams->wanIf.tfmCurrent.context[context].state == ZL5011X_STATE_NOT_IN_USE)
{
/* For TDM (wan) contexts when the mode is unframed then there is a one-to-one mapping between
contexts and streams. For Lan-to-Lan contexts any context number can be used */
if ((zl5011xParams->packetIf.lanLanContext[context] == ZL5011X_FALSE) &&
(zl5011xParams->wanIf.wanConnectionMode == ZL5011X_WAN_CONNECTION_UNFRAMED))
{
if (context >= zl5011xParams->wanIf.wanNumStreams)
{
if (zl5011xParams->devLimits.cesAvailable == ZL5011X_FALSE)
{
/* non CES part, so auxilliary clock is a valid option */
if (context != zl5011xParams->devLimits.wanAuxClockNum)
{
status = ZL5011X_CONTEXTID_RANGE;
}
}
else
{
status = ZL5011X_CONTEXTID_RANGE;
}
}
}
else
{
if (context >= zl5011xParams->devLimits.numContexts)
{
status = ZL5011X_CONTEXTID_RANGE;
}
}
}
}
if (status == ZL5011X_OK)
{
switch (check)
{
case ZL5011X_CHECK_CONTEXT_NUMBER:
break;
case ZL5011X_CHECK_CONTEXT_INIT:
if (zl5011xParams->wanIf.tfmCurrent.context[context].state != ZL5011X_STATE_INIT)
{
status = ZL5011X_CONTEXT_NOT_IN_INIT;
}
break;
case ZL5011X_CHECK_CONTEXT_MODIFY:
if ((zl5011xParams->wanIf.tfmCurrent.context[context].state != ZL5011X_STATE_INIT) &&
(zl5011xParams->wanIf.tfmCurrent.context[context].state != ZL5011X_STATE_TAKEN))
{
status = ZL5011X_CONTEXT_NOT_TAKEN;
}
break;
case ZL5011X_CHECK_CONTEXT_ACTIVE:
if ((zl5011xParams->wanIf.tfmCurrent.context[context].state != ZL5011X_STATE_TAKEN) &&
(zl5011xParams->wanIf.tfmCurrent.context[context].state != ZL5011X_STATE_ACTIVE) &&
(zl5011xParams->wanIf.tfmCurrent.context[context].state != ZL5011X_STATE_UPDATING))
{
status = ZL5011X_CONTEXT_NOT_ACTIVE;
}
break;
case ZL5011X_CHECK_CONTEXT_IN_USE:
if ((zl5011xParams->wanIf.tfmCurrent.context[context].state != ZL5011X_STATE_INIT) &&
(zl5011xParams->wanIf.tfmCurrent.context[context].state != ZL5011X_STATE_TAKEN) &&
(zl5011xParams->wanIf.tfmCurrent.context[context].state != ZL5011X_STATE_ACTIVE) &&
(zl5011xParams->wanIf.tfmCurrent.context[context].state != ZL5011X_STATE_UPDATING))
{
status = ZL5011X_CONTEXT_NOT_IN_USE;
}
break;
default:
status = ZL5011X_PARAMETER_INVALID;
}
}
return status;
}
/*******************************************************************************
Function:
zl5011xLanPortCheck
Description:
Used to check that a Lan port has been initialised.
Inputs:
zl5011xParams Pointer to the structure for this device instance
portNum which port to check
Outputs:
None
Returns:
zlStatusE
Remarks:
None
*******************************************************************************/
zlStatusE zl5011xLanPortCheck(zl5011xParamsS *zl5011xParams, Uint8T portNum)
{
zlStatusE status = ZL5011X_OK;
ZL5011X_TRACE(ZL5011X_MISC_FN_ID,
"zl5011xLanPortCheck: port %d",
portNum, 0, 0, 0, 0, 0);
if ((portNum >= zl5011xParams->devLimits.lanNumLanPorts) ||
(zl5011xParams->lanPortInitialised[portNum] == ZL5011X_FALSE))
{
status = ZL5011X_INVALID_PORT;
}
return status;
}
/******************************************************************************
Function:
zl5011xPacketCalculateChecksum
Description:
This function calculates the ones complement checksum for the data passed
in.
Inputs:
buf pointer to the array holding the packet header
length how many bytes to include in the checksum
Outputs:
chkOut checksum for the data
Returns:
zlStatusE
Remarks:
This checksum is as used in IPv4 and UDP protocols.
******************************************************************************/
zlStatusE zl5011xPacketCalculateChecksum(Uint8T *buf, Uint16T length, Uint16T *chkOut)
{
Uint32T checksum = 0;
Uint16T word16, index = 0;
ZL5011X_TRACE(ZL5011X_PACKET_FN_ID,
"zl5011xPacketCalculateChecksum:",
0, 0, 0, 0, 0, 0);
/* main checksum loop */
word16 = 0;
while (length > 1)
{
word16 = buf[index++] << 8;
word16 |= buf[index++] << 0;
checksum += word16;
length -= 2;
}
/* if there is an odd byte left over, then add it in */
if (length > 0)
{
checksum += buf[index] << 8;
}
/* the one's complement bit - add in the overflow bits */
while ((checksum >> 16) != 0)
{
checksum = (checksum >> 16) + (checksum & 0xffff);
}
*chkOut = (Uint16T)~checksum;
return ZL5011X_OK;
}
/******************************************************************************
Function:
zl5011xPacketChangeField
Description:
Allows a 16 bit field in the header to be modified. The difference between
the new value and the old value is returned, to allow the checksum to be
updated.
Updates the checksum value passed in, for multiple changes. For the first
change made, the chkChange parameter should be zero'd before calling this
function. This function may be required for calculating the UDP checksum.
Inputs:
buf pointer to the array holding the packet header
modPos position of the field to change in bytes from the start of buf
newValue the ammount that the checksum has to change by.
bitMask if a bit is set then the corresponding bit from newValue will be
used to replace the data in buf
Outputs:
chkChange updates the i/p value with the ammount that the header has
changed by
Returns:
zlStatusE
Remarks:
The modification position must correspond to a 16 bit aligned position in
the header.
******************************************************************************/
zlStatusE zl5011xPacketChangeField(Uint8T *buf, Uint8T modPos,
Uint16T newValue, Uint16T bitMask, Uint16T *chkChange)
{
Uint16T word16, temp16;
Uint32T newChk;
ZL5011X_TRACE(ZL5011X_PACKET_FN_ID,
"zl5011xPacketChangeField: new %04X, mask %04X",
newValue, bitMask, 0, 0, 0, 0);
if (buf == NULL)
{
/* if a buffer is not provided then assume the old word was 0 */
word16 = 0;
}
else
{
/* if a buffer is provided then replace the value in the buffer with
the new value, using the bit mask to qualify which bits to change */
word16 = buf[modPos] << 8;
word16 |= buf[modPos + 1];
newValue = (word16 & ~bitMask) | (newValue & bitMask);
buf[modPos] = (Uint8T)(newValue >> 8);
buf[modPos + 1] = (Uint8T)(newValue >> 0);
}
temp16 = ~word16;
newChk = (Uint32T)(*chkChange);
newChk += (Uint32T)newValue;
newChk += (Uint32T)temp16;
while ((newChk >> 16) != 0)
{
newChk = (newChk >> 16) + (newChk & 0xffff);
}
*chkChange = (Uint16T)newChk;
ZL5011X_TRACE(ZL5011X_PACKET_FN_ID,
"zl5011xPacketChangeField: new %04X, old %04X, change %04X",
newValue, word16, *chkChange, 0, 0, 0);
return ZL5011X_OK;
}
/******************************************************************************
Function:
zl5011xPacketUpdateChecksum
Description:
Updates the checksum in the header using a change value passed in for a
previous header modification.
Inputs:
buf pointer to the array holding the packet header
chkPos position of the checksum in bytes from the start of buf
chkChange the ammount that the checksum has to change by.
Outputs:
None
Returns:
zlStatusE
Remarks:
This checksum is as used in IPv4 and UDP protocols.
******************************************************************************/
zlStatusE zl5011xPacketUpdateChecksum(Uint8T *buf, Uint8T chkPos, Uint16T chkChange)
{
Uint16T word16, temp16;
Uint32T newChk;
ZL5011X_TRACE(ZL5011X_PACKET_FN_ID,
"zl5011xPacketUpdateChecksum: check offset %2d, change %04X",
chkPos, chkChange, 0, 0, 0, 0);
word16 = buf[chkPos] << 8;
word16 |= buf[chkPos + 1];
temp16 = ~word16;
newChk = temp16;
newChk += chkChange;
while ((newChk >> 16) != 0)
{
newChk = (newChk >> 16) + (newChk & 0xffff);
}
newChk = ~newChk;
buf[chkPos] = (Uint8T)(newChk >> 8);
buf[chkPos + 1] = (Uint8T)(newChk >> 0);
return ZL5011X_OK;
}
/******************************************************************************
Function:
zl5011xPacketInvertChecksum
Description:
Inverts the checksum in the header. This is used to convert a checksum to
a partial checksum - as required for the packet Tx blocks.
Inputs:
buf pointer to the array holding the packet header
chkPos position of the checksum in bytes from the start of buf
Outputs:
None
Returns:
zlStatusE
Remarks:
None
******************************************************************************/
zlStatusE zl5011xPacketInvertChecksum(Uint8T *buf, Uint8T chkPos)
{
Uint16T word16;
ZL5011X_TRACE(ZL5011X_PACKET_FN_ID,
"zl5011xPacketInvertChecksum: check offset %2d",
chkPos, 0, 0, 0, 0, 0);
word16 = buf[chkPos] << 8;
word16 |= buf[chkPos + 1];
word16 = ~word16;
buf[chkPos] = (Uint8T)(word16 >> 8);
buf[chkPos + 1] = (Uint8T)(word16 >> 0);
return ZL5011X_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -