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