zl5011xtfm.c

来自「Zalink50114----TDMoIP芯片驱动源码」· C语言 代码 · 共 1,986 行 · 第 1/5 页

C
1,986
字号

   if (status == ZL5011X_OK)
   {
      zl5011xParams->wanIf.tfmCurrent.context[context].numChannels--;

      bits = 0;

      bitMask = (ZL5011X_1BIT_MASK << ZL5011X_TFM_NEW_FIRST_CHAN_BIT) |
            (ZL5011X_1BIT_MASK << ZL5011X_TFM_NEW_VALID_CHAN_BIT);

      status = zl5011xReadModWrite(zl5011xParams,
            ZL5011X_TFM_CONTEXT_LOOKUP + (chanIndex * ZL5011X_TFM_LKUP_MEM_SIZE),
            bits, bitMask);

      /* update the structure */
      zl5011xParams->wanIf.tfmCurrent.channel[chanIndex].context = (Uint32T)ZL5011X_INVALID_CONTEXT;

      if (zl5011xParams->wanIf.tfmCurrent.context[context].firstChannelIndex == chanIndex)
      {
         zl5011xParams->wanIf.tfmCurrent.context[context].firstChannelIndex = (Uint32T)ZL5011X_INVALID_CHANNEL;
      }
   }

   return(status);
}

/*******************************************************************************

 Function:
   zl5011xTfmSetChanUnderrun

 Description:
   Sets the underrun mode and byte for the channel. This takes effect
   immediately, is context independent and does not require an update.

 Inputs:
   zl5011xParams   Pointer to the structure for this device instance
   tdm            stream / channel to set the underrun for
   underrunByte   8 bits to be used for underrun
   mode           controls whether the underrun byte is taken from the passed
                  in parameter, or is simply a repeat of the last byte.

 Outputs:
   None

 Returns:
   zlStatusE

 Remarks:
   None

*******************************************************************************/

zlStatusE zl5011xTfmSetChanUnderrun(zl5011xParamsS *zl5011xParams,
      zl5011xWanChannelS tdm, Uint8T underrunByte, zl5011xWanIfUnderrunModeE mode)
{
   zlStatusE status = ZL5011X_OK;
   Uint32T bits;
   Uint32T bitMask;
   Uint32T chanIndex;

   status = ZL5011X_CHECK_WAN_IF_UNDERRUN_MODE(mode);

   if (status == ZL5011X_OK)
   {
      status = zl5011xCalcChanIndex(zl5011xParams, tdm, &chanIndex);
   }

   if (status == ZL5011X_OK)
   {
      ZL5011X_TRACE_CONTEXT(ZL5011X_TFM_FN_ID, zl5011xParams->wanIf.tfmCurrent.channel[chanIndex].context,
            "zl5011xTfmSetChanUnderrun: context %3d, stream %2d, chan %2d, mode = %d, byte = %d",
            zl5011xParams->wanIf.tfmCurrent.channel[chanIndex].context,
            tdm.stream, tdm.channel, (Uint32T)mode, underrunByte, 0);

      /* set the bits in the register */
      bits = (underrunByte << ZL5011X_TFM_UNDERRUN_BYTE_BITS)
            | (mode << ZL5011X_TFM_UNDERRUN_MODE_BIT);

      bitMask = (ZL5011X_TFM_UNDERRUN_BYTE_MASK << ZL5011X_TFM_UNDERRUN_BYTE_BITS)
            | (ZL5011X_1BIT_MASK << ZL5011X_TFM_UNDERRUN_MODE_BIT);

      status = zl5011xReadModWrite(zl5011xParams,
            ZL5011X_TFM_CONTEXT_LOOKUP + (chanIndex * ZL5011X_TFM_LKUP_MEM_SIZE),
            bits, bitMask);

      /* save the settings in the device structure */
      zl5011xParams->wanIf.tfmCurrent.channel[chanIndex].underrunMode = mode;
      zl5011xParams->wanIf.tfmCurrent.channel[chanIndex].underrunByte = underrunByte;
   }

   return(status);
}

/*******************************************************************************

 Function:
    zl5011xTfmUpdateFirstChan

 Description:
   The first channel must be identified correctly before a context is updated.
   This function scans the current structure to find the first channel. If the
   first channel is no longer correct, then the new first channel is identified
   to the device.

 Inputs:
   zl5011xParams   Pointer to the structure for this device instance
   context        which context to do the first channel update for

 Outputs:
    None

 Returns:
    zlStatusE

 Remarks:
   In any add / remove channel operations the first channel is not tracked.

*******************************************************************************/

zlStatusE zl5011xTfmUpdateFirstChan(zl5011xParamsS *zl5011xParams,
      Uint32T context)
{
   zlStatusE status = ZL5011X_OK;
   zl5011xBooleanE foundFirst = ZL5011X_FALSE;
   zl5011xWanChannelS tdm;
   Uint32T chanIndex, loop, activeChannels;

   ZL5011X_TRACE_CONTEXT(ZL5011X_TFM_FN_ID, context,
         "zl5011xTfmUpdateFirstChan: context %3d",
         context, 0, 0, 0, 0, 0);

   /* the loops are arranged to represent the order in which the device does
      the search for the first channel -
      i.e.  channel 0 stream 0
            channel 0 stream 1
            channel 0 stream 2 etc. */
   for (tdm.channel = 0; ((tdm.channel < zl5011xParams->wanIf.wanNumChannels ) &&
         (foundFirst == ZL5011X_FALSE)); tdm.channel++)
   {
      /* Iterate around all possible streams. This allows non-contiguous stream numbers to be used */
      for (tdm.stream = 0; ((tdm.stream < ZL5011X_MAX_NUMBER_STREAMS) &&
            (foundFirst == ZL5011X_FALSE)); tdm.stream++)
      {
         if (status != ZL5011X_OK)
         {
            break;
         }

         /* Check that this stream is valid for this device. */
         if (zl5011xCheckStreamRange(zl5011xParams, tdm.stream)  == ZL5011X_OK)
         {
            status = zl5011xCalcChanIndex(zl5011xParams, tdm, &chanIndex);

            if (status == ZL5011X_OK)
            {
               if (zl5011xParams->wanIf.tfmCurrent.channel[chanIndex].context == context)
               {
                  foundFirst = ZL5011X_TRUE;
               }
            }
         }
       }
   }

   if (status == ZL5011X_OK)
   {
      /* if we have not found any channels, then something has gone seriously wrong */
      if (foundFirst != ZL5011X_TRUE)
      {
         status = ZL5011X_CTXT_NO_CHANNELS;
      }
   }

   if (status == ZL5011X_OK)
   {
      /* check that the number of channels is not being exceeded */
      activeChannels = 0;

      /* count the number of channels used by other contexts */
      for (loop = 0; loop < ZL5011X_MAX_NUMBER_CHANNELS; loop++)
      {
         Uint32T tempContext;

         /* check if a valid context number is specified in the active device copy */
         tempContext = zl5011xParams->wanIf.tfmActive.channel[loop].context;

         if (tempContext == (Uint32T)ZL5011X_INVALID_CONTEXT)
         {
            /* active context for this channel, so check in the modification copy */
            tempContext = zl5011xParams->wanIf.tfmCurrent.channel[loop].context;
         }

         if ((tempContext != (Uint32T)ZL5011X_INVALID_CONTEXT) && (tempContext != context))
         {
            /* got a context for this channel and it's not the one we are updating */
            switch (zl5011xParams->wanIf.tfmCurrent.context[tempContext].state)
            {
               case ZL5011X_STATE_TAKEN :
               case ZL5011X_STATE_ACTIVE :
                  if (zl5011xParams->wanIf.tfmActive.channel[loop].context != (Uint32T)ZL5011X_INVALID_CONTEXT)
                  {
                     /* the device usage for the state is represented in the active device copy */
                     activeChannels++;
                  }
                  break;

               case ZL5011X_STATE_UPDATING :
                  if (zl5011xParams->wanIf.tfmCurrent.channel[loop].context != (Uint32T)ZL5011X_INVALID_CONTEXT)
                  {
                     /* the device usage for the state is represented in the current device copy, that is
                        a change has been requested and the device is in the process of switching */
                     activeChannels++;
                  }
                  break;

               case ZL5011X_STATE_NOT_IN_USE :
               case ZL5011X_STATE_INIT :
               case ZL5011X_STATE_TEARING_DOWN :
               default :
                  /* channel not active */
                  break;
            }
         }
      }

      activeChannels += zl5011xParams->wanIf.tfmCurrent.context[context].numChannels;

      if (activeChannels > zl5011xParams->devLimits.numChannels)
      {
         status = ZL5011X_CHANNEL_CAPACITY;
      }
   }


   if (status == ZL5011X_OK)
   {
      if (zl5011xParams->wanIf.tfmCurrent.context[context].firstChannelIndex !=
            chanIndex)
      {
         /* we have a new first channel, so reset the first bit in the old one */
         status = zl5011xTfmClearFirstChan(zl5011xParams, context);

         /* and set the first bit in the new one */
         if (status == ZL5011X_OK)
         {
            status = zl5011xTfmSetFirstChan(zl5011xParams, context, chanIndex);
         }
      }
   }

   return status;
}

/*******************************************************************************

 Function:
    zl5011xTfmClearFirstChan

 Description:
   Clears the first channel for the context. Clears the bit in the channel mapping
   for the device and sets the first channel in the context structure to invalid.
   If the previous value was valid, then checks that it was in bounds.

 Inputs:
   zl5011xParams   Pointer to the structure for this device instance
   context     context to reset the first channel for.

 Outputs:
    None

 Returns:
    zlStatusE

 Remarks:
    None

*******************************************************************************/

zlStatusE zl5011xTfmClearFirstChan(zl5011xParamsS *zl5011xParams, Uint32T context)
{
   zlStatusE status = ZL5011X_OK;
   Uint32T tempFirstIndex;

   ZL5011X_TRACE_CONTEXT(ZL5011X_TFM_FN_ID, context,
         "zl5011xTfmClearFirstChan: ctxt %4X",
         context, 0, 0, 0, 0, 0);

   tempFirstIndex = zl5011xParams->wanIf.tfmCurrent.context[context].firstChannelIndex;

   /* if there wasn't a valid first channel, then just exit with OK, since
      this is to be expected */
   if (tempFirstIndex != (Uint32T)ZL5011X_INVALID_CHANNEL)
   {
      if (tempFirstIndex >= ZL5011X_MAX_NUMBER_CHANNELS)
      {
         status = ZL5011X_WAN_INVALID_FIRST_CHANNEL;
      }
      else
      {
         status = zl5011xReadModWrite(zl5011xParams,
               ZL5011X_TFM_CONTEXT_LOOKUP + (tempFirstIndex * ZL5011X_TFM_LKUP_MEM_SIZE),
               0,
               ZL5011X_1BIT_MASK << ZL5011X_TFM_NEW_FIRST_CHAN_BIT);

         zl5011xParams->wanIf.tfmCurrent.context[context].firstChannelIndex = (Uint32T)ZL5011X_INVALID_CHANNEL;
      }
   }

   return(status);
}

/*******************************************************************************

 Function:
    zl5011xTfmSetFirstChan

 Description:
   Sets the first channel for the context. Sets the bit in the channel mapping
   for the device and sets the first channel in the context structure to
   the context.

 Inputs:
   zl5011xParams   Pointer to the structure for this device instance
   context        context to set the first channel for.
   chanIndex      index into the array for the new first channel

 Outputs:
    None

 Returns:
    zlStatusE

 Remarks:
    None

*******************************************************************************/

zlStatusE zl5011xTfmSetFirstChan(zl5011xParamsS *zl5011xParams,
      Uint32T context, Uint32T chanIndex)
{
   zlStatusE status = ZL5011X_OK;

   ZL5011X_TRACE_CONTEXT(ZL5011X_TFM_FN_ID, context,
         "zl5011xTfmSetFirstChan: ctxt %4X, lkup %4X",
         context, chanIndex, 0, 0, 0, 0);

   status = zl5011xReadModWrite(zl5011xParams,
         ZL5011X_TFM_CONTEXT_LOOKUP + (chanIndex * ZL5011X_TFM_LKUP_MEM_SIZE),
         ZL5011X_1BIT_MASK << ZL5011X_TFM_NEW_FIRST_CHAN_BIT,
         ZL5011X_1BIT_MASK << ZL5011X_TFM_NEW_FIRST_CHAN_BIT);

   zl5011xParams->wanIf.tfmCurrent.context[context].firstChannelIndex = chanIndex;

   return(status);
}

/*****************************************************************************

Function:
   zl5011xTfmCheckChan

Description:
   Checks if a channel is in use. If the channel is in use, then the context
   number that it is attached to is returned.
   If that context is in update or teardown, then a check is made to see if
   the operation has finished. If it has, then the active and current structures
   are updated.

Inputs:
   zl5011xParams   Pointer to the structure for this device instance
   chanIndex      Index used to represent the channel

Outputs:
   context     Use to pass back the context associated with the channel.
               Can be either a channel or invalid if the channel is free.

Returns:
   zlStatusE

*****************************************************************************/

zlStatusE zl5011xTfmCheckChan(zl5011xParamsS *zl5011xParams,
      Uint32T *context, Uint32T chanIndex)
{
   zlStatusE status = ZL5011X_OK;
   Uint32T tempContext;

   ZL5011X_TRACE(ZL5011X_TFM_FN_ID, "zl5011xTfmCheckChan: lkup %4X",
         chanIndex, 0, 0, 0, 0, 0);

   /* determine if the channel is associated with a context */
   tempContext = zl5011xParams->wanIf.tfmActive.channel[chanIndex].context;

   /* check the modification buffer if active is unused */
   if (tempContext == (Uint32T)ZL5011X_INVALID_CONTEXT)
   {
      tempContext = zl5011xParams->wanIf.tfmCurrent.channel[chanIndex].context;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?