📄 zl5011xlan.c
字号:
for (loop = 0; loop < ZL5011X_PKC_CLASSIFY_NUM_MATCH_FIELDS; loop++)
{
/* default the classify match and mask bytes to the first byte in the header,
and to match on anything */
par->match.classifyMatchBytes[loop] = 0;
par->match.classifyMaskBytes[loop] = 0xff;
}
for (loop = 0; loop < ZL5011X_PKC_CLASSIFY_NUM_CHECK_FIELDS; loop++)
{
/* default the check bytes to 0 */
par->match.classifyCheckBytes[loop] = 0;
}
/* reset all of the entries in the output part of the structure */
par->output.classifyFlow = (zl5011xFlowTypeE)ZL5011X_INVALID;
par->output.classifyMpid = (Uint32T)ZL5011X_INVALID_CONTEXT;
par->output.classifyHeaderOffset = 0;
par->output.classifyLengthModifier = 0;
par->output.classifyLengthNoCalc = ZL5011X_TRUE;
par->output.classifyTwoByteLength = ZL5011X_TRUE;
par->output.classifyLengthFromPacket = ZL5011X_FALSE;
par->osExclusionEnable = ZL5011X_TRUE;
}
return status;
}
/*******************************************************************************
Function:
zl5011xLanRxSetContextMatch
Description:
This function sets a match in the packet Rx for a context. There are two
possible matches that can be assigned to a context - that is one for each
state of the context switch bit in the TFM.
When using the CD header for classification, the following sequence is
required:
* TFM context is created - context switch bit can be either 0 or 1 for
first message to TFM.
* Set header for the context - this will use header 0, and set the context
switch bit to 0.
(NOTE : this context switch bit state DOES NOT necessarily map to the
state of the bit in the actual ethernet header)
* Add next header - with context switch bit the other way up in the header
(this will use header 1).
* When the context is updated and then taken, the 2 headers will be
examined to determine which is in use and the state variable for each
updated
Inputs:
zl5011xParams Pointer to the structure for this device instance
par Pointer to the structure for configuration items. See below:
Structure inputs:
context which context to use
matchNum which classification match to use - can be set to
ZL5011X_INVALID, and any available match will be found
match structure to hold settings for the context match and check
output structure to hold settings for use once the context has been
identified.
osExclusionEnable ZL5011X_TRUE to enable OS exclusion
Structure outputs:
None
Returns:
zlStatusE
Remarks:
None
*******************************************************************************/
zlStatusE zl5011xLanRxSetContextMatch(zl5011xParamsS *zl5011xParams,
zl5011xLanRxSetContextMatchS *par)
{
zlStatusE status = ZL5011X_OK;
zl5011xBooleanE assignedMatch = ZL5011X_FALSE;
Uint8T selHeader = 0;
zl5011xBooleanE gotDevice = ZL5011X_FALSE;
zl5011xBooleanE foundHeader; /* Flag for whether we have a free header */
/* do some parameter checking */
status = ZL5011X_CHECK_POINTERS(zl5011xParams, par);
if (status == ZL5011X_OK)
{
status = ZL5011X_CHECK_RUNNING(zl5011xParams);
}
if ((status == ZL5011X_OK) && (par->osExclusionEnable == ZL5011X_TRUE))
{
/* get access to the device */
status = zl5011xGetDevice(zl5011xParams, ZL5011X_GET_DEVICE_TIMEOUT_MODE);
if (status == ZL5011X_OK)
{
gotDevice = ZL5011X_TRUE;
}
}
/* check that the Wan Tx context is valid */
if (status == ZL5011X_OK)
{
status = zl5011xContextCheckTx(zl5011xParams, par->context, ZL5011X_CHECK_CONTEXT_MODIFY);
}
/* main function code starts */
if (status ==ZL5011X_OK)
{
ZL5011X_TRACE_CONTEXT(ZL5011X_LAN_FN_ID, par->context,
"zl5011xLanRxSetContextMatch: ctxt %3d",
par->context, 0, 0, 0, 0, 0);
/* See if there is a free context match associated with this context */
selHeader = 0;
foundHeader = ZL5011X_FALSE;
/* Look at the first context match to see if it is available */
if ((zl5011xParams->packetIf.packetRx.contextRxPacketMatch[par->context].contextMatchState[selHeader] == ZL5011X_PKC_STATE_MATCH_NOT_ALLOCATED) ||
(zl5011xParams->packetIf.packetRx.contextRxPacketMatch[par->context].contextMatchState[selHeader] == ZL5011X_PKC_STATE_MATCH_UNUSED))
{
foundHeader = ZL5011X_TRUE;
}
else
{ /* First context match not available so look at the second if it has one.
Lan-to-lan contexts only have one possible context match, others have two */
if (zl5011xParams->packetIf.lanLanContext[par->context] != ZL5011X_TRUE)
{
selHeader++;
if ((zl5011xParams->packetIf.packetRx.contextRxPacketMatch[par->context].contextMatchState[selHeader] == ZL5011X_PKC_STATE_MATCH_NOT_ALLOCATED) ||
(zl5011xParams->packetIf.packetRx.contextRxPacketMatch[par->context].contextMatchState[selHeader] == ZL5011X_PKC_STATE_MATCH_UNUSED))
{
foundHeader = ZL5011X_TRUE;
}
}
}
/* Check whether we found one or not */
if (foundHeader == ZL5011X_FALSE)
{
status = ZL5011X_PKT_HEADER_IN_USE;
}
}
if (status ==ZL5011X_OK)
{
/* if the context already has a match allocated but not enabled, then check
that it is consistent with the one requested */
if (zl5011xParams->packetIf.packetRx.contextRxPacketMatch[par->context].contextMatchState[selHeader] == ZL5011X_PKC_STATE_MATCH_UNUSED)
{
/* this context match rule is allocated but not in use, so use for this setup, provided the match number requested is okay */
if (par->matchNum == (Uint32T)ZL5011X_INVALID)
{
/* automatically allocate a match, so take the one from the device structure */
par->matchNum = zl5011xParams->packetIf.packetRx.contextRxPacketMatch[par->context].pkcClassifyMatchNum[selHeader];
}
else
{ /* Caller requested a specific match number. Check that the requested number is the same as the one
already allocated */
if (par->matchNum != zl5011xParams->packetIf.packetRx.contextRxPacketMatch[par->context].pkcClassifyMatchNum[selHeader])
{
status = ZL5011X_PKT_INVALID_MATCH_NUM;
}
}
}
}
/* reserve the match entry in the pkc classifier */
if (status == ZL5011X_OK)
{
status = zl5011xPkcClassifyGetFreeEntry(zl5011xParams, &(par->matchNum));
/* if there are no available matches in the PKC classifier, then go
through and purge any unused matches and try again */
if (status == ZL5011X_NO_AVAIL_CLASSIFY_MATCH)
{
/* setting the context number to ZL5011X_INVALID for this function
call forces the check for unused matches to take place on
all contexts */
status = zl5011xLanRxPurgeContextHeaders(zl5011xParams, (Uint32T)ZL5011X_INVALID);
if (status == ZL5011X_OK)
{
/* some matches should have been free'd up so try again */
status = zl5011xPkcClassifyGetFreeEntry(zl5011xParams, &(par->matchNum));
}
}
/* if a match has been reserved then remember, so that it can be
free'd up if things go wrong */
if (status == ZL5011X_OK)
{
assignedMatch = ZL5011X_TRUE;
}
else
{
/* if the classifier match had already been allocated and used by this header
then just continue, but disable the entry before re-programming it. */
if (status == ZL5011X_CLASSIFY_MATCH_IN_USE)
{
if (par->matchNum == zl5011xParams->packetIf.packetRx.contextRxPacketMatch[par->context].pkcClassifyMatchNum[selHeader])
{
status = zl5011xPkcClassifyDisableEntry(zl5011xParams, par->matchNum);
}
}
}
}
/* setup the classifier match */
if (status == ZL5011X_OK)
{
if (par->output.classifyMpid == (Uint32T)ZL5011X_INVALID)
{
/* if the mpid hasn't been explicitly set, then set the MPID field to
represent the context number */
par->output.classifyMpid = (par->context & ZL5011X_PKC_CLASSIFY_CONTEXT_MASK);
/* Add in the state of the context switch bit, but don't allow context switches
if this is a lan-to-lan context */
if (zl5011xParams->packetIf.lanLanContext[par->context] != ZL5011X_TRUE)
{
par->output.classifyMpid |= ((selHeader & ZL5011X_1BIT_MASK) << ZL5011X_PKC_CLASSIFY_CONTEXT_SWITCH_BIT);
}
}
if (par->output.classifyFlow == (zl5011xFlowTypeE)ZL5011X_INVALID)
{
/* if the flow hasn't been explicitly set, then use the value
as set during context creation */
par->output.classifyFlow = zl5011xParams->wanIf.wanTxFlow[par->context];
}
status = zl5011xPkcClassifySetContextMatch(zl5011xParams,
par->context, par->matchNum, &(par->match), &(par->output));
}
/* enable the classifier match if it has been set up successfully */
if (status == ZL5011X_OK)
{
if (zl5011xParams->packetIf.lanLanContext[par->context] != ZL5011X_TRUE)
{
/* This is not a Lan-to-Lan context so enable the classifier rule immediately */
status = zl5011xPkcClassifyEnableEntry(zl5011xParams, par->matchNum);
zl5011xParams->packetIf.classifierEnablePending[par->context] = ZL5011X_FALSE;
/* Set state of the new header to indicate it will become active on next context switch */
zl5011xParams->packetIf.packetRx.contextRxPacketMatch[par->context].contextMatchState[selHeader] = ZL5011X_PKC_STATE_MATCH_NEW_UPDATING;
zl5011xParams->packetIf.packetRx.contextRxPacketMatch[par->context].pkcClassifyMatchNum[selHeader] = par->matchNum;
/* Set the state of the other header to indicate it is going to become inactive */
if (zl5011xParams->packetIf.packetRx.contextRxPacketMatch[par->context].contextMatchState[selHeader ^ 1] == ZL5011X_PKC_STATE_MATCH_ACTIVE)
{
zl5011xParams->packetIf.packetRx.contextRxPacketMatch[par->context].contextMatchState[selHeader ^ 1] = ZL5011X_PKC_STATE_MATCH_OLD_UPDATING;
}
}
else
{
/* This is a Lan-to-Lan context so don't call zl5011xPkcClassifyEnableEntry
but delay it until zl5011xLanLanContextUpdate is called. This allows both
packet Rx and packet Tx to be configured before the classification rule
might start to generate traffic. */
zl5011xParams->packetIf.classifierEnablePending[par->context] = ZL5011X_TRUE;
/* Set state of the context match to indicate it is being updated */
zl5011xParams->packetIf.packetRx.contextRxPacketMatch[par->context].contextMatchState[selHeader] = ZL5011X_PKC_STATE_MATCH_NEW_UPDATING;
zl5011xParams->packetIf.packetRx.contextRxPacketMatch[par->context].pkcClassifyMatchNum[selHeader] = par->matchNum;
}
}
else
{
/* failed, so free up the match number if it was allocated by this
function */
if (assignedMatch == ZL5011X_TRUE)
{
/* ignore the return code, since we already have an error. Just
recover as best as possible */
(void)zl5011xPkcClassifyDeleteEntry(zl5011xParams, par->matchNum);
}
}
if (gotDevice == ZL5011X_TRUE)
{
if (status == ZL5011X_OK)
{
status = zl5011xReleaseDevice(zl5011xParams);
}
else
{
/* already have an error code, so don't overwrite it */
(void)zl5011xReleaseDevice(zl5011xParams);
}
}
return status;
}
/*******************************************************************************
Function:
zl5011xLanRxDeleteContextMatchStructInit
Description:
Initialises structure used by zl5011xLanRxDeleteContextMatch function.
Inputs:
zl5011xParams Pointer to the structure for this device instance
par Pointer to the structure for configuration items.
See main function
Returns:
zlStatusE
Remarks:
None
*******************************************************************************/
zlStatusE zl5011xLanRxDeleteContextMatchStructInit(zl5011xParamsS *zl5011xParams,
zl5011xLanRxDeleteContextMatchS *par)
{
zlStatusE status = ZL5011X_OK;
/* do some parameter checking */
status = ZL5011X_CHECK_POINTERS(zl5011xParams, par);
/* main function code starts */
if (status == ZL5011X_OK)
{
ZL5011X_TRACE(ZL5011X_LAN_FN_ID,
"zl5011xLanRxDeleteContextMatchStructInit:",
0, 0, 0, 0, 0, 0);
par->context = (Uint32T)ZL5011X_INVALID_CONTEXT;
par->osExclusionEnable = ZL5011X_TRUE;
}
return status;
}
/*******************************************************************************
Function:
zl5011xLanRxDeleteContextMatch
Description:
This deletes any unused packet Rx matches attached to a context
Inputs:
zl5011xParams Pointer to the structure for this device instance
par Pointer to the structure for configuration items. See below:
Structure inputs:
context which context to use
osExclusionEnable ZL5011X_TRUE to enable OS exclusion
Structure outputs:
None
Returns:
zlStatusE
Remarks:
None
*******************************************************************************/
zlStatusE zl5011xLanRxDeleteContextMatch(zl5011xParamsS *zl5011xParams,
zl5011xLanRxDeleteContextMatchS *par)
{
zlStatusE status = ZL5011X_OK;
Uint8T hdrLoop = 0;
zl5011xBooleanE gotDevice = ZL5011X_FALSE;
/* do some parameter checking */
status = ZL5011X_CHECK_POINTERS(zl5011xParams, par);
if (status == ZL5011X_OK)
{
status = ZL5011X_CHECK_RUNNING(zl5011xParams);
}
if ((status == ZL5011X_OK) && (par->osEx
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -