Home | History | Annotate | Download | only in Data_Service
      1 /*
      2  * RxQueue.c
      3  *
      4  * Copyright(c) 1998 - 2009 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 
     48 /************************ static definition declaration *****************************/
     49 #define RX_QUEUE_ARRAY_SIZE		                            8
     50 #define RX_QUEUE_ARRAY_SIZE_BIT_MASK                        0x7 /* RX_QUEUE_ARRAY_SIZE -1 */
     51 #define RX_QUEUE_WIN_SIZE		                            RX_QUEUE_ARRAY_SIZE
     52 
     53 #define BA_SESSION_IS_A_BIGGER_THAN_B(A,B)       (((((A)-(B)) & 0xFFF) < 0x7FF) && ((A)!=(B)))
     54 #define BA_SESSION_IS_A_BIGGER_EQUAL_THAN_B(A,B) (((((A)-(B)) & 0xFFF) < 0x7FF))
     55 #define SEQ_NUM_WRAP 0x1000
     56 #define SEQ_NUM_MASK 0xFFF
     57 
     58 
     59 /************************ static structures declaration *****************************/
     60 /* structure describe one entry of save packet information in the packet queue array */
     61 typedef struct
     62 {
     63     void                *pPacket;	/* Packet address of the packet */
     64     TI_STATUS	        tStatus;	/* RxXfer status. */
     65     TI_UINT16           uFrameSn;
     66 } TRxQueuePacketEntry;
     67 
     68 /* structure describe set of data that one Tid, also including the arras himself */
     69 typedef struct
     70 {
     71     /* array packets Entries */
     72     TRxQueuePacketEntry aPaketsQueue [RX_QUEUE_ARRAY_SIZE];
     73     /* TID BA state */
     74     TI_BOOL	            aTidBaEstablished;
     75     /* index that winStar point on */
     76     TI_UINT32 	        aWinStartArrayInex;
     77     /* windows size */
     78     TI_UINT32	        aTidWinSize;
     79 	/* expected sequence number (ESN) */
     80     TI_UINT16	        aTidExpectedSn;
     81 } TRxQueueTidDataBase;
     82 
     83 /* structure describe set of data that assist of manage one SA RxQueue arrays */
     84 typedef struct
     85 {
     86     TRxQueueTidDataBase tSa1ArrayMng [MAX_NUM_OF_802_1d_TAGS];
     87 } TRxQueueArraysMng;
     88 
     89 /* main RxQueue structure in order to management the packets disordered array. */
     90 typedef struct
     91 {
     92     TI_HANDLE           hOs;                        /* OS handler */
     93     TI_HANDLE           hReport;                    /* Report handler */
     94     TRxQueueArraysMng   tRxQueueArraysMng;          /* manage each Source Address RxQueue arrays */
     95     TPacketReceiveCb    tReceivePacketCB;           /* Receive packets CB address */
     96     TI_HANDLE           hReceivePacketCB_handle;    /* Receive packets CB handler */
     97 
     98 } TRxQueue;
     99 
    100 /************************ static function declaration *****************************/
    101 static TI_STATUS RxQueue_PassPacket (TI_HANDLE hRxQueue, TI_STATUS tStatus, const void *pBuffer);
    102 
    103 /**
    104  * \fn     RxQueue_Create()
    105  * \brief  Create the RxQueue module.
    106  *
    107  * Allocate and clear the RxQueue module object.
    108  *
    109  * \param  hOs - Handle to Os Abstraction Layer
    110  * \return Handle of the allocated object
    111  * \sa     RxQueue_Destroy
    112  */
    113 TI_HANDLE RxQueue_Create (TI_HANDLE hOs)
    114 {
    115 	TRxQueue *pRxQueue;
    116 
    117 	/* allocate module object */
    118 	pRxQueue = os_memoryAlloc (hOs, sizeof(TRxQueue));
    119 
    120 	if (!pRxQueue)
    121 	{
    122 		WLAN_OS_REPORT (("RxQueue_Create():  Allocation failed!!\n"));
    123 		return NULL;
    124 	}
    125 
    126     os_memoryZero (hOs, pRxQueue, (sizeof(TRxQueue)));
    127 
    128     pRxQueue->hOs = hOs;
    129 
    130 	return (pRxQueue);
    131 }
    132 
    133 
    134 /**
    135  * \fn     RxQueue_Destroy()
    136  * \brief  Destroy the module.
    137  *
    138  * Free the module's queues and object.
    139  *
    140  * \param  hRxQueue - The module object
    141  * \return TI_OK on success or TI_NOK on failure
    142  * \sa     RxQueue_Create
    143  */
    144 TI_STATUS RxQueue_Destroy (TI_HANDLE hRxQueue)
    145 {
    146     TRxQueue *pRxQueue = (TRxQueue *)hRxQueue;
    147 
    148     /* free module object */
    149 	os_memoryFree (pRxQueue->hOs, pRxQueue, sizeof(TRxQueue));
    150 
    151     return TI_OK;
    152 }
    153 
    154 
    155 /**
    156  * \fn     RxQueue_Init()
    157  * \brief  Init required handles
    158  *
    159  * Init required handles and module variables.
    160  *
    161  * \note
    162  * \param  hRxQueue - The module object
    163  * \param  hReport - Report module Handles
    164  * \return TI_OK on success or TI_NOK on failure
    165  * \sa
    166  */
    167 TI_STATUS RxQueue_Init (TI_HANDLE hRxQueue, TI_HANDLE hReport)
    168 {
    169 	TRxQueue *pRxQueue = (TRxQueue *)hRxQueue;
    170 
    171     pRxQueue->hReport   = hReport;
    172 
    173 	return TI_OK;
    174 }
    175 
    176 
    177 /**
    178  * \fn     RxQueue_Register_CB()
    179  * \brief  Register the function to be called for received Rx.
    180  *
    181  * \note
    182  * \param  hRxQueue - The module object
    183  * \param  CallBackID - event ID
    184  * \param  CBFunc - function address.
    185  * \param  CBObj - function parameter.
    186  * \return TI_OK on success or TI_NOK on failure
    187  * \sa
    188  */
    189 void RxQueue_Register_CB (TI_HANDLE hRxQueue, TI_UINT32 uCallBackID, void *CBFunc, TI_HANDLE CBObj)
    190 {
    191     TRxQueue* pRxQueue = (TRxQueue *)hRxQueue;
    192 
    193     TRACE1(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION , "RxQueue_Register_CB: CallBack ID = 0x%x\n", uCallBackID);
    194 
    195     switch(uCallBackID)
    196     {
    197     case TWD_INT_RECEIVE_PACKET:
    198         pRxQueue->tReceivePacketCB = (TPacketReceiveCb)CBFunc;
    199         pRxQueue->hReceivePacketCB_handle = CBObj;
    200         break;
    201 
    202     default:
    203         TRACE0(pRxQueue->hReport, REPORT_SEVERITY_ERROR , "RxQueue_Register_CB: Illegal value\n");
    204         break;
    205     }
    206 }
    207 
    208 /**
    209  * \fn     RxQueue_CloseBaSession ()
    210  * \brief  Close BA session receiver and pass all packets in the TID queue to upper layer.
    211  *
    212  * \note
    213  * \param  hRxQueue - RxQueue handle.
    214  * \param  uFrameTid - TID session.
    215  * \return None
    216  * \sa
    217  */
    218 void RxQueue_CloseBaSession(TI_HANDLE hRxQueue, TI_UINT8 uFrameTid)
    219 {
    220     TRxQueue            *pRxQueue     = (TRxQueue *)hRxQueue;
    221     TI_UINT32            i;
    222     /*set the SA Tid pointer */
    223     TRxQueueTidDataBase *pTidDataBase = &(pRxQueue->tRxQueueArraysMng.tSa1ArrayMng[uFrameTid]);
    224 
    225     /* TID illegal value ? */
    226     if (uFrameTid >= MAX_NUM_OF_802_1d_TAGS)
    227     {
    228         TRACE1(pRxQueue->hReport, REPORT_SEVERITY_ERROR , "RxQueue_CloseBaSession: BA event - DELBA frame with TID value too big, TID = %d\n", uFrameTid);
    229 
    230         return;
    231     }
    232 
    233     if(pTidDataBase->aTidBaEstablished == TI_TRUE)
    234     {
    235         /* clean BA session */
    236         pTidDataBase->aTidBaEstablished = TI_FALSE;
    237 
    238         /* pass all valid entries at the array */
    239         for (i = 0; (i < RX_QUEUE_ARRAY_SIZE) && (i < RX_QUEUE_WIN_SIZE); i++)
    240         {
    241             if (pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket != NULL)
    242             {
    243                 RxQueue_PassPacket (pRxQueue,
    244                                     pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].tStatus,
    245                                     pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket);
    246 
    247                 pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket = NULL;
    248             }
    249 
    250             pTidDataBase->aWinStartArrayInex ++;
    251 
    252             /* aWinStartArrayInex % RX_QUEUE_ARRAY_SIZE */
    253             pTidDataBase->aWinStartArrayInex &= RX_QUEUE_ARRAY_SIZE_BIT_MASK;
    254         }
    255     }
    256 }
    257 
    258 
    259 /**
    260  * \fn     RxQueue_PassPacket()
    261  * \brief  Responsible on decode packet parameters and pass it to upper layer.
    262  *
    263  * \note
    264  * \param  hRxQueue - RxQueue handle.
    265  * \param  aStatus - RxXfer status that indicate if the upper layer should free the packet or use it.
    266  * \param  pFrame - paket address of the packet
    267  * \param  pRxParams - address to structure of the Rx Descriptor received by FW.
    268  * \return TI_OK on success or TI_NOK on failure
    269  * \sa
    270  */
    271 static TI_STATUS RxQueue_PassPacket (TI_HANDLE hRxQueue, TI_STATUS tStatus, const void *pBuffer)
    272 {
    273 
    274     TRxQueue            *pRxQueue   = (TRxQueue *)hRxQueue;
    275 
    276     if (tStatus == TI_OK)
    277     {
    278         /* Get the mac header location in the packet Buffer */
    279         dot11_header_t *pMacHdr = (dot11_header_t *)(TI_UINT8*)RX_BUF_DATA(pBuffer);
    280 
    281         /* Handle endian for the frame control fields */
    282         pMacHdr->fc  = ENDIAN_HANDLE_WORD(pMacHdr->fc);
    283         pMacHdr->duration = ENDIAN_HANDLE_WORD(pMacHdr->duration);
    284         pMacHdr->seqCtrl = ENDIAN_HANDLE_WORD(pMacHdr->seqCtrl);
    285     }
    286     else
    287     {
    288         RxIfDescriptor_t    *pRxParams  = (RxIfDescriptor_t*)pBuffer;
    289 
    290         pRxParams->status &= ~RX_DESC_STATUS_MASK;
    291         pRxParams->status |= RX_DESC_STATUS_DRIVER_RX_Q_FAIL;
    292     }
    293 
    294     TRACE0(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION , "RxQueue_PassPacket: call TWD_OWNER_RX_QUEUE CB. In std rxData_ReceivePacket()\n");
    295 
    296     /* Set the packet to upper layer */
    297     /* if the packet status not success it will be discarded */
    298     pRxQueue->tReceivePacketCB (pRxQueue->hReceivePacketCB_handle, pBuffer);
    299 
    300     return TI_OK;
    301 }
    302 
    303 
    304 /**
    305  * \fn     RxQueue_ReceivePacket()
    306  * \brief  Main function of the RxQueue module.
    307  * Responsible on reorder of the packets from the RxXfer to the RX module.
    308  * Call from RxXfer in order to pass packet to uppers layers.
    309  * In order to save disordered packets the module use array of structures per TID
    310  * that each entry describe a packet. The array elements is sorted in the way that
    311  * the winStart array index represent always the winStar packet and the lowest SN.
    312  * Each increment index represent index at the BA window. Array index winEnd  always
    313  * represent winEnd packet. The indexes of winStart and winEnd handled in cyclic manner.
    314  * The function functionality devided to parts:
    315  *   Part 1:
    316  * in case the modulo receive packet with SN equal to winStart:
    317  * "	pass it to upper layers
    318  * "	increases winStart and array index winStart
    319  * "	validate that all sequential queue packet are pass to the upper layers.
    320  *   Part 2:
    321  * in case the modulo receive packet that SN between winStart to winEnd:
    322  * "	Save it sorted at the array at index: Save index = ((SN - winStart) + index array winStart) % arraySize.
    323  *   Part 3:
    324  * in case the modulo receive packet that SN higher then winEnd:
    325  * "	Update winStart and WinEnd.
    326  * "	Save it sorted at the array in index winEnd index.
    327  * "	Pass to the upper layers all packets at the array indexes from old winStart index to the updated winStart index.
    328  *   Part 4 + 5:
    329  * in case the modulo receive BA event packet:
    330  * "	Update winStart and WinEnd
    331  * "	Pass to the upper layers all packets at the array indexes from old winStart index to the updated winStart index.
    332  * "	Free BA event packet via pass it to upper layers with error status.
    333  *
    334  * \note
    335  * \param  hRxQueue - RxQueue handle.
    336  * \param  aStatus - RxXfer status that indicate if the upper layer should free the packet or use it.
    337  * \param  pBuffer - paket address of the packet
    338  * \return None
    339  * \sa
    340  */
    341 void RxQueue_ReceivePacket (TI_HANDLE hRxQueue, const void * pBuffer)
    342 {
    343     TRxQueue            *pRxQueue   = (TRxQueue *)hRxQueue;
    344     RxIfDescriptor_t    *pRxParams  = (RxIfDescriptor_t*)pBuffer;
    345     TI_UINT8            *pFrame     = RX_BUF_DATA((TI_UINT8 *)pBuffer);
    346     TI_STATUS           tStatus     = TI_OK;
    347     dot11_header_t      *pHdr       = (dot11_header_t *)pFrame;
    348     TI_UINT16		    uQosControl;
    349 
    350     COPY_WLAN_WORD(&uQosControl, &pHdr->qosControl); /* copy with endianess handling. */
    351 
    352     /*
    353      * Retrieving the TAG from the packet itself and not from the Rx Descriptor since by now it is not correct
    354      * Note: in the DR TAG_CLASS_EAPOL packet handled as TAG_CLASS_QOS_DATA
    355      */
    356     if (IS_QOS_FRAME(*(TI_UINT16*)pFrame) && (pRxParams->packet_class_tag != TAG_CLASS_QOS_DATA) && (pRxParams->packet_class_tag != TAG_CLASS_AMSDU))
    357 	{
    358         TRACE1(pRxQueue->hReport, REPORT_SEVERITY_WARNING, "RxQueue_ReceivePacket: BAD CLASS TAG =0x%x from FW.\n", pRxParams->packet_class_tag);
    359 
    360         /* Get AMSDU bit from frame */
    361         if( uQosControl & DOT11_QOS_CONTROL_FIELD_A_MSDU_BITS)
    362         {
    363             pRxParams->packet_class_tag = TAG_CLASS_AMSDU;
    364         }
    365         else
    366         {
    367             pRxParams->packet_class_tag = TAG_CLASS_QOS_DATA;
    368         }
    369     }
    370 
    371     /*
    372      * packet doesn't need reorder ?
    373      */
    374     if ((pRxParams->packet_class_tag != TAG_CLASS_QOS_DATA) && (pRxParams->packet_class_tag != TAG_CLASS_BA_EVENT) && (pRxParams->packet_class_tag != TAG_CLASS_AMSDU))
    375     {
    376         TRACE0(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: pass packet without reorder.\n");
    377 
    378         RxQueue_PassPacket (pRxQueue, tStatus, pBuffer);
    379 
    380         return;
    381     }
    382 
    383 
    384     /*
    385      * pRxParams->type == TAG_CLASS_QOS_DATA ?
    386      */
    387     if ((pRxParams->packet_class_tag == TAG_CLASS_QOS_DATA) || (pRxParams->packet_class_tag == TAG_CLASS_AMSDU))
    388     {
    389         TI_UINT8            uFrameTid;
    390         TI_UINT16           uFrameSn;
    391         TI_UINT16		    uSequenceControl;
    392         TRxQueueTidDataBase *pTidDataBase;
    393 
    394         /* Get TID from frame */
    395         uFrameTid = uQosControl & DOT11_QOS_CONTROL_FIELD_TID_BITS;
    396 
    397         /* TID illegal value ? */
    398         if (uFrameTid >= MAX_NUM_OF_802_1d_TAGS)
    399         {
    400             TRACE1(pRxQueue->hReport, REPORT_SEVERITY_ERROR, "RxQueue_ReceivePacket: TID value too big, TID = %d. packet discarded!\n",uFrameTid);
    401 
    402             RxQueue_PassPacket (pRxQueue, TI_NOK, pBuffer);
    403 
    404             return;
    405         }
    406 
    407         /*set the SA Tid pointer */
    408         pTidDataBase = &(pRxQueue->tRxQueueArraysMng.tSa1ArrayMng[uFrameTid]);
    409 
    410         /* TID legal value */
    411         /* packet TID BA not established ? */
    412         if (pTidDataBase->aTidBaEstablished != TI_TRUE)
    413         {
    414             TRACE0(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: pass packet without reorder.\n");
    415 
    416             RxQueue_PassPacket (pRxQueue, tStatus, pBuffer);
    417 
    418             return;
    419         }
    420 
    421         /* packet TID BA established */
    422         /* Get Sequence Number from frame */
    423         COPY_WLAN_WORD(&uSequenceControl, &pHdr->seqCtrl); /* copy with endianess handling. */
    424         uFrameSn = (uSequenceControl & DOT11_SC_SEQ_NUM_MASK) >> 4;
    425 
    426         /*
    427          * note:
    428          * the FW never send paket, in establish TID BA, that the SN less then ESN !!!
    429          */
    430 
    431         /* frame Sequence Number is the expected one ? */
    432         if (uFrameSn == pTidDataBase->aTidExpectedSn)
    433         {
    434             TRACE0(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: frame Sequence Number == expected one Sequence Number.\n");
    435 
    436             /* pass the packet */
    437             RxQueue_PassPacket (pRxQueue, tStatus, pBuffer);
    438 
    439             pTidDataBase->aTidExpectedSn++;
    440             pTidDataBase->aTidExpectedSn &= 0xfff;
    441 
    442             /* increase the ArrayInex to the next */
    443             pTidDataBase->aWinStartArrayInex++;
    444 
    445             /* aWinStartArrayInex % RX_QUEUE_ARRAY_SIZE */
    446             pTidDataBase->aWinStartArrayInex &= RX_QUEUE_ARRAY_SIZE_BIT_MASK;
    447 
    448             /* pass all saved queue packets with SN higher then the expected one */
    449             while (pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket != NULL)
    450             {
    451                 RxQueue_PassPacket (pRxQueue,
    452                                     pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].tStatus,
    453                                     pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket);
    454 
    455                 pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket = NULL;
    456 
    457                 pTidDataBase->aWinStartArrayInex++;
    458 
    459                 /* aWinStartArrayInex % RX_QUEUE_ARRAY_SIZE */
    460                 pTidDataBase->aWinStartArrayInex &= RX_QUEUE_ARRAY_SIZE_BIT_MASK;
    461 
    462                  pTidDataBase->aTidExpectedSn++;
    463 				 pTidDataBase->aTidExpectedSn &= 0xfff;
    464             }
    465 
    466             return;
    467         }
    468 
    469         /* frame Sequence Number is lower then Expected sequence number (ISN) ? */
    470         if (! BA_SESSION_IS_A_BIGGER_THAN_B (uFrameSn, pTidDataBase->aTidExpectedSn))
    471         {
    472 			/* WLAN_OS_REPORT(("%s: ERROR - SN=%u is less than ESN=%u\n", __FUNCTION__, uFrameSn, pTidDataBase->aTidExpectedSn)); */
    473 
    474 			TRACE2(pRxQueue->hReport, REPORT_SEVERITY_ERROR,
    475 				   "RxQueue_ReceivePacket: frame SN=%u is less than ESN=%u\n",uFrameSn,pTidDataBase->aTidExpectedSn);
    476 
    477 			RxQueue_PassPacket (pRxQueue, TI_NOK, pBuffer);
    478 
    479             return;
    480         }
    481 
    482         /* frame Sequence Number between winStart and winEnd ? */
    483         if ((BA_SESSION_IS_A_BIGGER_THAN_B (uFrameSn, pTidDataBase->aTidExpectedSn)) &&
    484             /* mean: uFrameSn <= pTidDataBase->aTidExpectedSn + pTidDataBase->aTidWinSize) */
    485             ( ! BA_SESSION_IS_A_BIGGER_THAN_B (uFrameSn,(pTidDataBase->aTidExpectedSn + pTidDataBase->aTidWinSize - 1))))
    486         {
    487             TI_UINT16 uSaveInex = pTidDataBase->aWinStartArrayInex + (TI_UINT16)((uFrameSn + SEQ_NUM_WRAP - pTidDataBase->aTidExpectedSn) & SEQ_NUM_MASK);
    488             /* uSaveInex % RX_QUEUE_ARRAY_SIZE */
    489             uSaveInex &= RX_QUEUE_ARRAY_SIZE_BIT_MASK;
    490 
    491 
    492 			if (pTidDataBase->aPaketsQueue[uSaveInex].pPacket == NULL)
    493 			{
    494                 /* save the packet in the queue */
    495                 pTidDataBase->aPaketsQueue[uSaveInex].tStatus = tStatus;
    496                 pTidDataBase->aPaketsQueue[uSaveInex].pPacket = (void *)pBuffer;
    497                 pTidDataBase->aPaketsQueue[uSaveInex].uFrameSn = uFrameSn;
    498 			}
    499 			else
    500 			{
    501 				 TRACE1(pRxQueue->hReport, REPORT_SEVERITY_ERROR, "RxQueue_ReceivePacket: frame Sequence has allready saved. uFrameSn = %d\n",uFrameSn);
    502 				 RxQueue_PassPacket (pRxQueue, TI_NOK, pBuffer);
    503 				 return;
    504 			}
    505             return;
    506         }
    507 
    508 
    509         /*
    510         frame Sequence Number higher then winEnd ?
    511         */
    512         if ( BA_SESSION_IS_A_BIGGER_THAN_B (uFrameSn, (pTidDataBase->aTidExpectedSn + pTidDataBase->aTidWinSize - 1)) )
    513         {
    514             TI_UINT32 i;
    515             TI_UINT16 uNewWinStartSn = (uFrameSn + SEQ_NUM_WRAP - pTidDataBase->aTidWinSize + 1) & SEQ_NUM_MASK;
    516             TI_UINT16 uSaveInex;
    517 
    518 			TRACE0(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: frame Sequence Number higher then winEnd.\n");
    519 
    520             /* increase the ArrayInex to the next */
    521             pTidDataBase->aWinStartArrayInex++;
    522 
    523             /* aWinStartArrayInex % RX_QUEUE_ARRAY_SIZE */
    524             pTidDataBase->aWinStartArrayInex &= RX_QUEUE_ARRAY_SIZE_BIT_MASK;
    525 
    526             /* update the Expected SN since the current one is lost */
    527             pTidDataBase->aTidExpectedSn++;
    528             pTidDataBase->aTidExpectedSn &= 0xFFF;
    529 
    530             /* pass all saved queue packets with SN lower then the new win start */
    531             for (i = 0;
    532                  BA_SESSION_IS_A_BIGGER_THAN_B(uNewWinStartSn,pTidDataBase->aTidExpectedSn) &&
    533                   (i < RX_QUEUE_ARRAY_SIZE) &&
    534                   (i < pTidDataBase->aTidWinSize);
    535                  i++)
    536             {
    537                 if (pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket != NULL)
    538                 {
    539                     RxQueue_PassPacket (pRxQueue,
    540                                         pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].tStatus,
    541                                         pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket);
    542 
    543                     pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket = NULL;
    544                 }
    545 
    546                 pTidDataBase->aWinStartArrayInex++;
    547 
    548                 /* aWinStartArrayInex % RX_QUEUE_ARRAY_SIZE */
    549                 pTidDataBase->aWinStartArrayInex &= RX_QUEUE_ARRAY_SIZE_BIT_MASK;
    550 
    551                 pTidDataBase->aTidExpectedSn++;
    552                 pTidDataBase->aTidExpectedSn &= 0xFFF;
    553 
    554             }
    555 
    556             /* Calculate the new Expected SN */
    557             if (i == pTidDataBase->aTidWinSize)
    558             {
    559                 pTidDataBase->aTidExpectedSn = uNewWinStartSn;
    560             }
    561             else
    562             {
    563                 /* Incase the uWinStartDelta lower than aTidWinSize check if ther are packets stored in Array */
    564                 while (pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket != NULL) {
    565                     RxQueue_PassPacket (pRxQueue,
    566                                             pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].tStatus,
    567                                             pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket);
    568 
    569                     pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket = NULL;
    570 
    571                     pTidDataBase->aWinStartArrayInex++;
    572 
    573                     /* aWinStartArrayInex % RX_QUEUE_ARRAY_SIZE */
    574                     pTidDataBase->aWinStartArrayInex &= RX_QUEUE_ARRAY_SIZE_BIT_MASK;
    575 
    576                     pTidDataBase->aTidExpectedSn++;
    577                     pTidDataBase->aTidExpectedSn &= 0xFFF;
    578                 }
    579             }
    580 
    581             if(pTidDataBase->aTidExpectedSn == uFrameSn)
    582             {
    583                 /* pass the packet */
    584                 RxQueue_PassPacket (pRxQueue, tStatus, pBuffer);
    585                 pTidDataBase->aTidExpectedSn++;
    586 				pTidDataBase->aTidExpectedSn &= 0xfff;
    587             }
    588             else
    589             {
    590                 uSaveInex = pTidDataBase->aWinStartArrayInex + (TI_UINT16)((uFrameSn + SEQ_NUM_WRAP - pTidDataBase->aTidExpectedSn) & SEQ_NUM_MASK);
    591 
    592 				/* uSaveInex % RX_QUEUE_ARRAY_SIZE */
    593 				uSaveInex &= RX_QUEUE_ARRAY_SIZE_BIT_MASK;
    594 
    595             /* save the packet in the last entry of the queue */
    596                pTidDataBase->aPaketsQueue[uSaveInex].tStatus = tStatus;
    597                pTidDataBase->aPaketsQueue[uSaveInex].pPacket = (void *)pBuffer;
    598                pTidDataBase->aPaketsQueue[uSaveInex].pPacket = (void *)pBuffer;
    599             }
    600 
    601             return;
    602         }
    603     }
    604 
    605 
    606     /*
    607      * BA event ?
    608      */
    609     if (pRxParams->packet_class_tag == TAG_CLASS_BA_EVENT)
    610     {
    611         TRxQueueTidDataBase *pTidDataBase;
    612         TI_UINT8            *pDataFrameBody;
    613         TI_UINT16           ufc;
    614         TI_UINT8            uFrameTid;
    615         TI_UINT16           uStartingSequenceNumber;
    616         TI_UINT16           uWinStartDelta;
    617         TI_UINT16           uBarControlField;
    618         TI_UINT16           uBaStartingSequenceControlField;
    619         TI_UINT16           uBAParameterField;
    620         TI_UINT32           i;
    621 
    622         /* Get sub type from frame */
    623         COPY_WLAN_WORD(&ufc, &pHdr->fc); /* copy with endianess handling. */
    624 
    625         /* get the type to BA event */
    626         switch ((dot11_Fc_Sub_Type_e)(ufc & DOT11_FC_SUB_MASK))
    627         {
    628         case DOT11_FC_SUB_BAR:
    629             TRACE0(pRxQueue->hReport, REPORT_SEVERITY_INFORMATION , "RxQueue_ReceivePacket: BA event - BAR frame.\n");
    630 
    631             /* get pointer to the frame body */
    632             pDataFrameBody = pFrame + sizeof(dot11_BarFrameHeader_t);
    633 
    634             /* Get TID from BAR frame */
    635             COPY_WLAN_WORD (&uBarControlField, (TI_UINT16 *)pDataFrameBody); /* copy with endianess handling. */
    636             uFrameTid = (uBarControlField & DOT11_BAR_CONTROL_FIELD_TID_BITS) >> 12;
    637 
    638             /* TID illegal value ? */
    639             if (uFrameTid >= MAX_NUM_OF_802_1d_TAGS)
    640             {
    641                 TRACE1(pRxQueue->hReport, REPORT_SEVERITY_ERROR , "RxQueue_ReceivePacket: BA event - BAR frame with TID value too big, TID = %d.\n",uFrameTid);
    642 
    643                 RxQueue_PassPacket (pRxQueue, TI_NOK, pBuffer);
    644 
    645                 return;
    646             }
    647 
    648             /* set the SA Tid pointer */
    649             pTidDataBase = &(pRxQueue->tRxQueueArraysMng.tSa1ArrayMng[uFrameTid]);
    650 
    651             /* TID legal value */
    652             /* packet TID BA not established ? */
    653             if (pTidDataBase->aTidBaEstablished != TI_TRUE)
    654             {
    655                 TRACE1(pRxQueue->hReport, REPORT_SEVERITY_ERROR , "RxQueue_ReceivePacket: BA event - BAR frame for TID not established, TID = %d.\n",uFrameTid);
    656 
    657                 RxQueue_PassPacket (pRxQueue, TI_NOK, pBuffer);
    658 
    659                 return;
    660             }
    661 
    662             /* Get Starting Sequence number from BAR frame */
    663             pDataFrameBody = pDataFrameBody + 2;
    664             COPY_WLAN_WORD (&uBaStartingSequenceControlField, (TI_UINT16 *)pDataFrameBody); /* copy with endianess handling. */
    665             uStartingSequenceNumber = (uBaStartingSequenceControlField & DOT11_SC_SEQ_NUM_MASK) >> 4;
    666 
    667             /* Starting Sequence Number is higher then winStart ? */
    668             if ( BA_SESSION_IS_A_BIGGER_THAN_B (uStartingSequenceNumber, pTidDataBase->aTidExpectedSn) )
    669             {
    670                 uWinStartDelta = (uStartingSequenceNumber + SEQ_NUM_WRAP - pTidDataBase->aTidExpectedSn) & SEQ_NUM_MASK;
    671 
    672                 /* pass all saved queue packets with SN lower then the new win start */
    673                 for (i = 0;
    674                      ((i < uWinStartDelta) || (pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket != NULL)) &&
    675                       (i < RX_QUEUE_ARRAY_SIZE) &&
    676                       (i < RX_QUEUE_WIN_SIZE);
    677                      i++)
    678                 {
    679                     if (pTidDataBase->aPaketsQueue[pTidDataBase->aWinStartArrayInex].pPacket != NULL)
    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 
    688                     pTidDataBase->aWinStartArrayInex++;
    689 
    690                     /* aWinStartArrayInex % RX_QUEUE_ARRAY_SIZE */
    691                     pTidDataBase->aWinStartArrayInex &= RX_QUEUE_ARRAY_SIZE_BIT_MASK;
    692                 }
    693 
    694                 pTidDataBase->aTidExpectedSn = uStartingSequenceNumber;
    695             }
    696             break;
    697 
    698 
    699         case DOT11_FC_SUB_ACTION:
    700             /* get pointer to the frame body */
    701             pDataFrameBody = pFrame + sizeof(dot11_mgmtHeader_t);
    702 
    703             /* get Action field from BA action frame */
    704             pDataFrameBody++;
    705             switch(*pDataFrameBody)
    706             {
    707             case DOT11_BA_ACTION_ADDBA:
    708 
    709                 TRACE0( pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: BA event - ADDBA frame.\n");
    710 
    711                 /* get TID field and winSize from ADDBA action frame */
    712                 pDataFrameBody = pDataFrameBody + 2;
    713                 COPY_WLAN_WORD(&uBAParameterField, (TI_UINT16 *)pDataFrameBody); /* copy with endianess handling. */
    714                 uFrameTid = (uBAParameterField & DOT11_BA_PARAMETER_SET_FIELD_TID_BITS) >> 2;
    715 
    716                 /* TID illegal value ? */
    717                 if (uFrameTid >= MAX_NUM_OF_802_1d_TAGS)
    718                 {
    719                     TRACE1(pRxQueue->hReport, REPORT_SEVERITY_ERROR , "RxQueue_ReceivePacket: BA event - ADDBA frame with TID value too big, TID = %d.\n",uFrameTid);
    720 
    721                     RxQueue_PassPacket (pRxQueue, TI_NOK, pBuffer);
    722 
    723                     return;
    724                 }
    725 
    726                 /*set the SA Tid pointer */
    727                 pTidDataBase = &(pRxQueue->tRxQueueArraysMng.tSa1ArrayMng[uFrameTid]);
    728 
    729                 /* TID legal value */
    730                 /* packet TID BA established ? */
    731                 if (pTidDataBase->aTidBaEstablished == TI_TRUE)
    732                 {
    733                     TRACE1(pRxQueue->hReport, REPORT_SEVERITY_ERROR , "RxQueue_ReceivePacket: BA event - ADDBA frame for TID already established, TID = %d.\n",uFrameTid);
    734 
    735                     RxQueue_PassPacket (pRxQueue, TI_NOK, pBuffer);
    736 
    737                     return;
    738                 }
    739 
    740                 /* get winSize from ADDBA action frame */
    741                 pTidDataBase->aTidWinSize = (uBAParameterField & DOT11_BA_PARAMETER_SET_FIELD_WINSIZE_BITS) >> 6;
    742 
    743                 /* winSize illegal value ? */
    744                 if (pTidDataBase->aTidWinSize > RX_QUEUE_WIN_SIZE)
    745                 {
    746                     /* In case the win Size is higher then 8 the driver and the FW set it to 8 and inform the AP in ADDBA respond */
    747                     pTidDataBase->aTidWinSize = RX_QUEUE_WIN_SIZE;
    748                 }
    749 
    750                 /* packet TID BA not yet established and winSize legal */
    751                 /* establishe BA TID */
    752                 pTidDataBase->aTidBaEstablished = TI_TRUE;
    753 
    754                 /* get initial sequence number (ISN) from ADDBA action frame */
    755                 pDataFrameBody = pDataFrameBody + 4;
    756                 COPY_WLAN_WORD (&uStartingSequenceNumber, (TI_UINT16 *)pDataFrameBody); /* copy with endianess handling. */
    757                 pTidDataBase->aTidExpectedSn = (uStartingSequenceNumber & DOT11_SC_SEQ_NUM_MASK) >> 4;
    758                 pTidDataBase->aWinStartArrayInex = 0;
    759                 os_memoryZero (pRxQueue->hOs, pTidDataBase->aPaketsQueue, sizeof (TRxQueuePacketEntry) * RX_QUEUE_ARRAY_SIZE);
    760                 break;
    761 
    762             case DOT11_BA_ACTION_DELBA:
    763 
    764                 TRACE0( pRxQueue->hReport, REPORT_SEVERITY_INFORMATION, "RxQueue_ReceivePacket: BA event - DELBA frame.\n");
    765 
    766                 /* get TID field and winSize from ADDBA action frame */
    767                 pDataFrameBody = pDataFrameBody + 2;
    768                 COPY_WLAN_WORD(&uBAParameterField, (TI_UINT16 *)pDataFrameBody); /* copy with endianess handling. */
    769                 uFrameTid = (uBAParameterField & DOT11_DELBA_PARAMETER_FIELD_TID_BITS) >> 12;
    770 
    771                 /* TID illegal value ? */
    772                 if (uFrameTid >= MAX_NUM_OF_802_1d_TAGS)
    773                 {
    774                     TRACE1(pRxQueue->hReport, REPORT_SEVERITY_ERROR , "RxQueue_ReceivePacket: BA event - DELBA frame with TID value too big, TID = %d.\n",uFrameTid);
    775 
    776                     RxQueue_PassPacket (pRxQueue, TI_NOK, pBuffer);
    777 
    778                     return;
    779                 }
    780 
    781                 /*set the SA Tid pointer */
    782                 pTidDataBase = &(pRxQueue->tRxQueueArraysMng.tSa1ArrayMng[uFrameTid]);
    783 
    784                 /* TID legal value */
    785                 /* packet TID BA not established ? */
    786                 if (pTidDataBase->aTidBaEstablished != TI_TRUE)
    787                 {
    788                     TRACE1(pRxQueue->hReport, REPORT_SEVERITY_ERROR , "RxQueue_ReceivePacket: BA event - DELBA frame for TID not established, TID = %d.\n",uFrameTid);
    789 
    790                     RxQueue_PassPacket (pRxQueue, TI_NOK, pBuffer);
    791 
    792                     return;
    793                 }
    794 
    795                 RxQueue_CloseBaSession(hRxQueue, uFrameTid);
    796                 break;
    797 
    798             default:
    799                 TRACE1(pRxQueue->hReport, REPORT_SEVERITY_ERROR , "RxQueue_ReceivePacket: BA event Action field from BA action frame illegal. action = 0x%x\n",*pDataFrameBody);
    800 
    801                 RxQueue_PassPacket (pRxQueue, TI_NOK, pBuffer);
    802 
    803                 return;
    804             }
    805             break;
    806 
    807         default:
    808             TRACE1(pRxQueue->hReport, REPORT_SEVERITY_ERROR , "RxQueue_ReceivePacket: BA event with Subtype illegal. Subtype = 0x%x\n",((ufc & DOT11_FC_SUB_MASK) >> 4));
    809 
    810             RxQueue_PassPacket (pRxQueue, TI_NOK, pBuffer);
    811 
    812             return;
    813           }
    814 
    815     }
    816 
    817     TRACE1(pRxQueue->hReport, REPORT_SEVERITY_ERROR, "RxQueue_ReceivePacket: unknow type tag. tag = %d\n", pRxParams->packet_class_tag);
    818 
    819     RxQueue_PassPacket (pRxQueue, tStatus, pBuffer);
    820 
    821     return;
    822 }
    823 
    824