Home | History | Annotate | Download | only in Data_Service
      1 /*
      2  * RxQueue.c
      3  *
      4  * Copyright(c) 1998 - 2010 Texas Instruments. All rights reserved.
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  *
     11  *  * Redistributions of source code must retain the above copyright
     12  *    notice, this list of conditions and the following disclaimer.
     13  *  * Redistributions in binary form must reproduce the above copyright
     14  *    notice, this list of conditions and the following disclaimer in
     15  *    the documentation and/or other materials provided with the
     16  *    distribution.
     17  *  * Neither the name Texas Instruments nor the names of its
     18  *    contributors may be used to endorse or promote products derived
     19  *    from this software without specific prior written permission.
     20  *
     21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     24  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     25  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     26  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     27  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     32  */
     33 
     34 
     35 /** \file   RxQueue.c
     36  *  \brief  RX Queue module that responsible to support re-ordering of received packets to upper layers.
     37  *
     38  *  \see    RxQueue.h
     39  */
     40 #define __FILE_ID__  FILE_ID_98
     41 #include "tidef.h"
     42 #include "osApi.h"
     43 #include "report.h"
     44 #include "RxBuf.h"
     45 #include "TWDriver.h"
     46 #include "public_descriptors.h"
     47 #include "timer.h"
     48 
     49 /************************ static definition declaration *****************************/
     50 #define RX_QUEUE_ARRAY_SIZE		                            8
     51 #define RX_QUEUE_ARRAY_SIZE_BIT_MASK                        0x7 /* RX_QUEUE_ARRAY_SIZE -1 */
     52 #define RX_QUEUE_WIN_SIZE		                            RX_QUEUE_ARRAY_SIZE
     53 #define BA_SESSION_TIME_TO_SLEEP		                    (50)
     54 
     55 #define BA_SESSION_IS_A_BIGGER_THAN_B(A,B)       (((((A)-(B)) & 0xFFF) < 0x7FF) && ((A)!=(B)))
     56 #define BA_SESSION_IS_A_BIGGER_EQUAL_THAN_B(A,B) (((((A)-(B)) & 0xFFF) < 0x7FF))
     57 #define SEQ_NUM_WRAP 0x1000
     58 #define SEQ_NUM_MASK 0xFFF
     59 
     60 
     61 /************************ static structures declaration *****************************/
     62 /* structure describe one entry of save packet information in the packet queue array */
     63 typedef struct
     64 {
     65     void                *pPacket;	/* Packet address of the packet */
     66     TI_STATUS	        tStatus;	/* RxXfer status. */
     67     TI_UINT16           uFrameSn;
     68 } TRxQueuePacketEntry;
     69 
     70 /* structure describe set of data that one Tid, also including the arras himself */
     71 typedef struct
     72 {
     73     /* array packets Entries */
     74     TRxQueuePacketEntry aPaketsQueue [RX_QUEUE_ARRAY_SIZE];
     75     /* TID BA state */
     76     TI_BOOL	            aTidBaEstablished;
     77     /* index that winStar point on */
     78     TI_UINT32 	        aWinStartArrayInex;
     79     /* windows size */
     80     TI_UINT32	        aTidWinSize;
     81 	/* expected sequence number (ESN) */
     82     TI_UINT16	        aTidExpectedSn;
     83 } TRxQueueTidDataBase;
     84 
     85 /* structure describe set of data that assist of manage one SA RxQueue arrays */
     86 typedef struct
     87 {
     88     TRxQueueTidDataBase tSa1ArrayMng [MAX_NUM_OF_802_1d_TAGS];
     89 } TRxQueueArraysMng;
     90 
     91 typedef struct
     92 {
     93     TI_BOOL             bPacketMiss;                /* True - Wait for missing packets start timer
     94                                                        False - all packets received in order */
     95     TI_UINT16           aPacketsStored;             /* Represent the number of packets in Queue, 0 - Queue is empty */
     96     TI_UINT8            aFrameTid;                  /* save the TID of the missing packet */
     97 } TPacketTimeout;
     98 
     99 
    100 /* main RxQueue structure in order to management the packets disordered array. */
    101 typedef struct
    102 {
    103     TI_HANDLE           hOs;                        /* OS handler */
    104     TI_HANDLE           hReport;                    /* Report handler */
    105 	TI_HANDLE           hTimer;                     /* Timer Handle */
    106     TRxQueueArraysMng   tRxQueueArraysMng;          /* manage each Source Address RxQueue arrays */
    107     TPacketReceiveCb    tReceivePacketCB;           /* Receive packets CB address */
    108     TI_HANDLE           hReceivePacketCB_handle;    /* Receive packets CB handler */
    109 	TPacketTimeout      tPacketTimeout;             /* save information about the missing packet */
    110 } TRxQueue;
    111 
    112 /************************ static function declaration *****************************/
    113 static TI_STATUS RxQueue_PassPacket (TI_HANDLE hRxQueue, TI_STATUS tStatus, const void *pBuffer);
    114 static void RxQueue_PacketTimeOut (TI_HANDLE hRxQueue, TI_BOOL bTwdInitOccured);
    115 
    116 /**
    117  * \fn     RxQueue_Create()
    118  * \brief  Create the RxQueue module.
    119  *
    120  * Allocate and clear the RxQueue module object.
    121  *
    122  * \param  hOs - Handle to Os Abstraction Layer
    123  * \return Handle of the allocated object
    124  * \sa     RxQueue_Destroy
    125  */
    126 TI_HANDLE RxQueue_Create (TI_HANDLE hOs)
    127 {
    128 	TRxQueue *pRxQueue;
    129 
    130 	/* allocate module object */
    131 	pRxQueue = os_memoryAlloc (hOs, sizeof(TRxQueue));
    132 
    133 	if (!pRxQueue)
    134 	{
    135 		WLAN_OS_REPORT (("RxQueue_Create():  Allocation failed!!\n"));
    136 		return NULL;
    137 	}
    138 
    139     os_memoryZero (hOs, pRxQueue, (sizeof(TRxQueue)));
    140 
    141     pRxQueue->hOs = hOs;
    142 
    143 	return (pRxQueue);
    144 }
    145 
    146 
    147 /**
    148  * \fn     RxQueue_Destroy()
    149  * \brief  Destroy the module.
    150  *
    151  * Free the module's queues and object.
    152  *
    153  * \param  hRxQueue - The module object
    154  * \return TI_OK on success or TI_NOK on failure
    155  * \sa     RxQueue_Create
    156  */
    157 TI_STATUS RxQueue_Destroy (TI_HANDLE hRxQueue)
    158 {
    159     TRxQueue *pRxQueue;
    160 
    161     if (hRxQueue) {
    162         pRxQueue = (TRxQueue *)hRxQueue;
    163 
    164         if (pRxQueue->hTimer) {
    165             tmr_DestroyTimer (pRxQueue->hTimer);
    166             pRxQueue->hTimer = NULL;
    167         }
    168 
    169         /* free module object */
    170         os_memoryFree (pRxQueue->hOs, pRxQueue, sizeof(TRxQueue));
    171 
    172         return TI_OK;
    173     }
    174 
    175     return TI_NOK;
    176 }
    177 
    178 
    179 /**
    180  * \fn     RxQueue_Init()
    181  * \brief  Init required handles
    182  *
    183  * Init required handles and module variables.
    184  *
    185  * \note
    186  * \param  hRxQueue - The module object
    187  * \param  hReport - Report module Handles
    188  * \return TI_OK on success or TI_NOK on failure
    189  * \sa
    190  */
    191 TI_STATUS RxQueue_Init (TI_HANDLE hRxQueue, TI_HANDLE hReport, TI_HANDLE hTimerModule)
    192 {
    193 	TRxQueue *pRxQueue = (TRxQueue *)hRxQueue;
    194 
    195     pRxQueue->hReport   = hReport;
    196 
    197 	pRxQueue->hTimer = tmr_CreateTimer (hTimerModule);
    198 
    199 	return TI_OK;
    200 }
    201 
    202 
    203 /**
    204  * \fn     RxQueue_Register_CB()
    205  * \brief  Register the function to be called for received Rx.
    206  *
    207  * \note
    208  * \param  hRxQueue - The module object
    209  * \param  CallBackID - event ID
    210  * \param  CBFunc - function address.
    211  * \param  CBObj - function parameter.
    212  * \return TI_OK on success or TI_NOK on failure
    213  * \sa
    214  */
    215 void RxQueue_Register_CB (TI_HANDLE hRxQueue, TI_UINT32 uCallBackID, void *CBFunc, TI_HANDLE CBObj)
    216 {
    217     TRxQueue* pRxQueue = (TRxQueue *)hRxQueue;
    218 
    219     TRACE1(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION , "RxQueue_Register_CB: CallBack ID = 0x%x\n", uCallBackID);
    220 
    221     switch(uCallBackID)
    222     {
    223     case TWD_INT_RECEIVE_PACKET:
    224         pRxQueue->tReceivePacketCB = (TPacketReceiveCb)CBFunc;
    225         pRxQueue->hReceivePacketCB_handle = CBObj;
    226         break;
    227 
    228     default:
    229         TRACE0(pRxQueue->hReport, REPORT_SEVERITY_ERROR , "RxQueue_Register_CB: Illegal value\n");
    230         break;
    231     }
    232 }
    233 
    234 /**
    235  * \fn     RxQueue_CloseBaSession ()
    236  * \brief  Close BA session receiver and pass all packets in the TID queue to upper layer.
    237  *
    238  * \note
    239  * \param  hRxQueue - RxQueue handle.
    240  * \param  uFrameTid - TID session.
    241  * \return None
    242  * \sa
    243  */
    244 void RxQueue_CloseBaSession(TI_HANDLE hRxQueue, TI_UINT8 uFrameTid)
    245 {
    246     TRxQueue            *pRxQueue     = (TRxQueue *)hRxQueue;
    247     TI_UINT32            i;
    248     /*set the SA Tid pointer */
    249     TRxQueueTidDataBase *pTidDataBase = &(pRxQueue->tRxQueueArraysMng.tSa1ArrayMng[uFrameTid]);
    250 
    251     /* TID illegal value ? */
    252     if (uFrameTid >= MAX_NUM_OF_802_1d_TAGS)
    253     {
    254         TRACE1(pRxQueue->hReport, REPORT_SEVERITY_ERROR , "RxQueue_CloseBaSession: BA event - DELBA frame with TID value too big, TID = %d\n", uFrameTid);
    255 
    256         return;
    257     }
    258 
    259     if(pTidDataBase->aTidBaEstablished == TI_TRUE)
    260     {
    261         /* clean BA session */
    262         pTidDataBase->aTidBaEstablished = TI_FALSE;
    263 
    264         /* pass all valid entries at the array */
    265         for (i = 0; (i < RX_QUEUE_ARRAY_SIZE) && (i < RX_QUEUE_WIN_SIZE); i++)
    266         {
    267             if (pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket != NULL)
    268             {
    269                 RxQueue_PassPacket (pRxQueue,
    270                                     pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].tStatus,
    271                                     pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket);
    272 
    273                 pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket = NULL;
    274 
    275                 pRxQueue->tPacketTimeout.aPacketsStored--;
    276             }
    277 
    278             pTidDataBase->aWinStartArrayInex ++;
    279 
    280             /* aWinStartArrayInex % RX_QUEUE_ARRAY_SIZE */
    281             pTidDataBase->aWinStartArrayInex &= RX_QUEUE_ARRAY_SIZE_BIT_MASK;
    282         }
    283 
    284         if (pRxQueue->tPacketTimeout.bPacketMiss)
    285         {
    286                 tmr_StopTimer (pRxQueue->hTimer);
    287                 pRxQueue->tPacketTimeout.bPacketMiss = TI_FALSE;
    288         }
    289     }
    290 }
    291 
    292 
    293 /**
    294  * \fn     RxQueue_PassPacket()
    295  * \brief  Responsible on decode packet parameters and pass it to upper layer.
    296  *
    297  * \note
    298  * \param  hRxQueue - RxQueue handle.
    299  * \param  aStatus - RxXfer status that indicate if the upper layer should free the packet or use it.
    300  * \param  pFrame - paket address of the packet
    301  * \param  pRxParams - address to structure of the Rx Descriptor received by FW.
    302  * \return TI_OK on success or TI_NOK on failure
    303  * \sa
    304  */
    305 static TI_STATUS RxQueue_PassPacket (TI_HANDLE hRxQueue, TI_STATUS tStatus, const void *pBuffer)
    306 {
    307 
    308     TRxQueue            *pRxQueue   = (TRxQueue *)hRxQueue;
    309 
    310     if (tStatus == TI_OK)
    311     {
    312         /* Get the mac header location in the packet Buffer */
    313         dot11_header_t *pMacHdr = (dot11_header_t *)(TI_UINT8*)RX_BUF_DATA(pBuffer);
    314 
    315         /* Handle endian for the frame control fields */
    316         pMacHdr->fc  = ENDIAN_HANDLE_WORD(pMacHdr->fc);
    317         pMacHdr->duration = ENDIAN_HANDLE_WORD(pMacHdr->duration);
    318         pMacHdr->seqCtrl = ENDIAN_HANDLE_WORD(pMacHdr->seqCtrl);
    319     }
    320     else
    321     {
    322         RxIfDescriptor_t    *pRxParams  = (RxIfDescriptor_t*)pBuffer;
    323 
    324         pRxParams->status &= ~RX_DESC_STATUS_MASK;
    325         pRxParams->status |= RX_DESC_STATUS_DRIVER_RX_Q_FAIL;
    326     }
    327 
    328     TRACE0(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION , "RxQueue_PassPacket: call TWD_OWNER_RX_QUEUE CB. In std rxData_ReceivePacket()\n");
    329 
    330     /* Set the packet to upper layer */
    331     /* if the packet status not success it will be discarded */
    332     pRxQueue->tReceivePacketCB (pRxQueue->hReceivePacketCB_handle, pBuffer);
    333 
    334     return TI_OK;
    335 }
    336 
    337 
    338 /**
    339  * \fn     RxQueue_ReceivePacket()
    340  * \brief  Main function of the RxQueue module.
    341  * Responsible on reorder of the packets from the RxXfer to the RX module.
    342  * Call from RxXfer in order to pass packet to uppers layers.
    343  * In order to save disordered packets the module use array of structures per TID
    344  * that each entry describe a packet. The array elements is sorted in the way that
    345  * the winStart array index represent always the winStart packet and the lowest SN.
    346  * Each increment index represent index at the BA window. Array index winEnd  always
    347  * represent winEnd packet. The indexes of winStart and winEnd handled in cyclic manner.
    348  * The function functionality devided to parts:
    349  *   Part 1:
    350  * in case the modulo receive packet with SN equal to winStart:
    351  * "	pass it to upper layers
    352  * "	increases winStart and array index winStart
    353  * "	validate that all sequential queue packet are pass to the upper layers.
    354  *   Part 2:
    355  * in case the modulo receive packet that SN between winStart to winEnd:
    356  * "	Save it sorted at the array at index: Save index = ((SN - winStart) + index array winStart) % arraySize.
    357  *   Part 3:
    358  * in case the modulo receive packet that SN higher than winEnd:
    359  * "	Update winStart and WinEnd.
    360  * "	Save it sorted at the array in index winEnd index.
    361  * "	Pass to the upper layers all packets at the array indexes from old winStart index to the updated winStart index.
    362  *   Part 4 + 5:
    363  * in case the modulo receive BA event packet:
    364  * "	Update winStart and WinEnd
    365  * "	Pass to the upper layers all packets at the array indexes from old winStart index to the updated winStart index.
    366  * "	Free BA event packet via pass it to upper layers with error status.
    367  *
    368  * \note
    369  * \param  hRxQueue - RxQueue handle.
    370  * \param  aStatus - RxXfer status that indicate if the upper layer should free the packet or use it.
    371  * \param  pBuffer - paket address of the packet
    372  * \return None
    373  * \sa
    374  */
    375 void RxQueue_ReceivePacket (TI_HANDLE hRxQueue, const void * pBuffer)
    376 {
    377     TRxQueue            *pRxQueue   = (TRxQueue *)hRxQueue;
    378     RxIfDescriptor_t    *pRxParams  = (RxIfDescriptor_t*)pBuffer;
    379     TI_UINT8            *pFrame     = RX_BUF_DATA((TI_UINT8 *)pBuffer);
    380     TI_STATUS           tStatus     = TI_OK;
    381     dot11_header_t      *pHdr       = (dot11_header_t *)pFrame;
    382     TI_UINT16		    uQosControl;
    383 
    384     COPY_WLAN_WORD(&uQosControl, &pHdr->qosControl); /* copy with endianess handling. */
    385 
    386     TRACE2(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: packet_class_tag = 0x%x(%d)",pRxParams->packet_class_tag,pRxParams->packet_class_tag);
    387 
    388     /*
    389      * Retrieving the TAG from the packet itself and not from the Rx Descriptor since by now it is not correct
    390      * Note: in the DR TAG_CLASS_EAPOL packet handled as TAG_CLASS_QOS_DATA
    391      */
    392     if (IS_QOS_FRAME(*(TI_UINT16*)pFrame) && (pRxParams->packet_class_tag != TAG_CLASS_QOS_DATA) && (pRxParams->packet_class_tag != TAG_CLASS_AMSDU))
    393 	{
    394         TRACE1(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: BAD CLASS TAG =0x%x from FW.\n", pRxParams->packet_class_tag);
    395 
    396         /* Get AMSDU bit from frame */
    397         if( uQosControl & DOT11_QOS_CONTROL_FIELD_A_MSDU_BITS)
    398         {
    399             pRxParams->packet_class_tag = TAG_CLASS_AMSDU;
    400         }
    401         else
    402         {
    403             pRxParams->packet_class_tag = TAG_CLASS_QOS_DATA;
    404         }
    405     }
    406 
    407     /*
    408      * packet doesn't need reorder ?
    409      */
    410     if ((pRxParams->packet_class_tag != TAG_CLASS_QOS_DATA) && (pRxParams->packet_class_tag != TAG_CLASS_BA_EVENT) && (pRxParams->packet_class_tag != TAG_CLASS_AMSDU))
    411     {
    412         TRACE0(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: pass packet without reorder.\n");
    413 
    414         RxQueue_PassPacket (pRxQueue, tStatus, pBuffer);
    415 
    416         return;
    417     }
    418 
    419 
    420     /*
    421      * pRxParams->type == TAG_CLASS_QOS_DATA ?
    422      */
    423     if ((pRxParams->packet_class_tag == TAG_CLASS_QOS_DATA) || (pRxParams->packet_class_tag == TAG_CLASS_AMSDU))
    424     {
    425         TI_UINT8            uFrameTid;
    426         TI_UINT16           uFrameSn;
    427         TI_UINT16		    uSequenceControl;
    428         TRxQueueTidDataBase *pTidDataBase;
    429 
    430         /* Get TID from frame */
    431         uFrameTid = uQosControl & DOT11_QOS_CONTROL_FIELD_TID_BITS;
    432 
    433         TRACE0(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: QoS Packet received");
    434         TRACE2(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: uFrameTid = 0x%x(%d)",uFrameTid,uFrameTid);
    435 
    436         /* TID illegal value ? */
    437         if (uFrameTid >= MAX_NUM_OF_802_1d_TAGS)
    438         {
    439             TRACE1(pRxQueue->hReport, REPORT_SEVERITY_ERROR, "RxQueue_ReceivePacket: TID value too big, TID = %d. packet discarded!\n",uFrameTid);
    440 
    441             RxQueue_PassPacket (pRxQueue, TI_NOK, pBuffer);
    442 
    443             return;
    444         }
    445 
    446         /* Set the SA Tid pointer */
    447         pTidDataBase = &(pRxQueue->tRxQueueArraysMng.tSa1ArrayMng[uFrameTid]);
    448 
    449         /* TID legal value */
    450         /* Packet TID BA session not established ? */
    451         if (pTidDataBase->aTidBaEstablished != TI_TRUE)
    452         {
    453             TRACE0(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: pass packet without reorder.\n");
    454 
    455             RxQueue_PassPacket (pRxQueue, tStatus, pBuffer);
    456 
    457             return;
    458         }
    459 
    460         /* packet TID BA established */
    461         /* Get Sequence Number from frame */
    462         COPY_WLAN_WORD(&uSequenceControl, &pHdr->seqCtrl); /* copy with endianess handling. */
    463         uFrameSn = (uSequenceControl & DOT11_SC_SEQ_NUM_MASK) >> 4;
    464 
    465         TRACE2(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: uFrameSn = 0x%x(%d)", uFrameSn, uFrameSn);
    466         TRACE2(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: aTidExpectedSn = 0x%x(%d)",pTidDataBase->aTidExpectedSn, pTidDataBase->aTidExpectedSn);
    467 
    468         /*
    469          * Note:
    470          * The FW never sends packet, in establish TID BA, with SN less than ESN !!!
    471          */
    472 
    473         /* Part 1 - Frame Sequence Number is the expected one ? */
    474         if (uFrameSn == pTidDataBase->aTidExpectedSn)
    475         {
    476             TRACE0(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: frame Sequence Number == expected one Sequence Number.\n");
    477 
    478 			/* Stop timer in case that the expected SN received and timer was running */
    479 
    480 
    481             /* If we wait for 2 consecutive packets we should not stop the timer - This is why we are checking after the while loop, if we have
    482                more packets stored, and if we have, we start the timer again.
    483             */
    484             if (pRxQueue->tPacketTimeout.bPacketMiss)
    485             {
    486                 tmr_StopTimer (pRxQueue->hTimer);
    487                 pRxQueue->tPacketTimeout.bPacketMiss = TI_FALSE;
    488             }
    489 
    490 
    491             /* Pass the packet */
    492             RxQueue_PassPacket (pRxQueue, tStatus, pBuffer);
    493 
    494             /* Increase expected SN to the next */
    495             pTidDataBase->aTidExpectedSn++;
    496             pTidDataBase->aTidExpectedSn &= 0xfff;  /* SN is 12 bits long */
    497 
    498             /* Increase the ArrayInex to the next */
    499             pTidDataBase->aWinStartArrayInex++;
    500 
    501             /* aWinStartArrayInex % RX_QUEUE_ARRAY_SIZE */
    502             pTidDataBase->aWinStartArrayInex &= RX_QUEUE_ARRAY_SIZE_BIT_MASK;
    503 
    504             /* Pass all saved queue packets with SN higher than the expected one */
    505             while (pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket != NULL)
    506             {
    507                 TRACE0(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: Pass all saved queue packets with SN higher than the expected one that was just received.");
    508                 TRACE2(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: aTidExpectedSn = 0x%x(%d)", pTidDataBase->aTidExpectedSn, pTidDataBase->aTidExpectedSn);
    509                 TRACE2(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: aWinStartArrayInex = 0x%x(%d)", pTidDataBase->aWinStartArrayInex, pTidDataBase->aWinStartArrayInex);
    510 
    511                 RxQueue_PassPacket (pRxQueue,
    512                                     pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].tStatus,
    513                                     pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket);
    514 
    515                 pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket = NULL;
    516 
    517                 pTidDataBase->aWinStartArrayInex++;
    518 
    519                 /* aWinStartArrayInex % RX_QUEUE_ARRAY_SIZE */
    520                 pTidDataBase->aWinStartArrayInex &= RX_QUEUE_ARRAY_SIZE_BIT_MASK;
    521 
    522                  pTidDataBase->aTidExpectedSn++;
    523 				 pTidDataBase->aTidExpectedSn &= 0xfff; /* SN is 12 bits long */
    524 
    525 				 /* Decrease the packets in queue */
    526                 pRxQueue->tPacketTimeout.aPacketsStored--;
    527             }
    528 
    529 
    530             /* aTidExpectedSn % 0xfff in order to tack care of wrap around */
    531             pTidDataBase->aTidExpectedSn &= 0xfff;
    532 
    533             /* If there are still packets stored in the queue - start timer */
    534 			if (pRxQueue->tPacketTimeout.aPacketsStored)
    535             {
    536                 tmr_StartTimer (pRxQueue->hTimer, RxQueue_PacketTimeOut, pRxQueue, BA_SESSION_TIME_TO_SLEEP, TI_FALSE);
    537 
    538                 pRxQueue->tPacketTimeout.bPacketMiss = TI_TRUE;
    539                 pRxQueue->tPacketTimeout.aFrameTid   = uFrameTid;
    540             }
    541 
    542             return;
    543         }
    544 
    545         /* Frame Sequence Number is lower than Expected sequence number (ISN) ? */
    546         if (! BA_SESSION_IS_A_BIGGER_THAN_B (uFrameSn, pTidDataBase->aTidExpectedSn))
    547         {
    548             /* WLAN_OS_REPORT(("%s: ERROR - SN=%u is less than ESN=%u\n", __FUNCTION__, uFrameSn, pTidDataBase->aTidExpectedSn)); */
    549             TRACE0(pRxQueue->hReport, REPORT_SEVERITY_ERROR, "RxQueue_ReceivePacket: frame Sequence Number is lower than expected sequence number.\n");
    550 
    551             RxQueue_PassPacket (pRxQueue, tStatus, pBuffer);
    552 
    553             return;
    554         }
    555 
    556         /* Part 2 - Frame Sequence Number between winStart and winEnd ? */
    557         if ((BA_SESSION_IS_A_BIGGER_THAN_B (uFrameSn, pTidDataBase->aTidExpectedSn)) &&
    558             /* mean: uFrameSn <= pTidDataBase->aTidExpectedSn + pTidDataBase->aTidWinSize) */
    559             ( ! BA_SESSION_IS_A_BIGGER_THAN_B (uFrameSn,(pTidDataBase->aTidExpectedSn + pTidDataBase->aTidWinSize - 1))))
    560         {
    561             TI_UINT16 uSaveIndex = pTidDataBase->aWinStartArrayInex + (TI_UINT16)((uFrameSn + SEQ_NUM_WRAP - pTidDataBase->aTidExpectedSn) & SEQ_NUM_MASK);
    562 
    563             /* uSaveIndex % RX_QUEUE_ARRAY_SIZE */
    564             uSaveIndex &= RX_QUEUE_ARRAY_SIZE_BIT_MASK;
    565 
    566             TRACE0(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: frame Sequence Number between winStart and winEnd.\n");
    567             TRACE2(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: uSaveIndex = 0x%x(%d)",uSaveIndex,uSaveIndex);
    568 
    569             /* Before storing packet in queue, make sure the place in the queue is vacant */
    570 			if (pTidDataBase->aPaketsQueue[uSaveIndex].pPacket == NULL)
    571 			{
    572                 TRACE0(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: Enter packet to Reorder Queue");
    573 
    574                 /* Store the packet in the queue */
    575                 pTidDataBase->aPaketsQueue[uSaveIndex].tStatus  = tStatus;
    576                 pTidDataBase->aPaketsQueue[uSaveIndex].pPacket  = (void *)pBuffer;
    577                 pTidDataBase->aPaketsQueue[uSaveIndex].uFrameSn = uFrameSn;
    578 
    579 				pRxQueue->tPacketTimeout.aPacketsStored++;
    580 
    581 
    582 				/* Start Timer [only if timer is not already started - according to bPacketMiss] */
    583                 if(pRxQueue->tPacketTimeout.bPacketMiss == TI_FALSE)
    584                 {
    585 				    tmr_StartTimer (pRxQueue->hTimer, RxQueue_PacketTimeOut, pRxQueue, BA_SESSION_TIME_TO_SLEEP, TI_FALSE);
    586 				    pRxQueue->tPacketTimeout.bPacketMiss = TI_TRUE;
    587 				    pRxQueue->tPacketTimeout.aFrameTid   = uFrameTid;
    588 			    }
    589             }
    590 			else
    591 			{
    592  				 TRACE1(pRxQueue->hReport, REPORT_SEVERITY_ERROR, "RxQueue_ReceivePacket: frame Sequence has already saved. uFrameSn = %d\n", uFrameSn);
    593 
    594 				 RxQueue_PassPacket (pRxQueue, TI_NOK, pBuffer);
    595 				 return;
    596 			}
    597             return;
    598         }
    599 
    600 
    601         /*
    602         Part 3 - Frame Sequence Number higher than winEnd ?
    603         */
    604         if ( BA_SESSION_IS_A_BIGGER_THAN_B (uFrameSn, (pTidDataBase->aTidExpectedSn + pTidDataBase->aTidWinSize - 1)) )
    605         {
    606             TI_UINT32 i;
    607             TI_UINT16 uNewWinStartSn = (uFrameSn + SEQ_NUM_WRAP - pTidDataBase->aTidWinSize + 1) & SEQ_NUM_MASK;
    608             TI_UINT16 uSaveIndex;
    609 
    610 
    611 			TRACE0(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: frame Sequence Number higher than winEnd.\n");
    612             TRACE2(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: uNewWinStartSn = 0x%x(%d) STOP TIMER",uNewWinStartSn,uNewWinStartSn);
    613 
    614             /* If timer is on - stop it */
    615 			if (pRxQueue->tPacketTimeout.bPacketMiss)
    616             {
    617                 tmr_StopTimer (pRxQueue->hTimer);
    618                 pRxQueue->tPacketTimeout.bPacketMiss = TI_FALSE;
    619             }
    620 
    621             /* Increase the ArrayInex to the next */
    622             pTidDataBase->aWinStartArrayInex++;
    623 
    624             /* aWinStartArrayInex % RX_QUEUE_ARRAY_SIZE */
    625             pTidDataBase->aWinStartArrayInex &= RX_QUEUE_ARRAY_SIZE_BIT_MASK;
    626 
    627             /* Update the Expected SN since the current one is lost */
    628             pTidDataBase->aTidExpectedSn++;
    629             pTidDataBase->aTidExpectedSn &= 0xFFF;
    630 
    631             /* Pass all saved queue packets with SN lower than the new win start */
    632             for (i = 0;
    633                  BA_SESSION_IS_A_BIGGER_THAN_B(uNewWinStartSn,pTidDataBase->aTidExpectedSn) &&
    634                   (i < RX_QUEUE_ARRAY_SIZE) &&
    635                   (i < pTidDataBase->aTidWinSize);
    636                  i++)
    637             {
    638                 TRACE2(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: aTidExpectedSn = 0x%x(%d)",pTidDataBase->aTidExpectedSn,pTidDataBase->aTidExpectedSn);
    639                 TRACE2(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: aWinStartArrayInex = 0x%x(%d)",pTidDataBase->aWinStartArrayInex,pTidDataBase->aWinStartArrayInex);
    640 
    641                 if (pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket != NULL)
    642                 {
    643                     TRACE0(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: Send Packet to Upper layer");
    644                     RxQueue_PassPacket (pRxQueue,
    645                                         pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].tStatus,
    646                                         pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket);
    647 
    648                     pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket = NULL;
    649 
    650 					pRxQueue->tPacketTimeout.aPacketsStored--;
    651                 }
    652 
    653                 pTidDataBase->aWinStartArrayInex++;
    654 
    655                 /* aWinStartArrayInex % RX_QUEUE_ARRAY_SIZE */
    656                 pTidDataBase->aWinStartArrayInex &= RX_QUEUE_ARRAY_SIZE_BIT_MASK;
    657 
    658                 pTidDataBase->aTidExpectedSn++;
    659                 pTidDataBase->aTidExpectedSn &= 0xFFF;
    660 
    661             }
    662 
    663             TRACE2(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: aTidExpectedSn = 0x%x(%d)",pTidDataBase->aTidExpectedSn,pTidDataBase->aTidExpectedSn);
    664             TRACE1(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: i = %d",i);
    665 
    666             /* Calculate the new Expected SN */
    667             if (i == pTidDataBase->aTidWinSize)
    668             {
    669                 TRACE0(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: Set aTidExpectedSn to uNewWinStartSn");
    670                 pTidDataBase->aTidExpectedSn = uNewWinStartSn;
    671             }
    672             else
    673             {
    674                 TRACE0(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: Send all saved packets");
    675                 /* In case the uWinStartDelta lower than aTidWinSize check if ther are packets stored in Array */
    676 
    677                 while (pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket != NULL)
    678                 {
    679                     TRACE2(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: Send packet with SN = 0x%x(%d)",pTidDataBase->aTidExpectedSn,pTidDataBase->aTidExpectedSn);
    680 
    681                     RxQueue_PassPacket ( pRxQueue,
    682                                          pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].tStatus,
    683                                          pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket
    684                                        );
    685                     pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket = NULL;
    686 
    687                     pTidDataBase->aWinStartArrayInex++;
    688 
    689                     /* aWinStartArrayInex % RX_QUEUE_ARRAY_SIZE */
    690                     pTidDataBase->aWinStartArrayInex &= RX_QUEUE_ARRAY_SIZE_BIT_MASK;
    691 
    692                     pTidDataBase->aTidExpectedSn++;
    693                     pTidDataBase->aTidExpectedSn &= 0xFFF;
    694 
    695                     pRxQueue->tPacketTimeout.aPacketsStored--;
    696                 }
    697             }
    698 
    699             TRACE2(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: aTidExpectedSn = 0x%x(%d)",pTidDataBase->aTidExpectedSn,pTidDataBase->aTidExpectedSn);
    700 
    701             if(pTidDataBase->aTidExpectedSn == uFrameSn)
    702             {
    703                 TRACE0(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: Send current packet to uper layer");
    704                 /* pass the packet */
    705                 RxQueue_PassPacket (pRxQueue, tStatus, pBuffer);
    706                 pTidDataBase->aTidExpectedSn++;
    707 				pTidDataBase->aTidExpectedSn &= 0xfff;
    708             }
    709             else
    710             {
    711                 uSaveIndex = pTidDataBase->aWinStartArrayInex + (TI_UINT16)((uFrameSn + SEQ_NUM_WRAP - pTidDataBase->aTidExpectedSn) & SEQ_NUM_MASK);
    712 
    713                 TRACE0(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: Enter current packet to Reorder Queue");
    714                 TRACE2(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: uSaveIndex = 0x%x(%d)", uSaveIndex, uSaveIndex);
    715 
    716 				/* uSaveIndex % RX_QUEUE_ARRAY_SIZE */
    717 				uSaveIndex &= RX_QUEUE_ARRAY_SIZE_BIT_MASK;
    718 
    719 				/* Save the packet in the last entry of the queue */
    720 				pTidDataBase->aPaketsQueue[uSaveIndex].tStatus = tStatus;
    721 				pTidDataBase->aPaketsQueue[uSaveIndex].pPacket = (void *)pBuffer;
    722 				pTidDataBase->aPaketsQueue[uSaveIndex].pPacket = (void *)pBuffer;
    723 
    724                pRxQueue->tPacketTimeout.aPacketsStored++;
    725             }
    726 
    727 
    728             /* aTidExpectedSn % 0xfff in order to tack care of wrap around */
    729             pTidDataBase->aTidExpectedSn &= 0xfff;
    730 
    731             /* If there are still packets stored in the queue - start timer */
    732 			if (pRxQueue->tPacketTimeout.aPacketsStored)
    733             {
    734                 tmr_StartTimer (pRxQueue->hTimer, RxQueue_PacketTimeOut, pRxQueue, BA_SESSION_TIME_TO_SLEEP, TI_FALSE);
    735                 pRxQueue->tPacketTimeout.bPacketMiss = TI_TRUE;
    736                 pRxQueue->tPacketTimeout.aFrameTid   = uFrameTid;
    737             }
    738 
    739             return;
    740         }
    741     }
    742 
    743 
    744     /*
    745      * BA event ?
    746      */
    747     if (pRxParams->packet_class_tag == TAG_CLASS_BA_EVENT)
    748     {
    749         TRxQueueTidDataBase *pTidDataBase;
    750         TI_UINT8            *pDataFrameBody;
    751         TI_UINT16           ufc;
    752         TI_UINT8            uFrameTid;
    753         TI_UINT16           uStartingSequenceNumber;
    754         TI_UINT16           uWinStartDelta;
    755         TI_UINT16           uBarControlField;
    756         TI_UINT16           uBaStartingSequenceControlField;
    757         TI_UINT16           uBAParameterField;
    758         TI_UINT32           i;
    759 
    760         /* Get sub type from frame */
    761         COPY_WLAN_WORD(&ufc, &pHdr->fc); /* copy with endianess handling. */
    762 
    763         /* get the type to BA event */
    764         switch ((dot11_Fc_Sub_Type_e)(ufc & DOT11_FC_SUB_MASK))
    765         {
    766         case DOT11_FC_SUB_BAR:
    767             TRACE0(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION , "RxQueue_ReceivePacket: BA event - BAR frame.\n");
    768 
    769             /* get pointer to the frame body */
    770             pDataFrameBody = pFrame + sizeof(dot11_BarFrameHeader_t);
    771 
    772             /* Get TID from BAR frame */
    773             COPY_WLAN_WORD (&uBarControlField, (TI_UINT16 *)pDataFrameBody); /* copy with endianess handling. */
    774             uFrameTid = (uBarControlField & DOT11_BAR_CONTROL_FIELD_TID_BITS) >> 12;
    775 
    776             /* TID illegal value ? */
    777             if (uFrameTid >= MAX_NUM_OF_802_1d_TAGS)
    778             {
    779                 TRACE1(pRxQueue->hReport, REPORT_SEVERITY_ERROR , "RxQueue_ReceivePacket: BA event - BAR frame with TID value too big, TID = %d.\n",uFrameTid);
    780 
    781                 RxQueue_PassPacket (pRxQueue, TI_NOK, pBuffer);
    782 
    783                 return;
    784             }
    785 
    786             /* set the SA Tid pointer */
    787             pTidDataBase = &(pRxQueue->tRxQueueArraysMng.tSa1ArrayMng[uFrameTid]);
    788 
    789             /* TID legal value */
    790             /* packet TID BA not established ? */
    791             if (pTidDataBase->aTidBaEstablished != TI_TRUE)
    792             {
    793                 TRACE1(pRxQueue->hReport, REPORT_SEVERITY_ERROR , "RxQueue_ReceivePacket: BA event - BAR frame for TID not established, TID = %d.\n",uFrameTid);
    794 
    795                 RxQueue_PassPacket (pRxQueue, TI_NOK, pBuffer);
    796 
    797                 return;
    798             }
    799 
    800             /* Get Starting Sequence number from BAR frame */
    801             pDataFrameBody = pDataFrameBody + 2;
    802             COPY_WLAN_WORD (&uBaStartingSequenceControlField, (TI_UINT16 *)pDataFrameBody); /* copy with endianess handling. */
    803             uStartingSequenceNumber = (uBaStartingSequenceControlField & DOT11_SC_SEQ_NUM_MASK) >> 4;
    804 
    805             /* Starting Sequence Number is higher than winStart ? */
    806             if ( BA_SESSION_IS_A_BIGGER_THAN_B (uStartingSequenceNumber, pTidDataBase->aTidExpectedSn) )
    807             {
    808                 uWinStartDelta = uStartingSequenceNumber - pTidDataBase->aTidExpectedSn;
    809                 if (pRxQueue->tPacketTimeout.bPacketMiss)
    810                 {
    811                     tmr_StopTimer (pRxQueue->hTimer);
    812                     pRxQueue->tPacketTimeout.bPacketMiss = TI_FALSE;
    813                 }
    814 
    815                 /* pass all saved queue packets with SN lower than the new win start */
    816                 for (i = 0;
    817                      ((i < uWinStartDelta) || (pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket != NULL)) &&
    818                       (i < RX_QUEUE_ARRAY_SIZE) &&
    819                       (i < RX_QUEUE_WIN_SIZE);
    820                      i++)
    821                 {
    822                     if (pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket != NULL)
    823                     {
    824                         RxQueue_PassPacket (pRxQueue,
    825                                             pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].tStatus,
    826                                             pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket);
    827 
    828                         pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket = NULL;
    829                         pRxQueue->tPacketTimeout.aPacketsStored--;
    830                     }
    831 
    832                     pTidDataBase->aWinStartArrayInex++;
    833 
    834                     /* aWinStartArrayInex % RX_QUEUE_ARRAY_SIZE */
    835                     pTidDataBase->aWinStartArrayInex &= RX_QUEUE_ARRAY_SIZE_BIT_MASK;
    836                 }
    837 
    838                 if (pRxQueue->tPacketTimeout.aPacketsStored)
    839                 {
    840                     tmr_StartTimer (pRxQueue->hTimer, RxQueue_PacketTimeOut, pRxQueue, BA_SESSION_TIME_TO_SLEEP, TI_FALSE);
    841                     pRxQueue->tPacketTimeout.bPacketMiss = TI_TRUE;
    842                     pRxQueue->tPacketTimeout.aFrameTid = uFrameTid;
    843                 }
    844 
    845 
    846                 pTidDataBase->aTidExpectedSn = uStartingSequenceNumber;
    847             }
    848             break;
    849 
    850 
    851         case DOT11_FC_SUB_ACTION:
    852             /* get pointer to the frame body */
    853             pDataFrameBody = pFrame + sizeof(dot11_mgmtHeader_t);
    854 
    855             /* get Action field from BA action frame */
    856             pDataFrameBody++;
    857             switch(*pDataFrameBody)
    858             {
    859             case DOT11_BA_ACTION_ADDBA:
    860 
    861 
    862                 /* get TID field and winSize from ADDBA action frame */
    863                 pDataFrameBody = pDataFrameBody + 2;
    864                 COPY_WLAN_WORD(&uBAParameterField, (TI_UINT16 *)pDataFrameBody); /* copy with endianess handling. */
    865                 uFrameTid = (uBAParameterField & DOT11_BA_PARAMETER_SET_FIELD_TID_BITS) >> 2;
    866 
    867                 /* TID illegal value ? */
    868                 if (uFrameTid >= MAX_NUM_OF_802_1d_TAGS)
    869                 {
    870                     TRACE1(pRxQueue->hReport, REPORT_SEVERITY_ERROR , "RxQueue_ReceivePacket: BA event - ADDBA frame with TID value too big, TID = %d.\n",uFrameTid);
    871 
    872                     RxQueue_PassPacket (pRxQueue, TI_NOK, pBuffer);
    873 
    874                     return;
    875                 }
    876 
    877                 /*set the SA Tid pointer */
    878                 pTidDataBase = &(pRxQueue->tRxQueueArraysMng.tSa1ArrayMng[uFrameTid]);
    879 
    880                 /* TID legal value */
    881                 /* packet TID BA established ? */
    882                 if (pTidDataBase->aTidBaEstablished == TI_TRUE)
    883                 {
    884                     TRACE1(pRxQueue->hReport, REPORT_SEVERITY_ERROR , "RxQueue_ReceivePacket: BA event - ADDBA frame for TID already established, TID = %d.\n",uFrameTid);
    885 
    886                     RxQueue_PassPacket (pRxQueue, TI_NOK, pBuffer);
    887 
    888                     return;
    889                 }
    890 
    891                 /* get winSize from ADDBA action frame */
    892                 pTidDataBase->aTidWinSize = (uBAParameterField & DOT11_BA_PARAMETER_SET_FIELD_WINSIZE_BITS) >> 6;
    893 
    894                 /* winSize illegal value ? */
    895                 if (pTidDataBase->aTidWinSize > RX_QUEUE_WIN_SIZE)
    896                 {
    897                     /* In case the win Size is higher than 8 the driver and the FW set it to 8 and inform the AP in ADDBA respond */
    898                     pTidDataBase->aTidWinSize = RX_QUEUE_WIN_SIZE;
    899                 }
    900 
    901                 /* packet TID BA not yet established and winSize legal */
    902                 /* establishe BA TID */
    903                 pTidDataBase->aTidBaEstablished = TI_TRUE;
    904 
    905                 /* get initial sequence number (ISN) from ADDBA action frame */
    906                 pDataFrameBody = pDataFrameBody + 4;
    907                 COPY_WLAN_WORD (&uStartingSequenceNumber, (TI_UINT16 *)pDataFrameBody); /* copy with endianess handling. */
    908                 pTidDataBase->aTidExpectedSn = (uStartingSequenceNumber & DOT11_SC_SEQ_NUM_MASK) >> 4;
    909                 pTidDataBase->aWinStartArrayInex = 0;
    910                 os_memoryZero (pRxQueue->hOs, pTidDataBase->aPaketsQueue, sizeof (TRxQueuePacketEntry) * RX_QUEUE_ARRAY_SIZE);
    911                 break;
    912 
    913             case DOT11_BA_ACTION_DELBA:
    914 
    915 
    916                 /* get TID field and winSize from ADDBA action frame */
    917                 pDataFrameBody = pDataFrameBody + 1;
    918                 COPY_WLAN_WORD(&uBAParameterField, (TI_UINT16 *)pDataFrameBody); /* copy with endianess handling. */
    919                 uFrameTid = (uBAParameterField & DOT11_DELBA_PARAMETER_FIELD_TID_BITS) >> 12;
    920 
    921                 /* TID illegal value ? */
    922                 if (uFrameTid >= MAX_NUM_OF_802_1d_TAGS)
    923                 {
    924                     TRACE1(pRxQueue->hReport, REPORT_SEVERITY_ERROR , "RxQueue_ReceivePacket: BA event - DELBA frame with TID value too big, TID = %d.\n",uFrameTid);
    925 
    926                     RxQueue_PassPacket (pRxQueue, TI_NOK, pBuffer);
    927 
    928                     return;
    929                 }
    930 
    931                 /*set the SA Tid pointer */
    932                 pTidDataBase = &(pRxQueue->tRxQueueArraysMng.tSa1ArrayMng[uFrameTid]);
    933 
    934                 /* TID legal value */
    935                 /* packet TID BA not established ? */
    936                 if (pTidDataBase->aTidBaEstablished != TI_TRUE)
    937                 {
    938                     TRACE1(pRxQueue->hReport, REPORT_SEVERITY_ERROR , "RxQueue_ReceivePacket: BA event - DELBA frame for TID not established, TID = %d.\n",uFrameTid);
    939 
    940                     RxQueue_PassPacket (pRxQueue, TI_NOK, pBuffer);
    941 
    942                     return;
    943                 }
    944 
    945                 RxQueue_CloseBaSession(hRxQueue, uFrameTid);
    946                 break;
    947 
    948             default:
    949                 TRACE1(pRxQueue->hReport, REPORT_SEVERITY_ERROR , "RxQueue_ReceivePacket: BA event Action field from BA action frame illegal. action = 0x%x\n",*pDataFrameBody);
    950 
    951                 RxQueue_PassPacket (pRxQueue, TI_NOK, pBuffer);
    952 
    953                 return;
    954             }
    955             break;
    956 
    957         default:
    958             TRACE1(pRxQueue->hReport, REPORT_SEVERITY_ERROR , "RxQueue_ReceivePacket: BA event with Subtype illegal. Subtype = 0x%x\n",((ufc & DOT11_FC_SUB_MASK) >> 4));
    959 
    960             RxQueue_PassPacket (pRxQueue, TI_NOK, pBuffer);
    961 
    962             return;
    963           }
    964 
    965     }
    966 
    967     TRACE1(pRxQueue->hReport, REPORT_SEVERITY_ERROR, "RxQueue_ReceivePacket: unknow type tag. tag = %d\n", pRxParams->packet_class_tag);
    968 
    969     RxQueue_PassPacket (pRxQueue, tStatus, pBuffer);
    970 
    971     return;
    972 }
    973 
    974 
    975 /*
    976 Function Name : RxQueue_PacketTimeOut
    977 
    978 Description   : This function sends all consecutive old packets stored in a specific TID queue to the upper layer.
    979 
    980                 This function is called on timer wake up.
    981                 [The timer is started when we have stored packets in the RxQueue].
    982 
    983 
    984 Parameters    : hRxQueue        - A handle to the RxQueue structure.
    985                 bTwdInitOccured - Not used.
    986 
    987 Returned Value: void
    988 */
    989 static void RxQueue_PacketTimeOut (TI_HANDLE hRxQueue, TI_BOOL bTwdInitOccured)
    990 {
    991     TRxQueue            *pRxQueue   = (TRxQueue *)hRxQueue;
    992     TRxQueueTidDataBase *pTidDataBase;
    993 
    994     pRxQueue->tPacketTimeout.bPacketMiss = TI_FALSE;
    995 
    996     /* Set the SA Tid pointer */
    997     pTidDataBase = &(pRxQueue->tRxQueueArraysMng.tSa1ArrayMng[pRxQueue->tPacketTimeout.aFrameTid]);
    998 
    999 
   1000     if (pRxQueue->tPacketTimeout.aPacketsStored)
   1001     {
   1002 
   1003         /* Find the first stored packet */
   1004         while (pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket == NULL)
   1005         {
   1006             pTidDataBase->aWinStartArrayInex++;
   1007 
   1008             /* aWinStartArrayInex % RX_QUEUE_ARRAY_SIZE */
   1009             pTidDataBase->aWinStartArrayInex &= RX_QUEUE_ARRAY_SIZE_BIT_MASK;
   1010 
   1011             pTidDataBase->aTidExpectedSn++;
   1012             pTidDataBase->aTidExpectedSn &= 0xFFF;
   1013         }
   1014 
   1015 
   1016         /* Send all packets in order */
   1017         while ((pRxQueue->tPacketTimeout.aPacketsStored > 0) && (pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket != NULL))
   1018         {
   1019 
   1020             RxQueue_PassPacket (pRxQueue,
   1021                                 pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].tStatus,
   1022                                 pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket);
   1023 
   1024             pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket = NULL;
   1025 
   1026             pTidDataBase->aWinStartArrayInex++;
   1027 
   1028             /* aWinStartArrayInex % RX_QUEUE_ARRAY_SIZE */
   1029             pTidDataBase->aWinStartArrayInex &= RX_QUEUE_ARRAY_SIZE_BIT_MASK;
   1030 
   1031             pTidDataBase->aTidExpectedSn++;
   1032             pTidDataBase->aTidExpectedSn &= 0xFFF;
   1033 
   1034             pRxQueue->tPacketTimeout.aPacketsStored--;
   1035 
   1036         }
   1037     }
   1038 
   1039     if (pRxQueue->tPacketTimeout.aPacketsStored)
   1040     {
   1041         tmr_StartTimer (pRxQueue->hTimer, RxQueue_PacketTimeOut, pRxQueue, BA_SESSION_TIME_TO_SLEEP, TI_FALSE);
   1042         pRxQueue->tPacketTimeout.bPacketMiss = TI_TRUE;
   1043     }
   1044 }
   1045