/*
 * RxQueue.c
 *
 * Copyright(c) 1998 - 2009 Texas Instruments. All rights reserved.      
 * All rights reserved.                                                  
 *                                                                       
 * Redistribution and use in source and binary forms, with or without    
 * modification, are permitted provided that the following conditions    
 * are met:                                                              
 *                                                                       
 *  * Redistributions of source code must retain the above copyright     
 *    notice, this list of conditions and the following disclaimer.      
 *  * Redistributions in binary form must reproduce the above copyright  
 *    notice, this list of conditions and the following disclaimer in    
 *    the documentation and/or other materials provided with the         
 *    distribution.                                                      
 *  * Neither the name Texas Instruments nor the names of its            
 *    contributors may be used to endorse or promote products derived    
 *    from this software without specific prior written permission.      
 *                                                                       
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS   
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT     
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT  
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT      
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT   
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */


/** \file   RxQueue.c 
 *  \brief  RX Queue module that responsible to support re-ordering of received packets to upper layers.
 *  
 *  \see    RxQueue.h
 */
#define __FILE_ID__  FILE_ID_98
#include "tidef.h"
#include "osApi.h"
#include "report.h" 
#include "RxBuf.h"
#include "TWDriver.h"
#include "public_descriptors.h"

/************************ static definition declaration *****************************/
#define RX_QUEUE_ARRAY_SIZE		                            8
#define RX_QUEUE_ARRAY_SIZE_BIT_MASK                        0x7 /* RX_QUEUE_ARRAY_SIZE -1 */
#define RX_QUEUE_WIN_SIZE		                            RX_QUEUE_ARRAY_SIZE

#define BA_SESSION_IS_A_BIGGER_THAN_B(A,B)       (((((A)-(B)) & 0xFFF) < 0x7FF) && ((A)!=(B)))
#define BA_SESSION_IS_A_BIGGER_EQUAL_THAN_B(A,B) (((((A)-(B)) & 0xFFF) < 0x7FF))
#define SEQ_NUM_WRAP 0x1000
#define SEQ_NUM_MASK 0xFFF


/************************ static structures declaration *****************************/
/* structure describe one entry of save packet information in the packet queue array */
typedef struct 
{
    void                *pPacket;	/* Packet address of the packet */
    TI_STATUS	        tStatus;	/* RxXfer status. */
    TI_UINT16           uFrameSn;
} TRxQueuePacketEntry;	

/* structure describe set of data that one Tid, also including the arras himself */
typedef struct 
{
    /* array packets Entries */
    TRxQueuePacketEntry aPaketsQueue [RX_QUEUE_ARRAY_SIZE];	
    /* TID BA state */
    TI_BOOL	            aTidBaEstablished;	              
    /* index that winStar point on */
    TI_UINT32 	        aWinStartArrayInex;	                    
    /* windows size */
    TI_UINT32	        aTidWinSize;
	/* expected sequence number (ESN) */ 
    TI_UINT16	        aTidExpectedSn;
} TRxQueueTidDataBase;	

/* structure describe set of data that assist of manage one SA RxQueue arrays */
typedef struct 
{
    TRxQueueTidDataBase tSa1ArrayMng [MAX_NUM_OF_802_1d_TAGS];
} TRxQueueArraysMng;	

/* main RxQueue structure in order to management the packets disordered array. */
typedef struct 
{
    TI_HANDLE           hOs;                        /* OS handler */
    TI_HANDLE           hReport;                    /* Report handler */
    TRxQueueArraysMng   tRxQueueArraysMng;          /* manage each Source Address RxQueue arrays */
    TPacketReceiveCb    tReceivePacketCB;           /* Receive packets CB address */
    TI_HANDLE           hReceivePacketCB_handle;    /* Receive packets CB handler */

} TRxQueue;	

/************************ static function declaration *****************************/
static TI_STATUS RxQueue_PassPacket (TI_HANDLE hRxQueue, TI_STATUS tStatus, const void *pBuffer);

/** 
 * \fn     RxQueue_Create() 
 * \brief  Create the RxQueue module.
 * 
 * Allocate and clear the RxQueue module object.
 * 
 * \param  hOs - Handle to Os Abstraction Layer
 * \return Handle of the allocated object 
 * \sa     RxQueue_Destroy
 */ 
TI_HANDLE RxQueue_Create (TI_HANDLE hOs)
{
	TRxQueue *pRxQueue;

	/* allocate module object */
	pRxQueue = os_memoryAlloc (hOs, sizeof(TRxQueue));
	
	if (!pRxQueue)
	{
		WLAN_OS_REPORT (("RxQueue_Create():  Allocation failed!!\n"));
		return NULL;
	}
	
    os_memoryZero (hOs, pRxQueue, (sizeof(TRxQueue)));

    pRxQueue->hOs = hOs;

	return (pRxQueue);
}


/** 
 * \fn     RxQueue_Destroy()
 * \brief  Destroy the module. 
 * 
 * Free the module's queues and object.
 * 
 * \param  hRxQueue - The module object
 * \return TI_OK on success or TI_NOK on failure 
 * \sa     RxQueue_Create
 */ 
TI_STATUS RxQueue_Destroy (TI_HANDLE hRxQueue)
{
    TRxQueue *pRxQueue = (TRxQueue *)hRxQueue;

    /* free module object */
	os_memoryFree (pRxQueue->hOs, pRxQueue, sizeof(TRxQueue));
	
    return TI_OK;
}


/** 
 * \fn     RxQueue_Init() 
 * \brief  Init required handles 
 * 
 * Init required handles and module variables.
 * 
 * \note    
 * \param  hRxQueue - The module object
 * \param  hReport - Report module Handles
 * \return TI_OK on success or TI_NOK on failure  
 * \sa     
 */ 
TI_STATUS RxQueue_Init (TI_HANDLE hRxQueue, TI_HANDLE hReport)
{
	TRxQueue *pRxQueue = (TRxQueue *)hRxQueue;
    
    pRxQueue->hReport   = hReport;

	return TI_OK;
}


/** 
 * \fn     RxQueue_Register_CB()
 * \brief  Register the function to be called for received Rx.
 * 
 * \note   
 * \param  hRxQueue - The module object
 * \param  CallBackID - event ID
 * \param  CBFunc - function address.
 * \param  CBObj - function parameter.
 * \return TI_OK on success or TI_NOK on failure 
 * \sa     
 */ 
void RxQueue_Register_CB (TI_HANDLE hRxQueue, TI_UINT32 uCallBackID, void *CBFunc, TI_HANDLE CBObj)
{
    TRxQueue* pRxQueue = (TRxQueue *)hRxQueue;

    TRACE1(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION , "RxQueue_Register_CB: CallBack ID = 0x%x\n", uCallBackID);

    switch(uCallBackID)
    {
    case TWD_INT_RECEIVE_PACKET:
        pRxQueue->tReceivePacketCB = (TPacketReceiveCb)CBFunc;
        pRxQueue->hReceivePacketCB_handle = CBObj;
        break;

    default:
        TRACE0(pRxQueue->hReport, REPORT_SEVERITY_ERROR , "RxQueue_Register_CB: Illegal value\n");
        break;
    }
}

/**
 * \fn     RxQueue_CloseBaSession ()
 * \brief  Close BA session receiver and pass all packets in the TID queue to upper layer.
 *
 * \note   
 * \param  hRxQueue - RxQueue handle.
 * \param  uFrameTid - TID session.
 * \return None 
 * \sa     
 */ 
void RxQueue_CloseBaSession(TI_HANDLE hRxQueue, TI_UINT8 uFrameTid)
{
    TRxQueue            *pRxQueue     = (TRxQueue *)hRxQueue;
    TI_UINT32            i;
    /*set the SA Tid pointer */
    TRxQueueTidDataBase *pTidDataBase = &(pRxQueue->tRxQueueArraysMng.tSa1ArrayMng[uFrameTid]);
    
    /* TID illegal value ? */
    if (uFrameTid >= MAX_NUM_OF_802_1d_TAGS)
    {
        TRACE1(pRxQueue->hReport, REPORT_SEVERITY_ERROR , "RxQueue_CloseBaSession: BA event - DELBA frame with TID value too big, TID = %d\n", uFrameTid);
        
        return;
    }

    if(pTidDataBase->aTidBaEstablished == TI_TRUE)
    {
        /* clean BA session */
        pTidDataBase->aTidBaEstablished = TI_FALSE;

        /* pass all valid entries at the array */ 
        for (i = 0; (i < RX_QUEUE_ARRAY_SIZE) && (i < RX_QUEUE_WIN_SIZE); i++)
        {
            if (pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket != NULL)
            {
                RxQueue_PassPacket (pRxQueue, 
                                    pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].tStatus,
                                    pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket);

                pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket = NULL;
            }

            pTidDataBase->aWinStartArrayInex ++;

            /* aWinStartArrayInex % RX_QUEUE_ARRAY_SIZE */
            pTidDataBase->aWinStartArrayInex &= RX_QUEUE_ARRAY_SIZE_BIT_MASK;
        }
    }
}


/** 
 * \fn     RxQueue_PassPacket()
 * \brief  Responsible on decode packet parameters and pass it to upper layer.
 *
 * \note   
 * \param  hRxQueue - RxQueue handle.
 * \param  aStatus - RxXfer status that indicate if the upper layer should free the packet or use it.
 * \param  pFrame - paket address of the packet
 * \param  pRxParams - address to structure of the Rx Descriptor received by FW.
 * \return TI_OK on success or TI_NOK on failure 
 * \sa     
 */ 
static TI_STATUS RxQueue_PassPacket (TI_HANDLE hRxQueue, TI_STATUS tStatus, const void *pBuffer)
{

    TRxQueue            *pRxQueue   = (TRxQueue *)hRxQueue;

    if (tStatus == TI_OK)
    {
        /* Get the mac header location in the packet Buffer */
        dot11_header_t *pMacHdr = (dot11_header_t *)(TI_UINT8*)RX_BUF_DATA(pBuffer);

        /* Handle endian for the frame control fields */
        pMacHdr->fc  = ENDIAN_HANDLE_WORD(pMacHdr->fc);
        pMacHdr->duration = ENDIAN_HANDLE_WORD(pMacHdr->duration);
        pMacHdr->seqCtrl = ENDIAN_HANDLE_WORD(pMacHdr->seqCtrl);
    }
    else
    {
        RxIfDescriptor_t    *pRxParams  = (RxIfDescriptor_t*)pBuffer;

        pRxParams->status &= ~RX_DESC_STATUS_MASK;
        pRxParams->status |= RX_DESC_STATUS_DRIVER_RX_Q_FAIL;
    }

    TRACE0(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION , "RxQueue_PassPacket: call TWD_OWNER_RX_QUEUE CB. In std rxData_ReceivePacket()\n");

    /* Set the packet to upper layer */
    /* if the packet status not success it will be discarded */
    pRxQueue->tReceivePacketCB (pRxQueue->hReceivePacketCB_handle, pBuffer);

    return TI_OK;
}


/** 
 * \fn     RxQueue_ReceivePacket()
 * \brief  Main function of the RxQueue module. 
 * Responsible on reorder of the packets from the RxXfer to the RX module.
 * Call from RxXfer in order to pass packet to uppers layers.
 * In order to save disordered packets the module use array of structures per TID 
 * that each entry describe a packet. The array elements is sorted in the way that 
 * the winStart array index represent always the winStar packet and the lowest SN. 
 * Each increment index represent index at the BA window. Array index winEnd  always 
 * represent winEnd packet. The indexes of winStart and winEnd handled in cyclic manner.
 * The function functionality devided to parts:
 *   Part 1: 
 * in case the modulo receive packet with SN equal to winStart: 
 * "	pass it to upper layers
 * "	increases winStart and array index winStart
 * "	validate that all sequential queue packet are pass to the upper layers.
 *   Part 2: 
 * in case the modulo receive packet that SN between winStart to winEnd: 
 * "	Save it sorted at the array at index: Save index = ((SN - winStart) + index array winStart) % arraySize.
 *   Part 3: 
 * in case the modulo receive packet that SN higher then winEnd: 
 * "	Update winStart and WinEnd. 
 * "	Save it sorted at the array in index winEnd index.
 * "	Pass to the upper layers all packets at the array indexes from old winStart index to the updated winStart index.
 *   Part 4 + 5: 
 * in case the modulo receive BA event packet: 
 * "	Update winStart and WinEnd 
 * "	Pass to the upper layers all packets at the array indexes from old winStart index to the updated winStart index.
 * "	Free BA event packet via pass it to upper layers with error status.
 *
 * \note   
 * \param  hRxQueue - RxQueue handle.
 * \param  aStatus - RxXfer status that indicate if the upper layer should free the packet or use it.
 * \param  pBuffer - paket address of the packet
 * \return None 
 * \sa     
 */ 
void RxQueue_ReceivePacket (TI_HANDLE hRxQueue, const void * pBuffer)
{
    TRxQueue            *pRxQueue   = (TRxQueue *)hRxQueue;
    RxIfDescriptor_t    *pRxParams  = (RxIfDescriptor_t*)pBuffer;
    TI_UINT8            *pFrame     = RX_BUF_DATA((TI_UINT8 *)pBuffer);
    TI_STATUS           tStatus     = TI_OK;
    dot11_header_t      *pHdr       = (dot11_header_t *)pFrame;
    TI_UINT16		    uQosControl;

    COPY_WLAN_WORD(&uQosControl, &pHdr->qosControl); /* copy with endianess handling. */

    /* 
     * Retrieving the TAG from the packet itself and not from the Rx Descriptor since by now it is not correct
     * Note: in the DR TAG_CLASS_EAPOL packet handled as TAG_CLASS_QOS_DATA   
     */
    if (IS_QOS_FRAME(*(TI_UINT16*)pFrame) && (pRxParams->packet_class_tag != TAG_CLASS_QOS_DATA) && (pRxParams->packet_class_tag != TAG_CLASS_AMSDU))
	{
        TRACE1(pRxQueue->hReport, REPORT_SEVERITY_WARNING, "RxQueue_ReceivePacket: BAD CLASS TAG =0x%x from FW.\n", pRxParams->packet_class_tag);
		
        /* Get AMSDU bit from frame */
        if( uQosControl & DOT11_QOS_CONTROL_FIELD_A_MSDU_BITS)
        {
            pRxParams->packet_class_tag = TAG_CLASS_AMSDU;
        }
        else
        {
            pRxParams->packet_class_tag = TAG_CLASS_QOS_DATA;
        }
    }

    /* 
     * packet doesn't need reorder ? 
     */
    if ((pRxParams->packet_class_tag != TAG_CLASS_QOS_DATA) && (pRxParams->packet_class_tag != TAG_CLASS_BA_EVENT) && (pRxParams->packet_class_tag != TAG_CLASS_AMSDU))
    {
        TRACE0(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: pass packet without reorder.\n");
        
        RxQueue_PassPacket (pRxQueue, tStatus, pBuffer);

        return;
    }


    /* 
     * pRxParams->type == TAG_CLASS_QOS_DATA ? 
     */
    if ((pRxParams->packet_class_tag == TAG_CLASS_QOS_DATA) || (pRxParams->packet_class_tag == TAG_CLASS_AMSDU))
    {
        TI_UINT8            uFrameTid;
        TI_UINT16           uFrameSn;
        TI_UINT16		    uSequenceControl;
        TRxQueueTidDataBase *pTidDataBase;

        /* Get TID from frame */
        uFrameTid = uQosControl & DOT11_QOS_CONTROL_FIELD_TID_BITS;

        /* TID illegal value ? */
        if (uFrameTid >= MAX_NUM_OF_802_1d_TAGS)
        {
            TRACE1(pRxQueue->hReport, REPORT_SEVERITY_ERROR, "RxQueue_ReceivePacket: TID value too big, TID = %d. packet discarded!\n",uFrameTid);

            RxQueue_PassPacket (pRxQueue, TI_NOK, pBuffer);

            return;
        }

        /*set the SA Tid pointer */
        pTidDataBase = &(pRxQueue->tRxQueueArraysMng.tSa1ArrayMng[uFrameTid]);

        /* TID legal value */
        /* packet TID BA not established ? */ 
        if (pTidDataBase->aTidBaEstablished != TI_TRUE)
        {
            TRACE0(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: pass packet without reorder.\n");

            RxQueue_PassPacket (pRxQueue, tStatus, pBuffer);

            return;
        }

        /* packet TID BA established */
        /* Get Sequence Number from frame */
        COPY_WLAN_WORD(&uSequenceControl, &pHdr->seqCtrl); /* copy with endianess handling. */
        uFrameSn = (uSequenceControl & DOT11_SC_SEQ_NUM_MASK) >> 4;

        /* 
         * note: 
         * the FW never send paket, in establish TID BA, that the SN less then ESN !!! 
         */

        /* frame Sequence Number is the expected one ? */
        if (uFrameSn == pTidDataBase->aTidExpectedSn)
        {
            TRACE0(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: frame Sequence Number == expected one Sequence Number.\n");

            /* pass the packet */
            RxQueue_PassPacket (pRxQueue, tStatus, pBuffer);

            pTidDataBase->aTidExpectedSn++;
            pTidDataBase->aTidExpectedSn &= 0xfff;

            /* increase the ArrayInex to the next */
            pTidDataBase->aWinStartArrayInex++;

            /* aWinStartArrayInex % RX_QUEUE_ARRAY_SIZE */
            pTidDataBase->aWinStartArrayInex &= RX_QUEUE_ARRAY_SIZE_BIT_MASK;

            /* pass all saved queue packets with SN higher then the expected one */
            while (pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket != NULL)
            {
                RxQueue_PassPacket (pRxQueue, 
                                    pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].tStatus,
                                    pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket);

                pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket = NULL;

                pTidDataBase->aWinStartArrayInex++;

                /* aWinStartArrayInex % RX_QUEUE_ARRAY_SIZE */
                pTidDataBase->aWinStartArrayInex &= RX_QUEUE_ARRAY_SIZE_BIT_MASK;

                 pTidDataBase->aTidExpectedSn++;
				 pTidDataBase->aTidExpectedSn &= 0xfff;
            }

            return;
        }

        /* frame Sequence Number is lower then Expected sequence number (ISN) ? */ 
        if (! BA_SESSION_IS_A_BIGGER_THAN_B (uFrameSn, pTidDataBase->aTidExpectedSn))
        {
			/* WLAN_OS_REPORT(("%s: ERROR - SN=%u is less than ESN=%u\n", __FUNCTION__, uFrameSn, pTidDataBase->aTidExpectedSn)); */

			TRACE2(pRxQueue->hReport, REPORT_SEVERITY_ERROR,
				   "RxQueue_ReceivePacket: frame SN=%u is less than ESN=%u\n",uFrameSn,pTidDataBase->aTidExpectedSn);

			RxQueue_PassPacket (pRxQueue, TI_NOK, pBuffer);

            return;
        }

        /* frame Sequence Number between winStart and winEnd ? */
        if ((BA_SESSION_IS_A_BIGGER_THAN_B (uFrameSn, pTidDataBase->aTidExpectedSn)) &&
            /* mean: uFrameSn <= pTidDataBase->aTidExpectedSn + pTidDataBase->aTidWinSize) */
            ( ! BA_SESSION_IS_A_BIGGER_THAN_B (uFrameSn,(pTidDataBase->aTidExpectedSn + pTidDataBase->aTidWinSize - 1))))
        {
            TI_UINT16 uSaveInex = pTidDataBase->aWinStartArrayInex + (TI_UINT16)((uFrameSn + SEQ_NUM_WRAP - pTidDataBase->aTidExpectedSn) & SEQ_NUM_MASK);
            /* uSaveInex % RX_QUEUE_ARRAY_SIZE */
            uSaveInex &= RX_QUEUE_ARRAY_SIZE_BIT_MASK; 


			if (pTidDataBase->aPaketsQueue[uSaveInex].pPacket == NULL)
			{
                /* save the packet in the queue */
                pTidDataBase->aPaketsQueue[uSaveInex].tStatus = tStatus;
                pTidDataBase->aPaketsQueue[uSaveInex].pPacket = (void *)pBuffer;
                pTidDataBase->aPaketsQueue[uSaveInex].uFrameSn = uFrameSn;
			}
			else
			{
				 TRACE1(pRxQueue->hReport, REPORT_SEVERITY_ERROR, "RxQueue_ReceivePacket: frame Sequence has allready saved. uFrameSn = %d\n",uFrameSn);
				 RxQueue_PassPacket (pRxQueue, TI_NOK, pBuffer);
				 return;
			}
            return;
        }


        /* 
        frame Sequence Number higher then winEnd ? 
        */
        if ( BA_SESSION_IS_A_BIGGER_THAN_B (uFrameSn, (pTidDataBase->aTidExpectedSn + pTidDataBase->aTidWinSize - 1)) )
        {
            TI_UINT32 i;
            TI_UINT16 uNewWinStartSn = (uFrameSn + SEQ_NUM_WRAP - pTidDataBase->aTidWinSize + 1) & SEQ_NUM_MASK;
            TI_UINT16 uSaveInex;
            
			TRACE0(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: frame Sequence Number higher then winEnd.\n");

            /* increase the ArrayInex to the next */
            pTidDataBase->aWinStartArrayInex++;

            /* aWinStartArrayInex % RX_QUEUE_ARRAY_SIZE */
            pTidDataBase->aWinStartArrayInex &= RX_QUEUE_ARRAY_SIZE_BIT_MASK;

            /* update the Expected SN since the current one is lost */
            pTidDataBase->aTidExpectedSn++;
            pTidDataBase->aTidExpectedSn &= 0xFFF;

            /* pass all saved queue packets with SN lower then the new win start */
            for (i = 0;
                 BA_SESSION_IS_A_BIGGER_THAN_B(uNewWinStartSn,pTidDataBase->aTidExpectedSn) &&
                  (i < RX_QUEUE_ARRAY_SIZE) && 
                  (i < pTidDataBase->aTidWinSize);
                 i++)
            {
                if (pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket != NULL)
                {
                    RxQueue_PassPacket (pRxQueue, 
                                        pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].tStatus,
                                        pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket);

                    pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket = NULL;
                }

                pTidDataBase->aWinStartArrayInex++;

                /* aWinStartArrayInex % RX_QUEUE_ARRAY_SIZE */
                pTidDataBase->aWinStartArrayInex &= RX_QUEUE_ARRAY_SIZE_BIT_MASK;

                pTidDataBase->aTidExpectedSn++;
                pTidDataBase->aTidExpectedSn &= 0xFFF;

            }

            /* Calculate the new Expected SN */
            if (i == pTidDataBase->aTidWinSize)
            {
                pTidDataBase->aTidExpectedSn = uNewWinStartSn;
            }
            else
            {
                /* Incase the uWinStartDelta lower than aTidWinSize check if ther are packets stored in Array */
                while (pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket != NULL) {
                    RxQueue_PassPacket (pRxQueue,
                                            pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].tStatus,
                                            pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket);

                    pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket = NULL;

                    pTidDataBase->aWinStartArrayInex++;

                    /* aWinStartArrayInex % RX_QUEUE_ARRAY_SIZE */
                    pTidDataBase->aWinStartArrayInex &= RX_QUEUE_ARRAY_SIZE_BIT_MASK;

                    pTidDataBase->aTidExpectedSn++;
                    pTidDataBase->aTidExpectedSn &= 0xFFF;
                }
            }

            if(pTidDataBase->aTidExpectedSn == uFrameSn)
            {
                /* pass the packet */
                RxQueue_PassPacket (pRxQueue, tStatus, pBuffer);
                pTidDataBase->aTidExpectedSn++;
				pTidDataBase->aTidExpectedSn &= 0xfff;
            }
            else
            {
                uSaveInex = pTidDataBase->aWinStartArrayInex + (TI_UINT16)((uFrameSn + SEQ_NUM_WRAP - pTidDataBase->aTidExpectedSn) & SEQ_NUM_MASK);

				/* uSaveInex % RX_QUEUE_ARRAY_SIZE */
				uSaveInex &= RX_QUEUE_ARRAY_SIZE_BIT_MASK;

            /* save the packet in the last entry of the queue */
               pTidDataBase->aPaketsQueue[uSaveInex].tStatus = tStatus;
               pTidDataBase->aPaketsQueue[uSaveInex].pPacket = (void *)pBuffer;
               pTidDataBase->aPaketsQueue[uSaveInex].pPacket = (void *)pBuffer;
            }

            return;
        }
    }


    /* 
     * BA event ? 
     */
    if (pRxParams->packet_class_tag == TAG_CLASS_BA_EVENT)
    {
        TRxQueueTidDataBase *pTidDataBase;
        TI_UINT8            *pDataFrameBody;
        TI_UINT16           ufc;
        TI_UINT8            uFrameTid;
        TI_UINT16           uStartingSequenceNumber;
        TI_UINT16           uWinStartDelta;
        TI_UINT16           uBarControlField;
        TI_UINT16           uBaStartingSequenceControlField;
        TI_UINT16           uBAParameterField;         
        TI_UINT32           i;

        /* Get sub type from frame */
        COPY_WLAN_WORD(&ufc, &pHdr->fc); /* copy with endianess handling. */

        /* get the type to BA event */
        switch ((dot11_Fc_Sub_Type_e)(ufc & DOT11_FC_SUB_MASK))
        {
        case DOT11_FC_SUB_BAR:
            TRACE0(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION , "RxQueue_ReceivePacket: BA event - BAR frame.\n");

            /* get pointer to the frame body */
            pDataFrameBody = pFrame + sizeof(dot11_BarFrameHeader_t);

            /* Get TID from BAR frame */
            COPY_WLAN_WORD (&uBarControlField, (TI_UINT16 *)pDataFrameBody); /* copy with endianess handling. */
            uFrameTid = (uBarControlField & DOT11_BAR_CONTROL_FIELD_TID_BITS) >> 12;

            /* TID illegal value ? */
            if (uFrameTid >= MAX_NUM_OF_802_1d_TAGS)
            {
                TRACE1(pRxQueue->hReport, REPORT_SEVERITY_ERROR , "RxQueue_ReceivePacket: BA event - BAR frame with TID value too big, TID = %d.\n",uFrameTid);

                RxQueue_PassPacket (pRxQueue, TI_NOK, pBuffer);

                return;
            }

            /* set the SA Tid pointer */
            pTidDataBase = &(pRxQueue->tRxQueueArraysMng.tSa1ArrayMng[uFrameTid]);

            /* TID legal value */
            /* packet TID BA not established ? */ 
            if (pTidDataBase->aTidBaEstablished != TI_TRUE)
            {
                TRACE1(pRxQueue->hReport, REPORT_SEVERITY_ERROR , "RxQueue_ReceivePacket: BA event - BAR frame for TID not established, TID = %d.\n",uFrameTid);

                RxQueue_PassPacket (pRxQueue, TI_NOK, pBuffer);

                return;
            }

            /* Get Starting Sequence number from BAR frame */
            pDataFrameBody = pDataFrameBody + 2;
            COPY_WLAN_WORD (&uBaStartingSequenceControlField, (TI_UINT16 *)pDataFrameBody); /* copy with endianess handling. */
            uStartingSequenceNumber = (uBaStartingSequenceControlField & DOT11_SC_SEQ_NUM_MASK) >> 4;

            /* Starting Sequence Number is higher then winStart ? */
            if ( BA_SESSION_IS_A_BIGGER_THAN_B (uStartingSequenceNumber, pTidDataBase->aTidExpectedSn) )
            {
                uWinStartDelta = (uStartingSequenceNumber + SEQ_NUM_WRAP - pTidDataBase->aTidExpectedSn) & SEQ_NUM_MASK;

                /* pass all saved queue packets with SN lower then the new win start */
                for (i = 0;
                     ((i < uWinStartDelta) || (pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket != NULL)) &&
                      (i < RX_QUEUE_ARRAY_SIZE) && 
                      (i < RX_QUEUE_WIN_SIZE);
                     i++)
                {
                    if (pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket != NULL)
                    {
                        RxQueue_PassPacket (pRxQueue, 
                                            pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].tStatus,
                                            pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket);

                        pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket = NULL;
                    }

                    pTidDataBase->aWinStartArrayInex++;

                    /* aWinStartArrayInex % RX_QUEUE_ARRAY_SIZE */
                    pTidDataBase->aWinStartArrayInex &= RX_QUEUE_ARRAY_SIZE_BIT_MASK;
                }

                pTidDataBase->aTidExpectedSn = uStartingSequenceNumber;
            }
            break;


        case DOT11_FC_SUB_ACTION:
            /* get pointer to the frame body */
            pDataFrameBody = pFrame + sizeof(dot11_mgmtHeader_t);

            /* get Action field from BA action frame */
            pDataFrameBody++;
            switch(*pDataFrameBody)
            {
            case DOT11_BA_ACTION_ADDBA:

                TRACE0( pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: BA event - ADDBA frame.\n");

                /* get TID field and winSize from ADDBA action frame */
                pDataFrameBody = pDataFrameBody + 2;
                COPY_WLAN_WORD(&uBAParameterField, (TI_UINT16 *)pDataFrameBody); /* copy with endianess handling. */
                uFrameTid = (uBAParameterField & DOT11_BA_PARAMETER_SET_FIELD_TID_BITS) >> 2;

                /* TID illegal value ? */
                if (uFrameTid >= MAX_NUM_OF_802_1d_TAGS)
                {
                    TRACE1(pRxQueue->hReport, REPORT_SEVERITY_ERROR , "RxQueue_ReceivePacket: BA event - ADDBA frame with TID value too big, TID = %d.\n",uFrameTid);

                    RxQueue_PassPacket (pRxQueue, TI_NOK, pBuffer);

                    return;
                }

                /*set the SA Tid pointer */
                pTidDataBase = &(pRxQueue->tRxQueueArraysMng.tSa1ArrayMng[uFrameTid]);

                /* TID legal value */
                /* packet TID BA established ? */ 
                if (pTidDataBase->aTidBaEstablished == TI_TRUE)
                {
                    TRACE1(pRxQueue->hReport, REPORT_SEVERITY_ERROR , "RxQueue_ReceivePacket: BA event - ADDBA frame for TID already established, TID = %d.\n",uFrameTid);

                    RxQueue_PassPacket (pRxQueue, TI_NOK, pBuffer);

                    return;
                }

                /* get winSize from ADDBA action frame */
                pTidDataBase->aTidWinSize = (uBAParameterField & DOT11_BA_PARAMETER_SET_FIELD_WINSIZE_BITS) >> 6; 

                /* winSize illegal value ? */ 
                if (pTidDataBase->aTidWinSize > RX_QUEUE_WIN_SIZE)
                {
                    /* In case the win Size is higher then 8 the driver and the FW set it to 8 and inform the AP in ADDBA respond */
                    pTidDataBase->aTidWinSize = RX_QUEUE_WIN_SIZE;
                }

                /* packet TID BA not yet established and winSize legal */
                /* establishe BA TID */
                pTidDataBase->aTidBaEstablished = TI_TRUE;

                /* get initial sequence number (ISN) from ADDBA action frame */
                pDataFrameBody = pDataFrameBody + 4;
                COPY_WLAN_WORD (&uStartingSequenceNumber, (TI_UINT16 *)pDataFrameBody); /* copy with endianess handling. */
                pTidDataBase->aTidExpectedSn = (uStartingSequenceNumber & DOT11_SC_SEQ_NUM_MASK) >> 4;
                pTidDataBase->aWinStartArrayInex = 0;
                os_memoryZero (pRxQueue->hOs, pTidDataBase->aPaketsQueue, sizeof (TRxQueuePacketEntry) * RX_QUEUE_ARRAY_SIZE);
                break;

            case DOT11_BA_ACTION_DELBA:

                TRACE0( pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: BA event - DELBA frame.\n");

                /* get TID field and winSize from ADDBA action frame */
                pDataFrameBody = pDataFrameBody + 2;
                COPY_WLAN_WORD(&uBAParameterField, (TI_UINT16 *)pDataFrameBody); /* copy with endianess handling. */
                uFrameTid = (uBAParameterField & DOT11_DELBA_PARAMETER_FIELD_TID_BITS) >> 12;

                /* TID illegal value ? */
                if (uFrameTid >= MAX_NUM_OF_802_1d_TAGS)
                {
                    TRACE1(pRxQueue->hReport, REPORT_SEVERITY_ERROR , "RxQueue_ReceivePacket: BA event - DELBA frame with TID value too big, TID = %d.\n",uFrameTid);

                    RxQueue_PassPacket (pRxQueue, TI_NOK, pBuffer);

                    return;
                }

                /*set the SA Tid pointer */
                pTidDataBase = &(pRxQueue->tRxQueueArraysMng.tSa1ArrayMng[uFrameTid]);

                /* TID legal value */
                /* packet TID BA not established ? */ 
                if (pTidDataBase->aTidBaEstablished != TI_TRUE)
                {
                    TRACE1(pRxQueue->hReport, REPORT_SEVERITY_ERROR , "RxQueue_ReceivePacket: BA event - DELBA frame for TID not established, TID = %d.\n",uFrameTid);

                    RxQueue_PassPacket (pRxQueue, TI_NOK, pBuffer);

                    return;
                }

                RxQueue_CloseBaSession(hRxQueue, uFrameTid);
                break;

            default:
                TRACE1(pRxQueue->hReport, REPORT_SEVERITY_ERROR , "RxQueue_ReceivePacket: BA event Action field from BA action frame illegal. action = 0x%x\n",*pDataFrameBody);

                RxQueue_PassPacket (pRxQueue, TI_NOK, pBuffer);

                return;
            }
            break;

        default:
            TRACE1(pRxQueue->hReport, REPORT_SEVERITY_ERROR , "RxQueue_ReceivePacket: BA event with Subtype illegal. Subtype = 0x%x\n",((ufc & DOT11_FC_SUB_MASK) >> 4));

            RxQueue_PassPacket (pRxQueue, TI_NOK, pBuffer);

            return;
          }

    }

    TRACE1(pRxQueue->hReport, REPORT_SEVERITY_ERROR, "RxQueue_ReceivePacket: unknow type tag. tag = %d\n", pRxParams->packet_class_tag);

    RxQueue_PassPacket (pRxQueue, tStatus, pBuffer);

    return;
}

