📄 xtemac_sgdma.c
字号:
/* $Id: *//******************************************************************************** XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"* AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND* SOLUTIONS FOR XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE,* OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,* APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION* THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,* AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE* FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY* WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE* IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR* REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF* INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS* FOR A PARTICULAR PURPOSE.** (c) Copyright 2005-2006 Xilinx Inc.* All rights reserved.* This program is free software; you can redistribute it and/or modify it* under the terms of the GNU General Public License as published by the* Free Software Foundation; either version 2 of the License, or (at your* option) any later version.** You should have received a copy of the GNU General Public License* along with this program; if not, write to the Free Software* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA*******************************************************************************//*****************************************************************************//** * * @file xtemac_sgdma.c * * Functions in this file implement scatter-gather DMA frame transfer mode. * See xtemac.h for a detailed description of the driver. * * <pre> * MODIFICATION HISTORY: * * Ver Who Date Changes * ----- ---- -------- ------------------------------------------------------- * 1.00a rmm 06/01/05 First release * 2.00a rmm 11/21/05 Switched to local link DMA driver * rmm 06/22/06 Fixed C++ compiler warnings * * </pre> * ******************************************************************************//***************************** Include Files *********************************/#include "xtemac.h"#include "xtemac_i.h"#include "xdmav3_l.h"/************************** Constant Definitions *****************************//**************************** Type Definitions *******************************//***************** Macros (Inline Functions) Definitions *********************//************************** Variable Definitions *****************************//************************** Function Prototypes ******************************//*****************************************************************************//** * Allocate a set of BDs from the given SGDMA channel. It is expected the user * will attach buffers and set other DMA transaction parameters to the returned * BDs in preparation to calling XTemac_SgCommit(). The set of BDs returned is * a list starting with the BdPtr and extending for NumBd BDs. The list can be * navigated with macros XTemac_mSgRecvBdNext() for the XTE_RECV channel, and * XTemac_mSgSendBdNext() for the XTE_SEND channel. * * The BDs returned by this function are a segment of the BD ring maintained * by the SGDMA driver. Do not modify BDs past the end of the returned list. * Doing so will cause data corruption and may lead to system instability. * * This function and XTemac_SgCommit() must be called in the correct order. See * xtemac.h for more information on the SGDMA use model. * * @param InstancePtr is a pointer to the instance to be worked on. * @param Direction is the channel to address (XTE_SEND or XTE_RECV). * @param NumBd is the number of BDs to allocate. * @param BdPtr is an output parameter, it points to the first BD in the * returned list. * * @return * - XST_SUCCESS if the requested number of BDs was returned. * - XST_INVALID_PARAM if Direction did not specify a valid channel. * - XST_FAILURE if there were not enough free BDs to satisfy the request. * * @note * This function is not thread-safe. The user must provide mutually exclusive * access to this function if there are to be multiple threads that can call it. * ******************************************************************************/XStatus XTemac_SgAlloc(XTemac *InstancePtr, u32 Direction, unsigned NumBd, XDmaBdV3 **BdPtr){ XStatus Status; XDmaV3 *DmaPtr; u32 DgieReg; XASSERT_NONVOID(InstancePtr != NULL); XASSERT_NONVOID(BdPtr != NULL); XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); /* Which channel to address */ if (Direction == XTE_RECV) { DmaPtr = &InstancePtr->RecvDma; } else if (Direction == XTE_SEND) { DmaPtr = &InstancePtr->SendDma; } else { return(XST_INVALID_PARAM); } /* XDmaV3_SgBdAlloc() will return either XST_SUCCESS or XST_FAILURE * This is a critical section, prevent interrupts from the device while * the BD ring is being modified. */ DgieReg = XTemac_mGetIpifReg(XTE_DGIE_OFFSET); XTemac_mSetIpifReg(XTE_DGIE_OFFSET, 0); Status = XDmaV3_SgBdAlloc(DmaPtr, NumBd, BdPtr); XTemac_mSetIpifReg(XTE_DGIE_OFFSET, DgieReg); return(Status);}/*****************************************************************************//** * Fully or partially undo a XTemac_SgAlloc() operation. Use this function to * free BDs prior to being given to HW with XTemac_SgCommit(). * * An UnAlloc operation may be required if for some reason there is an error * (OS out of resources for example) prior to committing them. The last BD * in the list provided by XTemac_SgAlloc() must be the last BD in the list * provided to XTemac_SgUnAlloc(). * * @param InstancePtr is a pointer to the instance to be worked on. * @param Direction is the channel to address (XTE_SEND or XTE_RECV). * @param NumBd is the number of BDs to allocate. * @param BdPtr is an output parameter, it points to the first BD in the * returned list. * * @return * - XST_SUCCESS if the requested number of BDs was returned. * - XST_INVALID_PARAM if Direction did not specify a valid channel. * - XST_FAILURE if there were not enough free BDs to satisfy the request. * * @note * This function is not thread-safe. The user must provide mutually exclusive * access to this function if there are to be multiple threads that can call it. * ******************************************************************************/XStatus XTemac_SgUnAlloc(XTemac *InstancePtr, u32 Direction, unsigned NumBd, XDmaBdV3 *BdPtr){ XStatus Status; XDmaV3 *DmaPtr; u32 DgieReg; XASSERT_NONVOID(InstancePtr != NULL); XASSERT_NONVOID(BdPtr != NULL); XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); /* Which channel to address */ if (Direction == XTE_RECV) { DmaPtr = &InstancePtr->RecvDma; } else if (Direction == XTE_SEND) { DmaPtr = &InstancePtr->SendDma; } else { return(XST_INVALID_PARAM); } /* XDmaV3_SgBdAlloc() will return either XST_SUCCESS or XST_FAILURE * This is a critical section, prevent interrupts from the device while * the BD ring is being modified. */ DgieReg = XTemac_mGetIpifReg(XTE_DGIE_OFFSET); XTemac_mSetIpifReg(XTE_DGIE_OFFSET, 0); Status = XDmaV3_SgBdUnAlloc(DmaPtr, NumBd, BdPtr); XTemac_mSetIpifReg(XTE_DGIE_OFFSET, DgieReg); return(Status);}/*****************************************************************************//** * Commit a set of BDs to the SGDMA engine that had been allocated by * XTemac_SgAlloc() and prepared by the user to describe SGDMA transaction(s). * * This function and XTemac_SgAlloc() must be called in the correct order. See * xtemac.h for more information on the SGDMA use model. * * Upon return, the committed BDs go under hardware control. Do not modify BDs * after they have been committed. Doing so may cause data corruption and system * instability. * * This function may be called if the TEMAC device is started or stopped. If * started (see XTemac_Start()), then the BDs may be processed by HW at any * time. * * This function is non-blocking. Notification of error or successful * transmission/reception is done asynchronously through callback functions. * * For transmit (XTE_SEND): * * It is assumed that the upper layer software supplies a correctly formatted * Ethernet frame, including the destination and source addresses, the * type/length field, and the data field. * * For receive (XTE_RECV): * * It is assumed that BDs have an appropriately sized frame buffer attached * that corresponds to the network MTU. * * @param InstancePtr is a pointer to the instance to be worked on. * @param Direction is the channel to address (XTE_SEND or XTE_RECV). * @param NumBd is the number of BDs to commit. This is typically the same * value used when the BDs were allocated with XTemac_SgAlloc(). * @param BdPtr is the first BD in the set to commit and is typically the * same value returned by XTemac_SgAlloc(). * * @return * - XST_SUCCESS if the requested number of BDs was returned. * - XST_INVALID_PARAM if Direction did not specify a valid channel. * - XST_FAILURE if the last BD in the set does not have its "last" bit * set (see XDmaBdV3_mSetLast()). * - XST_DMA_SG_LIST_ERROR if BdPtr parameter does not reflect the correct * insertion point within the internally maintained BD ring. This error occurs * when this function and XTemac_SgAlloc() are called out of order. * * @note * This function is not thread-safe. The user must provide mutually exclusive * access to this function if there are to be multiple threads that can call it. * ******************************************************************************/XStatus XTemac_SgCommit(XTemac *InstancePtr, u32 Direction, unsigned NumBd, XDmaBdV3 *BdPtr){ XStatus Status; XDmaV3 *DmaPtr; u32 DgieReg; XASSERT_NONVOID(InstancePtr != NULL); XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); /* Which channel to address */ if (Direction == XTE_RECV) { DmaPtr = &InstancePtr->RecvDma; } else if (Direction == XTE_SEND) { DmaPtr = &InstancePtr->SendDma; } else { return(XST_INVALID_PARAM); } /* XDmaV3_SgToHw() will return either XST_SUCCESS, XST_FAILURE, or * XST_DMA_SG_LIST_ERROR * * This is a critical section, prevent interrupts from the device while * the BD ring is being modified. */ DgieReg = XTemac_mGetIpifReg(XTE_DGIE_OFFSET); XTemac_mSetIpifReg(XTE_DGIE_OFFSET, 0); Status = XDmaV3_SgBdToHw(DmaPtr, NumBd, BdPtr); XTemac_mSetIpifReg(XTE_DGIE_OFFSET, DgieReg); return(Status);}/*****************************************************************************//** * Retrieve BDs that have been processed by the SGDMA channel. This function is * called typically after the XTE_HANDLER_SGRECV handler has been invoked for * the receive channel or XTE_HANDLER_SGSEND for the transmit channel. * * The set of BDs returned is a list starting with the BdPtr and extending * for 1 or more BDs (the exact number is the return value of this function). * The list can be navigated with macros XTemac_mSgRecvBdNext() for the * XTE_RECV channel, and XTemac_mSgSendBdNext() for the XTE_SEND channel. * Treat the returned BDs as read-only. * * This function and XTemac_SgFree() must be called in the correct order. See * xtemac.h for more information on the SGDMA use model. * * The last BD in the returned list is guaranteed to have the "Last" bit set * (i.e. XDmaBdV3_IsLast evaluates to true). * * The returned BDs can be examined for the outcome of the SGDMA transaction. * * @param InstancePtr is a pointer to the instance to be worked on. * @param Direction is the channel to address (XTE_SEND or XTE_RECV). * @param BdPtr is an output parameter that points to the 1st BD in the returned * list. If no BDs were ready, then this parameter is unchanged. * @param NumBd is an upper limit to the number of BDs to retrieve. * * @return * Number of BDs that are ready for post processing. If the direction parameter * is invalid, then 0 is returned. * * @note * This function is not thread-safe. The user must provide mutually exclusive * access to this function if there are to be multiple threads that can call it. * ******************************************************************************/unsigned XTemac_SgGetProcessed(XTemac *InstancePtr, u32 Direction, unsigned NumBd, XDmaBdV3 **BdPtr){ u32 DgieReg; XDmaV3 *DmaPtr; unsigned Rc; XASSERT_NONVOID(InstancePtr != NULL); XASSERT_NONVOID(BdPtr != NULL); XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); /* Which channel to address */ if (Direction == XTE_RECV) { DmaPtr = &InstancePtr->RecvDma; } else if (Direction == XTE_SEND) { DmaPtr = &InstancePtr->SendDma; } else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -