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

📄 xemac_intr_dma.c

📁 powerpc405开发板的linux网口驱动程序
💻 C
📖 第 1 页 / 共 4 页
字号:
    }    return XST_SUCCESS;}/*****************************************************************************//**** Give the driver the memory space to be used for the scatter-gather DMA* receive descriptor list. This function should only be called once, during* initialization of the Ethernet driver. The memory space must be big enough* to hold some number of descriptors, depending on the needs of the system.* The xemac.h file defines minimum and default numbers of descriptors* which can be used to allocate this memory space.** The memory space must be 32-bit aligned. An assert will occur if asserts* are turned on and the memory is not aligned.** @param InstancePtr is a pointer to the XEmac instance to be worked on.* @param MemoryPtr is a pointer to the aligned memory.* @param ByteCount is the length, in bytes, of the memory space.** @return** - XST_SUCCESS if the space was initialized successfully* - XST_NOT_SGDMA if the MAC is not configured for scatter-gather DMA* - XST_DMA_SG_LIST_EXISTS if this list space has already been created** @note** If the device is configured for scatter-gather DMA, this function must be* called AFTER the XEmac_Initialize() function because the DMA channel* components must be initialized before the memory space is set.*******************************************************************************/XStatus XEmac_SetSgRecvSpace(XEmac *InstancePtr, Xuint32 *MemoryPtr,                             Xuint32 ByteCount){    XASSERT_NONVOID(InstancePtr != NULL);    XASSERT_NONVOID(MemoryPtr != NULL);    XASSERT_NONVOID(ByteCount != 0);    XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);    if (!XEmac_mIsSgDma(InstancePtr))    {        return XST_NOT_SGDMA;    }    return XDmaChannel_CreateSgList(&InstancePtr->RecvChannel, MemoryPtr,                                    ByteCount);}/*****************************************************************************//**** Give the driver the memory space to be used for the scatter-gather DMA* transmit descriptor list. This function should only be called once, during* initialization of the Ethernet driver. The memory space must be big enough* to hold some number of descriptors, depending on the needs of the system.* The xemac.h file defines minimum and default numbers of descriptors* which can be used to allocate this memory space.** The memory space must be 32-bit aligned. An assert will occur if asserts* are turned on and the memory is not aligned.** @param InstancePtr is a pointer to the XEmac instance to be worked on.* @param MemoryPtr is a pointer to the aligned memory.* @param ByteCount is the length, in bytes, of the memory space.** @return** - XST_SUCCESS if the space was initialized successfully* - XST_NOT_SGDMA if the MAC is not configured for scatter-gather DMA* - XST_DMA_SG_LIST_EXISTS if this list space has already been created** @note** If the device is configured for scatter-gather DMA, this function must be* called AFTER the XEmac_Initialize() function because the DMA channel* components must be initialized before the memory space is set.*******************************************************************************/XStatus XEmac_SetSgSendSpace(XEmac *InstancePtr, Xuint32 *MemoryPtr,                             Xuint32 ByteCount){    XASSERT_NONVOID(InstancePtr != NULL);    XASSERT_NONVOID(MemoryPtr != NULL);    XASSERT_NONVOID(ByteCount != 0);    XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);    if (!XEmac_mIsSgDma(InstancePtr))    {        return XST_NOT_SGDMA;    }    return XDmaChannel_CreateSgList(&InstancePtr->SendChannel, MemoryPtr,                                    ByteCount);}/*****************************************************************************//**** Return the number of free buffer descriptor slots that can be added to the* send descriptor ring with XEmac_SgSend() before filling it up.** @param InstancePtr is a pointer to the XEmac instance to be worked on.** @return** - The number of descriptors that can be given to the HW with XEmac_SgSend()* - 0 if no room is left or the device is not configured for SG DMA** @note** None.*******************************************************************************/unsigned XEmac_GetSgSendFreeDesc(XEmac *InstancePtr){    unsigned Slots;    XASSERT_NONVOID(InstancePtr != NULL);    XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);    Slots = InstancePtr->SendChannel.TotalDescriptorCount -        InstancePtr->SendChannel.ActiveDescriptorCount;    return Slots;}/*****************************************************************************//**** Return the number of free buffer descriptor slots that can be added to the* receive descriptor ring with XEmac_SgRecv() before filling it up.** @param InstancePtr is a pointer to the XEmac instance to be worked on.** @return** - The number of descriptors that can be given to the HW with XEmac_SgRecv()* - 0 if no room is left or the device is not configured for SG DMA** @note** None.*******************************************************************************/unsigned XEmac_GetSgRecvFreeDesc(XEmac *InstancePtr){    unsigned Slots;    XASSERT_NONVOID(InstancePtr != NULL);    XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);    Slots = InstancePtr->RecvChannel.TotalDescriptorCount -        InstancePtr->RecvChannel.ActiveDescriptorCount;    return Slots;}/*****************************************************************************//**** Set the callback function for handling received frames in scatter-gather DMA* mode.  The upper layer software should call this function during* initialization.  The callback is called once per frame received. The head of* a descriptor list is passed in along with the number of descriptors in the* list. Before leaving the callback, the upper layer software should attach a* new buffer to each descriptor in the list.** The callback is invoked by the driver within interrupt context, so it needs* to do its job quickly. Sending the received frame up the protocol stack* should be done at task-level. If there are other potentially slow operations* within the callback, these too should be done at task-level.** @param InstancePtr is a pointer to the XEmac instance to be worked on.* @param CallBackRef is a reference pointer to be passed back to the adapter in*        the callback. This helps the adapter correlate the callback to a*        particular driver.* @param FuncPtr is the pointer to the callback function.** @return** None.** @note** None.*******************************************************************************/void XEmac_SetSgRecvHandler(XEmac *InstancePtr, void *CallBackRef,                            XEmac_SgHandler FuncPtr){    /*     * Asserted IsDmaSg here instead of run-time check because there is really     * no ill-effects of setting these when not configured for scatter-gather.     */    XASSERT_VOID(InstancePtr != XNULL);    XASSERT_VOID(FuncPtr != XNULL);    XASSERT_VOID(XEmac_mIsSgDma(InstancePtr));    XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);    InstancePtr->SgRecvHandler = FuncPtr;    InstancePtr->SgRecvRef = CallBackRef;}/*****************************************************************************//**** Set the callback function for handling confirmation of transmitted frames in* scatter-gather DMA mode.  The upper layer software should call this function* during initialization.  The callback is called once per frame sent. The head* of a descriptor list is passed in along with the number of descriptors in* the list. The callback is responsible for freeing buffers attached to these* descriptors.** The callback is invoked by the driver within interrupt context, so it needs* to do its job quickly. If there are potentially slow operations within the* callback, these should be done at task-level.** @param InstancePtr is a pointer to the XEmac instance to be worked on.* @param CallBackRef is a reference pointer to be passed back to the adapter in*        the callback. This helps the adapter correlate the callback to a*        particular driver.* @param FuncPtr is the pointer to the callback function.** @return** None.** @note** None.*******************************************************************************/void XEmac_SetSgSendHandler(XEmac *InstancePtr, void *CallBackRef,                            XEmac_SgHandler FuncPtr){    /*     * Asserted IsDmaSg here instead of run-time check because there is really     * no ill-effects of setting these when not configured for scatter-gather.     */    XASSERT_VOID(InstancePtr != XNULL);    XASSERT_VOID(FuncPtr != XNULL);    XASSERT_VOID(XEmac_mIsSgDma(InstancePtr));    XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);    InstancePtr->SgSendHandler = FuncPtr;    InstancePtr->SgSendRef = CallBackRef;}/*****************************************************************************//*** Handle an interrupt from the DMA receive channel. DMA interrupts are:** - DMA error. DMA encountered a bus error or timeout. This is a fatal error*   that requires reset of the channel.  The driver calls the error handler*   of the upper layer software with an error code indicating the device should*   be reset.* - Packet count threshold reached.  For scatter-gather operations, indicates*   the threshold for the number of packets not serviced by software has been*   reached. The driver behaves as follows:*       - Get the value of the packet counter, which tells us how many packets*         are ready to be serviced*       - For each packet*           - For each descriptor, remove it from the scatter-gather list*           - Check for the last descriptor in the frame, and if set*               - Bump frame statistics*               - Decrement the packet counter by one*       - Call the scatter-gather receive callback function*       Note that there are no receive errors reported in the status word of*       the buffer descriptor.  If receive errors occur, the MAC drops the*       packet, and we only find out about the errors through various error*       count registers.* - Packet wait bound reached.  For scatter-gather, indicates the time to wait*   for the next packet has expired.  The driver follows the same logic as when*   the packet count threshold interrupt is received.* - Scatter-gather end acknowledge.  Hardware has reached the end of the*   descriptor list.  The driver follows the same logic as when the packet count*   threshold interrupt is received. In addition, the driver restarts the DMA*   scatter-gather channel in case there are newly inserted descriptors.** @param InstancePtr is a pointer to the XEmac instance to be worked on.** @return** Although the function returns void, there are asynchronous errors that can* be generated (by calling the ErrorHandler) from this function.  These are:* - XST_DMA_SG_LIST_EMPTY indicates we tried to get a buffer descriptor from the*   DMA channel, but there was not one ready for software.* - XST_DMA_ERROR indicates a DMA bus error or timeout occurred. This is a fatal*   error that requires reset.** @note** None.*******************************************************************************/static void HandleDmaRecvIntr(XEmac *InstancePtr){    XStatus Result;    Xuint32 IntrStatus;    Xuint32 NumBds;    Xuint32 PacketsLeft;    XBufDescriptor *BdHeadPtr;    XBufDescriptor *BdPtr;    /*     * Read the interrupt status     */    IntrStatus = XDmaChannel_GetIntrStatus(&InstancePtr->RecvChannel);    /*     * For packet threshold or wait bound interrupts, process desciptors. Also     * process descriptors on a SG end acknowledgement, which means the end of     * the descriptor list has been reached by the hardware. For receive, this     * is potentially trouble since it means the descriptor list is full,     * unless software can process enough packets quickly enough so the     * hardware has room to put new packets.     */    if (IntrStatus & (XDC_IXR_PKT_THRESHOLD_MASK |        XDC_IXR_PKT_WAIT_BOUND_MASK | XDC_IXR_SG_END_MASK))    {        /* Get the number of packets that need processing */        PacketsLeft = XDmaChannel_GetPktCount(&InstancePtr->RecvChannel);        if (PacketsLeft)        {            /* Get the buffer descriptor at the head of the list */            Result = XDmaChannel_GetDescriptor(&InstancePtr->RecvChannel,                                               &BdHeadPtr);            BdPtr = BdHeadPtr;            NumBds = 0;            /* Loop until all packets have been pulled or an error occurs */            while(1)            {                NumBds++;                /*                 * An error getting a buffer descriptor from the list.                 * This should not happen, but if it does, report it to                 * the error callback and break out of the loop to service                 * other interrupts.                 */                if (Result != XST_SUCCESS)                {                    InstancePtr->ErrorHandler(InstancePtr->ErrorRef, Result);

⌨️ 快捷键说明

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