• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
RxQueue_Create(TI_HANDLE hOs)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  */
RxQueue_Destroy(TI_HANDLE hRxQueue)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  */
RxQueue_Init(TI_HANDLE hRxQueue,TI_HANDLE hReport,TI_HANDLE hTimerModule)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  */
RxQueue_Register_CB(TI_HANDLE hRxQueue,TI_UINT32 uCallBackID,void * CBFunc,TI_HANDLE CBObj)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  */
RxQueue_CloseBaSession(TI_HANDLE hRxQueue,TI_UINT8 uFrameTid)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  */
RxQueue_PassPacket(TI_HANDLE hRxQueue,TI_STATUS tStatus,const void * pBuffer)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  */
RxQueue_ReceivePacket(TI_HANDLE hRxQueue,const void * pBuffer)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 */
RxQueue_PacketTimeOut(TI_HANDLE hRxQueue,TI_BOOL bTwdInitOccured)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