📄 xtemac_intr_sgdma.c
字号:
} /* Set HW */ if (Direction == XTE_SEND) { (void)XDmaV3_SgSetPktThreshold(&InstancePtr->SendDma, Threshold); XDmaV3_SgSetPktWaitbound(&InstancePtr->SendDma, Timer); } else if (Direction == XTE_RECV) { (void)XDmaV3_SgSetPktThreshold(&InstancePtr->RecvDma, Threshold); XDmaV3_SgSetPktWaitbound(&InstancePtr->RecvDma, Timer); } else { return(XST_INVALID_PARAM); } return(XST_SUCCESS);}/*****************************************************************************//**** Get the current interrupt coalescing settings. See xtemac.h for more* discussion of interrupt coalescing features.** @param InstancePtr is a pointer to the instance to be worked on.* @param Direction indicates the channel, XTE_SEND or XTE_RECV, to get.* @param ThresholdPtr is a pointer to the word into which the current value of* the packet threshold will be copied.* @param TimerPtr is a pointer to the word into which the current value of the* waitbound timer will be copied.** @return* - XST_SUCCESS if the packet threshold was retrieved successfully* - XST_NO_FEATURE if the MAC is not configured for scatter-gather DMA* - XST_INVALID_PARAM if Direction does not indicate a valid channel*******************************************************************************/XStatus XTemac_IntrSgCoalGet(XTemac *InstancePtr, u32 Direction, u16 *ThresholdPtr, u16 *TimerPtr){ XASSERT_NONVOID(InstancePtr != NULL); XASSERT_NONVOID(ThresholdPtr != NULL); XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); /* Must be SGDMA */ if (!XTemac_mIsSgDma(InstancePtr)) { return(XST_NO_FEATURE); } /* Get data from HW */ if (Direction == XTE_SEND) { *ThresholdPtr = XDmaV3_SgGetPktThreshold(&InstancePtr->SendDma); *TimerPtr = XDmaV3_SgGetPktWaitbound(&InstancePtr->SendDma); } else if (Direction == XTE_RECV) { *ThresholdPtr = XDmaV3_SgGetPktThreshold(&InstancePtr->RecvDma); *TimerPtr = XDmaV3_SgGetPktWaitbound(&InstancePtr->RecvDma); } else { return(XST_INVALID_PARAM); } return(XST_SUCCESS);}/*****************************************************************************//*** Master interrupt handler for SGDMA frame transfer mode. This routine will* query the status of the device, bump statistics, and invoke user callbacks* in the following priority:** This routine must be connected to an interrupt controller using OS/BSP* specific methods.** @param InstancePtr is a pointer to the TEMAC instance that has caused the* interrupt.*******************************************************************************/void XTemac_IntrSgHandler(void *TemacPtr){ u32 RegDISR; u32 CorePending = 0; u32 RegDmaPending; XTemac *InstancePtr = (XTemac*)TemacPtr; XASSERT_VOID(InstancePtr != NULL); /* This ISR will try to handle as many interrupts as it can in a single * call. However, in most of the places where the user's error handler is * called, this ISR exits because it is expected that the user will reset * the device in nearly all instances. */ /* Log interrupt */ XTemac_mBumpStats(Interrupts, 1); /* Get top level interrupt status */ RegDISR = XTemac_mGetIpifReg(XTE_DISR_OFFSET); /* IPIF transaction or data phase error */ if (RegDISR & (XTE_DXR_DPTO_MASK | XTE_DXR_TERR_MASK)) { XTemac_mBumpStats(IpifErrors, 1); ERR_HANDLER(XST_IPIF_ERROR, RegDISR, 0); return; } /* Handle core interupts */ if (RegDISR & XTE_DXR_CORE_MASK) { /* Get currently pending core interrupts */ CorePending = XTemac_mGetIpifReg(XTE_IPIER_OFFSET) & XTemac_mGetIpifReg(XTE_IPISR_OFFSET); /* Check for fatal status/length FIFO errors. These errors can't be * cleared */ if (CorePending & XTE_IPXR_FIFO_FATAL_ERROR_MASK) { XTemac_mBumpStats(FifoErrors, 1); ERR_HANDLER(XST_FIFO_ERROR, CorePending & XTE_IPXR_FIFO_FATAL_ERROR_MASK, 0); return; } /* Check for SGDMA receive interrupts */ if (CorePending & XTE_IPXR_RECV_DMA_MASK) { RegDmaPending = XDmaV3_GetInterruptStatus(&InstancePtr->RecvDma) & XDmaV3_GetInterruptEnable(&InstancePtr->RecvDma); XDmaV3_SetInterruptStatus(&InstancePtr->RecvDma, RegDmaPending); /* Check for errors */ if (RegDmaPending & XDMAV3_IPXR_DE_MASK) { XDmaV3_SetInterruptStatus(&InstancePtr->RecvDma, XDMAV3_IPXR_DE_MASK); XTemac_mBumpStats(RxDmaErrors, 1); ERR_HANDLER(XST_DMA_ERROR, XTE_RECV, XDmaV3_mGetStatus(&InstancePtr->RecvDma)); return; } /* Check for packets processed */ if (RegDmaPending & (XDMAV3_IPXR_PCTR_MASK | XDMAV3_IPXR_PWBR_MASK | XDMAV3_IPXR_SGEND_MASK)) { /* Invoke the user's receive handler. The handler may remove the * ready BDs from the list right away or defer until later */ SGRECV_HANDLER(); } } /* Check for SGDMA transmit interrupts */ if (CorePending & XTE_IPXR_XMIT_DMA_MASK) { RegDmaPending = XDmaV3_GetInterruptStatus(&InstancePtr->SendDma) & XDmaV3_GetInterruptEnable(&InstancePtr->SendDma); XDmaV3_SetInterruptStatus(&InstancePtr->SendDma, RegDmaPending); /* Check for errors */ if (RegDmaPending & XDMAV3_IPXR_DE_MASK) { XDmaV3_SetInterruptStatus(&InstancePtr->SendDma, XDMAV3_IPXR_DE_MASK); XTemac_mBumpStats(TxDmaErrors, 1); ERR_HANDLER(XST_DMA_ERROR, XTE_SEND, XDmaV3_mGetStatus(&InstancePtr->SendDma)); return; } /* Check for packets processed */ if (RegDmaPending & (XDMAV3_IPXR_PCTR_MASK | XDMAV3_IPXR_PWBR_MASK | XDMAV3_IPXR_SGEND_MASK)) { /* Invoke the user's send handler. The handler may remove the * ready BDs from the list right away or defer until later */ SGSEND_HANDLER(); } } /* Auto negotiation interrupt */ if (CorePending & XTE_IPXR_AUTO_NEG_MASK) { ANEG_HANDLER(); } /* Check for dropped receive frame. Ack the interupt then call the * error handler */ if (CorePending & XTE_IPXR_RECV_DROPPED_MASK) { XTemac_mBumpStats(RxRejectErrors, 1); ERR_HANDLER(XST_RECV_ERROR, CorePending & XTE_IPXR_RECV_DROPPED_MASK, 0); /* no return here, nonfatal error */ } } /* Ack core top level interrupt status */ XTemac_mSetIpifReg(XTE_IPISR_OFFSET, CorePending); XTemac_mSetIpifReg(XTE_DISR_OFFSET, RegDISR);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -