?? zl5011xtfq.c
字號:
/*******************************************************************************
*
* File name: zl5011xTfq.c
*
* Version: 28
*
* Author: MRC
*
* Date created: 23/04/2002
*
* Copyright 2002, 2003, 2004, 2005, Zarlink Semiconductor Limited.
* All rights reserved.
*
* Module Description:
*
* This file contains all the functions that will initialise and control
* the Tfq block.
*
* Revision History:
*
* Rev: Date: Author: Comments:
* 1 23/04/2002 MRC Creation
* 2 18/06/2002 PJE reorganised interruptMask
* 3 18/06/2002 PJE reorganised interruptMask
* 4 28/06/2002 MRC Changed the flush fn to allow bit to be set even
* resume is set.
* 5 03/07/2002 PJE modified(debugged) Enable & DisableInterrupts
* 6 19/09/2002 MRC Added max granule fn
* 7 01/10/2002 DJA Function TfqEnableInterrupts renamed to
* zl5011xTfqEnableInterrupts
* Function TfqDisableInterrupts renamed to
* zl5011xTfqDisableInterrupts
* 8 08/07/2002 PJE new zl5011xTfqClearGranuleThresholdIntr
* 9 21/10/2002 PJE new TfqEnable/DisableGranuleThresholdIntr
* 10 24/10/2002 PJE API tidy up
* 11 31/10/2002 MRC Added variants + minor fixes
* 12 22/11/2002 PJE debug // comments
* 13 22/11/2002 PJE debug ctxt %3d bad format
* 14 29/11/2002 MRC Added check to ensure that the TFQ has resumed
* allowing any queue depth modification.
* 15 06/02/2003 MRC Added TFQ reset function
* 16 24/03/2003 MRC Prevented use of 16 bit queue for rev A devices
* 17 22/05/2003 MRC Added fns to determine packet reception
* 18 05/06/2003 MRC Added fn to return queue status
* 19 21/06/2003 MRC Added fn to return current queue length and mask
* off invalid bits from the average length
* 20 07/01/2004 MRC Corrected comment for fn TfqGetReadPointer
* 21 25/03/2004 APL Corrected comment in fn TfqGetCurrentLength
* 22 23/07/2004 MRC Fixed some compiler warnings
* 23 26/08/2004 MRC Updated queue reset function
* 24 20/10/2004 MRC Fixed queue depth stats functions
* 25 02/12/2004 APL Added helper function zl5011xTfqFormatAvgLength
* 26 14/02/2005 MRC Modified comment
* 27 19/04/2005 MRC Clears extend / reduce when starting a queue
* 28 17/05/2005 MRC Added function to reset queue statistics
*
*******************************************************************************/
/***************** INCLUDE FILES *****************************/
#include "zl5011x.h"
#include "zl5011xTfq.h"
#include "zl5011xTfqMap.h"
#include "zl5011xUtilLib.h"
/***************** EXPORTED GLOBAL VARIABLES *****************************/
/***************** STATIC GLOBAL VARIABLES *****************************/
/*******************************************************************************
Function:
zl5011xTfqInit
Description:
This function initialises the TFQ block and data structure.
Inputs:
zl5011xParams Pointer to the structure for this device instance
Outputs:
None
Returns:
zlStatusE
Remarks:
None
*******************************************************************************/
zlStatusE zl5011xTfqInit(zl5011xParamsS *zl5011xParams)
{
zlStatusE status = ZL5011X_OK;
Uint32T loop;
ZL5011X_TRACE(ZL5011X_TFQ_FN_ID, "zl5011xTfqInit:", 0, 0, 0, 0, 0, 0);
/* initialise the device structure */
for (loop = 0; loop < ZL5011X_MAX_NUMBER_CONTEXTS; loop++)
{
zl5011xParams->wanIf.txQueue[loop].queueMode = ZL5011X_WAN_TX_QUEUE_FIFO;
zl5011xParams->wanIf.txQueue[loop].queueBaseAddress = (Uint32T)ZL5011X_NOT_INITIALISED;
}
return(status);
}
/*******************************************************************************
Function:
zl5011xTfqConfigure
Description:
This function configures the queue for a context. Sets the address, size and
mode of operation for the queue.
A queue may only be modified when the context is in the INIT state. That is,
the queue has not been previously updated.
Inputs:
zl5011xParams Pointer to the structure for this device instance
context Context to use
baseAddress the byte address of the queue in packet memory
size enum to control the size of the queue (2^size)
mode whether the queue should resequence, and if so, the size of
the sequence number
Outputs:
None
Returns:
zlStatusE
Remarks:
None
*******************************************************************************/
zlStatusE zl5011xTfqConfigure(zl5011xParamsS *zl5011xParams, Uint32T context,
Uint32T baseAddress, zl5011xWanTxQueueSizeE size,
zl5011xWanTxQueueOperationE mode)
{
zlStatusE status = ZL5011X_OK;
Uint32T bits = 0, address;
ZL5011X_TRACE_CONTEXT(ZL5011X_TFQ_FN_ID, context, "zl5011xTfqConfigure: ctxt %3ld, base 0x%08lx, size %d, mode %d",
context, baseAddress, size, mode, 0, 0);
if (zl5011xParams->wanIf.tfmCurrent.context[context].state != ZL5011X_STATE_INIT)
{
status = ZL5011X_CONTEXT_NOT_IN_INIT;
}
if (status == ZL5011X_OK)
{
if ((baseAddress & ~ZL5011X_TFQ_BASE_ADDRESS_MASK) != 0)
{
status = ZL5011X_PARAMETER_INVALID;
}
}
if (status == ZL5011X_OK)
{
status = ZL5011X_CHECK_WAN_TX_QUEUE_SIZE(size);
}
/* rev A does not support 16 bit sequence numbers for queue resequencing */
if (mode == ZL5011X_WAN_TX_QUEUE_RESEQUENCE_16)
{
mode = ZL5011X_WAN_TX_QUEUE_RESEQUENCE_8;
}
if (status == ZL5011X_OK)
{
/* work out which bits to set for the queue sequencing mode */
switch (mode)
{
case ZL5011X_WAN_TX_QUEUE_FIFO:
bits = 0;
break;
case ZL5011X_WAN_TX_QUEUE_RESEQUENCE_8:
/* in 8 bit sequence number mode, the maximum queue size
is 128 packets */
if (size > ZL5011X_WAN_TX_QUEUE_SIZE_128)
{
status = ZL5011X_PARAMETER_INVALID;
}
bits = (ZL5011X_1BIT_MASK << ZL5011X_TFQ_RESEQUENCE_MODE_BIT) |
(ZL5011X_1BIT_MASK << ZL5011X_TFQ_SEQUENCE_NUM_SIZE_BIT);
break;
case ZL5011X_WAN_TX_QUEUE_RESEQUENCE_16:
bits = (ZL5011X_1BIT_MASK << ZL5011X_TFQ_RESEQUENCE_MODE_BIT);
break;
default :
status = ZL5011X_PARAMETER_INVALID;
}
}
if (status == ZL5011X_OK)
{
address = ZL5011X_TFQ_CTXT_STATIC_SETUP +
(context * ZL5011X_TFQ_CTXT_CONTROL_SIZE);
/* shift the size and base address fields into their correct place */
bits |= (size << ZL5011X_TFQ_SIZE_BITS) |
(baseAddress << ZL5011X_TFQ_BASE_ADDRESS_BITS);
status = zl5011xWrite(zl5011xParams, address, bits);
}
/* stash the queue settings in the device structure */
if (status == ZL5011X_OK)
{
zl5011xParams->wanIf.txQueue[context].queueMode = mode;
zl5011xParams->wanIf.txQueue[context].queueBaseAddress = baseAddress;
zl5011xParams->wanIf.txQueue[context].queueSize = size;
}
return(status);
}
/*******************************************************************************
Function:
zl5011xTfqSetACP
Description:
The depth of the queue is continually averaged by the device, and the average
value used in the adaptive clocking algorithm (for asynchronous WAN
operation). The Averaging Control Parameter controls the number of packets
that are included in the averaging function (i.e. the time response) as
follows:
AVG[n] = AVG[n-1] + ((QUEUE_DEPTH[n] - AVG[n-1]) / 2^ACP)
Inputs:
zl5011xParams Pointer to the structure for this device instance
context context to use
avgMode enum to control the averaging of the queue (2^avgMode)
Outputs:
None
Returns:
zlStatusE
Remarks:
None
*******************************************************************************/
zlStatusE zl5011xTfqSetACP(zl5011xParamsS *zl5011xParams, Uint32T context,
zl5011xWanTxQueueAvgModeE avgMode)
{
zlStatusE status = ZL5011X_OK;
Uint32T bits, address;
ZL5011X_TRACE_CONTEXT(ZL5011X_TFQ_FN_ID, context, "zl5011xTfqSetACP: ctxt %3ld, mode %d",
context, avgMode, 0, 0, 0, 0);
if (status == ZL5011X_OK)
{
status = ZL5011X_CHECK_WAN_TX_QUEUE_AVG(avgMode);
}
if (status == ZL5011X_OK)
{
address = ZL5011X_TFQ_CTXT_MIN_MAX_LENGTH +
(context * ZL5011X_TFQ_CTXT_CONTROL_SIZE);
/* set the average mode, and also initialise the min queue length */
bits = (avgMode << ZL5011X_TFQ_ACP_BITS) |
(ZL5011X_TFQ_QUEUE_LENGTH_MASK << ZL5011X_TFQ_MIN_QUEUE_LENGTH_BITS);
status = zl5011xWrite(zl5011xParams, address, bits);
}
if (status == ZL5011X_OK)
{
zl5011xParams->wanIf.txQueue[context].queueAvgMode = avgMode;
}
return(status);
}
/*******************************************************************************
Function:
zl5011xTfqFlush
Description:
In order to do a teardown (delete the context), the queue is flushed. The
queue cannot be flushed if it is still in resume.
Inputs:
zl5011xParams Pointer to the structure for this device instance
context context to use
Outputs:
None
Returns:
zlStatusE
Remarks:
The base address for the queue is not initialised by this function. This
means that the queue can be resumed without needing to be configured again.
*******************************************************************************/
zlStatusE zl5011xTfqFlush(zl5011xParamsS *zl5011xParams, Uint32T context)
{
zlStatusE status = ZL5011X_OK;
Uint32T bits, address;
ZL5011X_TRACE_CONTEXT(ZL5011X_TFQ_FN_ID, context, "zl5011xTfqFlush: ctxt %3ld",
context, 0, 0, 0, 0, 0);
address = ZL5011X_TFQ_CTXT_STATIC_SETUP + (context * ZL5011X_TFQ_CTXT_CONTROL_SIZE);
/* read the current state of the register, to check that neither
flush or resume are already set */
status = zl5011xRead(zl5011xParams, address, &bits);
if (status == ZL5011X_OK)
{
if ((bits & (ZL5011X_1BIT_MASK << ZL5011X_TFQ_RESUME_BIT)) != 0)
{
status = ZL5011X_WAN_QUEUE_IN_RESUME;
}
else
{
if ((bits & (ZL5011X_1BIT_MASK << ZL5011X_TFQ_FLUSH_BIT)) != 0)
{
status = ZL5011X_WAN_QUEUE_IN_FLUSH;
}
}
/* the return codes set above are really just for information to the
calling function. So set the flush bit and clear the resume bit anyway. */
bits &= ~(ZL5011X_1BIT_MASK << ZL5011X_TFQ_RESUME_BIT);
bits |= ZL5011X_1BIT_MASK << ZL5011X_TFQ_FLUSH_BIT;
/* ignore the return code from the write operation */
(void)zl5011xWrite(zl5011xParams, address, bits);
}
return(status);
}
/*******************************************************************************
Function:
zl5011xTfqResume
Description:
In order to start a context, the queue needs to be resumed. The
queue cannot be resumed if it is still in flush.
A check is made, to ensure that the memory for the queue has been set up, and
the queue is them initialised to 0.
Inputs:
zl5011xParams Pointer to the structure for this device instance
context context to use
Outputs:
None
Returns:
zlStatusE
Remarks:
None
*******************************************************************************/
zlStatusE zl5011xTfqResume(zl5011xParamsS *zl5011xParams, Uint32T context)
{
zlStatusE status = ZL5011X_OK;
Uint32T bits, regAddress;
Uint32T queueAddress, loop, queueSize32Bits;
ZL5011X_TRACE_CONTEXT(ZL5011X_TFQ_FN_ID, context, "zl5011xTfqResume: ctxt %3ld",
context, 0, 0, 0, 0, 0);
regAddress = ZL5011X_TFQ_CTXT_STATIC_SETUP + (context * ZL5011X_TFQ_CTXT_CONTROL_SIZE);
/* read the current state of the register, to check that neither
flush or resume are already set */
status = zl5011xRead(zl5011xParams, regAddress, &bits);
if (status == ZL5011X_OK)
{
if ((bits & (ZL5011X_1BIT_MASK << ZL5011X_TFQ_RESUME_BIT)) != 0)
{
status = ZL5011X_WAN_QUEUE_IN_RESUME;
}
else
{
if ((bits & (ZL5011X_1BIT_MASK << ZL5011X_TFQ_FLUSH_BIT)) != 0)
{
status = ZL5011X_WAN_QUEUE_IN_FLUSH;
}
}
}
/* check that the queue size is set to a valid number */
if (status == ZL5011X_OK)
{
status = ZL5011X_CHECK_WAN_TX_QUEUE_SIZE(zl5011xParams->wanIf.txQueue[context].queueSize);
}
if (status == ZL5011X_OK)
{
/* check that the base address has been set, and if so zero out the queue */
if (zl5011xParams->wanIf.txQueue[context].queueBaseAddress == (Uint32T)ZL5011X_NOT_INITIALISED)
{
status = ZL5011X_ERROR;
}
}
/* this gives the length of the queue in Task Manager messages */
queueSize32Bits = ZL5011X_1BIT_MASK << zl5011xParams->wanIf.txQueue[context].queueSize;
/* converting this into 32 bits words gives */
queueSize32Bits *= ZL5011X_TFQ_MESSAGE_SIZE_WORDS;
/* get the start address of the queue */
queueAddress = zl5011xParams->wanIf.txQueue[context].queueBaseAddress;
/* zero the contents of the queue */
for (loop = 0; loop < queueSize32Bits; loop ++)
{
if (status != ZL5011X_OK)
break;
status = zl5011xWrite(zl5011xParams, queueAddress, 0);
queueAddress += sizeof(Uint32T);
}
if (status == ZL5011X_OK)
{
/* clear the dynamic control register bits with the exception of the interrupt enable */
status = zl5011xReadModWrite(zl5011xParams,
ZL5011X_TFQ_CTXT_DYNAMIC_SETUP + (context * ZL5011X_TFQ_CTXT_CONTROL_SIZE),
0,
~(ZL5011X_1BIT_MASK << ZL5011X_TFQ_OVERFLOW_INT_ENABLE));
}
if (status == ZL5011X_OK)
{
/* set the resume bit */
bits |= ZL5011X_1BIT_MASK << ZL5011X_TFQ_RESUME_BIT;
status = zl5011xWrite(zl5011xParams, regAddress, bits);
}
return(status);
}
/*******************************************************************************
Function:
zl5011xTfqGetQueueStatus
Description:
Returns whether the queue is active or not.
Inputs:
zl5011xParams Pointer to the structure for this device instance
context context to use
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -