/*
 * Copyright (c) 2011-2018 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 <adf_nbuf.h>          /* adf_nbuf_t, etc. */
#include <adf_os_mem.h>        /* adf_os_mem_alloc */

#include <ieee80211.h>         /* IEEE80211_SEQ_MAX */

/* external interfaces */
#include <ol_txrx_api.h>       /* ol_txrx_pdev_handle */
#include <ol_txrx_htt_api.h>   /* ol_rx_addba_handler, etc. */
#include <ol_ctrl_txrx_api.h>  /* ol_ctrl_rx_addba_complete */
#include <ol_htt_rx_api.h>     /* htt_rx_desc_frame_free */
#include <ol_ctrl_txrx_api.h> /* ol_rx_err */

/* datapath internal interfaces */
#include <ol_txrx_peer_find.h>     /* ol_txrx_peer_find_by_id */
#include <ol_txrx_internal.h>      /* TXRX_ASSERT */
#include <ol_rx_reorder_timeout.h> /* OL_RX_REORDER_TIMEOUT_REMOVE, etc. */
#include <ol_rx_reorder.h>
#include <ol_rx_defrag.h>


/*=== data types and defines ===*/
#define OL_RX_REORDER_ROUND_PWR2(value) g_log2ceil[value]

/*=== global variables ===*/

static char g_log2ceil[] = {
    1, // 0 -> 1
    1, // 1 -> 1
    2, // 2 -> 2
    4, 4, // 3-4 -> 4
    8, 8, 8, 8, // 5-8 -> 8
    16, 16, 16, 16, 16, 16, 16, 16, // 9-16 -> 16
    32, 32, 32, 32, 32, 32, 32, 32,
    32, 32, 32, 32, 32, 32, 32, 32, // 17-32 -> 32
    64, 64, 64, 64, 64, 64, 64, 64,
    64, 64, 64, 64, 64, 64, 64, 64,
    64, 64, 64, 64, 64, 64, 64, 64,
    64, 64, 64, 64, 64, 64, 64, 64, // 33-64 -> 64
};


/*=== function definitions ===*/

/*---*/

#define QCA_SUPPORT_RX_REORDER_RELEASE_CHECK 0
#define OL_RX_REORDER_IDX_START_SELF_SELECT(peer, tid, idx_start) /* no-op */
#define OL_RX_REORDER_IDX_WRAP(idx, win_sz, win_sz_mask) idx &= win_sz_mask;
#define OL_RX_REORDER_IDX_MAX(win_sz, win_sz_mask) win_sz_mask
#define OL_RX_REORDER_IDX_INIT(seq_num, win_sz, win_sz_mask) 0 /* n/a */
#define OL_RX_REORDER_NO_HOLES(rx_reorder) 0
#define OL_RX_REORDER_MPDU_CNT_INCR(rx_reorder, incr) /* n/a */
#define OL_RX_REORDER_MPDU_CNT_DECR(rx_reorder, decr) /* n/a */


/*---*/

/* reorder array elements are known to be non-NULL */
#define OL_RX_REORDER_LIST_APPEND(head_msdu, tail_msdu, rx_reorder_array_elem) \
    do { \
        if (tail_msdu) { \
            adf_nbuf_set_next(tail_msdu, rx_reorder_array_elem->head); \
        } \
    } while (0)


/* functions called by txrx components */

void ol_rx_reorder_init(struct ol_rx_reorder_t *rx_reorder, u_int8_t tid)
{
    rx_reorder->win_sz = 1;
    rx_reorder->win_sz_mask = 0;
    rx_reorder->array = &rx_reorder->base;
    rx_reorder->base.head = rx_reorder->base.tail = NULL;
    rx_reorder->tid = tid;
    rx_reorder->defrag_timeout_ms = 0;

    rx_reorder->defrag_waitlist_elem.tqe_next = NULL;
    rx_reorder->defrag_waitlist_elem.tqe_prev = NULL;
}

void ol_rx_reorder_update_history(struct ol_txrx_peer_t *peer,
	uint8_t msg_type, uint8_t tid, uint8_t start_seq,
	uint8_t end_seq, uint8_t reorder_idx)
{
	uint8_t index;

	if (!peer->reorder_history)
		return;

	index = peer->reorder_history->curr_index++;
	peer->reorder_history->record[index].msg_type = msg_type;
	peer->reorder_history->record[index].peer_id = peer->local_id;
	peer->reorder_history->record[index].tid = tid;
	peer->reorder_history->record[index].reorder_idx = reorder_idx;
	peer->reorder_history->record[index].start_seq = start_seq;
	peer->reorder_history->record[index].end_seq = end_seq;

	if (peer->reorder_history->curr_index >= OL_MAX_RX_REORDER_HISTORY) {
		peer->reorder_history->curr_index = 0;
		peer->reorder_history->wrap_around = 1;
	}
}

static enum htt_rx_status
ol_rx_reorder_seq_num_check(
    struct ol_txrx_pdev_t *pdev,
    struct ol_txrx_peer_t *peer,
    unsigned tid,
    unsigned seq_num)
{
    unsigned seq_num_delta;

    /* don't check the new seq_num against last_seq if last_seq is not valid */
    if (peer->tids_last_seq[tid] == IEEE80211_SEQ_MAX) {
        return htt_rx_status_ok;
    }
    /*
     * For duplicate detection, it might be helpful to also check
     * whether the retry bit is set or not - a strict duplicate packet
     * should be the one with retry bit set.
     * However, since many implementations do not set the retry bit,
     * and since this same function is also used for filtering out
     * late-arriving frames (frames that arive after their rx reorder
     * timeout has expired) which are not retries, don't bother checking
     * the retry bit for now.
     */
    /* note: if new seq_num == old seq_num, seq_num_delta = 4095 */
    seq_num_delta = (seq_num - 1 - peer->tids_last_seq[tid]) &
        (IEEE80211_SEQ_MAX-1); /* account for wraparound */

    if (seq_num_delta > (IEEE80211_SEQ_MAX >> 1)) {
         return htt_rx_status_err_replay; /* or maybe htt_rx_status_err_dup */
    }
    return htt_rx_status_ok;
}

/**
 * ol_rx_seq_num_check() - Does duplicate detection for mcast packets and
 *                           duplicate detection & check for out-of-order
 *                           packets for unicast packets.
 * @pdev:                        Pointer to pdev maintained by OL
 * @peer:                        Pointer to peer structure maintained by OL
 * @tid:                         TID value passed as part of HTT msg by f/w
 * @rx_mpdu_desc:                Pointer to Rx Descriptor for the given MPDU
 *
 *  This function
 *      1) For Multicast Frames -- does duplicate detection
 *          A frame is considered duplicate & dropped if it has a seq.number
 *          which is received twice in succession and with the retry bit set
 *          in the second case.
 *          A frame which is older than the last sequence number received
 *          is not considered duplicate but out-of-order. This function does
 *          perform out-of-order check for multicast frames, which is in
 *          keeping with the 802.11 2012 spec section 9.3.2.10
 *      2) For Unicast Frames -- does duplicate detection & out-of-order check
 *          only for non-aggregation tids.
 *
 * Return:        Returns htt_rx_status_err_replay, if packet needs to be
 *                dropped, htt_rx_status_ok otherwise.
 */
enum htt_rx_status
ol_rx_seq_num_check(struct ol_txrx_pdev_t *pdev,
					struct ol_txrx_peer_t *peer,
					uint8_t tid,
					void *rx_mpdu_desc)
{
	uint16_t pkt_tid = 0xffff;
	uint16_t seq_num = IEEE80211_SEQ_MAX;
	bool retry = 0;

	seq_num = htt_rx_mpdu_desc_seq_num(pdev->htt_pdev, rx_mpdu_desc);

	 /* For mcast packets, we only the dup-detection, not re-order check */

	if (adf_os_unlikely(OL_RX_MCAST_TID == tid)) {

		pkt_tid = htt_rx_mpdu_desc_tid(pdev->htt_pdev, rx_mpdu_desc);

		/* Invalid packet TID, expected only for HL */
		/* Pass the packet on */
		if (adf_os_unlikely(pkt_tid >= OL_TXRX_NUM_EXT_TIDS))
			return htt_rx_status_ok;

		retry = htt_rx_mpdu_desc_retry(pdev->htt_pdev, rx_mpdu_desc);

		/*
		 * At this point, we define frames to be duplicate if they arrive
		 * "ONLY" in succession with the same sequence number and the last
		 * one has the retry bit set. For an older frame, we consider that
		 * as an out of order frame, and hence do not perform the dup-detection
		 * or out-of-order check for multicast frames as per discussions & spec
		 * Hence "seq_num <= last_seq_num" check is not necessary.
		 */
		if (adf_os_unlikely(retry &&
			(seq_num == peer->tids_mcast_last_seq[pkt_tid]))) {/* drop mcast */
			TXRX_STATS_INCR(pdev, priv.rx.err.msdu_mc_dup_drop);
			return htt_rx_status_err_replay;
		} else {
			/*
			 * This is a multicast packet likely to be passed on...
			 * Set the mcast last seq number here
			 * This is fairly accurate since:
			 * a) f/w sends multicast as separate PPDU/HTT messages
			 * b) Mcast packets are not aggregated & hence single
			 * c) Result of b) is that, flush / release bit is set always
			 *	on the mcast packets, so likely to be immediatedly released.
			 */
			peer->tids_mcast_last_seq[pkt_tid] = seq_num;
			return htt_rx_status_ok;
		}
	} else
		return ol_rx_reorder_seq_num_check(pdev, peer, tid, seq_num);
}

void
ol_rx_reorder_store(
    struct ol_txrx_pdev_t *pdev,
    struct ol_txrx_peer_t *peer,
    unsigned tid,
    unsigned idx,
    adf_nbuf_t head_msdu,
    adf_nbuf_t tail_msdu)
{
    struct ol_rx_reorder_array_elem_t *rx_reorder_array_elem;

    idx &= peer->tids_rx_reorder[tid].win_sz_mask;
    rx_reorder_array_elem = &peer->tids_rx_reorder[tid].array[idx];
    if (rx_reorder_array_elem->head) {
        adf_nbuf_set_next(rx_reorder_array_elem->tail, head_msdu);
    } else {
        rx_reorder_array_elem->head = head_msdu;
	OL_RX_REORDER_MPDU_CNT_INCR(&peer->tids_rx_reorder[tid], 1);
    }
    rx_reorder_array_elem->tail = tail_msdu;
}

void
ol_rx_reorder_release(
    struct ol_txrx_vdev_t *vdev,
    struct ol_txrx_peer_t *peer,
    unsigned tid,
    unsigned idx_start,
    unsigned idx_end)
{
    unsigned idx;
    unsigned win_sz, win_sz_mask;
    struct ol_rx_reorder_array_elem_t *rx_reorder_array_elem;
    adf_nbuf_t head_msdu;
    adf_nbuf_t tail_msdu;

    OL_RX_REORDER_IDX_START_SELF_SELECT(peer, tid, &idx_start);
    peer->tids_next_rel_idx[tid] = (u_int16_t)idx_end; /* may get reset below */

    win_sz = peer->tids_rx_reorder[tid].win_sz;
    win_sz_mask = peer->tids_rx_reorder[tid].win_sz_mask;
    idx_start &= win_sz_mask;
    idx_end   &= win_sz_mask;
    rx_reorder_array_elem = &peer->tids_rx_reorder[tid].array[idx_start];

    head_msdu = rx_reorder_array_elem->head;
    tail_msdu = rx_reorder_array_elem->tail;
    rx_reorder_array_elem->head = rx_reorder_array_elem->tail = NULL;
    if (head_msdu) {
        OL_RX_REORDER_MPDU_CNT_DECR(&peer->tids_rx_reorder[tid], 1);
    }

    idx = (idx_start + 1);
    OL_RX_REORDER_IDX_WRAP(idx, win_sz, win_sz_mask);
    while (idx != idx_end) {
        rx_reorder_array_elem = &peer->tids_rx_reorder[tid].array[idx];
        if (rx_reorder_array_elem->head) {
            OL_RX_REORDER_MPDU_CNT_DECR(&peer->tids_rx_reorder[tid], 1);
            OL_RX_REORDER_LIST_APPEND(
                head_msdu, tail_msdu, rx_reorder_array_elem);
            tail_msdu = rx_reorder_array_elem->tail;
        }
        rx_reorder_array_elem->head = rx_reorder_array_elem->tail = NULL;
        idx++;
        OL_RX_REORDER_IDX_WRAP(idx, win_sz, win_sz_mask);
    }
    if (head_msdu) {
        u_int16_t seq_num;
        htt_pdev_handle htt_pdev = vdev->pdev->htt_pdev;

        /*
         * This logic is not quite correct - the last_seq value should be
         * the sequence number of the final MPDU released rather than the
         * initial MPDU released.
         * However, tracking the sequence number of the first MPDU in the
         * released batch works well enough:
         * For Peregrine and Rome, the last_seq is checked only for
         * non-aggregate cases, where only one MPDU at a time is released.
         * For Riva, Pronto, and Northstar, the last_seq is checked to
         * filter out late-arriving rx frames, whose sequence number will
         * be less than the first MPDU in this release batch.
         */
        seq_num = htt_rx_mpdu_desc_seq_num(
            htt_pdev, htt_rx_msdu_desc_retrieve(htt_pdev, head_msdu));
        peer->tids_last_seq[tid] = seq_num;
        /* rx_opt_proc takes a NULL-terminated list of msdu netbufs */
        adf_nbuf_set_next(tail_msdu, NULL);
        peer->rx_opt_proc(vdev, peer, tid, head_msdu);
    }
    /*
     * If the rx reorder timeout is handled by host SW rather than the
     * target's rx reorder logic, then stop the timer here.
     * (If there are remaining rx holes, then the timer will be restarted.)
     */
    OL_RX_REORDER_TIMEOUT_REMOVE(peer, tid);
}

void
ol_rx_reorder_flush(
    struct ol_txrx_vdev_t *vdev,
    struct ol_txrx_peer_t *peer,
    unsigned tid,
    unsigned idx_start,
    unsigned idx_end,
    enum htt_rx_flush_action action)
{
    struct ol_txrx_pdev_t *pdev;
    unsigned win_sz;
    u_int8_t win_sz_mask;
    struct ol_rx_reorder_array_elem_t *rx_reorder_array_elem;
    adf_nbuf_t head_msdu = NULL;
    adf_nbuf_t tail_msdu = NULL;

    pdev = vdev->pdev;
    win_sz = peer->tids_rx_reorder[tid].win_sz;
    win_sz_mask = peer->tids_rx_reorder[tid].win_sz_mask;

    OL_RX_REORDER_IDX_START_SELF_SELECT(peer, tid, &idx_start);
    /* a idx_end value of 0xffff means to flush the entire array */
    if (idx_end == 0xffff) {
        idx_end = idx_start;
        /*
         * The array is being flushed in entirety because the block
         * ack window has been shifted to a new position that does not
         * overlap with the old position.  (Or due to reception of a
         * DELBA.)
         * Thus, since the block ack window is essentially being reset,
         * reset the "next release index".
         */
        peer->tids_next_rel_idx[tid] = OL_RX_REORDER_IDX_INIT(
            0/*n/a*/, win_sz, win_sz_mask);
    } else {
        peer->tids_next_rel_idx[tid] = (u_int16_t)idx_end;
    }

    idx_start &= win_sz_mask;
    idx_end   &= win_sz_mask;

    do {
        rx_reorder_array_elem =
            &peer->tids_rx_reorder[tid].array[idx_start];
        idx_start = (idx_start + 1);
        OL_RX_REORDER_IDX_WRAP(idx_start, win_sz, win_sz_mask);

        if (rx_reorder_array_elem->head) {
            OL_RX_REORDER_MPDU_CNT_DECR(&peer->tids_rx_reorder[tid], 1);
            if (head_msdu == NULL) {
                head_msdu = rx_reorder_array_elem->head;
                tail_msdu = rx_reorder_array_elem->tail;
                rx_reorder_array_elem->head = NULL;
                rx_reorder_array_elem->tail = NULL;
                continue;
            }
            adf_nbuf_set_next(tail_msdu, rx_reorder_array_elem->head);
            tail_msdu = rx_reorder_array_elem->tail;
            rx_reorder_array_elem->head = rx_reorder_array_elem->tail = NULL;
        }
    } while (idx_start != idx_end);

    ol_rx_defrag_waitlist_remove(peer, tid);

    if (head_msdu) {
        u_int16_t seq_num;
        htt_pdev_handle htt_pdev = vdev->pdev->htt_pdev;

        seq_num = htt_rx_mpdu_desc_seq_num(
            htt_pdev, htt_rx_msdu_desc_retrieve(htt_pdev, head_msdu));
        peer->tids_last_seq[tid] = seq_num;
        /* rx_opt_proc takes a NULL-terminated list of msdu netbufs */
        adf_nbuf_set_next(tail_msdu, NULL);
        if (action == htt_rx_flush_release) {
            peer->rx_opt_proc(vdev, peer, tid, head_msdu);
        } else {
            do {
                adf_nbuf_t next;
                next = adf_nbuf_next(head_msdu);
                htt_rx_desc_frame_free(pdev->htt_pdev, head_msdu);
                head_msdu = next;
            } while (head_msdu);
        }
    }
    /*
     * If the rx reorder array is empty, then reset the last_seq value -
     * it is likely that a BAR or a sequence number shift caused the
     * sequence number to jump, so the old last_seq value is not relevant.
     */
    if (OL_RX_REORDER_NO_HOLES(&peer->tids_rx_reorder[tid])) {
        peer->tids_last_seq[tid] = IEEE80211_SEQ_MAX; /* invalid */
    }

    OL_RX_REORDER_TIMEOUT_REMOVE(peer, tid);
}

void
ol_rx_reorder_first_hole(
    struct ol_txrx_peer_t *peer,
    unsigned tid,
    unsigned *idx_end)
{
    unsigned win_sz, win_sz_mask;
    unsigned idx_start = 0, tmp_idx = 0;

    win_sz = peer->tids_rx_reorder[tid].win_sz;
    win_sz_mask = peer->tids_rx_reorder[tid].win_sz_mask;

    OL_RX_REORDER_IDX_START_SELF_SELECT(peer, tid, &idx_start);
    tmp_idx++;
    OL_RX_REORDER_IDX_WRAP(tmp_idx, win_sz, win_sz_mask);
    /* bypass the initial hole */
    while (tmp_idx != idx_start &&
           !peer->tids_rx_reorder[tid].array[tmp_idx].head)
    {
        tmp_idx++;
        OL_RX_REORDER_IDX_WRAP(tmp_idx, win_sz, win_sz_mask);
    }
    /* bypass the present frames following the initial hole */
    while (tmp_idx != idx_start &&
           peer->tids_rx_reorder[tid].array[tmp_idx].head)
    {
        tmp_idx++;
        OL_RX_REORDER_IDX_WRAP(tmp_idx, win_sz, win_sz_mask);
    }
    /*
     * idx_end is exclusive rather than inclusive.
     * In other words, it is the index of the first slot of the second
     * hole, rather than the index of the final present frame following
     * the first hole.
     */
    *idx_end = tmp_idx;
}

#ifdef HL_RX_AGGREGATION_HOLE_DETCTION

/**
 * ol_rx_reorder_detect_hole - ol rx reorder detect hole
 * @peer: ol_txrx_peer_t
 * @tid: tid
 * @idx_start: idx_start
 *
 * Return: void
 */
static void ol_rx_reorder_detect_hole(struct ol_txrx_peer_t *peer,
					uint32_t tid,
					uint32_t idx_start)
{
	uint32_t win_sz_mask, next_rel_idx, hole_size;

	if (peer->tids_next_rel_idx[tid] == INVALID_REORDER_INDEX)
		return;

	win_sz_mask = peer->tids_rx_reorder[tid].win_sz_mask;
	/* Return directly if block-ack not enable */
	if (win_sz_mask == 0)
		return;

	idx_start &= win_sz_mask;
	next_rel_idx = peer->tids_next_rel_idx[tid] & win_sz_mask;

	if (idx_start != next_rel_idx) {
		hole_size = ((int)idx_start - (int)next_rel_idx) & win_sz_mask;

		ol_rx_aggregation_hole(hole_size);
	}

	return;
}

#else

/**
 * ol_rx_reorder_detect_hole - ol rx reorder detect hole
 * @peer: ol_txrx_peer_t
 * @tid: tid
 * @idx_start: idx_start
 *
 * Return: void
 */
static void ol_rx_reorder_detect_hole(struct ol_txrx_peer_t *peer,
					uint32_t tid,
					uint32_t idx_start)
{
	/* no-op */
}

#endif

void
ol_rx_reorder_peer_cleanup(
    struct ol_txrx_vdev_t *vdev, struct ol_txrx_peer_t *peer)
{
    int tid;
    for (tid = 0; tid < OL_TXRX_NUM_EXT_TIDS; tid++) {
        ol_rx_reorder_flush(vdev, peer, tid, 0, 0, htt_rx_flush_discard);
    }
    OL_RX_REORDER_TIMEOUT_PEER_CLEANUP(peer);
}


/* functions called by HTT */

void
ol_rx_addba_handler(
    ol_txrx_pdev_handle pdev,
    u_int16_t peer_id,
    u_int8_t tid,
    u_int8_t win_sz,
    u_int16_t start_seq_num,
    u_int8_t failed)
{
    u_int8_t round_pwr2_win_sz;
    unsigned array_size;
    struct ol_txrx_peer_t *peer;
    struct ol_rx_reorder_t *rx_reorder;

    if (tid >= OL_TXRX_NUM_EXT_TIDS) {
        TXRX_PRINT(TXRX_PRINT_LEVEL_ERR,
                "%s:  invalid tid, %u\n", __func__, tid);
        WARN_ON(1);
        return;
    }

    peer = ol_txrx_peer_find_by_id(pdev, peer_id);
    if (peer == NULL) {
        return;
    }

    if (pdev->cfg.host_addba) {
        ol_ctrl_rx_addba_complete(
            pdev->ctrl_pdev, &peer->mac_addr.raw[0], tid, failed);
    }
    if (failed) {
        return;
    }

    peer->tids_last_seq[tid] = IEEE80211_SEQ_MAX; /* invalid */
    rx_reorder = &peer->tids_rx_reorder[tid];

    TXRX_ASSERT2(win_sz <= 64);
    rx_reorder->win_sz = win_sz;
    round_pwr2_win_sz = OL_RX_REORDER_ROUND_PWR2(win_sz);
    array_size = round_pwr2_win_sz * sizeof(struct ol_rx_reorder_array_elem_t);
    rx_reorder->array = adf_os_mem_alloc(pdev->osdev, array_size);
    TXRX_ASSERT1(rx_reorder->array);
    adf_os_mem_set(rx_reorder->array, 0x0, array_size);

    rx_reorder->win_sz_mask = round_pwr2_win_sz - 1;
    rx_reorder->num_mpdus = 0;

    peer->tids_next_rel_idx[tid] = OL_RX_REORDER_IDX_INIT(
        start_seq_num, rx_reorder->win_sz, rx_reorder->win_sz_mask);
}

void
ol_rx_delba_handler(
    ol_txrx_pdev_handle pdev,
    u_int16_t peer_id,
    u_int8_t tid)
{
    struct ol_txrx_peer_t *peer;
    struct ol_rx_reorder_t *rx_reorder;

    if (tid >= OL_TXRX_NUM_EXT_TIDS) {
        TXRX_PRINT(TXRX_PRINT_LEVEL_ERR,
                "%s:  invalid tid, %u\n", __func__, tid);
        WARN_ON(1);
        return;
    }

    peer = ol_txrx_peer_find_by_id(pdev, peer_id);
    if (peer == NULL) {
        return;
    }
    peer->tids_next_rel_idx[tid] = INVALID_REORDER_INDEX; /* invalid value */
    rx_reorder = &peer->tids_rx_reorder[tid];

    /* check that there really was a block ack agreement */
    TXRX_ASSERT1(rx_reorder->win_sz_mask != 0);
    /*
     * Deallocate the old rx reorder array.
     * The call to ol_rx_reorder_init below
     * will reset rx_reorder->array to point to
     * the single-element statically-allocated reorder array
     * used for non block-ack cases.
     */
    if (rx_reorder->array != &rx_reorder->base) {
        TXRX_PRINT(TXRX_PRINT_LEVEL_INFO1, "%s, delete reorder array, tid:%d\n",
                   __func__, tid);
        adf_os_mem_free(rx_reorder->array);
    }

    /* set up the TID with default parameters (ARQ window size = 1) */
    ol_rx_reorder_init(rx_reorder, tid);
}

void
ol_rx_flush_handler(
    ol_txrx_pdev_handle pdev,
    u_int16_t peer_id,
    u_int8_t tid,
    u_int16_t idx_start,
    u_int16_t idx_end,
    enum htt_rx_flush_action action)
{
    struct ol_txrx_vdev_t *vdev = NULL;
    void *rx_desc;
    struct ol_txrx_peer_t *peer;
    int idx;
    struct ol_rx_reorder_array_elem_t *rx_reorder_array_elem;
    htt_pdev_handle htt_pdev = pdev->htt_pdev;

    if (tid >= OL_TXRX_NUM_EXT_TIDS) {
        TXRX_PRINT(TXRX_PRINT_LEVEL_ERR,
                    "%s:  invalid tid, %u\n",
                    __FUNCTION__,
                    tid);
        return;
    }

    peer = ol_txrx_peer_find_by_id(pdev, peer_id);
    if (peer) {
        vdev = peer->vdev;
    } else {
        return;
    }

    OL_RX_REORDER_TIMEOUT_MUTEX_LOCK(pdev);

    idx = idx_start & peer->tids_rx_reorder[tid].win_sz_mask;
    rx_reorder_array_elem = &peer->tids_rx_reorder[tid].array[idx];
    if (rx_reorder_array_elem->head) {
        rx_desc =
            htt_rx_msdu_desc_retrieve(htt_pdev, rx_reorder_array_elem->head);
        if (htt_rx_msdu_is_frag(htt_pdev, rx_desc)) {
            ol_rx_reorder_flush_frag(htt_pdev, peer, tid, idx_start);
            /*
             * Assuming flush message sent seperately for frags
             * and for normal frames
             */
            OL_RX_REORDER_TIMEOUT_MUTEX_UNLOCK(pdev);
            return;
        }
    }

    if (action == htt_rx_flush_release)
        ol_rx_reorder_detect_hole(peer, tid, idx_start);

    ol_rx_reorder_flush(
        vdev, peer, tid, idx_start, idx_end, action);
    /*
     * If the rx reorder timeout is handled by host SW, see if there are
     * remaining rx holes that require the timer to be restarted.
     */
    OL_RX_REORDER_TIMEOUT_UPDATE(peer, tid);
    OL_RX_REORDER_TIMEOUT_MUTEX_UNLOCK(pdev);
}

void
ol_rx_pn_ind_handler(
    ol_txrx_pdev_handle pdev,
    u_int16_t peer_id,
    u_int8_t tid,
    u_int16_t seq_num_start,
    u_int16_t seq_num_end,
    u_int8_t pn_ie_cnt,
    u_int8_t *pn_ie)
{
    struct ol_txrx_vdev_t *vdev = NULL;
    void *rx_desc;
    struct ol_txrx_peer_t *peer;
    struct ol_rx_reorder_array_elem_t *rx_reorder_array_elem;
    unsigned win_sz_mask;
    adf_nbuf_t head_msdu = NULL;
    adf_nbuf_t tail_msdu = NULL;
    htt_pdev_handle htt_pdev = pdev->htt_pdev;
    u_int16_t seq_num;
    int i=0;

    if (tid >= OL_TXRX_NUM_EXT_TIDS) {
        TXRX_PRINT(TXRX_PRINT_LEVEL_ERR,
                "%s:  invalid tid, %u\n", __func__, tid);
        WARN_ON(1);
        return;
    }

    peer = ol_txrx_peer_find_by_id(pdev, peer_id);

    if (!peer) {
        /* If we can't find a peer send this packet to OCB interface using
           OCB self peer */
        if (!ol_txrx_get_ocb_peer(pdev, &peer))
			peer = NULL;
    }

    if (peer) {
        vdev = peer->vdev;
    } else {
        return;
    }

    adf_os_atomic_set(&peer->fw_pn_check, 1);
    /*TODO: Fragmentation case*/
    win_sz_mask = peer->tids_rx_reorder[tid].win_sz_mask;
    seq_num_start &= win_sz_mask;
    seq_num_end   &= win_sz_mask;
    seq_num = seq_num_start;

    do {
        rx_reorder_array_elem =
            &peer->tids_rx_reorder[tid].array[seq_num];

        if (rx_reorder_array_elem->head) {
            if (pn_ie_cnt && seq_num == (int)(pn_ie[i])) {
                adf_nbuf_t msdu, next_msdu, mpdu_head, mpdu_tail;
                static u_int32_t last_pncheck_print_time = 0;
                int log_level;
                u_int32_t current_time_ms;
                union htt_rx_pn_t pn = {0};
                int index, pn_len;

                mpdu_head = msdu = rx_reorder_array_elem->head;
                mpdu_tail = rx_reorder_array_elem->tail;

                pn_ie_cnt--;
                i++;
                rx_desc = htt_rx_msdu_desc_retrieve(htt_pdev, msdu);
                index = htt_rx_msdu_is_wlan_mcast(pdev->htt_pdev, rx_desc) ?
                                   txrx_sec_mcast : txrx_sec_ucast;
                pn_len = pdev->rx_pn[peer->security[index].sec_type].len;
                htt_rx_mpdu_desc_pn(htt_pdev, rx_desc, &pn, pn_len);

                current_time_ms = adf_os_ticks_to_msecs(adf_os_ticks());
                if (TXRX_PN_CHECK_FAILURE_PRINT_PERIOD_MS <
                      (current_time_ms - last_pncheck_print_time)) {
                    last_pncheck_print_time = current_time_ms;
                    log_level = TXRX_PRINT_LEVEL_WARN;
                }
                else {
                    log_level = TXRX_PRINT_LEVEL_INFO2;
                }
                TXRX_PRINT(log_level,
                    "Tgt PN check failed - TID %d, peer %pK "
                    "(%02x:%02x:%02x:%02x:%02x:%02x)\n"
                    "    PN (u64 x2)= 0x%08llx %08llx (LSBs = %lld)\n"
                    "    new seq num = %d\n",
                    tid, peer,
                    peer->mac_addr.raw[0], peer->mac_addr.raw[1],
                    peer->mac_addr.raw[2], peer->mac_addr.raw[3],
                    peer->mac_addr.raw[4], peer->mac_addr.raw[5],
                    pn.pn128[1],
                    pn.pn128[0],
                    pn.pn128[0] & 0xffffffffffffULL,
                    htt_rx_mpdu_desc_seq_num(htt_pdev, rx_desc));
                    ol_rx_err(
                        pdev->ctrl_pdev,
                        vdev->vdev_id, peer->mac_addr.raw, tid,
                        htt_rx_mpdu_desc_tsf32(htt_pdev, rx_desc),
                        OL_RX_ERR_PN, mpdu_head, NULL, 0);

                /* free all MSDUs within this MPDU */
                do {
                    next_msdu = adf_nbuf_next(msdu);
                    htt_rx_desc_frame_free(htt_pdev, msdu);
                    if (msdu == mpdu_tail) {
                        break;
                    } else {
                        msdu = next_msdu;
                    }
                }while(1);

            } else {
                if (head_msdu == NULL) {
                    head_msdu = rx_reorder_array_elem->head;
                    tail_msdu = rx_reorder_array_elem->tail;
                } else {
                    adf_nbuf_set_next(tail_msdu, rx_reorder_array_elem->head);
                    tail_msdu = rx_reorder_array_elem->tail;
                }
            }
            rx_reorder_array_elem->head = NULL;
            rx_reorder_array_elem->tail = NULL;
        }
        seq_num = (seq_num + 1) & win_sz_mask;
    } while (seq_num != seq_num_end);

    if (head_msdu) {
        /* rx_opt_proc takes a NULL-terminated list of msdu netbufs */
        adf_nbuf_set_next(tail_msdu, NULL);
        peer->rx_opt_proc(vdev, peer, tid, head_msdu);
    }
}

#if defined(ENABLE_RX_REORDER_TRACE)

A_STATUS
ol_rx_reorder_trace_attach(ol_txrx_pdev_handle pdev)
{
    int num_elems;

    num_elems = 1 << TXRX_RX_REORDER_TRACE_SIZE_LOG2;
    pdev->rx_reorder_trace.idx = 0;
    pdev->rx_reorder_trace.cnt = 0;
    pdev->rx_reorder_trace.mask = num_elems - 1;
    pdev->rx_reorder_trace.data = adf_os_mem_alloc(
        pdev->osdev, sizeof(*pdev->rx_reorder_trace.data) * num_elems);
    if (! pdev->rx_reorder_trace.data) {
        return A_ERROR;
    }
    while (--num_elems >= 0) {
        pdev->rx_reorder_trace.data[num_elems].seq_num = 0xffff;
    }

    return A_OK;
}

void
ol_rx_reorder_trace_detach(ol_txrx_pdev_handle pdev)
{
    adf_os_mem_free(pdev->rx_reorder_trace.data);
}

void
ol_rx_reorder_trace_add(
    ol_txrx_pdev_handle pdev,
    u_int8_t tid,
    u_int16_t reorder_idx,
    u_int16_t seq_num,
    int num_mpdus)
{
    u_int32_t idx = pdev->rx_reorder_trace.idx;

    pdev->rx_reorder_trace.data[idx].tid = tid;
    pdev->rx_reorder_trace.data[idx].reorder_idx = reorder_idx;
    pdev->rx_reorder_trace.data[idx].seq_num = seq_num;
    pdev->rx_reorder_trace.data[idx].num_mpdus = num_mpdus;
    pdev->rx_reorder_trace.cnt++;
    idx++;
    pdev->rx_reorder_trace.idx = idx & pdev->rx_reorder_trace.mask;
}

void
ol_rx_reorder_trace_display(ol_txrx_pdev_handle pdev, int just_once, int limit)
{
    static int print_count = 0;
    u_int32_t i, start, end;
    u_int64_t cnt;
    int elems;

    if (print_count != 0 && just_once) {
        return;
    }
    print_count++;

    end = pdev->rx_reorder_trace.idx;
    if (pdev->rx_reorder_trace.data[end].seq_num == 0xffff) {
        /* trace log has not yet wrapped around - start at the top */
        start = 0;
        cnt = 0;
    } else {
        start = end;
        cnt = pdev->rx_reorder_trace.cnt - (pdev->rx_reorder_trace.mask + 1);
    }
    elems = (end - 1 - start) & pdev->rx_reorder_trace.mask;
    if (limit > 0 && elems > limit) {
        int delta;
        delta = elems - limit;
        start += delta;
        start &= pdev->rx_reorder_trace.mask;
        cnt += delta;
    }

    i = start;
    VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO,
        "           log       array seq\n");
    VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO,
        "   count   idx  tid   idx  num (LSBs)\n");
    do {
        u_int16_t seq_num, reorder_idx;
        seq_num = pdev->rx_reorder_trace.data[i].seq_num;
        reorder_idx = pdev->rx_reorder_trace.data[i].reorder_idx;
        if (seq_num < (1 << 14)) {
            VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO,
                "  %6lld  %4d  %3d  %4d  %4d (%d)\n",
                cnt, i, pdev->rx_reorder_trace.data[i].tid,
                reorder_idx, seq_num, seq_num & 63);
        } else {
            int err = TXRX_SEQ_NUM_ERR(seq_num);
            VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO,
                "  %6lld  %4d err %d (%d MPDUs)\n",
                cnt, i, err, pdev->rx_reorder_trace.data[i].num_mpdus);
        }
        cnt++;
        i++;
        i &= pdev->rx_reorder_trace.mask;
    } while (i != end);
}

#endif /* ENABLE_RX_REORDER_TRACE */
