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

📄 zl5011xmisc.c

📁 Zalink50114----TDMoIP芯片驱动源码
💻 C
📖 第 1 页 / 共 3 页
字号:
*******************************************************************************/

zlStatusE zl5011xContextCheckRx(zl5011xParamsS *zl5011xParams, Uint32T context,
      zl5011xCheckContextStateE check)
{
   zlStatusE status = ZL5011X_OK;

   ZL5011X_TRACE(ZL5011X_MISC_FN_ID,
         "zl5011xContextCheckRx: ctxt %d, check %d",
         context, check, 0, 0, 0, 0);

   /* check that the context number does not exceed the maximum allowed */
   if (context >= ZL5011X_MAX_NUMBER_CONTEXTS)
   {
      status = ZL5011X_CONTEXTID_RANGE;
   }
   else
   {
      /* if the context is currently in use then it's number must be valid. If it is
         not in use then check it */
      if (zl5011xParams->wanIf.plaCurrent.context[context].state == ZL5011X_STATE_NOT_IN_USE)
      {
         /* For TDM (wan) contexts when the mode is unframed then there is a one-to-one mapping between
            contexts and streams. For Lan-to-Lan contexts any context number can be used */
         if ((zl5011xParams->packetIf.lanLanContext[context] == ZL5011X_FALSE) &&
             (zl5011xParams->wanIf.wanConnectionMode == ZL5011X_WAN_CONNECTION_UNFRAMED))
         {
            if (context >= zl5011xParams->wanIf.wanNumStreams)
            {
               if (zl5011xParams->devLimits.cesAvailable == ZL5011X_FALSE)
               {
                  /* non CES part, so auxilliary clock is a valid option */
                  if (context != zl5011xParams->devLimits.wanAuxClockNum)
                  {
                     status = ZL5011X_CONTEXTID_RANGE;
                  }
               }
               else
               {
                  status = ZL5011X_CONTEXTID_RANGE;
               }
            }
         }
         else
         {
            if (context >= zl5011xParams->devLimits.numContexts)
            {
               status = ZL5011X_CONTEXTID_RANGE;
            }
         }
      }
   }

   if (status == ZL5011X_OK)
   {
      switch (check)
      {
         case ZL5011X_CHECK_CONTEXT_NUMBER:
               break;

         case ZL5011X_CHECK_CONTEXT_INIT:
               if (zl5011xParams->wanIf.plaCurrent.context[context].state != ZL5011X_STATE_INIT)
               {
                  status = ZL5011X_CONTEXT_NOT_IN_INIT;
               }
               break;

         case ZL5011X_CHECK_CONTEXT_MODIFY:
               if ((zl5011xParams->wanIf.plaCurrent.context[context].state != ZL5011X_STATE_INIT) &&
                  (zl5011xParams->wanIf.plaCurrent.context[context].state != ZL5011X_STATE_TAKEN))
               {
                  status = ZL5011X_CONTEXT_NOT_TAKEN;
               }
               break;

         case ZL5011X_CHECK_CONTEXT_ACTIVE:
               if ((zl5011xParams->wanIf.plaCurrent.context[context].state != ZL5011X_STATE_TAKEN) &&
                  (zl5011xParams->wanIf.plaCurrent.context[context].state != ZL5011X_STATE_ACTIVE) &&
                  (zl5011xParams->wanIf.plaCurrent.context[context].state != ZL5011X_STATE_UPDATING))
               {
                  status = ZL5011X_CONTEXT_NOT_ACTIVE;
               }
               break;

         case ZL5011X_CHECK_CONTEXT_IN_USE:
               if ((zl5011xParams->wanIf.plaCurrent.context[context].state != ZL5011X_STATE_INIT) &&
                  (zl5011xParams->wanIf.plaCurrent.context[context].state != ZL5011X_STATE_TAKEN) &&
                  (zl5011xParams->wanIf.plaCurrent.context[context].state != ZL5011X_STATE_ACTIVE) &&
                  (zl5011xParams->wanIf.plaCurrent.context[context].state != ZL5011X_STATE_UPDATING))
               {
                  status = ZL5011X_CONTEXT_NOT_IN_USE;
               }
               break;

         default:
               status = ZL5011X_PARAMETER_INVALID;
      }
   }

   return status;
}

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

 Function:
    zl5011xContextCheckTx

 Description:
   Used to check that a Wan Tx context number is valid. Can also check that
   the context is in a valid state for modification - i.e. taken or init

 Inputs:
   zl5011xParams   Pointer to the structure for this device instance
   check          which check to perform on the context

 Outputs:
   None

 Returns:
  zlStatusE

 Remarks:
   None

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

zlStatusE zl5011xContextCheckTx(zl5011xParamsS *zl5011xParams, Uint32T context,
      zl5011xCheckContextStateE check)
{
   zlStatusE status = ZL5011X_OK;

   ZL5011X_TRACE(ZL5011X_MISC_FN_ID,
         "zl5011xContextCheckTx: ctxt %d, check %d",
         context, check, 0, 0, 0, 0);

   /* check that the context number does not exceed the maximum allowed */
   if (context >= ZL5011X_MAX_NUMBER_CONTEXTS)
   {
      status = ZL5011X_CONTEXTID_RANGE;
   }
   else
   {
      /* if the context is currently in use then it's number must be valid. If it is
         not in use then check it */
      if (zl5011xParams->wanIf.tfmCurrent.context[context].state == ZL5011X_STATE_NOT_IN_USE)
      {
         /* For TDM (wan) contexts when the mode is unframed then there is a one-to-one mapping between
            contexts and streams. For Lan-to-Lan contexts any context number can be used */
         if ((zl5011xParams->packetIf.lanLanContext[context] == ZL5011X_FALSE) &&
             (zl5011xParams->wanIf.wanConnectionMode == ZL5011X_WAN_CONNECTION_UNFRAMED))
         {
            if (context >= zl5011xParams->wanIf.wanNumStreams)
            {
               if (zl5011xParams->devLimits.cesAvailable == ZL5011X_FALSE)
               {
                  /* non CES part, so auxilliary clock is a valid option */
                  if (context != zl5011xParams->devLimits.wanAuxClockNum)
                  {
                     status = ZL5011X_CONTEXTID_RANGE;
                  }
               }
               else
               {
                  status = ZL5011X_CONTEXTID_RANGE;
               }
            }
         }
         else
         {
            if (context >= zl5011xParams->devLimits.numContexts)
            {
               status = ZL5011X_CONTEXTID_RANGE;
            }
         }
      }
   }

   if (status == ZL5011X_OK)
   {
      switch (check)
      {
         case ZL5011X_CHECK_CONTEXT_NUMBER:
               break;

         case ZL5011X_CHECK_CONTEXT_INIT:
               if (zl5011xParams->wanIf.tfmCurrent.context[context].state != ZL5011X_STATE_INIT)
               {
                  status = ZL5011X_CONTEXT_NOT_IN_INIT;
               }
               break;

         case ZL5011X_CHECK_CONTEXT_MODIFY:
               if ((zl5011xParams->wanIf.tfmCurrent.context[context].state != ZL5011X_STATE_INIT) &&
                  (zl5011xParams->wanIf.tfmCurrent.context[context].state != ZL5011X_STATE_TAKEN))
               {
                  status = ZL5011X_CONTEXT_NOT_TAKEN;
               }
               break;

         case ZL5011X_CHECK_CONTEXT_ACTIVE:
               if ((zl5011xParams->wanIf.tfmCurrent.context[context].state != ZL5011X_STATE_TAKEN) &&
                  (zl5011xParams->wanIf.tfmCurrent.context[context].state != ZL5011X_STATE_ACTIVE) &&
                  (zl5011xParams->wanIf.tfmCurrent.context[context].state != ZL5011X_STATE_UPDATING))
               {
                  status = ZL5011X_CONTEXT_NOT_ACTIVE;
               }
               break;

         case ZL5011X_CHECK_CONTEXT_IN_USE:
               if ((zl5011xParams->wanIf.tfmCurrent.context[context].state != ZL5011X_STATE_INIT) &&
                  (zl5011xParams->wanIf.tfmCurrent.context[context].state != ZL5011X_STATE_TAKEN) &&
                  (zl5011xParams->wanIf.tfmCurrent.context[context].state != ZL5011X_STATE_ACTIVE) &&
                  (zl5011xParams->wanIf.tfmCurrent.context[context].state != ZL5011X_STATE_UPDATING))
               {
                  status = ZL5011X_CONTEXT_NOT_IN_USE;
               }
               break;

         default:
               status = ZL5011X_PARAMETER_INVALID;
      }
   }

   return status;
}

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

 Function:
    zl5011xLanPortCheck

 Description:
   Used to check that a Lan port has been initialised.

 Inputs:
   zl5011xParams   Pointer to the structure for this device instance
   portNum        which port to check

 Outputs:
   None

 Returns:
  zlStatusE

 Remarks:
   None

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

zlStatusE zl5011xLanPortCheck(zl5011xParamsS *zl5011xParams, Uint8T portNum)
{
   zlStatusE status = ZL5011X_OK;

   ZL5011X_TRACE(ZL5011X_MISC_FN_ID,
         "zl5011xLanPortCheck: port %d",
         portNum, 0, 0, 0, 0, 0);

   if ((portNum >= zl5011xParams->devLimits.lanNumLanPorts) ||
      (zl5011xParams->lanPortInitialised[portNum] == ZL5011X_FALSE))
   {
      status = ZL5011X_INVALID_PORT;
   }

   return status;
}

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

 Function:
    zl5011xPacketCalculateChecksum

 Description:
    This function calculates the ones complement checksum for the data passed
    in.

 Inputs:
   buf         pointer to the array holding the packet header
   length      how many bytes to include in the checksum

 Outputs:
   chkOut      checksum for the data

 Returns:
    zlStatusE

 Remarks:
    This checksum is as used in IPv4 and UDP protocols.

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

zlStatusE zl5011xPacketCalculateChecksum(Uint8T *buf, Uint16T length, Uint16T *chkOut)
{
   Uint32T checksum = 0;
   Uint16T word16, index = 0;

   ZL5011X_TRACE(ZL5011X_PACKET_FN_ID,
         "zl5011xPacketCalculateChecksum:",
         0, 0, 0, 0, 0, 0);

   /* main checksum loop */
   word16 = 0;
   while (length > 1)
   {
      word16 = buf[index++] << 8;
      word16 |= buf[index++] << 0;

      checksum += word16;
      length -= 2;
   }

   /* if there is an odd byte left over, then add it in */
   if (length > 0)
   {
      checksum += buf[index] << 8;
   }

   /*  the one's complement bit - add in the overflow bits */
   while ((checksum >> 16) != 0)
   {
      checksum = (checksum >> 16) + (checksum & 0xffff);
   }

   *chkOut = (Uint16T)~checksum;

   return ZL5011X_OK;
}

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

 Function:
    zl5011xPacketChangeField

 Description:
   Allows a 16 bit field in the header to be modified. The difference between
   the new value and the old value is returned, to allow the checksum to be
   updated.
   Updates the checksum value passed in, for multiple changes. For the first
   change made, the chkChange parameter should be zero'd before calling this
   function. This function may be required for calculating the UDP checksum.

 Inputs:
   buf         pointer to the array holding the packet header
   modPos      position of the field to change in bytes from the start of buf
   newValue    the ammount that the checksum has to change by.
   bitMask     if a bit is set then the corresponding bit from newValue will be
               used to replace the data in buf

 Outputs:
   chkChange   updates the i/p value with the ammount that the header has
               changed by

 Returns:
    zlStatusE

 Remarks:
    The modification position must correspond to a 16 bit aligned position in
    the header.

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

zlStatusE zl5011xPacketChangeField(Uint8T *buf, Uint8T modPos,
      Uint16T newValue, Uint16T bitMask, Uint16T *chkChange)
{
   Uint16T word16, temp16;
   Uint32T newChk;

   ZL5011X_TRACE(ZL5011X_PACKET_FN_ID,
         "zl5011xPacketChangeField: new %04X, mask %04X",
         newValue, bitMask, 0, 0, 0, 0);

   if (buf == NULL)
   {
      /* if a buffer is not provided then assume the old word was 0 */
      word16 = 0;
   }
   else
   {
      /* if a buffer is provided then replace the value in the buffer with
         the new value, using the bit mask to qualify which bits to change */
      word16 = buf[modPos] << 8;
      word16 |= buf[modPos + 1];

      newValue = (word16 & ~bitMask) | (newValue & bitMask);

      buf[modPos] = (Uint8T)(newValue >> 8);
      buf[modPos + 1] = (Uint8T)(newValue >> 0);
   }

   temp16 = ~word16;
   newChk = (Uint32T)(*chkChange);
   newChk += (Uint32T)newValue;
   newChk += (Uint32T)temp16;

   while ((newChk >> 16) != 0)
   {
      newChk = (newChk >> 16) + (newChk & 0xffff);
   }

   *chkChange = (Uint16T)newChk;

   ZL5011X_TRACE(ZL5011X_PACKET_FN_ID,
         "zl5011xPacketChangeField: new %04X, old %04X, change %04X",
         newValue, word16, *chkChange, 0, 0, 0);

   return ZL5011X_OK;
}

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

 Function:
    zl5011xPacketUpdateChecksum

 Description:
   Updates the checksum in the header using a change value passed in for a
   previous header modification.

 Inputs:
   buf         pointer to the array holding the packet header
   chkPos      position of the checksum in bytes from the start of buf
   chkChange   the ammount that the checksum has to change by.

 Outputs:
    None

 Returns:
    zlStatusE

 Remarks:
   This checksum is as used in IPv4 and UDP protocols.

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

zlStatusE zl5011xPacketUpdateChecksum(Uint8T *buf, Uint8T chkPos, Uint16T chkChange)
{
   Uint16T word16, temp16;
   Uint32T newChk;

   ZL5011X_TRACE(ZL5011X_PACKET_FN_ID,
         "zl5011xPacketUpdateChecksum: check offset %2d, change %04X",
         chkPos, chkChange, 0, 0, 0, 0);

   word16 = buf[chkPos] << 8;
   word16 |= buf[chkPos + 1];

   temp16 = ~word16;
   newChk = temp16;
   newChk += chkChange;

   while ((newChk >> 16) != 0)
   {
      newChk = (newChk >> 16) + (newChk & 0xffff);
   }

   newChk = ~newChk;

   buf[chkPos] = (Uint8T)(newChk >> 8);
   buf[chkPos + 1] = (Uint8T)(newChk >> 0);

   return ZL5011X_OK;
}

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

 Function:
    zl5011xPacketInvertChecksum

 Description:
   Inverts the checksum in the header. This is used to convert a checksum to
   a partial checksum - as required for the packet Tx blocks.

 Inputs:
   buf         pointer to the array holding the packet header
   chkPos      position of the checksum in bytes from the start of buf

 Outputs:
   None

 Returns:
   zlStatusE

 Remarks:
   None
******************************************************************************/

zlStatusE zl5011xPacketInvertChecksum(Uint8T *buf, Uint8T chkPos)
{
   Uint16T word16;

   ZL5011X_TRACE(ZL5011X_PACKET_FN_ID,
         "zl5011xPacketInvertChecksum: check offset %2d",
         chkPos, 0, 0, 0, 0, 0);

   word16 = buf[chkPos] << 8;
   word16 |= buf[chkPos + 1];

   word16 = ~word16;

   buf[chkPos] = (Uint8T)(word16 >> 8);
   buf[chkPos + 1] = (Uint8T)(word16 >> 0);

   return ZL5011X_OK;
}

⌨️ 快捷键说明

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