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

📄 zl5011xlan.c

📁 Zalink50114----TDMoIP芯片驱动源码
💻 C
📖 第 1 页 / 共 5 页
字号:
      for (loop = 0; loop < ZL5011X_PKC_CLASSIFY_NUM_MATCH_FIELDS; loop++)
      {
         /* default the classify match and mask bytes to the first byte in the header,
            and to match on anything */
         par->match.classifyMatchBytes[loop] = 0;
         par->match.classifyMaskBytes[loop] = 0xff;
      }

      for (loop = 0; loop < ZL5011X_PKC_CLASSIFY_NUM_CHECK_FIELDS; loop++)
      {
         /* default the check bytes to 0 */
         par->match.classifyCheckBytes[loop] = 0;
      }

      /* reset all of the entries in the output part of the structure */
      par->output.classifyFlow = (zl5011xFlowTypeE)ZL5011X_INVALID;
      par->output.classifyMpid = (Uint32T)ZL5011X_INVALID_CONTEXT;
      par->output.classifyHeaderOffset = 0;
      par->output.classifyLengthModifier = 0;
      par->output.classifyLengthNoCalc = ZL5011X_TRUE;
      par->output.classifyTwoByteLength = ZL5011X_TRUE;
      par->output.classifyLengthFromPacket = ZL5011X_FALSE;

      par->osExclusionEnable = ZL5011X_TRUE;
   }

   return status;
}

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

 Function:
   zl5011xLanRxSetContextMatch

 Description:
   This function sets a match in the packet Rx for a context. There are two
   possible matches that can be assigned to a context - that is one for each
   state of the context switch bit in the TFM.

   When using the CD header for classification, the following sequence is
   required:
    * TFM context is created - context switch bit can be either 0 or 1 for
      first message to TFM.
    * Set header for the context - this will use header 0, and set the context
      switch bit to 0.
      (NOTE : this context switch bit state DOES NOT necessarily map to the
      state of the bit in the actual ethernet header)
    * Add next header - with context switch bit the other way up in the header
      (this will use header 1).
    * When the context is updated and then taken, the 2 headers will be
      examined to determine which is in use and the state variable for each
      updated

 Inputs:
   zl5011xParams   Pointer to the structure for this device instance
   par            Pointer to the structure for configuration items. See below:

 Structure inputs:
   context        which context to use
   matchNum       which classification match to use - can be set to
                  ZL5011X_INVALID, and any available match will be found
   match          structure to hold settings for the context match and check
   output         structure to hold settings for use once the context has been
                  identified.
   osExclusionEnable ZL5011X_TRUE to enable OS exclusion

 Structure outputs:
   None

 Returns:
   zlStatusE

 Remarks:
   None

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

zlStatusE zl5011xLanRxSetContextMatch(zl5011xParamsS *zl5011xParams,
      zl5011xLanRxSetContextMatchS *par)
{
   zlStatusE status = ZL5011X_OK;
   zl5011xBooleanE assignedMatch = ZL5011X_FALSE;
   Uint8T selHeader = 0;
   zl5011xBooleanE gotDevice = ZL5011X_FALSE;
   zl5011xBooleanE foundHeader;    /* Flag for whether we have a free header */

   /* do some parameter checking */
   status = ZL5011X_CHECK_POINTERS(zl5011xParams, par);

   if (status == ZL5011X_OK)
   {
      status = ZL5011X_CHECK_RUNNING(zl5011xParams);
   }

   if ((status == ZL5011X_OK) && (par->osExclusionEnable == ZL5011X_TRUE))
   {
      /* get access to the device */
      status = zl5011xGetDevice(zl5011xParams, ZL5011X_GET_DEVICE_TIMEOUT_MODE);

      if (status == ZL5011X_OK)
      {
         gotDevice = ZL5011X_TRUE;
      }
   }

   /* check that the Wan Tx context is valid */
   if (status == ZL5011X_OK)
   {
      status = zl5011xContextCheckTx(zl5011xParams, par->context, ZL5011X_CHECK_CONTEXT_MODIFY);
   }

   /* main function code starts */


   if (status ==ZL5011X_OK)
   {
      ZL5011X_TRACE_CONTEXT(ZL5011X_LAN_FN_ID, par->context,
        "zl5011xLanRxSetContextMatch: ctxt %3d",
        par->context, 0, 0, 0, 0, 0);


      /* See if there is a free context match associated with this context */
      selHeader = 0;
      foundHeader = ZL5011X_FALSE;
      /* Look at the first context match to see if it is available */
      if ((zl5011xParams->packetIf.packetRx.contextRxPacketMatch[par->context].contextMatchState[selHeader] == ZL5011X_PKC_STATE_MATCH_NOT_ALLOCATED) ||
          (zl5011xParams->packetIf.packetRx.contextRxPacketMatch[par->context].contextMatchState[selHeader] == ZL5011X_PKC_STATE_MATCH_UNUSED))
      {
         foundHeader = ZL5011X_TRUE;
      }
      else
      {  /* First context match  not available so look at the second if it has one.
            Lan-to-lan contexts only have one possible context match, others have two */
         if (zl5011xParams->packetIf.lanLanContext[par->context] != ZL5011X_TRUE)
         {
            selHeader++;
            if ((zl5011xParams->packetIf.packetRx.contextRxPacketMatch[par->context].contextMatchState[selHeader] == ZL5011X_PKC_STATE_MATCH_NOT_ALLOCATED) ||
                (zl5011xParams->packetIf.packetRx.contextRxPacketMatch[par->context].contextMatchState[selHeader] == ZL5011X_PKC_STATE_MATCH_UNUSED))
            {
               foundHeader = ZL5011X_TRUE;
            }
         }
      }
      /* Check whether we found one or not */
      if (foundHeader == ZL5011X_FALSE)
      {
         status = ZL5011X_PKT_HEADER_IN_USE;
      }
   }

   if (status ==ZL5011X_OK)
   {
      /* if the context already has a match allocated but not enabled, then check
         that it is consistent with the one requested */
      if (zl5011xParams->packetIf.packetRx.contextRxPacketMatch[par->context].contextMatchState[selHeader] == ZL5011X_PKC_STATE_MATCH_UNUSED)
      {
         /* this context match rule is allocated but not in use, so use for this setup, provided the match number requested is okay */
         if (par->matchNum == (Uint32T)ZL5011X_INVALID)
         {
            /* automatically allocate a match, so take the one from the device structure */
            par->matchNum = zl5011xParams->packetIf.packetRx.contextRxPacketMatch[par->context].pkcClassifyMatchNum[selHeader];
         }
         else
         {  /* Caller requested a specific match number.  Check that the requested number is the same as the one
               already allocated */
            if (par->matchNum != zl5011xParams->packetIf.packetRx.contextRxPacketMatch[par->context].pkcClassifyMatchNum[selHeader])
            {
               status = ZL5011X_PKT_INVALID_MATCH_NUM;
            }
         }
      }
   }

   /* reserve the match entry in the pkc classifier */
   if (status == ZL5011X_OK)
   {
      status = zl5011xPkcClassifyGetFreeEntry(zl5011xParams, &(par->matchNum));

      /* if there are no available matches in the PKC classifier, then go
         through and purge any unused matches and try again */
      if (status == ZL5011X_NO_AVAIL_CLASSIFY_MATCH)
      {
         /* setting the context number to ZL5011X_INVALID for this function
            call forces the check for unused matches to take place on
            all contexts */
         status = zl5011xLanRxPurgeContextHeaders(zl5011xParams, (Uint32T)ZL5011X_INVALID);

         if (status == ZL5011X_OK)
         {
            /* some matches should have been free'd up so try again */
            status = zl5011xPkcClassifyGetFreeEntry(zl5011xParams, &(par->matchNum));
         }
      }

      /* if a match has been reserved then remember, so that it can be
         free'd up if things go wrong */
      if (status == ZL5011X_OK)
      {
         assignedMatch = ZL5011X_TRUE;
      }
      else
      {
         /* if the classifier match had already been allocated and used by this header
            then just continue, but disable the entry before re-programming it. */
         if (status == ZL5011X_CLASSIFY_MATCH_IN_USE)
         {
            if (par->matchNum == zl5011xParams->packetIf.packetRx.contextRxPacketMatch[par->context].pkcClassifyMatchNum[selHeader])
            {
               status = zl5011xPkcClassifyDisableEntry(zl5011xParams, par->matchNum);
            }
         }
      }
   }

   /* setup the classifier match */
   if (status == ZL5011X_OK)
   {
      if (par->output.classifyMpid == (Uint32T)ZL5011X_INVALID)
      {
         /* if the mpid hasn't been explicitly set, then set the MPID field to
            represent the context number */
         par->output.classifyMpid = (par->context & ZL5011X_PKC_CLASSIFY_CONTEXT_MASK);

         /* Add in the state of the context switch bit, but don't allow context switches
            if this is a lan-to-lan context */
         if (zl5011xParams->packetIf.lanLanContext[par->context] != ZL5011X_TRUE)
         {
            par->output.classifyMpid |= ((selHeader & ZL5011X_1BIT_MASK) << ZL5011X_PKC_CLASSIFY_CONTEXT_SWITCH_BIT);
         }
      }

      if (par->output.classifyFlow == (zl5011xFlowTypeE)ZL5011X_INVALID)
      {
         /* if the flow hasn't been explicitly set, then use the value
            as set during context creation */
         par->output.classifyFlow = zl5011xParams->wanIf.wanTxFlow[par->context];
      }

      status = zl5011xPkcClassifySetContextMatch(zl5011xParams,
            par->context, par->matchNum, &(par->match), &(par->output));
   }

   /* enable the classifier match if it has been set up successfully */
   if (status == ZL5011X_OK)
   {
      if (zl5011xParams->packetIf.lanLanContext[par->context] != ZL5011X_TRUE)
      {
         /* This is not a Lan-to-Lan context so enable the classifier rule immediately */
         status = zl5011xPkcClassifyEnableEntry(zl5011xParams, par->matchNum);
         zl5011xParams->packetIf.classifierEnablePending[par->context] = ZL5011X_FALSE;

        /* Set state of the new header to indicate it will become active on next context switch */
         zl5011xParams->packetIf.packetRx.contextRxPacketMatch[par->context].contextMatchState[selHeader] = ZL5011X_PKC_STATE_MATCH_NEW_UPDATING;
         zl5011xParams->packetIf.packetRx.contextRxPacketMatch[par->context].pkcClassifyMatchNum[selHeader] = par->matchNum;

         /* Set the state of the other header to indicate it is going to become inactive */
         if (zl5011xParams->packetIf.packetRx.contextRxPacketMatch[par->context].contextMatchState[selHeader ^ 1] == ZL5011X_PKC_STATE_MATCH_ACTIVE)
         {
            zl5011xParams->packetIf.packetRx.contextRxPacketMatch[par->context].contextMatchState[selHeader ^ 1] = ZL5011X_PKC_STATE_MATCH_OLD_UPDATING;
         }
      }
      else
      {
         /* This is a Lan-to-Lan context so don't call zl5011xPkcClassifyEnableEntry
            but delay it until zl5011xLanLanContextUpdate is called. This allows both
            packet Rx and packet Tx to be configured before the classification rule
            might start to generate traffic. */
         zl5011xParams->packetIf.classifierEnablePending[par->context] = ZL5011X_TRUE;

         /* Set state of the context match to indicate it is being updated */
         zl5011xParams->packetIf.packetRx.contextRxPacketMatch[par->context].contextMatchState[selHeader] = ZL5011X_PKC_STATE_MATCH_NEW_UPDATING;
         zl5011xParams->packetIf.packetRx.contextRxPacketMatch[par->context].pkcClassifyMatchNum[selHeader] = par->matchNum;
      }
   }
   else
   {
      /* failed, so free up the match number if it was allocated by this
         function */
      if (assignedMatch == ZL5011X_TRUE)
      {
         /* ignore the return code, since we already have an error. Just
            recover as best as possible */
         (void)zl5011xPkcClassifyDeleteEntry(zl5011xParams, par->matchNum);
      }
   }

   if (gotDevice == ZL5011X_TRUE)
   {
      if (status == ZL5011X_OK)
      {
         status = zl5011xReleaseDevice(zl5011xParams);
      }
      else
      {
         /* already have an error code, so don't overwrite it */
         (void)zl5011xReleaseDevice(zl5011xParams);
      }
   }

   return status;
}

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

 Function:
    zl5011xLanRxDeleteContextMatchStructInit

 Description:
   Initialises structure used by zl5011xLanRxDeleteContextMatch function.

 Inputs:
   zl5011xParams   Pointer to the structure for this device instance
   par            Pointer to the structure for configuration items.
                  See main function

 Returns:
   zlStatusE

 Remarks:
    None

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

zlStatusE zl5011xLanRxDeleteContextMatchStructInit(zl5011xParamsS *zl5011xParams,
      zl5011xLanRxDeleteContextMatchS *par)
{
   zlStatusE status = ZL5011X_OK;

   /* do some parameter checking */
   status = ZL5011X_CHECK_POINTERS(zl5011xParams, par);

   /* main function code starts */

   if (status == ZL5011X_OK)
   {
      ZL5011X_TRACE(ZL5011X_LAN_FN_ID,
            "zl5011xLanRxDeleteContextMatchStructInit:",
            0, 0, 0, 0, 0, 0);

      par->context = (Uint32T)ZL5011X_INVALID_CONTEXT;

      par->osExclusionEnable = ZL5011X_TRUE;
   }

   return status;
}

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

 Function:
   zl5011xLanRxDeleteContextMatch

 Description:
   This deletes any unused packet Rx matches attached to a context

 Inputs:
   zl5011xParams   Pointer to the structure for this device instance
   par            Pointer to the structure for configuration items. See below:

 Structure inputs:
   context        which context to use
   osExclusionEnable ZL5011X_TRUE to enable OS exclusion

 Structure outputs:
   None

 Returns:
   zlStatusE

 Remarks:
   None

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

zlStatusE zl5011xLanRxDeleteContextMatch(zl5011xParamsS *zl5011xParams,
      zl5011xLanRxDeleteContextMatchS *par)
{
   zlStatusE status = ZL5011X_OK;
   Uint8T hdrLoop = 0;
   zl5011xBooleanE gotDevice = ZL5011X_FALSE;

   /* do some parameter checking */
   status = ZL5011X_CHECK_POINTERS(zl5011xParams, par);

   if (status == ZL5011X_OK)
   {
      status = ZL5011X_CHECK_RUNNING(zl5011xParams);
   }

   if ((status == ZL5011X_OK) && (par->osEx

⌨️ 快捷键说明

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