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

📄 xtemac_sgdma.c

📁 xilinx trimode mac driver for linux
💻 C
📖 第 1 页 / 共 2 页
字号:
    {        return(0);    }    /* 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);    /* Extract ready BDs */    Rc = XDmaV3_SgBdFromHw(DmaPtr, NumBd, BdPtr);    /* End critical section */    XTemac_mSetIpifReg(XTE_DGIE_OFFSET, DgieReg);    return(Rc);}/*****************************************************************************//** * Free a set of BDs that had been retrieved by XTemac_SgGetProcessed(). If BDs * are not freed, then eventually the channel will run out of BDs to * XTemac_SgAlloc(). * * This function and XTemac_SgGetProcessed() 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 BdPtr is the first BD in the set to free. This is typically the same *        value returned by XTemac_SgGetProcessed(). * @param NumBd is the number of BDs to free. This is typically the same value *        returned by XTemac_SgGetProcessed(). * * @return * - XST_SUCCESS if the requested number of BDs was returned. * - XST_INVALID_PARAM if Direction did not specify a valid channel. * - 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_SgGetProcessed() 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_SgFree(XTemac *InstancePtr, u32 Direction,                      unsigned NumBd, XDmaBdV3 *BdPtr){    u32 DgieReg;    XDmaV3 *DmaPtr;    XStatus Status;    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);    }    /* 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_SgBdFree(DmaPtr, NumBd, BdPtr);    XTemac_mSetIpifReg(XTE_DGIE_OFFSET, DgieReg);    return(Status);}/*****************************************************************************//** * Give the driver memory space to be used for the scatter-gather DMA * descriptor list. This function should only be called once for each channel * during initialization. If a list had already been created, then it is * destroyed and replaced with a new one. * * To increase performance, a BdTemplate parameter is provided to allow the * user to permanently set BD fields in all BDs for this SGDMA channel. For * example, if every BD describes a buffer that will contain a full packet (as * it typically does with receive channels), then XDmaBdV3_mSetLast(BdTemplate) * can be performed prior to calling this function and when it returns every BD * will have the "last" bit set in it's DMACR word. The user will never have to * explicitly set the "last" bit again. * * The following operations can be replicated for the BdTemplate: *   - XDmaBdV3_mSetId() *   - XDmaBdV3_mSetLast() *   - XDmaBdV3_mClearLast() *   - XDmaBdV3_mSetBufIncrement() *   - XDmaBdV3_mSetBufNoIncrement() *   - XDmaBdV3_mSetDevSel() *   - XDmaBdV3_mSetBdPage() *   - XDmaBdV3_mSetTransferType() *   - XDmaBdV3_mSetBufAddrHigh() *   - XDmaBdV3_mSetBufAddrLow() *   - XTemac_mSgSendBdCsumEnable()  -- transmit channel only *   - XTemac_mSgSendBdCsumDisable() -- transmit channel only *   - XTemac_mSgSendBdCsumSetup()   -- transmit channel only *   - XTemac_mSgSendBdCsumSeed()    -- transmit channel only * * The base address of the memory space must be aligned according to buffer * descriptor requirements (see xtemac.h). * * The size of the memory space is assumed to be big enough to contain BdCount * buffers at the given alignment. If the region is too small, then adjacent * data may be overwritten causing system instability. There are tools in the * DMA driver that help calculate the sizing requirments. See macros * XDmaV3_mSgListCntCalc() and XDmaV3_mSgListMemCalc(). * * @param InstancePtr is a pointer to the instance to be worked on. * @param Direction is the channel to address. * @param PhysicalAddr is the physical base address of user memory region. * @param VirtualAddr is the virtual base address of the user memory region. If *        address translation is not being utilized, then VirtAddr should be *        equivalent to PhysAddr. * @param Alignment governs the byte alignment of individual BDs. This function *        will enforce a minimum alignment of 8 bytes with no maximum as long as *        it is specified as a power of 2. * @param BdCount is the number of BDs to allocate in the memory region. It is *        assumed the region is large enough to contain all the BDs. * @param BdTemplate is copied to each BD after the list is created. If the user *        does not have a need to replicate any BD fields then this parameter *        should be zeroed (XDmaBdV3_mClear()). This parameter will be modified *        by this function. * * @return * - XST_SUCCESS if the space was initialized successfully * - XST_DEVICE_IS_STARTED if the device has not been stopped. * - XST_NOT_SGDMA if the MAC is not configured for scatter-gather DMA per *   the configuration information contained in XTemac_Config. * - XST_INVALID_PARAM if: 1) Direction is not either XTE_SEND or XTE_RECV; *   2) PhysicalAddr and/or VirtualAddr are not aligned to the given *   alignment parameter; 3) Alignment parameter does not meet minimum *   requirements of this device; 3) BdCount is 0. * - XST_DMA_SG_LIST_ERROR if the memory segment containing the list spans *   over address 0x00000000 in virtual address space. * - XST_NO_FEATURE if the DMA sub-driver discovers that the HW is not SGDMA *   capable. * - XST_FAILURE for other failures that shouldn't occur. If this is returned, *   then the driver is experiencing a problem that should be reported to *   Xilinx. * * @note * If the device is configured for scatter-gather DMA, this function must be * called AFTER the XTemac_Initialize() function because the DMA channel * components must be initialized before the memory space is set. * ******************************************************************************/XStatus XTemac_SgSetSpace(XTemac *InstancePtr, u32 Direction,                          u32 PhysicalAddr, u32 VirtualAddr,                          u32 Alignment, unsigned BdCount,                          XDmaBdV3 *BdTemplate){    XStatus Status;    XASSERT_NONVOID(InstancePtr != NULL);    XASSERT_NONVOID(BdTemplate != NULL);    XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);    /* Make sure device is ready for this operation */    if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED)    {        return(XST_DEVICE_IS_STARTED);    }    /* Must have sgdma */    if (!XTemac_mIsSgDma(InstancePtr))    {        return(XST_NOT_SGDMA);    }    /* Check alignment */    if (Alignment < XTE_PLB_BD_ALIGNMENT)    {        return(XST_INVALID_PARAM);    }    if (Direction == XTE_SEND)    {        /* Create the list. This function will return one of XST_SUCCESS,         * XST_INVALID_PARAM (for alignment violations), or         * XST_DMA_SG_LIST_ERROR (if memory segment spans address 0)         */        Status = XDmaV3_SgListCreate(&InstancePtr->SendDma, PhysicalAddr,                                     VirtualAddr, Alignment, BdCount);        if (Status != XST_SUCCESS)        {            return(Status);        }        /* Clone the template BD. This should always work. If it does not         * then something is seriously wrong         */        Status = XDmaV3_SgListClone(&InstancePtr->SendDma, BdTemplate);        if (Status != XST_SUCCESS)        {            return(XST_FAILURE);        }        else        {            return(XST_SUCCESS);        }    }    else if (Direction == XTE_RECV)    {        /* Create the list. This function will return one of XST_SUCCESS,         * XST_INVALID_PARAM (for alignment violations), or         * XST_DMA_SG_LIST_ERROR (if memory segment spans address 0)         */        Status = XDmaV3_SgListCreate(&InstancePtr->RecvDma, PhysicalAddr,                                     VirtualAddr, Alignment, BdCount);        if (Status != XST_SUCCESS)        {            return(Status);        }        /* Clone the template BD */        Status = XDmaV3_SgListClone(&InstancePtr->RecvDma, BdTemplate);        if (Status != XST_SUCCESS)        {            return(XST_FAILURE);        }        else        {            return(XST_SUCCESS);        }    }    /* Direction is incorrect */    return(XST_INVALID_PARAM);}/*****************************************************************************//** * Verify the consistency of the SGDMA BD ring. While the check occurs, the * device is stopped. If any problems are found the device is left stopped. * * Use this function to troubleshoot SGDMA problems. * * @param InstancePtr is a pointer to the instance to be worked on. * @param Direction is the channel to check (XTE_SEND or XTE_RECV) * * @return * - XST_SUCCESS if no problems are found. * - XST_INVALID_PARAM if Direction is not XTE_SEND or XTE_RECV. * - XST_DMA_SG_NO_LIST if the SG list has not yet been setup. * - XST_DMA_BD_ERROR if a BD has been corrupted. * - XST_DMA_SG_LIST_ERROR if the internal data structures of the BD ring are *   inconsistent. * * @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_SgCheck(XTemac *InstancePtr, u32 Direction){    XDmaV3 *DmaPtr;    XDmaBdV3 *BdPtr;    unsigned i;    int Restart = 0;    XStatus Rc;    XASSERT_NONVOID(InstancePtr != NULL);    /* Select channel to check */    if (Direction == XTE_SEND)    {        DmaPtr = &InstancePtr->SendDma;    }    else if (Direction == XTE_RECV)    {        DmaPtr = &InstancePtr->RecvDma;    }    else    {        return(XST_INVALID_PARAM);    }    /* Stop the device if it is running */    if (InstancePtr->IsStarted == XST_DEVICE_IS_STARTED)    {        XTemac_Stop(InstancePtr);        Restart = 1;    }    /* Perform check of ring structure using DMA driver routine */    Rc = XDmaV3_SgCheck(DmaPtr);    /* Check BDs for consistency as used by TEMAC */    if (Rc == XST_SUCCESS)    {        /* Verify DMACR is setup for Tx direction */        if (Direction == XTE_SEND)        {            BdPtr = (XDmaBdV3*)DmaPtr->BdRing.BaseAddr;            for (i=0; i<DmaPtr->BdRing.AllCnt; i++)            {                if (XDmaV3_mReadBd(BdPtr, XDMAV3_DMACR_OFFSET) &                    XDMAV3_DMACR_DIR_RX_MASK)                {                    return(XST_DMA_BD_ERROR);                }            }        }        else  /* XTE_RECV */        {            BdPtr = (XDmaBdV3*)DmaPtr->BdRing.BaseAddr;            for (i=0; i<DmaPtr->BdRing.AllCnt; i++)            {                if (!(XDmaV3_mReadBd(BdPtr, XDMAV3_DMACR_OFFSET) &                      XDMAV3_DMACR_DIR_RX_MASK))                {                    return(XST_DMA_BD_ERROR);                }            }        }    }    /* Restart the device if it was stopped by this function */    if ((Rc == XST_SUCCESS) && Restart)    {        XTemac_Start(InstancePtr);    }    return(Rc);}

⌨️ 快捷键说明

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