/*********************************************************************
 *
 *                 Ethernet Controller API 
 *
 *********************************************************************
 * FileName:        eth_descriptors_remove_lib.c
 * Dependencies:
 * Processor:       PIC32
 *
 * Complier:        MPLAB C32
 *                  MPLAB IDE
 * Company:         Microchip Technology, Inc.
 *
 * Software License Agreement
 * Microchip Audio Library  PIC32 Software.
 * Copyright  2008 Microchip Technology Inc.  All rights reserved.
 * 
 * Microchip licenses the Software for your use with Microchip microcontrollers
 * and Microchip digital signal controllers pursuant to the terms of the
 * Non-Exclusive Software License Agreement accompanying this Software.
 *
 * SOFTWARE AND DOCUMENTATION ARE PROVIDED AS IS WITHOUT WARRANTY
 * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION,
 * ANY WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS
 * FOR A PARTICULAR PURPOSE.
 * MICROCHIP AND ITS LICENSORS ASSUME NO RESPONSIBILITY FOR THE ACCURACY,
 * RELIABILITY OR APPLICATION OF THE SOFTWARE AND DOCUMENTATION.
 * IN NO EVENT SHALL MICROCHIP OR ITS LICENSORS BE LIABLE OR OBLIGATED
 * UNDER CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH
 * OF WARRANTY, OR OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT
 * DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL,
 * SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS
 * OR LOST DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY,
 * SERVICES, OR ANY CLAIMS BY THIRD PARTIES (INCLUDING BUT NOT LIMITED
 * TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
 *
 *$Id: $
 ********************************************************************/

#include "_eth_include.h"


#ifdef _ETH	// the Ethernet device is present

/****************************************************************************
 * Function:        EthDescriptorsRemove
 *
 * PreCondition:    EthMACOpen should have been called.
 *
 * Input:           nDescriptors - number of descriptors to be removed
 *                  dType        - tx/rx descriptors requested
 *                  fFree        - function to release the the memory or NULL
 *
 * Output:          the number of descriptors removed
 *
 * Side Effects:    None
 *
 * Overview:        This function tries to remove the specified number of descriptors from the pool of transmit/receive descriptors.
 *                  These descriptors that are NOT used at the time of call can be freed (i.e. the Tx descriptors not queued for a transmission
 *                  or the not busy Rx descriptors).
 *
 * Note:            - If fFree is 0 then the standard free() is used to release the allocated memory.
 *                  The allocation/deallocation memory functions should be consistent.
 *                  - The complete clean-up is done by EthDescriptorsCleanUp();
 *                  - ETH_DCPT_TYPE_ALL use is invalid. A proper descriptor type (RX or TX) has to be used.
 *****************************************************************************/
int EthDescriptorsRemove(int nDescriptors, eEthDcptType dType, pEthDcptFreeF fFree)
{
	sEthDcptList*	pList;
	sEthDNode*	pN;
	int		removed=0;

	if(dType == ETH_DCPT_TYPE_TX)
	{
		pList=&_EthTxFreeList;
	}
	else if(dType == ETH_DCPT_TYPE_RX)
	{
		pList=&_EthRxFreeList;
	}
	else
	{
		return 0;
	}

	if(!fFree)
	{
		fFree=free;
	}
	
	while(nDescriptors--)
	{
		pN=SlRemoveHead(pList);
		if(!pN)
		{
			break;
		}
		(*fFree)(pN);
		removed++;
	}

	return removed;
}



/****************************************************************************
 * Function:        EthDescriptorsCleanUp
 *
 * PreCondition:    EthClose should have been called. 
 *
 * Input:           dType        - tx/rx/all descriptors requested
 *                  fFree        - function to release the the memory or NULL
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        This function performs descriptors clean-up and removes all the specified descriptors from the pool of transmit/receive descriptors.
 *
 * Note:            - If fFree is 0 then the standard free() is used to release the allocated memory.
 *                  The allocation/deallocation memory functions should be consistent.
 *                  - It does not free the memory allocated for the application supplied "sticky" buffers.
 *                  It is the calling app responsibility.
 *                  - EthClose should have been called or no tx/rx activity should be enabled at the time this function is called.
 *                  - If ETH_DCPT_TYPE_ALL is supplied the function will perform the clean-up of both types of descriptors.
 ******************************************************************************/
void EthDescriptorsCleanUp(eEthDcptType dType, pEthDcptFreeF fFree)
{
	// free all allocated descriptors
	if(!fFree)
	{
		fFree=free;
	}

	if(dType&ETH_DCPT_TYPE_TX)
	{
		_EthFreeDcptList(&_EthTxFreeList, fFree);
		_EthFreeDcptList(&_EthTxBusyList, fFree);
	}

	if(dType&ETH_DCPT_TYPE_RX)
	{
		_EthFreeDcptList(&_EthRxFreeList, fFree);
		_EthFreeDcptList(&_EthRxBusyList, fFree);
	}


}


/****************************************************************************
 * Function:        _EthFreeDcptList
 *
 * PreCondition:    None
 *
 * Input:           pList - list to be cleaned-up
 *                  fFree - function to return the allocated memory
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Helper to clean-up a list.
 *                  The standard free() is used to release the allocated memory.
 *
 * Note:            None
 *****************************************************************************/
void _EthFreeDcptList(sEthDcptList* pList, pEthDcptFreeF fFree)
{
	sEthDNode*	pN;

	while((pN=SlRemoveHead(pList)))
	{
		(*fFree)(pN);
	}

}


#endif	// _ETH


