?? zl5011xinterrupts.c
字號:
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 + -