⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zl5011xtfq.c

📁 Zalink50114----TDMoIP芯片驱动源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/*******************************************************************************
*
*  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 + -