/*******************************************************************************
*
* File name: zl5011xPkcPreClassify.c
*
* Version: 16
*
* Author: MRC
*
* Date created: 13/05/2002
*
* Copyright 2002, 2003, 2004, 2005, Zarlink Semiconductor Limited.
* All rights reserved.
*
* Module Description:
*
* This file contains all the functions that will control the pre-classifier
* part of the Pkc block. The pre-classifier is used to match protocol types.
*
* The various stages in the PKC are as follows:
*
* pre-processor matches ethertype / MAC addresses for directing to the host.
* pre-classifier matches the protocol type and extracts bytes from the header
* for use in the classification stage
* classifier matches the bytes extracted by the pre-classifier, to
* determine the context number for data transactions. Is also
* used to direct control packets related to a data path to the
* host.
*
* Revision History:
*
* Rev: Date: Author: Comments:
* 1 13/05/2002 MRC Creation
* 2 21/05/2002 MRC PKC Rams have to be written in reverse order.
* 3 13/05/2002 MRC Updated the get free function and added delete fn
* 4 03/07/2002 MRC Changed the protocol match structure names
* 5 12/07/2002 MRC Rationalised the 2 enums for CPU queues
* 6 04/09/2002 MRC Changed the name of a structure entry from
* protocolLength16Bits to protocolTwoByteSeq
* 7 31/10/2002 MRC Added variants + minor fixes
* 8 30/04/2003 ARW Temporary altered file checked in by accident
* 9 30/04/2003 ARW Revision 7 restored as the most recent version
* 10 30/04/2003 JFE Made change to allow for preclassify bug (errata 2.56)
* 11 30/04/2003 JFE Added missing bracket.
* 12 28/10/2003 AMS Added zl5011xPkcProtocolConflictCheck function (essential
* to new way that packet helper functions work)
* 13 04/11/2003 AMS Added some tracing to ProtocolConflictCheck function
* 14 18/11/2003 APL Fixed compiler warning
* 15 23/07/2004 MRC Fixed some compiler warnings
* 16 21/07/2005 MRC Added function to check if an entry is used
*
*******************************************************************************/
/***************** INCLUDE FILES *****************************/
#include "zl5011x.h"
#include "zl5011xPkc.h"
#include "zl5011xPkcMap.h"
#include "zl5011xUtilLib.h"
/*******************************************************************************
Function:
zl5011xPkcProtocolConfigure
Description:
This function controls the behaviour for packets that are not matched in
the pre classifier. They can be discarded or forwarded to the host using a
specified queue.
Inputs:
zl5011xParams Pointer to the structure for this device instance
discard ZL5011X_TRUE to discard non-matching packets,
ZL5011X_FALSE to forward to the host
queueNum queue number to use for packets forwarded to host
Outputs:
None
Returns:
zlStatusE
Remarks:
None
*******************************************************************************/
zlStatusE zl5011xPkcProtocolConfigure(zl5011xParamsS *zl5011xParams,
zl5011xBooleanE discard, zl5011xQueueE queueNum)
{
zlStatusE status = ZL5011X_OK;
Uint32T bits = 0;
ZL5011X_TRACE(ZL5011X_PKC_FN_ID,
"zl5011xPkcProtocolConfigure: drop %d, queue %d",
discard, queueNum, 0, 0, 0, 0);
status = ZL5011X_CHECK_BOOLEAN(discard);
if (status == ZL5011X_OK)
{
if (discard == ZL5011X_FALSE)
{
status = ZL5011X_CHECK_QUEUE_NUMBER(queueNum);
/* if the packets are being directed to the CPU, then set the
queue ID and leave the discard bit */
if (status == ZL5011X_OK)
bits = queueNum << ZL5011X_PKC_PRE_NO_MATCH_QUEUE_BITS;
}
else
{
/* if discarding the packets, then set the bit to enable this */
bits = ZL5011X_1BIT_MASK << ZL5011X_PKC_PRE_NO_MATCH_DROP_BIT;
}
}
if (status == ZL5011X_OK)
{
status = zl5011xWrite(zl5011xParams, ZL5011X_PKC_PROTOCOL_NO_MATCH, bits);
/* store the discard and queue settings in the device structure */
zl5011xParams->packetIf.packetRx.pkcProtocolDiscard = discard;
zl5011xParams->packetIf.packetRx.pkcProtocolCpuQueue = queueNum;
}
return(status);
}
/*******************************************************************************
Function:
zl5011xPkcProtocolCheckFreeEntry
Description:
This function is provided to allow the application to check whether a PKC
protocol match is in use without actually reserving it for use.
Inputs:
zl5011xParams Pointer to the structure for this device instance
matchNum the classifier match number to check
Outputs:
entryFree ZL5011X_TRUE if the entry is unused
Returns:
zlStatusE
Remarks:
None
*******************************************************************************/
zlStatusE zl5011xPkcProtocolCheckFreeEntry(zl5011xParamsS *zl5011xParams,
Uint32T matchNum, zl5011xBooleanE *entryFree)
{
zlStatusE status = ZL5011X_OK;
ZL5011X_TRACE(ZL5011X_PKC_FN_ID,
"zl5011xPkcProtocolCheckFreeEntry: match %d",
matchNum, 0, 0, 0, 0, 0);
*entryFree = ZL5011X_FALSE;
/* check that a valid match number was specified */
if (matchNum >= ZL5011X_PKC_NUM_PROTOCOL_ENTRIES)
{
status = ZL5011X_PARAMETER_INVALID;
}
else
{
/* check whether the match is in use */
if (zl5011xParams->packetIf.packetRx.pkcProtocol[matchNum].protocolReserved == ZL5011X_FALSE)
{
*entryFree = ZL5011X_TRUE;
}
}
if (status == ZL5011X_OK)
{
ZL5011X_TRACE(ZL5011X_PKC_FN_ID,
"zl5011xPkcProtocolCheckFreeEntry: match %d, avail %d",
matchNum, *entryFree, 0, 0, 0, 0);
}
return(status);
}
/*******************************************************************************
Function:
zl5011xPkcProtocolGetFreeEntry
Description:
This function can reserve an entry in the pre-classifier if a valid match
number is provided, or will allocate one if possible.
Inputs:
zl5011xParams Pointer to the structure for this device instance
matchNum the number of a free entry or ZL5011X_INVALID to allocate a
match number
Outputs:
matchNum the number of a free entry if at input it was ZL5011X_INVALID
Returns:
zlStatusE
Remarks:
None
*******************************************************************************/
zlStatusE zl5011xPkcProtocolGetFreeEntry(zl5011xParamsS *zl5011xParams,
Uint32T *matchNum)
{
Uint32T loop;
zlStatusE status = ZL5011X_OK;
ZL5011X_TRACE(ZL5011X_PKC_FN_ID,
"zl5011xPkcProtocolGetFreeEntry: match in %d",
*matchNum, 0, 0, 0, 0, 0);
/* if the match number was set to a special value of invalid,
then one will be automatically found */
if (*matchNum == (Uint32T)ZL5011X_INVALID)
{
for (loop = 0; loop < ZL5011X_PKC_NUM_PROTOCOL_ENTRIES; loop++)
{
if (zl5011xParams->packetIf.packetRx.pkcProtocol[loop].protocolReserved == ZL5011X_FALSE)
break;
}
if (loop >= ZL5011X_PKC_NUM_PROTOCOL_ENTRIES)
{
/* no free matches in the classifier, so return error */
status = ZL5011X_NO_AVAIL_PROTOCOL_MATCH;
}
else
{
*matchNum = loop;
}
}
else
{
/* if the number was specified, but was not valid, then throw an error */
if (*matchNum >= ZL5011X_PKC_NUM_PROTOCOL_ENTRIES)
{
status = ZL5011X_PARAMETER_INVALID;
}
else
{
/* check that the match is not already in use */
if (zl5011xParams->packetIf.packetRx.pkcProtocol[*matchNum].protocolReserved == ZL5011X_TRUE)
{
status = ZL5011X_PROTOCOL_MATCH_IN_USE;
}
}
}
/* reserve the match if there has not been an error */
if (status == ZL5011X_OK)
{
zl5011xParams->packetIf.packetRx.pkcProtocol[*matchNum].protocolReserved = ZL5011X_TRUE;
ZL5011X_TRACE(ZL5011X_PKC_FN_ID,
"zl5011xPkcProtocolGetFreeEntry: match out %d",
*matchNum, 0, 0, 0, 0, 0);
}
return(status);
}
/*******************************************************************************
Function:
zl5011xPkcProtocolEnableEntry
Description:
Enables a pre classifier entry. The entry should be configured before it is
enabled.
Inputs:
zl5011xParams Pointer to the structure for this device instance
matchNum the number of the entry to enable
Outputs:
None
Returns:
zlStatusE
Remarks:
None
*******************************************************************************/
zlStatusE zl5011xPkcProtocolEnableEntry(zl5011xParamsS *zl5011xParams,
Uint32T matchNum)
{
zlStatusE status = ZL5011X_OK;
ZL5011X_TRACE(ZL5011X_PKC_FN_ID,
"zl5011xPkcProtocolEnableEntry: match %3d",
matchNum, 0, 0, 0, 0, 0);
/* check pre classifier entry number is in range */
if (matchNum >= ZL5011X_PKC_NUM_PROTOCOL_ENTRIES)
{
status = ZL5011X_PARAMETER_INVALID;
}
if (status == ZL5011X_OK)
{
zl5011xParams->packetIf.packetRx.pkcProtocol[matchNum].protocolInUse = ZL5011X_TRUE;
zl5011xParams->packetIf.packetRx.pkcProtocol[matchNum].protocolReserved = ZL5011X_TRUE;
/* set the bit to enable the pre classifier entry */
status = zl5011xReadModWrite(zl5011xParams, ZL5011X_PKC_PROTOCOL_ENABLE,
ZL5011X_1BIT_MASK << (matchNum*2),
ZL5011X_1BIT_MASK << (matchNum*2));
}
return status;
}
/*******************************************************************************
Function:
zl5011xPkcProtocolDisableEntry
Description:
Disables a pre classifier entry. The entry is still reserved, but is disabled
in the device.
Inputs:
zl5011xParams Pointer to the structure for this device instance
matchNum the number of the entry to disable
Outputs:
None
Returns:
zlStatusE
Remarks:
None
*******************************************************************************/
zlStatusE zl5011xPkcProtocolDisableEntry(zl5011xParamsS *zl5011xParams,
Uint32T matchNum)
{
zlStatusE status = ZL5011X_OK;
ZL5011X_TRACE(ZL5011X_PKC_FN_ID,
"zl5011xPkcProtocolDisableEntry: match %3d",
matchNum, 0, 0, 0, 0, 0);
/* check pre classifier entry number is in range */
if (matchNum >= ZL5011X_PKC_NUM_PROTOCOL_ENTRIES)
{
status = ZL5011X_PARAMETER_INVALID;
}
if (status == ZL5011X_OK)
{
zl5011xParams->packetIf.packetRx.pkcProtocol[matchNum].protocolInUse = ZL5011X_FALSE;
/* set the bit to disable the pre classifier entry */
status = zl5011xReadModWrite(zl5011xParams, ZL5011X_PKC_PROTOCOL_ENABLE,
0,
ZL5011X_1BIT_MASK << (matchNum*2));
}
return status;
}
/*******************************************************************************
Function:
zl5011xPkcProtocolDeleteEntry
Description:
Deletes a pre classifier entry. The entry is marked as free, to allow it to
be allocated again.
Inputs:
zl5011xParams Pointer to the structure for this device instance
matchNum the number of the entry to delete
Outputs:
None
Returns:
zlStatusE
Remarks:
None
*******************************************************************************/
zlStatusE zl5011xPkcProtocolDeleteEntry(zl5011xParamsS *zl5011xParams,
Uint32T matchNum)
{
zlStatusE status = ZL5011X_OK;
ZL5011X_TRACE(ZL5011X_PKC_FN_ID,
"zl5011xPkcProtocolDeleteEntry: match %3d",
matchNum, 0, 0, 0, 0, 0);
status = zl5011xPkcProtocolDisableEntry(zl5011xParams, matchNum);
/* if the disable was okay, then free the protocol match by clearing
the reserved flag */
if (status == ZL5011X_OK)
{
zl5011xParams->packetIf.packetRx.pkcProtocol[matchNum].protocolReserved = ZL5011X_FALSE;
}
return status;
}
/*******************************************************************************
Function:
zl5011xPkcProtocolSetMatchField
Description:
Sets the match bytes in the pre classifier. There is also a mask field, that
is used to control which of the bits in these mask bytes are compared.
Inputs:
zl5011xParams Pointer to the structure for this device instance
matchNum the number of the entry to set
matchIndex array of bytes to be used
Outputs:
None
Returns:
zlStatusE
Remarks:
None
*******************************************************************************/
zlStatusE zl5011xPkcProtocolSetMatchField(zl5011xParamsS *zl5011xParams,
Uint32T matchNum, Uint8T *matchIndex)
{
Uint32T tempWord[(ZL5011X_PKC_PROTOCOL_MATCH_SIZE / 4) + 1];
Uint8T tempPos = 0;
Uint8T index = 0;
Uint32T address;
Uint32T loop;
zlStatusE status = ZL5011X_OK;
ZL5011X_TRACE(ZL5011X_PKC_FN_ID,
"zl5011xPkcProtocolSetMatchField: match %3d",
matchNum, 0, 0, 0, 0, 0);
address = ZL5011X_PKC_PROTOCOL_MATCH +
((matchNum*2) * ZL5011X_PKC_PROTOCOL_MATCH_SIZE);
/* assemble the classify match entries into 32 bit words and
then write them to the device */
for (loop = 0; loop < ZL5011X_PKC_PROTOCOL_NUM_MATCH_FIELDS; loop++)
{
if (status != ZL5011X_OK)
break;
status = zl5011xAssembleBitFields(tempWord, &index, &tempPos,
matchIndex[loop], ZL5011X_PKC_PROTOCOL_SIZE_MATCH_FIELD);
}