📄 zl5011xtfq.c
字号:
{
/* work out how many bits in the average are actually useful. This depends on the
ACP value being used for the queue, such that any bits less than the ACP
position should not be used */
maxQueue = (ZL5011X_1BIT_MASK << zl5011xParams->wanIf.txQueue[context].queueAvgMode) - 1;
mask = maxQueue << ZL5011X_TFQ_AVG_FRACT_LENGTH_BITS;
mask = ~mask & ((ZL5011X_TFQ_AVG_LENGTH_MASK << ZL5011X_TFQ_AVG_LENGTH_BITS) |
(ZL5011X_TFQ_AVG_FRACT_LENGTH_MASK << ZL5011X_TFQ_AVG_FRACT_LENGTH_BITS));
/* extract the bits from the register for the length field. Use the
mask for the integer and fractional parts of the count to clear
the other parts of this register. The value returned will be the
queue length x 2^16. i.e. 16 bits of integer and 16 bits fractional */
*avgLength = bits & mask;
if (((*avgLength & (ZL5011X_TFQ_AVG_LENGTH_MASK << ZL5011X_TFQ_AVG_LENGTH_BITS)) != 0) &&
((*avgLength >> ZL5011X_TFQ_AVG_LENGTH_BITS) < maxQueue))
{
*avgLength += 1 << ZL5011X_TFQ_AVG_LENGTH_BITS;
}
ZL5011X_TRACE_CONTEXT(ZL5011X_TFQ_FN_ID, context, "zl5011xTfqGetAvgLength: ctxt %3ld, avg %08X",
context, *avgLength, 0, 0, 0, 0);
}
return(status);
}
/*******************************************************************************
Function:
zl5011xTfqGetLatePackets
Description:
This function is used to read the number of packets that arrived too late to
be played out.
This is used in the adaptive clocking algorithm (for asynchronous
WAN operation).
Inputs:
zl5011xParams Pointer to the structure for this device instance
context context to use
Outputs:
count count of late packets
Returns:
zlStatusE
Remarks:
None
*******************************************************************************/
zlStatusE zl5011xTfqGetLatePackets(zl5011xParamsS *zl5011xParams, Uint32T context,
Uint32T *count)
{
zlStatusE status = ZL5011X_OK;
Uint32T bits, regAddress;
ZL5011X_TRACE_CONTEXT(ZL5011X_TFQ_FN_ID, context, "zl5011xTfqGetLatePackets: ctxt %3ld",
context, 0, 0, 0, 0, 0);
regAddress = ZL5011X_TFQ_CTXT_LATE_PACKETS + (context * ZL5011X_TFQ_CTXT_CONTROL_SIZE);
/* read the register that holds the length bits */
status = zl5011xRead(zl5011xParams, regAddress, &bits);
if (status == ZL5011X_OK)
{
/* extract the bits from the register */
*count = (bits >> ZL5011X_TFQ_LATE_PACKETS_BITS) &
ZL5011X_TFQ_LATE_PACKETS_MASK;
ZL5011X_TRACE_CONTEXT(ZL5011X_TFQ_FN_ID, context, "zl5011xTfqGetLatePackets: ctxt %3ld, count %d",
context, *count, 0, 0, 0, 0);
}
return(status);
}
/*******************************************************************************
Function:
zl5011xTfqGetEarlyPackets
Description:
This function is used to read the number of packets that arrived too early
to be put into the queue (not enough room in the queue).
This is used in the adaptive clocking algorithm (for asynchronous
WAN operation).
Inputs:
zl5011xParams Pointer to the structure for this device instance
context context to use
Outputs:
count count of early packets
Returns:
zlStatusE
Remarks:
None
*******************************************************************************/
zlStatusE zl5011xTfqGetEarlyPackets(zl5011xParamsS *zl5011xParams, Uint32T context,
Uint32T *count)
{
zlStatusE status = ZL5011X_OK;
Uint32T bits, regAddress;
ZL5011X_TRACE_CONTEXT(ZL5011X_TFQ_FN_ID, context, "zl5011xTfqGetEarlyPackets: ctxt %3ld",
context, 0, 0, 0, 0, 0);
regAddress = ZL5011X_TFQ_CTXT_EARLY_PACKETS + (context * ZL5011X_TFQ_CTXT_CONTROL_SIZE);
/* read the register that holds the length bits */
status = zl5011xRead(zl5011xParams, regAddress, &bits);
if (status == ZL5011X_OK)
{
/* extract the bits from the register */
*count = (bits >> ZL5011X_TFQ_EARLY_PACKETS_BITS) &
ZL5011X_TFQ_EARLY_PACKETS_MASK;
ZL5011X_TRACE_CONTEXT(ZL5011X_TFQ_FN_ID, context, "zl5011xTfqGetEarlyPackets: ctxt %3ld, count %d",
context, *count, 0, 0, 0, 0);
}
return(status);
}
/*******************************************************************************
Function:
zl5011xTfqGetUnderrunCount
Description:
This function is used to read the number of underruns that have been issued
in response to data requests from the TFM.
This is used in the adaptive clocking algorithm (for asynchronous
WAN operation).
Inputs:
zl5011xParams Pointer to the structure for this device instance
context context to use
Outputs:
count count of underruns
Returns:
zlStatusE
Remarks:
None
*******************************************************************************/
zlStatusE zl5011xTfqGetUnderrunCount(zl5011xParamsS *zl5011xParams, Uint32T context,
Uint32T *count)
{
zlStatusE status = ZL5011X_OK;
Uint32T bits, regAddress;
ZL5011X_TRACE_CONTEXT(ZL5011X_TFQ_FN_ID, context, "zl5011xTfqGetUnderrunCount: ctxt %3ld",
context, 0, 0, 0, 0, 0);
regAddress = ZL5011X_TFQ_CTXT_UNDERRUNS + (context * ZL5011X_TFQ_CTXT_CONTROL_SIZE);
/* read the register that holds the length bits */
status = zl5011xRead(zl5011xParams, regAddress, &bits);
if (status == ZL5011X_OK)
{
/* extract the bits from the register */
*count = (bits >> ZL5011X_TFQ_UNDERRUN_BITS) &
ZL5011X_TFQ_UNDERRUN_MASK;
ZL5011X_TRACE_CONTEXT(ZL5011X_TFQ_FN_ID, context, "zl5011xTfqGetUnderrunCount: ctxt %3ld, count %d",
context, *count, 0, 0, 0, 0);
}
return(status);
}
/*******************************************************************************
Function:
zl5011xTfqGetStats
Description:
This function is used to read the various statistics for a queue. That is
min, max, avg length and various packet counts.
These are used in the adaptive clocking algorithm (for asynchronous
WAN operation).
Inputs:
zl5011xParams Pointer to the structure for this device instance
context context to use
Outputs:
stats counts and lengths collected for the queue
Returns:
zlStatusE
Remarks:
None
*******************************************************************************/
zlStatusE zl5011xTfqGetStats(zl5011xParamsS *zl5011xParams, Uint32T context,
zl5011xTfqStatsS *stats)
{
zlStatusE status = ZL5011X_OK;
ZL5011X_TRACE_CONTEXT(ZL5011X_TFQ_FN_ID, context, "zl5011xTfqGetStats: ctxt %3ld",
context, 0, 0, 0, 0, 0);
status = zl5011xTfqGetMinMaxLengths(zl5011xParams, context,
&(stats->minLength), &(stats->maxLength));
if (status == ZL5011X_OK)
{
status = zl5011xTfqGetAvgLength(zl5011xParams, context,
&(stats->avgLength));
}
if (status == ZL5011X_OK)
{
status = zl5011xTfqGetLatePackets(zl5011xParams, context,
&(stats->latePackets));
}
if (status == ZL5011X_OK)
{
status = zl5011xTfqGetEarlyPackets(zl5011xParams, context,
&(stats->earlyPackets));
}
if (status == ZL5011X_OK)
{
status = zl5011xTfqGetUnderrunCount(zl5011xParams, context,
&(stats->underruns));
}
return(status);
}
/*******************************************************************************
Function:
zl5011xTfqResetStats
Description:
This function is used to reset the various statistics for a queue.
Inputs:
zl5011xParams Pointer to the structure for this device instance
context context to use
Outputs:
None
Returns:
zlStatusE
Remarks:
Note that these registers are read only, so this operation is actually
performed by reading the current counts. The relative count difference
can then be determined when reading the statistics registers.
*******************************************************************************/
zlStatusE zl5011xTfqResetStats(zl5011xParamsS *zl5011xParams, Uint32T context)
{
zlStatusE status = ZL5011X_OK;
ZL5011X_TRACE_CONTEXT(ZL5011X_TFQ_FN_ID, context, "zl5011xTfqResetStats: ctxt %3ld",
context, 0, 0, 0, 0, 0);
if (status == ZL5011X_OK)
{
status = zl5011xTfqGetLatePackets(zl5011xParams, context,
&(zl5011xParams->wanIf.txQueue[context].stats.latePackets));
}
if (status == ZL5011X_OK)
{
status = zl5011xTfqGetEarlyPackets(zl5011xParams, context,
&(zl5011xParams->wanIf.txQueue[context].stats.earlyPackets));
}
if (status == ZL5011X_OK)
{
status = zl5011xTfqGetUnderrunCount(zl5011xParams, context,
&(zl5011xParams->wanIf.txQueue[context].stats.underruns));
}
return(status);
}
/*****************************************************************************
Function:
zl5011xTfqResetQueue
Description:
If the queue is resequencing, and the sequence numbers do match that
expected for the queue, then packets will be rejected even if the queue is
empty. To recover from this, the queue can be reset, whereby the next
packet is used to reset the queue start sequence number.
Inputs:
zl5011xParams Pointer to the structure for this device instance
context which queue to reset
Outputs:
None
Returns:
zlStatusE
Remarks:
None
*****************************************************************************/
zlStatusE zl5011xTfqResetQueue(zl5011xParamsS *zl5011xParams,
Uint32T context)
{
zlStatusE status = ZL5011X_OK;
Uint32T bits, bitMask, regAddress, statusAddress, readValue;
zl5011xBooleanE clearFlag = ZL5011X_FALSE;
ZL5011X_TRACE_CONTEXT(ZL5011X_TFQ_FN_ID, context, "zl5011xTfqResetQueue: ctxt %3ld",
context, 0, 0, 0, 0, 0);
/* check that the queue has been configured */
if (zl5011xParams->wanIf.txQueue[context].queueBaseAddress == (Uint32T)ZL5011X_NOT_INITIALISED)
{
status = ZL5011X_ERROR;
}
if (status == ZL5011X_OK)
{
/* check to see if the queue is empty by reading the status flag */
statusAddress = ZL5011X_TFQ_CTXT_STATUS + (context * ZL5011X_TFQ_CTXT_CONTROL_SIZE);
status = zl5011xRead(zl5011xParams, statusAddress, &readValue);
}
if (status == ZL5011X_OK)
{
if ((readValue & (ZL5011X_1BIT_MASK << ZL5011X_TFQ_QUEUE_EMPTY_BIT)) != 0)
{
/* check an entry in the queue to confirm the status */
status = zl5011xRead(zl5011xParams,
zl5011xParams->wanIf.txQueue[context].queueBaseAddress + sizeof(Uint32T),
&readValue);
if ((readValue & (ZL5011X_1BIT_MASK << ZL5011X_TFQ_QUEUE_POS_OCCUPIED_BIT)) != 0)
{
clearFlag = ZL5011X_TRUE;
}
}
}
if (status == ZL5011X_OK)
{
regAddress = ZL5011X_TFQ_CTXT_DYNAMIC_SETUP + (context * ZL5011X_TFQ_CTXT_CONTROL_SIZE);
/* set the restart the queue bit, and clear the reduce, extend or min/max bits */
bits = ZL5011X_1BIT_MASK << ZL5011X_TFQ_RESTART_QUEUE_BIT;
bitMask = (ZL5011X_1BIT_MASK << ZL5011X_TFQ_RESTART_QUEUE_BIT) |
(ZL5011X_1BIT_MASK << ZL5011X_TFQ_EXTEND_QUEUE_BIT) |
(ZL5011X_1BIT_MASK << ZL5011X_TFQ_REDUCE_QUEUE_BIT) |
(ZL5011X_1BIT_MASK << ZL5011X_TFQ_CLEAR_MIN_LENGTH_BIT) |
(ZL5011X_1BIT_MASK << ZL5011X_TFQ_CLEAR_MAX_LENGTH_BIT);
status = zl5011xReadModWrite(zl5011xParams, regAddress, bits, bitMask);
}
if (status == ZL5011X_OK)
{
if (clearFlag == ZL5011X_TRUE)
{
/* clear the empty flag in the status register */
status = zl5011xReadModWrite(zl5011xParams,
statusAddress,
0,
ZL5011X_1BIT_MASK << ZL5011X_TFQ_QUEUE_EMPTY_BIT);
}
}
return(status);
}
/*****************************************************************************
Function:
zl5011xTfqGetErroredContext
Description:
This function is called to get a context ID from the interrupt queue.
Inputs:
zl5011xParams Pointer to the structure for this device instance
Outputs:
context ID from the interrupt queue
Returns:
zlStatusE
Remarks:
None
*****************************************************************************/
zlStatusE zl5011xTfqGetErroredContext(zl5011xParamsS *zl5011xParams,
Uint32T *context)
{
zlStatusE status = ZL5011X_OK;
Uint32T readValue;
ZL5011X_TRACE(ZL5011X_TFQ_FN_ID, "zl5011xTfqGetErroredContext", 0, 0, 0, 0, 0, 0);
status = zl5011xRead(zl5011xParams, ZL5011X_TFQ_INTERRUPT_QUEUE, &readValue);
*context = (readValue >> ZL5011X_TFQ_INT_QUEUE_CTXT_BITS) & ZL5011X_TFQ_CONTEXT_MASK;
ZL5011X_TRACE(ZL5011X_TFQ_FN_ID, "zl5011xTfqGetErroredContext: ctxt %3ld", *context, 0, 0, 0, 0, 0);
return(status);
}
/*****************************************************************************
Function:
zl5011xTfqGetError
Description:
Collects the error flags for a context, and resets them.
Inputs:
zl5011xParams Pointer to the structure for this device instance
context which context to collect the
Outputs:
error bits are set to indicate the source of the error
Returns:
zlStatusE
Remarks:
None
*****************************************************************************/
zlStatusE zl5011xTfqGetError(zl5011xParamsS *zl5011xParams, Uint32T context, Uint32T *error)
{
zlStatusE status = ZL5011X_OK;
ZL5011X_TRACE_CONTEXT(ZL5011X_TFQ_FN_ID, context, "zl5011xTfqGetError: ctxt %3ld",
context, 0, 0, 0, 0, 0);
/* the only possible error is that the queue has overflowed, so return
that error code */
*error = ZL5011X_1BIT_MASK << ZL5011X_TFQ_OVERFLOW_INT;
return(status);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -