/*
 * Copyright (c) 2012-2016 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.
 */

/*=== header file includes ===*/
/* generic utilities */
#include <qdf_nbuf.h>           /* qdf_nbuf_t, etc. */
#include <qdf_timer.h>
#include <qdf_time.h>

/* datapath internal interfaces */
#include <ol_txrx_types.h>      /* ol_txrx_pdev_t, etc. */
#include <ol_txrx_internal.h>   /* TXRX_ASSERT, etc. */
#include <ol_rx_reorder.h>      /* ol_rx_reorder_flush, etc. */

#ifdef QCA_SUPPORT_OL_RX_REORDER_TIMEOUT

void ol_rx_reorder_timeout_remove(struct ol_txrx_peer_t *peer, unsigned tid)
{
	struct ol_txrx_pdev_t *pdev;
	struct ol_tx_reorder_cat_timeout_t *rx_reorder_timeout_ac;
	struct ol_rx_reorder_timeout_list_elem_t *list_elem;
	int ac;

	pdev = peer->vdev->pdev;
	ac = TXRX_TID_TO_WMM_AC(tid);
	rx_reorder_timeout_ac = &pdev->rx.reorder_timeout.access_cats[ac];
	list_elem = &peer->tids_rx_reorder[tid].timeout;
	if (!list_elem->active) {
		/* this element has already been removed */
		return;
	}
	list_elem->active = 0;
	TAILQ_REMOVE(&rx_reorder_timeout_ac->virtual_timer_list, list_elem,
		     reorder_timeout_list_elem);
}

static void
ol_rx_reorder_timeout_start(struct ol_tx_reorder_cat_timeout_t
			    *rx_reorder_timeout_ac, uint32_t time_now_ms)
{
	uint32_t duration_ms;
	struct ol_rx_reorder_timeout_list_elem_t *list_elem;

	list_elem = TAILQ_FIRST(&rx_reorder_timeout_ac->virtual_timer_list);

	duration_ms = list_elem->timestamp_ms - time_now_ms;
	qdf_timer_start(&rx_reorder_timeout_ac->timer, duration_ms);
}

static inline void
ol_rx_reorder_timeout_add(struct ol_txrx_peer_t *peer, uint8_t tid)
{
	uint32_t time_now_ms;
	struct ol_txrx_pdev_t *pdev;
	struct ol_tx_reorder_cat_timeout_t *rx_reorder_timeout_ac;
	struct ol_rx_reorder_timeout_list_elem_t *list_elem;
	int ac;
	int start;

	pdev = peer->vdev->pdev;
	ac = TXRX_TID_TO_WMM_AC(tid);
	rx_reorder_timeout_ac = &pdev->rx.reorder_timeout.access_cats[ac];
	list_elem = &peer->tids_rx_reorder[tid].timeout;

	list_elem->active = 1;
	list_elem->peer = peer;
	list_elem->tid = tid;

	/* set the expiration timestamp */
	time_now_ms = qdf_system_ticks_to_msecs(qdf_system_ticks());
	list_elem->timestamp_ms =
		time_now_ms + rx_reorder_timeout_ac->duration_ms;

	/* add to the queue */
	start = TAILQ_EMPTY(&rx_reorder_timeout_ac->virtual_timer_list);
	TAILQ_INSERT_TAIL(&rx_reorder_timeout_ac->virtual_timer_list,
			  list_elem, reorder_timeout_list_elem);
	if (start)
		ol_rx_reorder_timeout_start(rx_reorder_timeout_ac, time_now_ms);
}

void ol_rx_reorder_timeout_update(struct ol_txrx_peer_t *peer, uint8_t tid)
{
	if (!peer)
		return;

	/*
	 * If there are no holes, i.e. no queued frames,
	 * then timeout doesn't apply.
	 */
	if (peer->tids_rx_reorder[tid].num_mpdus == 0)
		return;

	/*
	 * If the virtual timer for this peer-TID is already running,
	 * then leave it.
	 */
	if (peer->tids_rx_reorder[tid].timeout.active)
		return;

	ol_rx_reorder_timeout_add(peer, tid);
}

static void ol_rx_reorder_timeout(void *arg)
{
	struct ol_txrx_pdev_t *pdev;
	struct ol_rx_reorder_timeout_list_elem_t *list_elem, *tmp;
	uint32_t time_now_ms;
	struct ol_tx_reorder_cat_timeout_t *rx_reorder_timeout_ac;

	rx_reorder_timeout_ac = (struct ol_tx_reorder_cat_timeout_t *)arg;
	time_now_ms = qdf_system_ticks_to_msecs(qdf_system_ticks());

	pdev = rx_reorder_timeout_ac->pdev;
	qdf_spin_lock(&pdev->rx.mutex);
/* TODO: conditionally take mutex lock during regular rx */
	TAILQ_FOREACH_SAFE(list_elem,
			   &rx_reorder_timeout_ac->virtual_timer_list,
			   reorder_timeout_list_elem, tmp) {
		unsigned idx_start, idx_end;
		struct ol_txrx_peer_t *peer;

		if (list_elem->timestamp_ms > time_now_ms)
			break;  /* time has not expired yet for this element */

		list_elem->active = 0;
		/* remove the expired element from the list */
		TAILQ_REMOVE(&rx_reorder_timeout_ac->virtual_timer_list,
			     list_elem, reorder_timeout_list_elem);

		peer = list_elem->peer;

		idx_start = 0xffff;     /* start from next_rel_idx */
		ol_rx_reorder_first_hole(peer, list_elem->tid, &idx_end);
		ol_rx_reorder_flush(peer->vdev,
				    peer,
				    list_elem->tid,
				    idx_start, idx_end, htt_rx_flush_release);
	}
	/* restart the timer if unexpired elements are left in the list */
	if (!TAILQ_EMPTY(&rx_reorder_timeout_ac->virtual_timer_list))
		ol_rx_reorder_timeout_start(rx_reorder_timeout_ac, time_now_ms);

	qdf_spin_unlock(&pdev->rx.mutex);
}

void ol_rx_reorder_timeout_init(struct ol_txrx_pdev_t *pdev)
{
	int i;

	for (i = 0; i < QDF_ARRAY_SIZE(pdev->rx.reorder_timeout.access_cats);
		i++) {
		struct ol_tx_reorder_cat_timeout_t *rx_reorder_timeout_ac;
		rx_reorder_timeout_ac =
			&pdev->rx.reorder_timeout.access_cats[i];
		/* init the per-AC timers */
		qdf_timer_init(pdev->osdev,
				       &rx_reorder_timeout_ac->timer,
				       ol_rx_reorder_timeout,
				       rx_reorder_timeout_ac);
		/* init the virtual timer list */
		TAILQ_INIT(&rx_reorder_timeout_ac->virtual_timer_list);
		rx_reorder_timeout_ac->pdev = pdev;
	}
	pdev->rx.reorder_timeout.access_cats[TXRX_WMM_AC_VO].duration_ms = 40;
	pdev->rx.reorder_timeout.access_cats[TXRX_WMM_AC_VI].duration_ms = 100;
	pdev->rx.reorder_timeout.access_cats[TXRX_WMM_AC_BE].duration_ms = 100;
	pdev->rx.reorder_timeout.access_cats[TXRX_WMM_AC_BK].duration_ms = 100;
}

void ol_rx_reorder_timeout_peer_cleanup(struct ol_txrx_peer_t *peer)
{
	int tid;

	for (tid = 0; tid < OL_TXRX_NUM_EXT_TIDS; tid++) {
		if (peer->tids_rx_reorder[tid].timeout.active)
			ol_rx_reorder_timeout_remove(peer, tid);
	}
}

void ol_rx_reorder_timeout_cleanup(struct ol_txrx_pdev_t *pdev)
{
	int i;

	for (i = 0; i < QDF_ARRAY_SIZE(pdev->rx.reorder_timeout.access_cats);
		i++) {
		struct ol_tx_reorder_cat_timeout_t *rx_reorder_timeout_ac;
		rx_reorder_timeout_ac =
			&pdev->rx.reorder_timeout.access_cats[i];
		qdf_timer_stop(&rx_reorder_timeout_ac->timer);
		qdf_timer_free(&rx_reorder_timeout_ac->timer);
	}
}

#endif /* QCA_SUPPORT_OL_RX_REORDER_TIMEOUT */
