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

📄 zl5011xpacketloopback.c

📁 Zalink50114----TDMoIP芯片驱动源码
💻 C
📖 第 1 页 / 共 2 页
字号:
         /* the header for the loopback Tx has now been set, so mark the
            context as in use to prevent it from being changed */
         zl5011xParams->wanIf.plaCurrent.context[context].state = ZL5011X_STATE_INIT;
      }
   }

   /* free up the memory allocated for the headers */
   if (layer2and3Header != NULL)
   {
      free(layer2and3Header);
   }

   return(status);
}

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

 Function:
   zl5011xLoopbackUpdateIPChecksum

 Description:
   In IPv4 mode, the checksum needs to be presented to the device, based on the
   length and the identification fields being zero for the partial checksum.
   This function, amends the checksum based on these fields being zero.

 Inputs:
    layer2and3Header  Pointer to the zl5011xLanTxSetLayer2and3HeaderS structure.
    par               Pointer to the zl5011xPacketLoopbackConfigS structure.

 Outputs:
    None

 Returns:
    zlStatusE

 Remarks:
   The PTX uses the length field from a seperate register in the control
   header. The value in the header itself is as set by the calling function
   - and as used for calculating the checksum. So, change this field to
   zero and re-calculate the checksum.

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

zlStatusE zl5011xLoopbackUpdateIPChecksum(zl5011xLanTxSetLayer2and3HeaderS *layer2and3Header,
      zl5011xPacketLoopbackConfigS * par)
{
   zlStatusE status = ZL5011X_OK;
   Uint16T chkChange;
   Uint8T tempArray[2];

   ZL5011X_TRACE(ZL5011X_INIT_FN_ID,
         "zl5011xLoopbackUpdateIPChecksum:",
         0, 0, 0, 0, 0, 0);

   chkChange = 0;

   if (status == ZL5011X_OK)
   {
      /* change the length field to 0 */
      status = zl5011xPacketChangeField(layer2and3Header->header.txLowData,
            layer2and3Header->header.layer3LengthPos,
            0, 0xffff, &chkChange);
   }

   if (status == ZL5011X_OK)
   {
      /* extract the identification fields, so that they can be reset to 0 for
         the purpose of the checksum */
      tempArray[0] = layer2and3Header->header.txLowData[layer2and3Header->header.layer3LengthPos +
            (ZL5011X_PKT_IPV4_IDENT_POS - ZL5011X_PKT_IPV4_LEN_POS)];
      tempArray[1] = layer2and3Header->header.txLowData[layer2and3Header->header.layer3LengthPos +
            (ZL5011X_PKT_IPV4_IDENT_POS - ZL5011X_PKT_IPV4_LEN_POS) + 1];

      /* change the identification field to 0 */
      status = zl5011xPacketChangeField(tempArray, 0, 0, 0xffff, &chkChange);
   }

   /* update the IPv4 checksum in the header */
   if (status == ZL5011X_OK)
   {
      status = zl5011xPacketUpdateChecksum(layer2and3Header->header.txLowData,
            layer2and3Header->header.layer3ChecksumPos, chkChange);
   }

   /* invert the checksum in the header as required for the partial checksum */
   if (status == ZL5011X_OK)
   {
      status = zl5011xPacketInvertChecksum(layer2and3Header->header.txLowData,
            layer2and3Header->header.layer3ChecksumPos);
   }

   return(status);
}

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

 Function:
    zl5011xLoopbackCopyHeaders

 Description:
    The primary intention of this function is to copy the header arrays across
    from the array passed in, to the low headers as required to program
    the device.

 Inputs:
    layer2and3Header  Pointer to the zl5011xLanTxSetLayer2and3HeaderS structure.
    par               Pointer to the zl5011xPacketLoopbackConfigS structure.

 Outputs:
    None

 Returns:
    zlStatusE

 Remarks:

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

zlStatusE zl5011xLoopbackCopyHeaders(zl5011xLanTxSetLayer2and3HeaderS *layer2and3Header,
      zl5011xPacketLoopbackConfigS * par)
{
   zlStatusE status = ZL5011X_OK;
   Uint32T n;

   ZL5011X_TRACE(ZL5011X_INIT_FN_ID,
         "zl5011xLoopbackCopyHeaders:",
         0, 0, 0, 0, 0, 0);

   for (n = 0; n < layer2and3Header->header.txLowLength; n++)
   {
      layer2and3Header->header.txLowData[n] = par->header[n];
   }

   return(status);
}

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

 Function:
    zl5011xPacketRxLoopback

 Description:
    Sets up the packet Rx for unmatched packets.

 Inputs:
   zl5011xParams   Pointer to the structure for this device instance
   matchedProtocol   enable loopback for packets passing the protocol match, but
                  failing to be classified.
   unmatchedProtocol enable loopback for packets not passing the protocol match

 Outputs:
   None

 Returns:
    zlStatusE

 Remarks:

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

zlStatusE zl5011xPacketRxLoopback(zl5011xParamsS *zl5011xParams,
      zl5011xPacketLoopbackConfigS *par, zl5011xBooleanE unmatchedProtocol)
{
   zlStatusE status = ZL5011X_OK;
   zl5011xLanRxSetProtocolMatchS protocolMatch;
   zl5011xLanRxSetContextMatchS contextMatch;
   Uint32T matchNum;

   ZL5011X_TRACE(ZL5011X_INIT_FN_ID,
         "zl5011xPacketRxLoopback: unmatched %d",
         unmatchedProtocol, 0, 0, 0, 0, 0);

   /* initialise the context match settings */
   status = zl5011xLanRxSetContextMatchStructInit(zl5011xParams, &contextMatch);

   if (status == ZL5011X_OK)
   {
      if (par->protocolType == ZL5011X_LOOPBACK_ETHERNET)
      {
         contextMatch.output.classifyHeaderOffset = ZL5011X_PKT_ETHERNET_HDR_LEN - ZL5011X_PKT_ETHERTYPE_LEN;
      }

      contextMatch.output.classifyFlow = ZL5011X_FLOW_PKT_PKT;
      contextMatch.output.classifyMpid = ZL5011X_LOOPBACK_CONTEXT_NUMBER;
      contextMatch.output.classifyLengthFromPacket = ZL5011X_TRUE;
   }

   if (unmatchedProtocol == ZL5011X_TRUE)
   {
      /* setup a classification entry for the last protocol match */
      matchNum = ZL5011X_PKC_NUM_CLASSIFY_ENTRIES - 1;
      contextMatch.match.protocolMatchNum = ZL5011X_PKC_NUM_PROTOCOL_ENTRIES - 1;

      if (status == ZL5011X_OK)
      {
         /* reserve the classification entry - to mark it as in use */
         status = zl5011xPkcClassifyGetFreeEntry(zl5011xParams, &matchNum);
      }

      if (status == ZL5011X_OK)
      {
         status = zl5011xPkcClassifySetContextMatch(zl5011xParams, ZL5011X_LOOPBACK_CONTEXT_NUMBER,
               matchNum, &contextMatch.match, &contextMatch.output);
      }

      /* setup the last protocol match, in order to match any packets that do not
         match any of the other protocol entries, to allow them to be sent back
         out of the packet Tx */

      if (status == ZL5011X_OK)
      {
         matchNum = ZL5011X_PKC_NUM_PROTOCOL_ENTRIES - 1;
         status = zl5011xPkcProtocolGetFreeEntry(zl5011xParams, &matchNum);
      }

      if (status == ZL5011X_OK)
      {
         /* set up defaults for the protocol match settings */
         status = zl5011xLanRxSetProtocolMatchStructInit(zl5011xParams, &protocolMatch);
      }

      if (status == ZL5011X_OK)
      {
         protocolMatch.output.discardUdpCheckFails = ZL5011X_FALSE;
         protocolMatch.output.protocolIpv4 = ZL5011X_FALSE;

         status = zl5011xPkcProtocolSetMatch(zl5011xParams, ZL5011X_PKC_NUM_PROTOCOL_ENTRIES - 1,
               &protocolMatch.match, &protocolMatch.output);
      }

      if (status == ZL5011X_OK)
      {
         status = zl5011xPkcProtocolEnableEntry(zl5011xParams, ZL5011X_PKC_NUM_PROTOCOL_ENTRIES - 1);
      }
   }

   return(status);
}

⌨️ 快捷键说明

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