/*
 *
 * Copyright (c) 2010 Atheros Communications Inc.
 * All rights reserved.
 *
 * 
//
// 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.
//
//
 *
 */

#include <a_config.h>
#include <athdefs.h>
#include <a_osapi.h>
#include <a_debug.h>
#include "pkt_log.h"
#include "aggr_recv_api.h"
#include "aggr_rx_internal.h"
#include "wmi.h"

extern int
wmi_dot3_2_dix(void *osbuf);

static void
aggr_slice_amsdu(struct aggr_info *p_aggr, struct rxtid *rxtid, void **osbuf);

static void
aggr_timeout(unsigned long arg);

static void
aggr_deque_frms(struct aggr_info *p_aggr, u8 tid, u16 seq_no, u8 order);

static void
aggr_dispatch_frames(struct aggr_info *p_aggr, A_NETBUF_QUEUE_T *q);

static void *
aggr_get_osbuf(struct aggr_info *p_aggr);

void *
aggr_init(ALLOC_NETBUFS netbuf_allocator)
{
    struct aggr_info   *p_aggr = NULL;
    struct rxtid *rxtid;
    u8 i;
    int status = 0;

    A_PRINTF("In aggr_init..\n");

    do {
        p_aggr = A_MALLOC(sizeof(struct aggr_info));
        if(!p_aggr) {
            A_PRINTF("Failed to allocate memory for aggr_node\n");
            status = A_ERROR;
            break;
        }

        /* Init timer and data structures */
        A_MEMZERO(p_aggr, sizeof(struct aggr_info));
        p_aggr->aggr_sz = AGGR_SZ_DEFAULT;
        A_INIT_TIMER(&p_aggr->timer, aggr_timeout, p_aggr);
        p_aggr->timerScheduled = false;
        A_NETBUF_QUEUE_INIT(&p_aggr->freeQ);

        p_aggr->netbuf_allocator = netbuf_allocator;
        p_aggr->netbuf_allocator(&p_aggr->freeQ, AGGR_NUM_OF_FREE_NETBUFS);

        for(i = 0; i < NUM_OF_TIDS; i++) {
            rxtid = AGGR_GET_RXTID(p_aggr, i);
            rxtid->aggr = false;
            rxtid->progress = false;
            rxtid->timerMon = false;
            A_NETBUF_QUEUE_INIT(&rxtid->q);
            A_MUTEX_INIT(&rxtid->lock);
        }
    }while(false);

    A_PRINTF("going out of aggr_init..status %s\n",
                    (status == 0) ? "OK":"Error");

    if (status) {
        /* Cleanup */
        aggr_module_destroy(p_aggr);
    }
    return ((status == 0) ? p_aggr : NULL);
}

/* utility function to clear rx hold_q for a tid */
static void
aggr_delete_tid_state(struct aggr_info *p_aggr, u8 tid)
{
    struct rxtid *rxtid;
    struct rxtid_stats *stats;

    A_ASSERT(tid < NUM_OF_TIDS && p_aggr);

    rxtid = AGGR_GET_RXTID(p_aggr, tid);
    stats = AGGR_GET_RXTID_STATS(p_aggr, tid);

    if(rxtid->aggr) {
        aggr_deque_frms(p_aggr, tid, 0, ALL_SEQNO);
    }

    rxtid->aggr = false;
    rxtid->progress = false;
    rxtid->timerMon = false;
    rxtid->win_sz = 0;
    rxtid->seq_next = 0;
    rxtid->hold_q_sz = 0;

    if(rxtid->hold_q) {
        kfree(rxtid->hold_q);
        rxtid->hold_q = NULL;
    }

    A_MEMZERO(stats, sizeof(struct rxtid_stats));
}

void
aggr_module_destroy(void *cntxt)
{
    struct aggr_info *p_aggr = (struct aggr_info *)cntxt;
    struct rxtid *rxtid;
    u8 i, k;
    A_PRINTF("%s(): aggr = %p\n",_A_FUNCNAME_, p_aggr);
    A_ASSERT(p_aggr);

    if(p_aggr) {
        if(p_aggr->timerScheduled) {
            A_UNTIMEOUT(&p_aggr->timer);
            p_aggr->timerScheduled = false;
        }

        for(i = 0; i < NUM_OF_TIDS; i++) {
            rxtid = AGGR_GET_RXTID(p_aggr, i);
            /* Free the hold q contents and hold_q*/
            if(rxtid->hold_q) {
                for(k = 0; k< rxtid->hold_q_sz; k++) {
                    if(rxtid->hold_q[k].osbuf) {
                        A_NETBUF_FREE(rxtid->hold_q[k].osbuf);
                    }
                }
                kfree(rxtid->hold_q);
            }
            /* Free the dispatch q contents*/
            while(A_NETBUF_QUEUE_SIZE(&rxtid->q)) {
                A_NETBUF_FREE(A_NETBUF_DEQUEUE(&rxtid->q));
            }
            if (A_IS_MUTEX_VALID(&rxtid->lock)) {
                A_MUTEX_DELETE(&rxtid->lock);
            }
        }
        /* free the freeQ and its contents*/
        while(A_NETBUF_QUEUE_SIZE(&p_aggr->freeQ)) {
            A_NETBUF_FREE(A_NETBUF_DEQUEUE(&p_aggr->freeQ));
        }
        kfree(p_aggr);
    }
    A_PRINTF("out aggr_module_destroy\n");
}


void
aggr_register_rx_dispatcher(void *cntxt, void * dev, RX_CALLBACK fn)
{
    struct aggr_info *p_aggr = (struct aggr_info *)cntxt;

    A_ASSERT(p_aggr && fn && dev);

    p_aggr->rx_fn = fn;
    p_aggr->dev = dev;
}


void
aggr_process_bar(void *cntxt, u8 tid, u16 seq_no)
{
    struct aggr_info *p_aggr = (struct aggr_info *)cntxt;
    struct rxtid_stats *stats;

    A_ASSERT(p_aggr);
    stats = AGGR_GET_RXTID_STATS(p_aggr, tid);
    stats->num_bar++;

    aggr_deque_frms(p_aggr, tid, seq_no, ALL_SEQNO);
}


void
aggr_recv_addba_req_evt(void *cntxt, u8 tid, u16 seq_no, u8 win_sz)
{
    struct aggr_info *p_aggr = (struct aggr_info *)cntxt;
    struct rxtid *rxtid;
    struct rxtid_stats *stats;

    A_ASSERT(p_aggr);
    rxtid = AGGR_GET_RXTID(p_aggr, tid);
    stats = AGGR_GET_RXTID_STATS(p_aggr, tid);

    A_PRINTF("%s(): win_sz = %d aggr %d\n", _A_FUNCNAME_, win_sz, rxtid->aggr);
    if(win_sz < AGGR_WIN_SZ_MIN || win_sz > AGGR_WIN_SZ_MAX) {
        A_PRINTF("win_sz %d, tid %d\n", win_sz, tid);
    }

    if(rxtid->aggr) {
        /* Just go and  deliver all the frames up from this
         * queue, as if we got DELBA and re-initialize the queue
         */
        aggr_delete_tid_state(p_aggr, tid);
    }

    rxtid->seq_next = seq_no;
    /* create these queues, only upon receiving of ADDBA for a
     * tid, reducing memory requirement
     */
    rxtid->hold_q = A_MALLOC(HOLD_Q_SZ(win_sz));
    if((rxtid->hold_q == NULL)) {
        A_PRINTF("Failed to allocate memory, tid = %d\n", tid);
        A_ASSERT(0);
    }
    A_MEMZERO(rxtid->hold_q, HOLD_Q_SZ(win_sz));

    /* Update rxtid for the window sz */
    rxtid->win_sz = win_sz;
    /* hold_q_sz inicates the depth of holding q - which  is
     * a factor of win_sz. Compute once, as it will be used often
     */
    rxtid->hold_q_sz = TID_WINDOW_SZ(win_sz);
    /* There should be no frames on q - even when second ADDBA comes in.
     * If aggr was previously ON on this tid, we would have cleaned up
     * the q
     */
    if(A_NETBUF_QUEUE_SIZE(&rxtid->q) != 0) {
        A_PRINTF("ERROR: Frames still on queue ?\n");
        A_ASSERT(0);
    }

    rxtid->aggr = true;
}

void
aggr_recv_delba_req_evt(void *cntxt, u8 tid)
{
    struct aggr_info *p_aggr = (struct aggr_info *)cntxt;
    struct rxtid *rxtid;

    A_ASSERT(p_aggr);
    A_PRINTF("%s(): tid %d\n", _A_FUNCNAME_, tid);

    rxtid = AGGR_GET_RXTID(p_aggr, tid);

    if(rxtid->aggr) {
        aggr_delete_tid_state(p_aggr, tid);
    }
}

static void
aggr_deque_frms(struct aggr_info *p_aggr, u8 tid, u16 seq_no, u8 order)
{
    struct rxtid *rxtid;
    struct osbuf_hold_q *node;
    u16 idx, idx_end, seq_end;
    struct rxtid_stats *stats;

    A_ASSERT(p_aggr);
    rxtid = AGGR_GET_RXTID(p_aggr, tid);
    stats = AGGR_GET_RXTID_STATS(p_aggr, tid);

    /* idx is absolute location for first frame */
    idx = AGGR_WIN_IDX(rxtid->seq_next, rxtid->hold_q_sz);

    /* idx_end is typically the last possible frame in the window,
     * but changes to 'the' seq_no, when BAR comes. If seq_no
     * is non-zero, we will go up to that and stop.
     * Note: last seq no in current window will occupy the same
     * index position as index that is just previous to start.
     * An imp point : if win_sz is 7, for seq_no space of 4095,
     * then, there would be holes when sequence wrap around occurs.
     * Target should judiciously choose the win_sz, based on
     * this condition. For 4095, (TID_WINDOW_SZ = 2 x win_sz
     * 2, 4, 8, 16 win_sz works fine).
     * We must deque from "idx" to "idx_end", including both.
     */
    seq_end = (seq_no) ? seq_no : rxtid->seq_next;
    idx_end = AGGR_WIN_IDX(seq_end, rxtid->hold_q_sz);

    /* Critical section begins */
    A_MUTEX_LOCK(&rxtid->lock);
    do {

        node = &rxtid->hold_q[idx];

        if((order == CONTIGUOUS_SEQNO) && (!node->osbuf))
            break;

        /* chain frames and deliver frames bcos:
         *  1. either the frames are in order and window is contiguous, OR
         *  2. we need to deque frames, irrespective of holes
         */
        if(node->osbuf) {
            if(node->is_amsdu) {
                aggr_slice_amsdu(p_aggr, rxtid, &node->osbuf);
            } else {
                A_NETBUF_ENQUEUE(&rxtid->q, node->osbuf);
            }
            node->osbuf = NULL;
        } else {
            stats->num_hole++;
        }

        /* window is moving */
        rxtid->seq_next = IEEE80211_NEXT_SEQ_NO(rxtid->seq_next);
        idx = AGGR_WIN_IDX(rxtid->seq_next, rxtid->hold_q_sz);
    } while(idx != idx_end);
    /* Critical section ends */
    A_MUTEX_UNLOCK(&rxtid->lock);

    stats->num_delivered += A_NETBUF_QUEUE_SIZE(&rxtid->q);
    aggr_dispatch_frames(p_aggr, &rxtid->q);
}

static void *
aggr_get_osbuf(struct aggr_info *p_aggr)
{
    void *buf = NULL;

    /* Starving for buffers?  get more from OS
     *  check for low netbuffers( < 1/4 AGGR_NUM_OF_FREE_NETBUFS) :
     *      re-allocate bufs if so
     * allocate a free buf from freeQ
     */
    if (A_NETBUF_QUEUE_SIZE(&p_aggr->freeQ) < (AGGR_NUM_OF_FREE_NETBUFS >> 2)) {
        p_aggr->netbuf_allocator(&p_aggr->freeQ, AGGR_NUM_OF_FREE_NETBUFS);
    }

    if (A_NETBUF_QUEUE_SIZE(&p_aggr->freeQ)) {
        buf = A_NETBUF_DEQUEUE(&p_aggr->freeQ);
    }

    return buf;
}


static void
aggr_slice_amsdu(struct aggr_info *p_aggr, struct rxtid *rxtid, void **osbuf)
{
    void *new_buf;
    u16 frame_8023_len, payload_8023_len, mac_hdr_len, amsdu_len;
    u8 *framep;

    /* Frame format at this point:
     *  [DIX hdr | 802.3 | 802.3 | ... | 802.3]
     *
     * Strip the DIX header.
     * Iterate through the osbuf and do:
     *  grab a free netbuf from freeQ
     *  find the start and end of a frame
     *  copy it to netbuf(Vista can do better here)
     *  convert all msdu's(802.3) frames to upper layer format - os routine
     *      -for now lets convert from 802.3 to dix
     *  enque this to dispatch q of tid
     * repeat
     * free the osbuf - to OS. It's been sliced.
     */

    mac_hdr_len = sizeof(ATH_MAC_HDR);
    framep = A_NETBUF_DATA(*osbuf) + mac_hdr_len;
    amsdu_len = A_NETBUF_LEN(*osbuf) - mac_hdr_len;

    while(amsdu_len > mac_hdr_len) {
        /* Begin of a 802.3 frame */
        payload_8023_len = A_BE2CPU16(((ATH_MAC_HDR *)framep)->typeOrLen);
#define MAX_MSDU_SUBFRAME_PAYLOAD_LEN 1508
#define MIN_MSDU_SUBFRAME_PAYLOAD_LEN 46
        if(payload_8023_len < MIN_MSDU_SUBFRAME_PAYLOAD_LEN || payload_8023_len > MAX_MSDU_SUBFRAME_PAYLOAD_LEN) {
            A_PRINTF("802.3 AMSDU frame bound check failed. len %d\n", payload_8023_len);
            break;
        }
        frame_8023_len = payload_8023_len + mac_hdr_len;
        new_buf = aggr_get_osbuf(p_aggr);
        if(new_buf == NULL) {
            A_PRINTF("No buffer available \n");
            break;
        }

        memcpy(A_NETBUF_DATA(new_buf), framep, frame_8023_len);
        A_NETBUF_PUT(new_buf, frame_8023_len);
        if (wmi_dot3_2_dix(new_buf) != 0) {
            A_PRINTF("dot3_2_dix err..\n");
            A_NETBUF_FREE(new_buf);
            break;
        }

        A_NETBUF_ENQUEUE(&rxtid->q, new_buf);

        /* Is this the last subframe within this aggregate ? */
        if ((amsdu_len - frame_8023_len) == 0) {
            break;
        }

        /* Add the length of A-MSDU subframe padding bytes -
         * Round to nearest word.
         */
        frame_8023_len = ((frame_8023_len + 3) & ~3);

        framep += frame_8023_len;
        amsdu_len -= frame_8023_len;
    }

    A_NETBUF_FREE(*osbuf);
    *osbuf = NULL;
}

void
aggr_process_recv_frm(void *cntxt, u8 tid, u16 seq_no, bool is_amsdu, void **osbuf)
{
    struct aggr_info *p_aggr = (struct aggr_info *)cntxt;
    struct rxtid *rxtid;
    struct rxtid_stats *stats;
    u16 idx, st, cur, end;
    u16 *log_idx;
    struct osbuf_hold_q *node;
    PACKET_LOG *log;

    A_ASSERT(p_aggr);
    A_ASSERT(tid < NUM_OF_TIDS);

    rxtid = AGGR_GET_RXTID(p_aggr, tid);
    stats = AGGR_GET_RXTID_STATS(p_aggr, tid);

    stats->num_into_aggr++;

    if(!rxtid->aggr) {
        if(is_amsdu) {
            aggr_slice_amsdu(p_aggr, rxtid, osbuf);
            stats->num_amsdu++;
            aggr_dispatch_frames(p_aggr, &rxtid->q);
        }
        return;
    }

    /* Check the incoming sequence no, if it's in the window */
    st = rxtid->seq_next;
    cur = seq_no;
    end = (st + rxtid->hold_q_sz-1) & IEEE80211_MAX_SEQ_NO;
    /* Log the pkt info for future analysis */
    log = &p_aggr->pkt_log;
    log_idx = &log->last_idx;
    log->info[*log_idx].cur = cur;
    log->info[*log_idx].st = st;
    log->info[*log_idx].end = end;
    *log_idx = IEEE80211_NEXT_SEQ_NO(*log_idx);

    if(((st < end) && (cur < st || cur > end)) ||
      ((st > end) && (cur > end) && (cur < st))) {
        /* the cur frame is outside the window. Since we know
         * our target would not do this without reason it must
         * be assumed that the window has moved for some valid reason.
         * Therefore, we dequeue all frames and start fresh.
         */
        u16 extended_end;

        extended_end = (end + rxtid->hold_q_sz-1) & IEEE80211_MAX_SEQ_NO;

        if(((end < extended_end) && (cur < end || cur > extended_end)) ||
           ((end > extended_end) && (cur > extended_end) && (cur < end))) {
            // dequeue all frames in queue and shift window to new frame
            aggr_deque_frms(p_aggr, tid, 0, ALL_SEQNO);
            //set window start so that new frame is last frame in window
            if(cur >= rxtid->hold_q_sz-1) {
                rxtid->seq_next = cur - (rxtid->hold_q_sz-1);
            }else{
                rxtid->seq_next = IEEE80211_MAX_SEQ_NO - (rxtid->hold_q_sz-2 - cur);
            }
        } else {
            // dequeue only those frames that are outside the new shifted window
            if(cur >= rxtid->hold_q_sz-1) {
                st = cur - (rxtid->hold_q_sz-1);
            }else{
                st = IEEE80211_MAX_SEQ_NO - (rxtid->hold_q_sz-2 - cur);
            }

            aggr_deque_frms(p_aggr, tid, st, ALL_SEQNO);
        }

        stats->num_oow++;
    }

    idx = AGGR_WIN_IDX(seq_no, rxtid->hold_q_sz);

    /*enque the frame, in hold_q */
    node = &rxtid->hold_q[idx];

    A_MUTEX_LOCK(&rxtid->lock);
    if(node->osbuf) {
        /* Is the cur frame duplicate or something beyond our
         * window(hold_q -> which is 2x, already)?
         * 1. Duplicate is easy - drop incoming frame.
         * 2. Not falling in current sliding window.
         *  2a. is the frame_seq_no preceding current tid_seq_no?
         *      -> drop the frame. perhaps sender did not get our ACK.
         *         this is taken care of above.
         *  2b. is the frame_seq_no beyond window(st, TID_WINDOW_SZ);
         *      -> Taken care of it above, by moving window forward.
         *
         */
        A_NETBUF_FREE(node->osbuf);
        stats->num_dups++;
    }

    node->osbuf = *osbuf;
    node->is_amsdu = is_amsdu;
    node->seq_no = seq_no;
    if(node->is_amsdu) {
        stats->num_amsdu++;
    } else {
        stats->num_mpdu++;
    }
    A_MUTEX_UNLOCK(&rxtid->lock);

    *osbuf = NULL;
    aggr_deque_frms(p_aggr, tid, 0, CONTIGUOUS_SEQNO);

    if(p_aggr->timerScheduled) {
        rxtid->progress = true;
    }else{
        for(idx=0 ; idx<rxtid->hold_q_sz ; idx++) {
            if(rxtid->hold_q[idx].osbuf) {
                /* there is a frame in the queue and no timer so
                 * start a timer to ensure that the frame doesn't remain
                 * stuck forever. */
                p_aggr->timerScheduled = true;
                A_TIMEOUT_MS(&p_aggr->timer, AGGR_RX_TIMEOUT, 0);
                rxtid->progress = false;
                rxtid->timerMon = true;
                break;
            }
        }
    }
}

/*
 * aggr_reset_state -- Called when it is deemed necessary to clear the aggregate
 *  hold Q state.  Examples include when a Connect event or disconnect event is
 *  received.
 */
void
aggr_reset_state(void *cntxt)
{
    u8 tid;
    struct aggr_info *p_aggr = (struct aggr_info *)cntxt;

    A_ASSERT(p_aggr);

    for(tid=0 ; tid<NUM_OF_TIDS ; tid++) {
        aggr_delete_tid_state(p_aggr, tid);
    }
}


static void
aggr_timeout(unsigned long arg)
{
    u8 i,j;
    struct aggr_info *p_aggr = (struct aggr_info *)arg;
    struct rxtid   *rxtid;
    struct rxtid_stats *stats;
    /*
     * If the q for which the timer was originally started has
     * not progressed then it is necessary to dequeue all the
     * contained frames so that they are not held forever.
     */
    for(i = 0; i < NUM_OF_TIDS; i++) {
        rxtid = AGGR_GET_RXTID(p_aggr, i);
        stats = AGGR_GET_RXTID_STATS(p_aggr, i);

        if(rxtid->aggr == false ||
           rxtid->timerMon == false ||
           rxtid->progress == true) {
            continue;
        }
        // dequeue all frames in for this tid
        stats->num_timeouts++;
        A_PRINTF("TO: st %d end %d\n", rxtid->seq_next, ((rxtid->seq_next + rxtid->hold_q_sz-1) & IEEE80211_MAX_SEQ_NO));
        aggr_deque_frms(p_aggr, i, 0, ALL_SEQNO);
    }

    p_aggr->timerScheduled = false;
    // determine whether a new timer should be started.
    for(i = 0; i < NUM_OF_TIDS; i++) {
        rxtid = AGGR_GET_RXTID(p_aggr, i);

        if(rxtid->aggr == true && rxtid->hold_q) {
            for(j = 0 ; j < rxtid->hold_q_sz ; j++)
            {
                if(rxtid->hold_q[j].osbuf)
                {
                    p_aggr->timerScheduled = true;
                    rxtid->timerMon = true;
                    rxtid->progress = false;
                    break;
                }
            }

            if(j >= rxtid->hold_q_sz) {
                rxtid->timerMon = false;
            }
        }
    }

    if(p_aggr->timerScheduled) {
        /* Rearm the timer*/
        A_TIMEOUT_MS(&p_aggr->timer, AGGR_RX_TIMEOUT, 0);
    }

}

static void
aggr_dispatch_frames(struct aggr_info *p_aggr, A_NETBUF_QUEUE_T *q)
{
    void *osbuf;

    while((osbuf = A_NETBUF_DEQUEUE(q))) {
        p_aggr->rx_fn(p_aggr->dev, osbuf);
    }
}

void
aggr_dump_stats(void *cntxt, PACKET_LOG **log_buf)
{
    struct aggr_info *p_aggr = (struct aggr_info *)cntxt;
    struct rxtid   *rxtid;
    struct rxtid_stats *stats;
    u8 i;

    *log_buf = &p_aggr->pkt_log;
    A_PRINTF("\n\n================================================\n");
    A_PRINTF("tid: num_into_aggr, dups, oow, mpdu, amsdu, delivered, timeouts, holes, bar, seq_next\n");
    for(i = 0; i < NUM_OF_TIDS; i++) {
        stats = AGGR_GET_RXTID_STATS(p_aggr, i);
        rxtid = AGGR_GET_RXTID(p_aggr, i);
        A_PRINTF("%d: %d %d %d %d %d %d %d %d %d : %d\n", i, stats->num_into_aggr, stats->num_dups,
                    stats->num_oow, stats->num_mpdu,
                    stats->num_amsdu, stats->num_delivered, stats->num_timeouts,
                    stats->num_hole, stats->num_bar,
                    rxtid->seq_next);
    }
    A_PRINTF("================================================\n\n");

}
