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

📄 zl5011xinterrupts.c

📁 Zalink50114----TDMoIP芯片驱动源码
💻 C
📖 第 1 页 / 共 5 页
字号:
         intrMsg.interruptSource = ZL5011X_GRANULE_INTERRUPT;
         (void)zl5011xGmGetStatus(zl5011xParams, &(intrMsg.activeInterrupts));

         /* if the GM raises an interrupt, then it is probably going to persist,
            so disable the interrupt */
         (void)zl5011xGmDisableInterrupts(zl5011xParams, intrMsg.activeInterrupts);
         break;

      case ZL5011X_1BIT_MASK << ZL5011X_HOST_OVERFLOW_INTERRUPT:
         intrMsg.interruptSource = ZL5011X_HOST_OVERFLOW_INTERRUPT;

         (void)zl5011xCpqGetStatus(zl5011xParams, &(intrMsg.activeInterrupts));

         /* the interrupt is a threshold, so may remain asserted. Therefore, the
            only option is to clear the interrupt at the top level. The application can
            turn this int back on again after taking any corrective action */
         (void)zl5011xAdmDisableInterruptSource(zl5011xParams, ZL5011X_INTERRUPT_ZERO, ZL5011X_1BIT_MASK << admIntrBit);
         break;

      case ZL5011X_1BIT_MASK << ZL5011X_HOST_GRANULES_INTERRUPT:
         intrMsg.interruptSource = ZL5011X_HOST_GRANULES_INTERRUPT;

         /* the interrupt is a threshold, so may remain asserted. Therefore, the
            only option is to clear the interrupt at the top level. The application can
            turn this int back on again after taking any corrective action */
         (void)zl5011xAdmDisableInterruptSource(zl5011xParams, ZL5011X_INTERRUPT_ZERO, ZL5011X_1BIT_MASK << admIntrBit);
         break;

      case ZL5011X_1BIT_MASK << ZL5011X_MEMORY_PARITY_INTERRUPT:
         intrMsg.interruptSource = ZL5011X_MEMORY_PARITY_INTERRUPT;
         (void)zl5011xMmGetParityStatus(zl5011xParams, &temp8, (zl5011xBooleanE *)(&(intrMsg.activeInterrupts)));
         intrMsg.misc = (Uint32T)temp8;
         break;

      case ZL5011X_1BIT_MASK << ZL5011X_WAN_TX_ERROR_OVERFLOW_INTERRUPT:
         intrMsg.interruptSource = ZL5011X_WAN_TX_ERROR_OVERFLOW_INTERRUPT;
         break;

      case ZL5011X_1BIT_MASK << ZL5011X_WAN_TX_INFO_OVERFLOW_INTERRUPT:
         intrMsg.interruptSource = ZL5011X_WAN_TX_INFO_OVERFLOW_INTERRUPT;
         break;

      case ZL5011X_1BIT_MASK << ZL5011X_WAN_TX_QUEUE_OVERFLOW_INTERRUPT:
         intrMsg.interruptSource = ZL5011X_WAN_TX_QUEUE_OVERFLOW_INTERRUPT;
         break;

      case ZL5011X_1BIT_MASK << ZL5011X_WAN_RX_OVERFLOW_INTERRUPT:
         intrMsg.interruptSource = ZL5011X_WAN_RX_OVERFLOW_INTERRUPT;
         break;

      case ZL5011X_1BIT_MASK << ZL5011X_WAN_RX_TASK_OVERFLOW_INTERRUPT:
         intrMsg.interruptSource = ZL5011X_WAN_RX_TASK_OVERFLOW_INTERRUPT;
         break;

      case ZL5011X_1BIT_MASK << ZL5011X_HOST_DMA_RX_INTERRUPT:
         intrMsg.interruptSource = ZL5011X_HOST_DMA_RX_INTERRUPT;
         (void)zl5011xCpuDmaGetIntrStatus(zl5011xParams, &(intrMsg.activeInterrupts));

         if (zl5011xIrqDmaRxFuncEnableFlag == ZL5011X_TRUE)
         {
            if (zl5011xIrqDmaRxFunc != NULL)
            {
               (void)zl5011xIrqDmaRxFunc();

               /* processed the interrupt internally, so don't pass on to the application */
               matchedInt = ZL5011X_FALSE;
            }
         }
         break;

      default :
         matchedInt = ZL5011X_FALSE;
         break;
   }

   if (matchedInt == ZL5011X_TRUE)
   {
      /* queue the intr messages to deferred routine */
      status = zl5011xIsrQueueUpInterrupts(zl5011xParams, &intrMsg);
   }

   return status;
}

/*******************************************************************************
 Function:
    zl5011xIsrApiHandler

 Description:
   This is the ISR function for the API interrupt.


 Inputs:

 Outputs:
    none
 Returns:
   none
 Remarks:

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

void zl5011xIsrApiHandler(void)
{
   zl5011xParamsS* zl5011xParams;

   zlStatusE status = ZL5011X_OK;
   Uint32T temp, index= 0;
   Uint32T admIntrStatus= 0;
   Uint32T intContext= 0;
   Uint32T rollOverFlags= 0;
   Uint8T  portNum=0;
   zl5011xInterruptQueueDataS intr;

#ifdef _DEBUG
   Uint32T tempTraceFnFilter = 0;
   Uint32T tempTraceCtxtFnFilter = 0;
   Uint32T tempTraceCtxtFilter = 0;

   if (zl5011xTraceIsrEnable == ZL5011X_FALSE)
   {
      /* disable the trace during the interrupt handler */
      tempTraceFnFilter = zl5011xTraceFnFilter;
      tempTraceCtxtFnFilter = zl5011xTraceCtxtFnFilter;
      tempTraceCtxtFilter = zl5011xTraceCtxtFilter;

      zl5011xTraceFnFilter = 0;
      zl5011xTraceCtxtFnFilter = 0;
      zl5011xTraceCtxtFilter = 0;
   }
#endif

   ZL5011X_TRACE(ZL5011X_ISR_FN_ID, "zl5011xIsrApiHandler:", 0,0,0,0,0,0);

   for (index = 0; index <ZL5011X_ISR_MAX_NUMBER_DEVICES; index++)
   {
      zl5011xParams = zl5011xIsrDeviceTable[index];
      if (zl5011xParams != NULL)
      {
         (void)zl5011xAdmGetInterruptStatus(zl5011xParams, &admIntrStatus);

         ZL5011X_TRACE(ZL5011X_ISR_FN_ID, "zl5011xIsrApiHandler: device %u (%08X), int %08X",
               index, (Uint32T)zl5011xParams, admIntrStatus, 0, 0, 0);

         /* mask out any interrupts that are not for this interrupt pin */
         admIntrStatus &= zl5011xParams->interruptMasks.admMasks[ZL5011X_INTERRUPT_ONE];

         /* check if the PAC interrupt is active */
         if ((admIntrStatus & (ZL5011X_1BIT_MASK << ZL5011X_WAN_CLK_INTERRUPT)) != 0)
         {
            (void)zl5011xPacGetStatus(zl5011xParams, &temp);

            if ((temp & (ZL5011X_1BIT_MASK << ZL5011X_PAC_ASYNC_INT)) != 0)
            {
               if (zl5011xCetMsgQid != NULL)
               {
                  (void)zl5011xHandleCetIntr(zl5011xParams);
               }
            }

            if (zl5011xIsrAppIntNum != (Uint32T)ZL5011X_INVALID)
            {
               /* application interrupt is running so pass on any changes to the PLL status */
               if ((temp & ((ZL5011X_1BIT_MASK << ZL5011X_DPLL_LOCK_INT) |
                  (ZL5011X_1BIT_MASK << ZL5011X_DPLL_REF_CHANGE_INT) | (ZL5011X_1BIT_MASK << ZL5011X_DPLL_HOLDOVER_INT))) != 0)
               {
                  intr.interruptSource = ZL5011X_WAN_CLK_INTERRUPT;
                  intr.activeInterrupts = temp & ~(ZL5011X_1BIT_MASK << ZL5011X_PAC_ASYNC_INT);
                  intr.context = (Uint32T)ZL5011X_INVALID_CONTEXT;

                  /* retrieve the DPLL status, since the application is going to need
                     that to determine what has happened */
                  (void)zl5011xPacDpllGetStatusValue(zl5011xParams,  &(intr.misc));

                  /* send the message */
                  (void)zl5011xIsrQueueUpInterrupts(zl5011xParams, &intr);
               }
            }

            /* if the slew rate interrupt is enabled then need to mask it out, since it may
               be set again immediately. The other interrupts are status changes, so only
               need to reset the interrupt */
            if ((temp & (ZL5011X_1BIT_MASK << ZL5011X_DPLL_SLEW_RATE_INT)) != 0)
            {
               (void)zl5011xPacDisableInterrupts(zl5011xParams, ZL5011X_1BIT_MASK << ZL5011X_DPLL_SLEW_RATE_INT);
            }

            /* Now clear any interrupts that were active */
            (void)zl5011xPacClearInterrupts(zl5011xParams, temp);
         }

         /* check RTP counter interrupt */
         if ((admIntrStatus & (ZL5011X_1BIT_MASK << ZL5011X_RTP_STATS_INTERRUPT)) != 0)
         {
            /* find out which context it is for */
            status = zl5011xRtpGetInterruptStatus(zl5011xParams,
                  &intContext, &rollOverFlags);

            if (status ==ZL5011X_OK)
            {
               status = zl5011xRtpUpdateStatistics(zl5011xParams, intContext, rollOverFlags);
            }
         }

         /* check MAC interrupt */
         if ((admIntrStatus & (ZL5011X_1BIT_MASK << ZL5011X_MAC_IF_INTERRUPT)) != 0)
         {
            /* test which port */
            for( portNum= 0; portNum < zl5011xParams->devLimits.lanNumLanPorts; portNum++)
            {
             (void)zl5011xPkiUpdateCounters(zl5011xParams, portNum);
            }

            /* check if a PCS int is active */
            intr.interruptSource = ZL5011X_MAC_IF_INTERRUPT;
            (void)zl5011xPkiGetPcsStatus(zl5011xParams, &(intr.activeInterrupts));

            if (intr.activeInterrupts != 0)
            {
               /* only send a message if an interrupt is set */
               (void)zl5011xIsrQueueUpInterrupts(zl5011xParams, &intr);
            }
         }

         /* clear interrupts in this device */
         (void)zl5011xAdmClearInterruptSource( zl5011xParams, admIntrStatus);
      }
   }

#ifdef _DEBUG
   if (zl5011xTraceIsrEnable == ZL5011X_FALSE)
   {
      /* restore the trace variables now that the interrupt has finished */
      zl5011xTraceFnFilter = tempTraceFnFilter;
      zl5011xTraceCtxtFnFilter = tempTraceCtxtFnFilter;
      zl5011xTraceCtxtFilter = tempTraceCtxtFilter;
   }
#endif
}

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

 Function:
    zl5011xHandleCetIntr

 Description:
     This function is called in the Isr Task, after we established that there is this
     device in the dev table and
     the PAC interrupt mask   is set in the ADM block and
     the PAC interrupt status is set in the ADM.

     It sends messages to the CET task using its message queue, after checking
     in PAC that relevant mask bit is enabled and relevant status bit set.

 Inputs:
   zl5011xParams      Pointer to the structure for this device instance

 Outputs:

 Returns:
    zlStatusE

 Remarks:

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

static zlStatusE zl5011xHandleCetIntr(zl5011xParamsS *zl5011xParams)
{
   zlStatusE status= ZL5011X_OK;

   if (OS_MSG_Q_SEND(zl5011xCetMsgQid, (char *)&zl5011xParams, sizeof(zl5011xParamsS *),
         OS_NO_WAIT, 0) == OS_ERROR)
   {
       status= ZL5011X_ERROR;
       ZL5011X_TRACE(ZL5011X_ISR_FN_ID, "zl5011xHandleCetIntr: ERROR queueing",
                     0,0,0,0,0,0);
   }

   return status;
}

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

 Function:
    zl5011xIsrIsRunning

 Description:
   This function can be called to verify that the ISR is running.

 Inputs:
   none

 Outputs:
   pFlag    ZL5011X_TRUE for ISR Started and ZL5011X_FALSE for not started.

 Returns:
    zlStatusE

 Remarks:

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

zlStatusE zl5011xIsrIsRunning(zl5011xBooleanE *pFlag)
{
   if (zl5011xIsrApiIntNum == (Uint32T)ZL5011X_INVALID)
   {
      *pFlag = ZL5011X_FALSE;
   }
   else
   {
      *pFlag = ZL5011X_TRUE;
   }

   return ZL5011X_OK;
}

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

 Function:
    zl5011xIsrCheckDevice

 Description:
   This function can be called to verify that the application ISR is running
   for the given device.

 Inputs:
   zl5011xParams   Pointer to the structure for this device instance

 Outputs:
   pFlag          ZL5011X_TRUE for ISR Started and ZL5011X_FALSE for not started.

 Returns:
    zlStatusE

 Remarks:

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

zlStatusE zl5011xIsrCheckDevice(zl5011xParamsS *zl5011xParams, zl5011xBooleanE *pFlag)
{
   zlStatusE status= ZL5011X_OK;

   if (zl5011xIsrAppIntNum == (Uint32T)ZL5011X_INVALID)
   {
      *pFlag = ZL5011X_FALSE;
   }
   else
   {
      Uint32T index;

      /* check if the device is listed in the interrupt service table */
      for (index = 0; index < ZL5011X_ISR_MAX_NUMBER_DEVICES; index++)
      {
         if(zl5011xIsrDeviceTable[index] == zl5011xParams)
         {
            *pFlag = ZL5011X_TRUE;
            break;
         }
      }
   }

   return status;
}

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

 Function:
    zl5011xIsrSetCetQueueid

 Description:
     This function is called by the CET code to give the local static CET Queue ID a
     new val

⌨️ 快捷键说明

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