/******************************************************************************
*
* Copyright (C) 2010 - 2015 Xilinx, Inc.  All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xemacps_bdring.c
* @addtogroup emacps_v3_1
* @{
*
* This file implements buffer descriptor ring related functions.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver   Who  Date     Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00a wsy  01/10/10 First release
* 1.00a asa  11/21/11 The function XEmacPs_BdRingFromHwTx is modified.
*		      Earlier it used to search in "BdLimit" number of BDs to
*		      know which BDs are processed. Now one more check is
*		      added. It looks for BDs till the current BD pointer
*		      reaches HwTail. By doing this processing time is saved.
* 1.00a asa  01/24/12 The function XEmacPs_BdRingFromHwTx in file
*		      xemacps_bdring.c is modified. Now start of packet is
*		      searched for returning the number of BDs processed.
* 1.05a asa  09/23/13 Cache operations on BDs are not required and hence
*		      removed. It is expected that all BDs are allocated in
*		      from uncached area. Fix for CR #663885.
* 2.1   srt  07/15/14 Add support for Zynq Ultrascale Mp architecture.
* 3.0   kvn  02/13/15 Modified code for MISRA-C:2012 compliance.
*
* </pre>
******************************************************************************/

/***************************** Include Files *********************************/

#include "xstatus.h"
#include "xil_cache.h"
#include "xemacps_hw.h"
#include "xemacps_bd.h"
#include "xemacps_bdring.h"

/************************** Constant Definitions *****************************/

/**************************** Type Definitions *******************************/


/***************** Macros (Inline Functions) Definitions *********************/

/****************************************************************************
 * Compute the virtual address of a descriptor from its physical address
 *
 * @param BdPtr is the physical address of the BD
 *
 * @returns Virtual address of BdPtr
 *
 * @note Assume BdPtr is always a valid BD in the ring
 ****************************************************************************/
#define XEMACPS_PHYS_TO_VIRT(BdPtr) \
    ((UINTPTR)(BdPtr) + (RingPtr->BaseBdAddr - RingPtr->PhysBaseAddr))

/****************************************************************************
 * Compute the physical address of a descriptor from its virtual address
 *
 * @param BdPtr is the physical address of the BD
 *
 * @returns Physical address of BdPtr
 *
 * @note Assume BdPtr is always a valid BD in the ring
 ****************************************************************************/
#define XEMACPS_VIRT_TO_PHYS(BdPtr) \
    ((UINTPTR)(BdPtr) - (RingPtr->BaseBdAddr - RingPtr->PhysBaseAddr))

/****************************************************************************
 * Move the BdPtr argument ahead an arbitrary number of BDs wrapping around
 * to the beginning of the ring if needed.
 *
 * We know if a wrapaound should occur if the new BdPtr is greater than
 * the high address in the ring OR if the new BdPtr crosses over the
 * 0xFFFFFFFF to 0 boundary. The latter test is a valid one since we do not
 * allow a BD space to span this boundary.
 *
 * @param RingPtr is the ring BdPtr appears in
 * @param BdPtr on input is the starting BD position and on output is the
 *        final BD position
 * @param NumBd is the number of BD spaces to increment
 *
 ****************************************************************************/
#define XEMACPS_RING_SEEKAHEAD(RingPtr, BdPtr, NumBd)                  \
    {                                                                   \
        UINTPTR Addr = (UINTPTR)(void *)(BdPtr);                        \
                                                                        \
        Addr += ((RingPtr)->Separation * (NumBd));                        \
        if ((Addr > (RingPtr)->HighBdAddr) || ((UINTPTR)(void *)(BdPtr) > Addr))  \
        {                                                               \
            Addr -= (RingPtr)->Length;                                  \
        }                                                               \
                                                                        \
        (BdPtr) = (XEmacPs_Bd*)(void *)Addr;                                     \
    }

/****************************************************************************
 * Move the BdPtr argument backwards an arbitrary number of BDs wrapping
 * around to the end of the ring if needed.
 *
 * We know if a wrapaound should occur if the new BdPtr is less than
 * the base address in the ring OR if the new BdPtr crosses over the
 * 0xFFFFFFFF to 0 boundary. The latter test is a valid one since we do not
 * allow a BD space to span this boundary.
 *
 * @param RingPtr is the ring BdPtr appears in
 * @param BdPtr on input is the starting BD position and on output is the
 *        final BD position
 * @param NumBd is the number of BD spaces to increment
 *
 ****************************************************************************/
#define XEMACPS_RING_SEEKBACK(RingPtr, BdPtr, NumBd)                   \
    {                                                                   \
        UINTPTR Addr = (UINTPTR)(void *)(BdPtr);                                  \
                                                                        \
        Addr -= ((RingPtr)->Separation * (NumBd));                        \
        if ((Addr < (RingPtr)->BaseBdAddr) || ((UINTPTR)(void*)(BdPtr) < Addr))  \
        {                                                               \
            Addr += (RingPtr)->Length;                                  \
        }                                                               \
                                                                        \
        (BdPtr) = (XEmacPs_Bd*)(void*)Addr;                                     \
    }


/************************** Function Prototypes ******************************/

static void XEmacPs_BdSetRxWrap(UINTPTR BdPtr);
static void XEmacPs_BdSetTxWrap(UINTPTR BdPtr);

/************************** Variable Definitions *****************************/

/*****************************************************************************/
/**
 * Using a memory segment allocated by the caller, create and setup the BD list
 * for the given DMA channel.
 *
 * @param RingPtr is the instance to be worked on.
 * @param PhysAddr is the physical base address of user memory region.
 * @param VirtAddr 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 4 bytes with no maximum as long
 *        as it is specified as a power of 2.
 * @param BdCount is the number of BDs to setup in the user memory region. It
 *        is assumed the region is large enough to contain the BDs.
 *
 * @return
 *
 * - XST_SUCCESS if initialization was successful
 * - XST_NO_FEATURE if the provided instance is a non DMA type
 *   channel.
 * - XST_INVALID_PARAM under any of the following conditions:
 *   1) PhysAddr and/or VirtAddr are not aligned to the given Alignment
 *      parameter.
 *   2) Alignment parameter does not meet minimum requirements or is not a
 *      power of 2 value.
 *   3) BdCount is 0.
 * - XST_DMA_SG_LIST_ERROR if the memory segment containing the list spans
 *   over address 0x00000000 in virtual address space.
 *
 * @note
 * Make sure to pass in the right alignment value.
 *****************************************************************************/
LONG XEmacPs_BdRingCreate(XEmacPs_BdRing * RingPtr, UINTPTR PhysAddr,
			  UINTPTR VirtAddr, u32 Alignment, u32 BdCount)
{
	u32 i;
	UINTPTR BdVirtAddr;
	UINTPTR BdPhyAddr;
	UINTPTR VirtAddrLoc = VirtAddr;

	/* In case there is a failure prior to creating list, make sure the
	 * following attributes are 0 to prevent calls to other functions
	 * from doing anything.
	 */
	RingPtr->AllCnt = 0U;
	RingPtr->FreeCnt = 0U;
	RingPtr->HwCnt = 0U;
	RingPtr->PreCnt = 0U;
	RingPtr->PostCnt = 0U;

	/* Make sure Alignment parameter meets minimum requirements */
	if (Alignment < (u32)XEMACPS_DMABD_MINIMUM_ALIGNMENT) {
		return (LONG)(XST_INVALID_PARAM);
	}

	/* Make sure Alignment is a power of 2 */
	if (((Alignment - 0x00000001U) & Alignment)!=0x00000000U) {
		return (LONG)(XST_INVALID_PARAM);
	}

	/* Make sure PhysAddr and VirtAddr are on same Alignment */
	if (((PhysAddr % Alignment)!=(u32)0) || ((VirtAddrLoc % Alignment)!=(u32)0)) {
		return (LONG)(XST_INVALID_PARAM);
	}

	/* Is BdCount reasonable? */
	if (BdCount == 0x00000000U) {
		return (LONG)(XST_INVALID_PARAM);
	}

	/* Figure out how many bytes will be between the start of adjacent BDs */
	RingPtr->Separation = ((u32)sizeof(XEmacPs_Bd));

	/* Must make sure the ring doesn't span address 0x00000000. If it does,
	 * then the next/prev BD traversal macros will fail.
	 */
	if (VirtAddrLoc > ((VirtAddrLoc + (RingPtr->Separation * BdCount)) - (u32)1)) {
		return (LONG)(XST_DMA_SG_LIST_ERROR);
	}

	/* Initial ring setup:
	 *  - Clear the entire space
	 *  - Setup each BD's BDA field with the physical address of the next BD
	 */
	(void)memset((void *) VirtAddrLoc, 0, (RingPtr->Separation * BdCount));

	BdVirtAddr = VirtAddrLoc;
	BdPhyAddr = PhysAddr + RingPtr->Separation;
	for (i = 1U; i < BdCount; i++) {
		BdVirtAddr += RingPtr->Separation;
		BdPhyAddr += RingPtr->Separation;
	}

	/* Setup and initialize pointers and counters */
	RingPtr->RunState = (u32)(XST_DMA_SG_IS_STOPPED);
	RingPtr->BaseBdAddr = VirtAddrLoc;
	RingPtr->PhysBaseAddr = PhysAddr;
	RingPtr->HighBdAddr = BdVirtAddr;
	RingPtr->Length =
		((RingPtr->HighBdAddr - RingPtr->BaseBdAddr) + RingPtr->Separation);
	RingPtr->AllCnt = (u32)BdCount;
	RingPtr->FreeCnt = (u32)BdCount;
	RingPtr->FreeHead = (XEmacPs_Bd *)(void *)VirtAddrLoc;
	RingPtr->PreHead = (XEmacPs_Bd *)VirtAddrLoc;
	RingPtr->HwHead = (XEmacPs_Bd *)VirtAddrLoc;
	RingPtr->HwTail = (XEmacPs_Bd *)VirtAddrLoc;
	RingPtr->PostHead = (XEmacPs_Bd *)VirtAddrLoc;
	RingPtr->BdaRestart = (XEmacPs_Bd *)(void *)PhysAddr;

	return (LONG)(XST_SUCCESS);
}


/*****************************************************************************/
/**
 * Clone the given BD into every BD in the list.
 * every field of the source BD is replicated in every BD of the list.
 *
 * This function can be called only when all BDs are in the free group such as
 * they are immediately after initialization with XEmacPs_BdRingCreate().
 * This prevents modification of BDs while they are in use by hardware or the
 * user.
 *
 * @param RingPtr is the pointer of BD ring instance to be worked on.
 * @param SrcBdPtr is the source BD template to be cloned into the list. This
 *        BD will be modified.
 * @param Direction is either XEMACPS_SEND or XEMACPS_RECV that indicates
 *        which direction.
 *
 * @return
 *   - XST_SUCCESS if the list was modified.
 *   - XST_DMA_SG_NO_LIST if a list has not been created.
 *   - XST_DMA_SG_LIST_ERROR if some of the BDs in this channel are under
 *     hardware or user control.
 *   - XST_DEVICE_IS_STARTED if the DMA channel has not been stopped.
 *
 *****************************************************************************/
LONG XEmacPs_BdRingClone(XEmacPs_BdRing * RingPtr, XEmacPs_Bd * SrcBdPtr,
			 u8 Direction)
{
	u32 i;
	UINTPTR CurBd;

	/* Can't do this function if there isn't a ring */
	if (RingPtr->AllCnt == 0x00000000U) {
		return (LONG)(XST_DMA_SG_NO_LIST);
	}

	/* Can't do this function with the channel running */
	if (RingPtr->RunState == (u32)XST_DMA_SG_IS_STARTED) {
		return (LONG)(XST_DEVICE_IS_STARTED);
	}

	/* Can't do this function with some of the BDs in use */
	if (RingPtr->FreeCnt != RingPtr->AllCnt) {
		return (LONG)(XST_DMA_SG_LIST_ERROR);
	}

	if ((Direction != (u8)XEMACPS_SEND) && (Direction != (u8)XEMACPS_RECV)) {
		return (LONG)(XST_INVALID_PARAM);
	}

	/* Starting from the top of the ring, save BD.Next, overwrite the entire
	 * BD with the template, then restore BD.Next
	 */
	CurBd = RingPtr->BaseBdAddr;
	for (i = 0U; i < RingPtr->AllCnt; i++) {
		memcpy((void *)CurBd, SrcBdPtr, sizeof(XEmacPs_Bd));
	CurBd += RingPtr->Separation;
	}

	CurBd -= RingPtr->Separation;

	if (Direction == XEMACPS_RECV) {
		XEmacPs_BdSetRxWrap(CurBd);
	}
	else {
		XEmacPs_BdSetTxWrap(CurBd);
	}

	return (LONG)(XST_SUCCESS);
}


/*****************************************************************************/
/**
 * Reserve locations in the BD list. The set of returned BDs may be modified
 * in preparation for future DMA transaction(s). Once the BDs are ready to be
 * submitted to hardware, the user must call XEmacPs_BdRingToHw() in the same
 * order which they were allocated here. Example:
 *
 * <pre>
 *        NumBd = 2,
 *        Status = XEmacPs_BdRingAlloc(MyRingPtr, NumBd, &MyBdSet),
 *
 *        if (Status != XST_SUCCESS)
 *        {
 *            *Not enough BDs available for the request*
 *        }
 *
 *        CurBd = MyBdSet,
 *        for (i=0; i<NumBd; i++)
 *        {
 *            * Prepare CurBd *.....
 *
 *            * Onto next BD *
 *            CurBd = XEmacPs_BdRingNext(MyRingPtr, CurBd),
 *        }
 *
 *        * Give list to hardware *
 *        Status = XEmacPs_BdRingToHw(MyRingPtr, NumBd, MyBdSet),
 * </pre>
 *
 * A more advanced use of this function may allocate multiple sets of BDs.
 * They must be allocated and given to hardware in the correct sequence:
 * <pre>
 *        * Legal *
 *        XEmacPs_BdRingAlloc(MyRingPtr, NumBd1, &MySet1),
 *        XEmacPs_BdRingToHw(MyRingPtr, NumBd1, MySet1),
 *
 *        * Legal *
 *        XEmacPs_BdRingAlloc(MyRingPtr, NumBd1, &MySet1),
 *        XEmacPs_BdRingAlloc(MyRingPtr, NumBd2, &MySet2),
 *        XEmacPs_BdRingToHw(MyRingPtr, NumBd1, MySet1),
 *        XEmacPs_BdRingToHw(MyRingPtr, NumBd2, MySet2),
 *
 *        * Not legal *
 *        XEmacPs_BdRingAlloc(MyRingPtr, NumBd1, &MySet1),
 *        XEmacPs_BdRingAlloc(MyRingPtr, NumBd2, &MySet2),
 *        XEmacPs_BdRingToHw(MyRingPtr, NumBd2, MySet2),
 *        XEmacPs_BdRingToHw(MyRingPtr, NumBd1, MySet1),
 * </pre>
 *
 * Use the API defined in xemacps_bd.h to modify individual BDs. Traversal
 * of the BD set can be done using XEmacPs_BdRingNext() and
 * XEmacPs_BdRingPrev().
 *
 * @param RingPtr is a pointer to the BD ring instance to be worked on.
 * @param NumBd is the number of BDs to allocate
 * @param BdSetPtr is an output parameter, it points to the first BD available
 *        for modification.
 *
 * @return
 *   - XST_SUCCESS if the requested number of BDs was returned in the BdSetPtr
 *     parameter.
 *   - XST_FAILURE if there were not enough free BDs to satisfy the request.
 *
 * @note This function should not be preempted by another XEmacPs_Bd function
 *       call that modifies the BD space. It is the caller's responsibility to
 *       provide a mutual exclusion mechanism.
 *
 * @note Do not modify more BDs than the number requested with the NumBd
 *       parameter. Doing so will lead to data corruption and system
 *       instability.
 *
 *****************************************************************************/
LONG XEmacPs_BdRingAlloc(XEmacPs_BdRing * RingPtr, u32 NumBd,
			 XEmacPs_Bd ** BdSetPtr)
{
	LONG Status;
	/* Enough free BDs available for the request? */
	if (RingPtr->FreeCnt < NumBd) {
		Status = (LONG)(XST_FAILURE);
	} else {
	/* Set the return argument and move FreeHead forward */
	*BdSetPtr = RingPtr->FreeHead;
	XEMACPS_RING_SEEKAHEAD(RingPtr, RingPtr->FreeHead, NumBd);
	RingPtr->FreeCnt -= NumBd;
	RingPtr->PreCnt += NumBd;
		Status = (LONG)(XST_SUCCESS);
	}
	return Status;
}

/*****************************************************************************/
/**
 * Fully or partially undo an XEmacPs_BdRingAlloc() operation. Use this
 * function if all the BDs allocated by XEmacPs_BdRingAlloc() could not be
 * transferred to hardware with XEmacPs_BdRingToHw().
 *
 * This function helps out in situations when an unrelated error occurs after
 * BDs have been allocated but before they have been given to hardware.
 * An example of this type of error would be an OS running out of resources.
 *
 * This function is not the same as XEmacPs_BdRingFree(). The Free function
 * returns BDs to the free list after they have been processed by hardware,
 * while UnAlloc returns them before being processed by hardware.
 *
 * There are two scenarios where this function can be used. Full UnAlloc or
 * Partial UnAlloc. A Full UnAlloc means all the BDs Alloc'd will be returned:
 *
 * <pre>
 *    Status = XEmacPs_BdRingAlloc(MyRingPtr, 10, &BdPtr),
 *        ...
 *    if (Error)
 *    {
 *        Status = XEmacPs_BdRingUnAlloc(MyRingPtr, 10, &BdPtr),
 *    }
 * </pre>
 *
 * A partial UnAlloc means some of the BDs Alloc'd will be returned:
 *
 * <pre>
 *    Status = XEmacPs_BdRingAlloc(MyRingPtr, 10, &BdPtr),
 *    BdsLeft = 10,
 *    CurBdPtr = BdPtr,
 *
 *    while (BdsLeft)
 *    {
 *       if (Error)
 *       {
 *          Status = XEmacPs_BdRingUnAlloc(MyRingPtr, BdsLeft, CurBdPtr),
 *       }
 *
 *       CurBdPtr = XEmacPs_BdRingNext(MyRingPtr, CurBdPtr),
 *       BdsLeft--,
 *    }
 * </pre>
 *
 * A partial UnAlloc must include the last BD in the list that was Alloc'd.
 *
 * @param RingPtr is a pointer to the instance to be worked on.
 * @param NumBd is the number of BDs to allocate
 * @param BdSetPtr is an output parameter, it points to the first BD available
 *        for modification.
 *
 * @return
 *   - XST_SUCCESS if the BDs were unallocated.
 *   - XST_FAILURE if NumBd parameter was greater that the number of BDs in
 *     the preprocessing state.
 *
 * @note This function should not be preempted by another XEmacPs_Bd function
 *       call that modifies the BD space. It is the caller's responsibility to
 *       provide a mutual exclusion mechanism.
 *
 *****************************************************************************/
LONG XEmacPs_BdRingUnAlloc(XEmacPs_BdRing * RingPtr, u32 NumBd,
			   XEmacPs_Bd * BdSetPtr)
{
	LONG Status;
	(void *)BdSetPtr;
	Xil_AssertNonvoid(RingPtr != NULL);
	Xil_AssertNonvoid(BdSetPtr != NULL);

	/* Enough BDs in the free state for the request? */
	if (RingPtr->PreCnt < NumBd) {
		Status = (LONG)(XST_FAILURE);
	} else {
	/* Set the return argument and move FreeHead backward */
		XEMACPS_RING_SEEKBACK(RingPtr, (RingPtr->FreeHead), NumBd);
	RingPtr->FreeCnt += NumBd;
	RingPtr->PreCnt -= NumBd;
		Status = (LONG)(XST_SUCCESS);
	}
	return Status;
}


/*****************************************************************************/
/**
 * Enqueue a set of BDs to hardware that were previously allocated by
 * XEmacPs_BdRingAlloc(). Once this function returns, the argument BD set goes
 * under hardware control. Any changes made to these BDs after this point will
 * corrupt the BD list leading to data corruption and system instability.
 *
 * The set will be rejected if the last BD of the set does not mark the end of
 * a packet (see XEmacPs_BdSetLast()).
 *
 * @param RingPtr is a pointer to the instance to be worked on.
 * @param NumBd is the number of BDs in the set.
 * @param BdSetPtr is the first BD of the set to commit to hardware.
 *
 * @return
 *   - XST_SUCCESS if the set of BDs was accepted and enqueued to hardware.
 *   - XST_FAILURE if the set of BDs was rejected because the last BD of the set
 *     did not have its "last" bit set.
 *   - XST_DMA_SG_LIST_ERROR if this function was called out of sequence with
 *     XEmacPs_BdRingAlloc().
 *
 * @note This function should not be preempted by another XEmacPs_Bd function
 *       call that modifies the BD space. It is the caller's responsibility to
 *       provide a mutual exclusion mechanism.
 *
 *****************************************************************************/
LONG XEmacPs_BdRingToHw(XEmacPs_BdRing * RingPtr, u32 NumBd,
			XEmacPs_Bd * BdSetPtr)
{
	XEmacPs_Bd *CurBdPtr;
	u32 i;
	LONG Status;
	/* if no bds to process, simply return. */
	if (0U == NumBd){
		Status = (LONG)(XST_SUCCESS);
	} else {
	/* Make sure we are in sync with XEmacPs_BdRingAlloc() */
	if ((RingPtr->PreCnt < NumBd) || (RingPtr->PreHead != BdSetPtr)) {
			Status = (LONG)(XST_DMA_SG_LIST_ERROR);
		} else {
	CurBdPtr = BdSetPtr;
			for (i = 0U; i < NumBd; i++) {
				CurBdPtr = (XEmacPs_Bd *)((void *)XEmacPs_BdRingNext(RingPtr, CurBdPtr));
	}
	/* Adjust ring pointers & counters */
	XEMACPS_RING_SEEKAHEAD(RingPtr, RingPtr->PreHead, NumBd);
	RingPtr->PreCnt -= NumBd;
	RingPtr->HwTail = CurBdPtr;
	RingPtr->HwCnt += NumBd;

			Status = (LONG)(XST_SUCCESS);
		}
	}
	return Status;
}


/*****************************************************************************/
/**
 * Returns a set of BD(s) that have been processed by hardware. The returned
 * BDs may be examined to determine the outcome of the DMA transaction(s).
 * Once the BDs have been examined, the user must call XEmacPs_BdRingFree()
 * in the same order which they were retrieved here. Example:
 *
 * <pre>
 *        NumBd = XEmacPs_BdRingFromHwTx(MyRingPtr, MaxBd, &MyBdSet),
 *        if (NumBd == 0)
 *        {
 *           * hardware has nothing ready for us yet*
 *        }
 *
 *        CurBd = MyBdSet,
 *        for (i=0; i<NumBd; i++)
 *        {
 *           * Examine CurBd for post processing *.....
 *
 *           * Onto next BD *
 *           CurBd = XEmacPs_BdRingNext(MyRingPtr, CurBd),
 *           }
 *
 *           XEmacPs_BdRingFree(MyRingPtr, NumBd, MyBdSet),  *Return list*
 *        }
 * </pre>
 *
 * A more advanced use of this function may allocate multiple sets of BDs.
 * They must be retrieved from hardware and freed in the correct sequence:
 * <pre>
 *        * Legal *
 *        XEmacPs_BdRingFromHwTx(MyRingPtr, NumBd1, &MySet1),
 *        XEmacPs_BdRingFree(MyRingPtr, NumBd1, MySet1),
 *
 *        * Legal *
 *        XEmacPs_BdRingFromHwTx(MyRingPtr, NumBd1, &MySet1),
 *        XEmacPs_BdRingFromHwTx(MyRingPtr, NumBd2, &MySet2),
 *        XEmacPs_BdRingFree(MyRingPtr, NumBd1, MySet1),
 *        XEmacPs_BdRingFree(MyRingPtr, NumBd2, MySet2),
 *
 *        * Not legal *
 *        XEmacPs_BdRingFromHwTx(MyRingPtr, NumBd1, &MySet1),
 *        XEmacPs_BdRingFromHwTx(MyRingPtr, NumBd2, &MySet2),
 *        XEmacPs_BdRingFree(MyRingPtr, NumBd2, MySet2),
 *        XEmacPs_BdRingFree(MyRingPtr, NumBd1, MySet1),
 * </pre>
 *
 * If hardware has only partially completed a packet spanning multiple BDs,
 * then none of the BDs for that packet will be included in the results.
 *
 * @param RingPtr is a pointer to the instance to be worked on.
 * @param BdLimit is the maximum number of BDs to return in the set.
 * @param BdSetPtr is an output parameter, it points to the first BD available
 *        for examination.
 *
 * @return
 *   The number of BDs processed by hardware. A value of 0 indicates that no
 *   data is available. No more than BdLimit BDs will be returned.
 *
 * @note Treat BDs returned by this function as read-only.
 *
 * @note This function should not be preempted by another XEmacPs_Bd function
 *       call that modifies the BD space. It is the caller's responsibility to
 *       provide a mutual exclusion mechanism.
 *
 *****************************************************************************/
u32 XEmacPs_BdRingFromHwTx(XEmacPs_BdRing * RingPtr, u32 BdLimit,
				 XEmacPs_Bd ** BdSetPtr)
{
	XEmacPs_Bd *CurBdPtr;
	u32 BdStr = 0U;
	u32 BdCount;
	u32 BdPartialCount;
	u32 Sop = 0U;
	u32 Status;
	u32 BdLimitLoc = BdLimit;
	CurBdPtr = RingPtr->HwHead;
	BdCount = 0U;
	BdPartialCount = 0U;

	/* If no BDs in work group, then there's nothing to search */
	if (RingPtr->HwCnt == 0x00000000U) {
		*BdSetPtr = NULL;
		Status = 0U;
	} else {

		if (BdLimitLoc > RingPtr->HwCnt){
			BdLimitLoc = RingPtr->HwCnt;
	}
	/* Starting at HwHead, keep moving forward in the list until:
	 *  - A BD is encountered with its new/used bit set which means
	 *    hardware has not completed processing of that BD.
	 *  - RingPtr->HwTail is reached and RingPtr->HwCnt is reached.
	 *  - The number of requested BDs has been processed
	 */
		while (BdCount < BdLimitLoc) {
		/* Read the status */
			if(CurBdPtr != NULL){
		BdStr = XEmacPs_BdRead(CurBdPtr, XEMACPS_BD_STAT_OFFSET);
			}

			if ((Sop == 0x00000000U) && ((BdStr & XEMACPS_TXBUF_USED_MASK)!=0x00000000U)){
				Sop = 1U;
			}
			if (Sop == 0x00000001U) {
			BdCount++;
			BdPartialCount++;
		}

		/* hardware has processed this BD so check the "last" bit.
		 * If it is clear, then there are more BDs for the current
		 * packet. Keep a count of these partial packet BDs.
		 */
			if ((Sop == 0x00000001U) && ((BdStr & XEMACPS_TXBUF_LAST_MASK)!=0x00000000U)) {
				Sop = 0U;
				BdPartialCount = 0U;
		}

		/* Move on to next BD in work group */
		CurBdPtr = XEmacPs_BdRingNext(RingPtr, CurBdPtr);
	}

	/* Subtract off any partial packet BDs found */
        BdCount -= BdPartialCount;

	/* If BdCount is non-zero then BDs were found to return. Set return
	 * parameters, update pointers and counters, return success
	 */
		if (BdCount > 0x00000000U) {
		*BdSetPtr = RingPtr->HwHead;
		RingPtr->HwCnt -= BdCount;
		RingPtr->PostCnt += BdCount;
		XEMACPS_RING_SEEKAHEAD(RingPtr, RingPtr->HwHead, BdCount);
			Status = (BdCount);
		} else {
			*BdSetPtr = NULL;
			Status = 0U;
	}
	}
	return Status;
}


/*****************************************************************************/
/**
 * Returns a set of BD(s) that have been processed by hardware. The returned
 * BDs may be examined to determine the outcome of the DMA transaction(s).
 * Once the BDs have been examined, the user must call XEmacPs_BdRingFree()
 * in the same order which they were retrieved here. Example:
 *
 * <pre>
 *        NumBd = XEmacPs_BdRingFromHwRx(MyRingPtr, MaxBd, &MyBdSet),
 *
 *        if (NumBd == 0)
 *        {
 *           *hardware has nothing ready for us yet*
 *        }
 *
 *        CurBd = MyBdSet,
 *        for (i=0; i<NumBd; i++)
 *        {
 *           * Examine CurBd for post processing *.....
 *
 *           * Onto next BD *
 *           CurBd = XEmacPs_BdRingNext(MyRingPtr, CurBd),
 *           }
 *
 *           XEmacPs_BdRingFree(MyRingPtr, NumBd, MyBdSet),  * Return list *
 *        }
 * </pre>
 *
 * A more advanced use of this function may allocate multiple sets of BDs.
 * They must be retrieved from hardware and freed in the correct sequence:
 * <pre>
 *        * Legal *
 *        XEmacPs_BdRingFromHwRx(MyRingPtr, NumBd1, &MySet1),
 *        XEmacPs_BdRingFree(MyRingPtr, NumBd1, MySet1),
 *
 *        * Legal *
 *        XEmacPs_BdRingFromHwRx(MyRingPtr, NumBd1, &MySet1),
 *        XEmacPs_BdRingFromHwRx(MyRingPtr, NumBd2, &MySet2),
 *        XEmacPs_BdRingFree(MyRingPtr, NumBd1, MySet1),
 *        XEmacPs_BdRingFree(MyRingPtr, NumBd2, MySet2),
 *
 *        * Not legal *
 *        XEmacPs_BdRingFromHwRx(MyRingPtr, NumBd1, &MySet1),
 *        XEmacPs_BdRingFromHwRx(MyRingPtr, NumBd2, &MySet2),
 *        XEmacPs_BdRingFree(MyRingPtr, NumBd2, MySet2),
 *        XEmacPs_BdRingFree(MyRingPtr, NumBd1, MySet1),
 * </pre>
 *
 * If hardware has only partially completed a packet spanning multiple BDs,
 * then none of the BDs for that packet will be included in the results.
 *
 * @param RingPtr is a pointer to the instance to be worked on.
 * @param BdLimit is the maximum number of BDs to return in the set.
 * @param BdSetPtr is an output parameter, it points to the first BD available
 *        for examination.
 *
 * @return
 *   The number of BDs processed by hardware. A value of 0 indicates that no
 *   data is available. No more than BdLimit BDs will be returned.
 *
 * @note Treat BDs returned by this function as read-only.
 *
 * @note This function should not be preempted by another XEmacPs_Bd function
 *       call that modifies the BD space. It is the caller's responsibility to
 *       provide a mutual exclusion mechanism.
 *
 *****************************************************************************/
u32 XEmacPs_BdRingFromHwRx(XEmacPs_BdRing * RingPtr, u32 BdLimit,
				 XEmacPs_Bd ** BdSetPtr)
{
	XEmacPs_Bd *CurBdPtr;
	u32 BdStr = 0U;
	u32 BdCount;
	u32 BdPartialCount;
	u32 Status;

	CurBdPtr = RingPtr->HwHead;
	BdCount = 0U;
	BdPartialCount = 0U;

	/* If no BDs in work group, then there's nothing to search */
	if (RingPtr->HwCnt == 0x00000000U) {
		*BdSetPtr = NULL;
		Status = 0U;
	} else {

	/* Starting at HwHead, keep moving forward in the list until:
	 *  - A BD is encountered with its new/used bit set which means
	 *    hardware has completed processing of that BD.
	 *  - RingPtr->HwTail is reached and RingPtr->HwCnt is reached.
	 *  - The number of requested BDs has been processed
	 */
	while (BdCount < BdLimit) {

		/* Read the status */
			if(CurBdPtr!=NULL){
		BdStr = XEmacPs_BdRead(CurBdPtr, XEMACPS_BD_STAT_OFFSET);
			}
			if ((!(XEmacPs_BdIsRxNew(CurBdPtr)))==TRUE) {
			break;
		}

		BdCount++;

		/* hardware has processed this BD so check the "last" bit. If
                 * it is clear, then there are more BDs for the current packet.
                 * Keep a count of these partial packet BDs.
		 */
			if ((BdStr & XEMACPS_RXBUF_EOF_MASK)!=0x00000000U) {
				BdPartialCount = 0U;
			} else {
			BdPartialCount++;
		}

		/* Move on to next BD in work group */
		CurBdPtr = XEmacPs_BdRingNext(RingPtr, CurBdPtr);
	}

	/* Subtract off any partial packet BDs found */
	BdCount -= BdPartialCount;

	/* If BdCount is non-zero then BDs were found to return. Set return
	 * parameters, update pointers and counters, return success
	 */
		if (BdCount > 0x00000000U) {
		*BdSetPtr = RingPtr->HwHead;
		RingPtr->HwCnt -= BdCount;
		RingPtr->PostCnt += BdCount;
		XEMACPS_RING_SEEKAHEAD(RingPtr, RingPtr->HwHead, BdCount);
			Status = (BdCount);
	}
	else {
		*BdSetPtr = NULL;
			Status = 0U;
	}
}
	return Status;
}


/*****************************************************************************/
/**
 * Frees a set of BDs that had been previously retrieved with
 * XEmacPs_BdRingFromHw().
 *
 * @param RingPtr is a pointer to the instance to be worked on.
 * @param NumBd is the number of BDs to free.
 * @param BdSetPtr is the head of a list of BDs returned by
 * XEmacPs_BdRingFromHw().
 *
 * @return
 *   - XST_SUCCESS if the set of BDs was freed.
 *   - XST_DMA_SG_LIST_ERROR if this function was called out of sequence with
 *     XEmacPs_BdRingFromHw().
 *
 * @note This function should not be preempted by another XEmacPs_Bd function
 *       call that modifies the BD space. It is the caller's responsibility to
 *       provide a mutual exclusion mechanism.
 *
 *****************************************************************************/
LONG XEmacPs_BdRingFree(XEmacPs_BdRing * RingPtr, u32 NumBd,
			XEmacPs_Bd * BdSetPtr)
{
	LONG Status;
	/* if no bds to process, simply return. */
	if (0x00000000U == NumBd){
		Status = (LONG)(XST_SUCCESS);
	} else {
	/* Make sure we are in sync with XEmacPs_BdRingFromHw() */
	if ((RingPtr->PostCnt < NumBd) || (RingPtr->PostHead != BdSetPtr)) {
			Status = (LONG)(XST_DMA_SG_LIST_ERROR);
		} else {
	/* Update pointers and counters */
	RingPtr->FreeCnt += NumBd;
	RingPtr->PostCnt -= NumBd;
	XEMACPS_RING_SEEKAHEAD(RingPtr, RingPtr->PostHead, NumBd);
			Status = (LONG)(XST_SUCCESS);
		}
	}
	return Status;
}


/*****************************************************************************/
/**
 * Check the internal data structures of the BD ring for the provided channel.
 * The following checks are made:
 *
 *   - Is the BD ring linked correctly in physical address space.
 *   - Do the internal pointers point to BDs in the ring.
 *   - Do the internal counters add up.
 *
 * The channel should be stopped prior to calling this function.
 *
 * @param RingPtr is a pointer to the instance to be worked on.
 * @param Direction is either XEMACPS_SEND or XEMACPS_RECV that indicates
 *        which direction.
 *
 * @return
 *   - XST_SUCCESS if the set of BDs was freed.
 *   - XST_DMA_SG_NO_LIST if the list has not been created.
 *   - XST_IS_STARTED if the channel is not stopped.
 *   - XST_DMA_SG_LIST_ERROR if a problem is found with the internal data
 *     structures. If this value is returned, the channel should be reset to
 *     avoid data corruption or system instability.
 *
 * @note This function should not be preempted by another XEmacPs_Bd function
 *       call that modifies the BD space. It is the caller's responsibility to
 *       provide a mutual exclusion mechanism.
 *
 *****************************************************************************/
LONG XEmacPs_BdRingCheck(XEmacPs_BdRing * RingPtr, u8 Direction)
{
	UINTPTR AddrV, AddrP;
	u32 i;

	if ((Direction != (u8)XEMACPS_SEND) && (Direction != (u8)XEMACPS_RECV)) {
		return (LONG)(XST_INVALID_PARAM);
	}

	/* Is the list created */
	if (RingPtr->AllCnt == 0x00000000U) {
		return (LONG)(XST_DMA_SG_NO_LIST);
	}

	/* Can't check if channel is running */
	if (RingPtr->RunState == (u32)XST_DMA_SG_IS_STARTED) {
		return (LONG)(XST_IS_STARTED);
	}

	/* RunState doesn't make sense */
	if (RingPtr->RunState != (u32)XST_DMA_SG_IS_STOPPED) {
		return (LONG)(XST_DMA_SG_LIST_ERROR);
	}

	/* Verify internal pointers point to correct memory space */
	AddrV = (UINTPTR) RingPtr->FreeHead;
	if ((AddrV < RingPtr->BaseBdAddr) || (AddrV > RingPtr->HighBdAddr)) {
		return (LONG)(XST_DMA_SG_LIST_ERROR);
	}

	AddrV = (UINTPTR) RingPtr->PreHead;
	if ((AddrV < RingPtr->BaseBdAddr) || (AddrV > RingPtr->HighBdAddr)) {
		return (LONG)(XST_DMA_SG_LIST_ERROR);
	}

	AddrV = (UINTPTR) RingPtr->HwHead;
	if ((AddrV < RingPtr->BaseBdAddr) || (AddrV > RingPtr->HighBdAddr)) {
		return (LONG)(XST_DMA_SG_LIST_ERROR);
	}

	AddrV = (UINTPTR) RingPtr->HwTail;
	if ((AddrV < RingPtr->BaseBdAddr) || (AddrV > RingPtr->HighBdAddr)) {
		return (LONG)(XST_DMA_SG_LIST_ERROR);
	}

	AddrV = (UINTPTR) RingPtr->PostHead;
	if ((AddrV < RingPtr->BaseBdAddr) || (AddrV > RingPtr->HighBdAddr)) {
		return (LONG)(XST_DMA_SG_LIST_ERROR);
	}

	/* Verify internal counters add up */
	if ((RingPtr->HwCnt + RingPtr->PreCnt + RingPtr->FreeCnt +
	     RingPtr->PostCnt) != RingPtr->AllCnt) {
		return (LONG)(XST_DMA_SG_LIST_ERROR);
	}

	/* Verify BDs are linked correctly */
	AddrV = RingPtr->BaseBdAddr;
	AddrP = RingPtr->PhysBaseAddr + RingPtr->Separation;

	for (i = 1U; i < RingPtr->AllCnt; i++) {
		/* Check BDA for this BD. It should point to next physical addr */
		if (XEmacPs_BdRead(AddrV, XEMACPS_BD_ADDR_OFFSET) != AddrP) {
			return (LONG)(XST_DMA_SG_LIST_ERROR);
		}

		/* Move on to next BD */
		AddrV += RingPtr->Separation;
		AddrP += RingPtr->Separation;
	}

	/* Last BD should have wrap bit set */
	if (XEMACPS_SEND == Direction) {
		if ((!XEmacPs_BdIsTxWrap(AddrV))==TRUE) {
			return (LONG)(XST_DMA_SG_LIST_ERROR);
		}
	}
	else {			/* XEMACPS_RECV */
		if ((!XEmacPs_BdIsRxWrap(AddrV))==TRUE) {
			return (LONG)(XST_DMA_SG_LIST_ERROR);
		}
	}

	/* No problems found */
	return (LONG)(XST_SUCCESS);
}

/*****************************************************************************/
/**
 * Set this bit to mark the last descriptor in the receive buffer descriptor
 * list.
 *
 * @param  BdPtr is the BD pointer to operate on
 *
 * @note
 * C-style signature:
 *    void XEmacPs_BdSetRxWrap(XEmacPs_Bd* BdPtr)
 *
 *****************************************************************************/
static void XEmacPs_BdSetRxWrap(UINTPTR BdPtr)
{
    u32 DataValueRx;
	u32 *TempPtr;

	BdPtr += (u32)(XEMACPS_BD_ADDR_OFFSET);
	TempPtr = (u32 *)BdPtr;
	if(TempPtr != NULL) {
		DataValueRx = *TempPtr;
		DataValueRx |= XEMACPS_RXBUF_WRAP_MASK;
		*TempPtr = DataValueRx;
	}
}

/*****************************************************************************/
/**
 * Sets this bit to mark the last descriptor in the transmit buffer
 * descriptor list.
 *
 * @param  BdPtr is the BD pointer to operate on
 *
 * @note
 * C-style signature:
 *    void XEmacPs_BdSetTxWrap(XEmacPs_Bd* BdPtr)
 *
 *****************************************************************************/
static void XEmacPs_BdSetTxWrap(UINTPTR BdPtr)
{
    u32 DataValueTx;
	u32 *TempPtr;

	BdPtr += (u32)(XEMACPS_BD_STAT_OFFSET);
	TempPtr = (u32 *)BdPtr;
	if(TempPtr != NULL) {
		DataValueTx = *TempPtr;
		DataValueTx |= XEMACPS_TXBUF_WRAP_MASK;
		*TempPtr = DataValueTx;
	}
}
/** @} */
