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 */ 63typedef 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 */ 71typedef 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 */ 86typedef struct 87{ 88 TRxQueueTidDataBase tSa1ArrayMng [MAX_NUM_OF_802_1d_TAGS]; 89} TRxQueueArraysMng; 90 91typedef 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. */ 101typedef 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 *****************************/ 113static TI_STATUS RxQueue_PassPacket (TI_HANDLE hRxQueue, TI_STATUS tStatus, const void *pBuffer); 114static 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 */ 126TI_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 */ 157TI_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 */ 191TI_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 */ 215void 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 */ 244void 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 */ 305static 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 */ 375void 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_INFORMATION, "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/* 976Function Name : RxQueue_PacketTimeOut 977 978Description : 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 984Parameters : hRxQueue - A handle to the RxQueue structure. 985 bTwdInitOccured - Not used. 986 987Returned Value: void 988*/ 989static 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