/*
 * Copyright (c) 2011-2012, 2014-2015 The Linux Foundation. All rights reserved.
 *
 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
 *
 *
 * Permission to use, copy, modify, and/or distribute this software for
 * any purpose with or without fee is hereby granted, provided that the
 * above copyright notice and this permission notice appear in all
 * copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

/*
 * This file was originally distributed by Qualcomm Atheros, Inc.
 * under proprietary terms before Copyright ownership was assigned
 * to the Linux Foundation.
 */

/** ------------------------------------------------------------------------- *
    ------------------------------------------------------------------------- *
    \file csr_link_list.c

    Implementation for the Common link list interfaces.
   ========================================================================== */

#include "csr_link_list.h"
#include "cdf_lock.h"
#include "cdf_memory.h"
#include "cdf_trace.h"
#include "cdf_mc_timer.h"

CDF_INLINE_FN void csr_list_init(tListElem *pList)
{
	pList->last = pList->next = pList;
}

CDF_INLINE_FN void csr_list_remove_entry(tListElem *pEntry)
{
	tListElem *pLast;
	tListElem *pNext;

	pLast = pEntry->last;
	pNext = pEntry->next;
	pLast->next = pNext;
	pNext->last = pLast;
}

CDF_INLINE_FN tListElem *csr_list_remove_head(tListElem *pHead)
{
	tListElem *pEntry;
	tListElem *pNext;

	pEntry = pHead->next;
	pNext = pEntry->next;
	pHead->next = pNext;
	pNext->last = pHead;

	return pEntry;
}

CDF_INLINE_FN tListElem *csr_list_remove_tail(tListElem *pHead)
{
	tListElem *pEntry;
	tListElem *pLast;

	pEntry = pHead->last;
	pLast = pEntry->last;
	pHead->last = pLast;
	pLast->next = pHead;

	return pEntry;
}

CDF_INLINE_FN void csr_list_insert_tail(tListElem *pHead, tListElem *pEntry)
{
	tListElem *pLast;

	pLast = pHead->last;
	pEntry->last = pLast;
	pEntry->next = pHead;
	pLast->next = pEntry;
	pHead->last = pEntry;
}

CDF_INLINE_FN void csr_list_insert_head(tListElem *pHead, tListElem *pEntry)
{
	tListElem *pNext;

	pNext = pHead->next;
	pEntry->next = pNext;
	pEntry->last = pHead;
	pNext->last = pEntry;
	pHead->next = pEntry;
}

/* Insert pNewEntry before pEntry */
void csr_list_insert_entry(tListElem *pEntry, tListElem *pNewEntry)
{
	tListElem *pLast;
	if (!pEntry) {
		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_FATAL,
			  "%s: Error!! pEntry is Null", __func__);
		return;
	}

	pLast = pEntry->last;
	pLast->next = pNewEntry;
	pEntry->last = pNewEntry;
	pNewEntry->next = pEntry;
	pNewEntry->last = pLast;
}

uint32_t csr_ll_count(tDblLinkList *pList)
{
	uint32_t c = 0;

	if (!pList) {
		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_FATAL,
			  "%s: Error!! pList is Null", __func__);
		return c;
	}

	if (pList && (LIST_FLAG_OPEN == pList->Flag)) {
		c = pList->Count;
	}

	return c;
}

void csr_ll_lock(tDblLinkList *pList)
{

	if (!pList) {
		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_FATAL,
			  "%s: Error!! pList is Null", __func__);
		return;
	}

	if (LIST_FLAG_OPEN == pList->Flag) {
		cdf_mutex_acquire(&pList->Lock);
	}
}

void csr_ll_unlock(tDblLinkList *pList)
{

	if (!pList) {
		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_FATAL,
			  "%s: Error!! pList is Null", __func__);
		return;
	}

	if (LIST_FLAG_OPEN == pList->Flag) {
		cdf_mutex_release(&pList->Lock);
	}
}

bool csr_ll_is_list_empty(tDblLinkList *pList, bool fInterlocked)
{
	bool fEmpty = true;

	if (!pList) {
		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_FATAL,
			  "%s: Error!! pList is Null", __func__);
		return fEmpty;
	}

	if (LIST_FLAG_OPEN == pList->Flag) {
		if (fInterlocked) {
			csr_ll_lock(pList);
		}

		fEmpty = csrIsListEmpty(&pList->ListHead);

		if (fInterlocked) {
			csr_ll_unlock(pList);
		}
	}
	return fEmpty;
}

bool csr_ll_find_entry(tDblLinkList *pList, tListElem *pEntryToFind)
{
	bool fFound = false;
	tListElem *pEntry;

	if (!pList) {
		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_FATAL,
			  "%s: Error!! pList is Null", __func__);
		return fFound;
	}

	if (LIST_FLAG_OPEN == pList->Flag) {
		pEntry = csr_ll_peek_head(pList, LL_ACCESS_NOLOCK);

		/* Have to make sure we don't loop back to the head of the list, which will */
		/* happen if the entry is NOT on the list... */

		while (pEntry && (pEntry != &pList->ListHead)) {
			if (pEntry == pEntryToFind) {
				fFound = true;
				break;
			}
			pEntry = pEntry->next;
		}

	}
	return fFound;
}

CDF_STATUS csr_ll_open(tHddHandle hHdd, tDblLinkList *pList)
{
	CDF_STATUS status = CDF_STATUS_SUCCESS;
	CDF_STATUS cdf_status;

	if (!pList) {
		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_FATAL,
			  "%s: Error!! pList is Null", __func__);
		return CDF_STATUS_E_FAILURE;
	}

	if (LIST_FLAG_OPEN != pList->Flag) {
		pList->Count = 0;
		pList->cmdTimeoutTimer = NULL;
		cdf_status = cdf_mutex_init(&pList->Lock);

		if (CDF_IS_STATUS_SUCCESS(cdf_status)) {
			csr_list_init(&pList->ListHead);
			pList->Flag = LIST_FLAG_OPEN;
			pList->hHdd = hHdd;
		} else {
			status = CDF_STATUS_E_FAILURE;
		}
	}
	return status;
}

void csr_ll_close(tDblLinkList *pList)
{
	if (!pList) {
		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_FATAL,
			  "%s: Error!! pList is Null", __func__);
		return;
	}

	if (LIST_FLAG_OPEN == pList->Flag) {
		/* Make sure the list is empty... */
		csr_ll_purge(pList, LL_ACCESS_LOCK);
		cdf_mutex_destroy(&pList->Lock);
		pList->Flag = LIST_FLAG_CLOSE;
	}
}

void csr_ll_insert_tail(tDblLinkList *pList, tListElem *pEntry,
			bool fInterlocked)
{
	if (!pList) {
		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_FATAL,
			  "%s: Error!! pList is Null", __func__);
		return;
	}

	if (LIST_FLAG_OPEN == pList->Flag) {
		if (fInterlocked) {
			csr_ll_lock(pList);
		}
		csr_list_insert_tail(&pList->ListHead, pEntry);
		pList->Count++;
		if (fInterlocked) {
			csr_ll_unlock(pList);
		}
	}
}

void csr_ll_insert_head(tDblLinkList *pList, tListElem *pEntry,
			bool fInterlocked)
{

	if (!pList) {
		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_FATAL,
			  "%s: Error!! pList is Null", __func__);
		return;
	}

	if (LIST_FLAG_OPEN == pList->Flag) {
		if (fInterlocked) {
			csr_ll_lock(pList);
		}
		csr_list_insert_head(&pList->ListHead, pEntry);
		pList->Count++;
		if (fInterlocked) {
			csr_ll_unlock(pList);
		}
		if (pList->cmdTimeoutTimer && pList->cmdTimeoutDuration) {
			/* timer to detect pending command in activelist */
			cdf_mc_timer_start(pList->cmdTimeoutTimer,
					   pList->cmdTimeoutDuration);
		}
	}
}

void csr_ll_insert_entry(tDblLinkList *pList, tListElem *pEntry,
			 tListElem *pNewEntry, bool fInterlocked)
{
	if (!pList) {
		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_FATAL,
			  "%s: Error!! pList is Null", __func__);
		return;
	}

	if (LIST_FLAG_OPEN == pList->Flag) {
		if (fInterlocked) {
			csr_ll_lock(pList);
		}
		csr_list_insert_entry(pEntry, pNewEntry);
		pList->Count++;
		if (fInterlocked) {
			csr_ll_unlock(pList);
		}
	}
}

tListElem *csr_ll_remove_tail(tDblLinkList *pList, bool fInterlocked)
{
	tListElem *pEntry = NULL;

	if (!pList) {
		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_FATAL,
			  "%s: Error!! pList is Null", __func__);
		return pEntry;
	}

	if (LIST_FLAG_OPEN == pList->Flag) {
		if (fInterlocked) {
			csr_ll_lock(pList);
		}

		if (!csrIsListEmpty(&pList->ListHead)) {

			pEntry = csr_list_remove_tail(&pList->ListHead);
			pList->Count--;
		}
		if (fInterlocked) {
			csr_ll_unlock(pList);
		}
	}

	return pEntry;
}

tListElem *csr_ll_peek_tail(tDblLinkList *pList, bool fInterlocked)
{
	tListElem *pEntry = NULL;

	if (!pList) {
		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_FATAL,
			  "%s: Error!! pList is Null", __func__);
		return pEntry;
	}

	if (LIST_FLAG_OPEN == pList->Flag) {
		if (fInterlocked) {
			csr_ll_lock(pList);
		}

		if (!csrIsListEmpty(&pList->ListHead)) {
			pEntry = pList->ListHead.last;
		}
		if (fInterlocked) {
			csr_ll_unlock(pList);
		}
	}

	return pEntry;
}

tListElem *csr_ll_remove_head(tDblLinkList *pList, bool fInterlocked)
{
	tListElem *pEntry = NULL;

	if (!pList) {
		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_FATAL,
			  "%s: Error!! pList is Null", __func__);
		return pEntry;
	}

	if (LIST_FLAG_OPEN == pList->Flag) {
		if (fInterlocked) {
			csr_ll_lock(pList);
		}

		if (!csrIsListEmpty(&pList->ListHead)) {
			pEntry = csr_list_remove_head(&pList->ListHead);
			pList->Count--;
		}

		if (fInterlocked) {
			csr_ll_unlock(pList);
		}
	}

	return pEntry;
}

tListElem *csr_ll_peek_head(tDblLinkList *pList, bool fInterlocked)
{
	tListElem *pEntry = NULL;

	if (!pList) {
		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_FATAL,
			  "%s: Error!! pList is Null", __func__);
		return pEntry;
	}

	if (LIST_FLAG_OPEN == pList->Flag) {
		if (fInterlocked) {
			csr_ll_lock(pList);
		}

		if (!csrIsListEmpty(&pList->ListHead)) {
			pEntry = pList->ListHead.next;
		}
		if (fInterlocked) {
			csr_ll_unlock(pList);
		}
	}

	return pEntry;
}

void csr_ll_purge(tDblLinkList *pList, bool fInterlocked)
{
	tListElem *pEntry;

	if (!pList) {
		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_FATAL,
			  "%s: Error!! pList is Null", __func__);
		return;
	}

	if (LIST_FLAG_OPEN == pList->Flag) {
		if (fInterlocked) {
			csr_ll_lock(pList);
		}
		while ((pEntry = csr_ll_remove_head(pList, LL_ACCESS_NOLOCK))) {
			/* just remove everything from the list until */
			/* nothing left on the list. */
		}
		if (fInterlocked) {
			csr_ll_unlock(pList);
		}
	}
}

bool csr_ll_remove_entry(tDblLinkList *pList, tListElem *pEntryToRemove,
			 bool fInterlocked)
{
	bool fFound = false;
	tListElem *pEntry;

	if (!pList) {
		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_FATAL,
			  "%s: Error!! pList is Null", __func__);
		return fFound;
	}

	if (LIST_FLAG_OPEN == pList->Flag) {
		if (fInterlocked) {
			csr_ll_lock(pList);
		}

		pEntry = csr_ll_peek_head(pList, LL_ACCESS_NOLOCK);

		/* Have to make sure we don't loop back to the head of the list, which will */
		/* happen if the entry is NOT on the list... */
		while (pEntry && (pEntry != &pList->ListHead)) {
			if (pEntry == pEntryToRemove) {
				csr_list_remove_entry(pEntry);
				pList->Count--;

				fFound = true;
				break;
			}

			pEntry = pEntry->next;
		}
		if (fInterlocked) {
			csr_ll_unlock(pList);
		}
		if (pList->cmdTimeoutTimer) {
			cdf_mc_timer_stop(pList->cmdTimeoutTimer);
		}
	}

	return fFound;
}

tListElem *csr_ll_next(tDblLinkList *pList, tListElem *pEntry,
		       bool fInterlocked)
{
	tListElem *pNextEntry = NULL;

	if (!pList) {
		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_FATAL,
			  "%s: Error!! pList is Null", __func__);
		return pNextEntry;
	}

	if (LIST_FLAG_OPEN == pList->Flag) {
		if (fInterlocked) {
			csr_ll_lock(pList);
		}

		if (!csrIsListEmpty(&pList->ListHead)
		    && csr_ll_find_entry(pList, pEntry)) {
			pNextEntry = pEntry->next;
			/* Make sure we don't walk past the head */
			if (pNextEntry == &pList->ListHead) {
				pNextEntry = NULL;
			}
		}

		if (fInterlocked) {
			csr_ll_unlock(pList);
		}
	}

	return pNextEntry;
}

tListElem *csr_ll_previous(tDblLinkList *pList, tListElem *pEntry,
			   bool fInterlocked)
{
	tListElem *pNextEntry = NULL;

	if (!pList) {
		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_FATAL,
			  "%s: Error!! pList is Null", __func__);
		return pNextEntry;
	}

	if (LIST_FLAG_OPEN == pList->Flag) {
		if (fInterlocked) {
			csr_ll_lock(pList);
		}

		if (!csrIsListEmpty(&pList->ListHead)
		    && csr_ll_find_entry(pList, pEntry)) {
			pNextEntry = pEntry->last;
			/* Make sure we don't walk past the head */
			if (pNextEntry == &pList->ListHead) {
				pNextEntry = NULL;
			}
		}

		if (fInterlocked) {
			csr_ll_unlock(pList);
		}
	}

	return pNextEntry;
}
