1/*
2 * rx.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/*                                                                         */
36/*      MODULE: Rx.c                                                       */
37/*    PURPOSE:  Rx module functions                                        */
38/*                                                                         */
39/***************************************************************************/
40#define __FILE_ID__  FILE_ID_54
41#include "tidef.h"
42#include "paramOut.h"
43#include "rx.h"
44#include "osApi.h"
45#include "timer.h"
46#include "DataCtrl_Api.h"
47#include "Ctrl.h"
48#include "802_11Defs.h"
49#include "Ethernet.h"
50#include "report.h"
51#include "rate.h"
52#include "mlmeApi.h"
53#include "rsnApi.h"
54#include "smeApi.h"
55#include "siteMgrApi.h"
56#include "GeneralUtil.h"
57#include "EvHandler.h"
58#ifdef XCC_MODULE_INCLUDED
59#include "XCCMngr.h"
60#endif
61#include "TWDriver.h"
62#include "RxBuf.h"
63#include "DrvMainModules.h"
64#include "bmtrace_api.h"
65#include "PowerMgr_API.h"
66
67
68#define EAPOL_PACKET                    0x888E
69#define IAPP_PACKET                     0x0000
70#define PREAUTH_EAPOL_PACKET            0x88C7
71
72
73#define RX_DATA_FILTER_FLAG_NO_BIT_MASK         0
74#define RX_DATA_FILTER_FLAG_USE_BIT_MASK        1
75#define RX_DATA_FILTER_FLAG_IP_HEADER           0
76#define RX_DATA_FILTER_FLAG_ETHERNET_HEADER     2
77#define RX_DATA_FILTER_ETHERNET_HEADER_BOUNDARY 14
78
79#define PADDING_ETH_PACKET_SIZE                 2
80
81/* CallBack for recieving packet from rxXfer */
82static void rxData_ReceivePacket (TI_HANDLE   hRxData,  void  *pBuffer);
83
84static ERxBufferStatus rxData_RequestForBuffer (TI_HANDLE   hRxData, void **pBuf, TI_UINT16 aLength, TI_UINT32 uEncryptionFlag,PacketClassTag_e ePacketClassTag);
85
86#if 0
87static TI_STATUS rxData_checkBssIdAndBssType(TI_HANDLE hRxData,
88											 dot11_header_t* dot11_header,
89											 TMacAddr **rxBssid,
90											 ScanBssType_e  *currBssType,
91											 TMacAddr  *currBssId);
92#endif
93static TI_STATUS rxData_convertWlanToEthHeader (TI_HANDLE hRxData, void *pBuffer, TI_UINT16 * etherType);
94static TI_STATUS rxData_ConvertAmsduToEthPackets (TI_HANDLE hRxData, void *pBuffer, TRxAttr* pRxAttr);
95static void rxData_dataPacketDisptcher (TI_HANDLE hRxData, void *pBuffer, TRxAttr* pRxAttr);
96static void rxData_discardPacket (TI_HANDLE hRxData, void *pBuffer, TRxAttr* pRxAttr);
97static void rxData_discardPacketVlan (TI_HANDLE hRxData, void *pBuffer, TRxAttr* pRxAttr);
98static void rxData_rcvPacketInOpenNotify (TI_HANDLE hRxData, void *pBuffer, TRxAttr* pRxAttr);
99static void rxData_rcvPacketEapol (TI_HANDLE hRxData, void *pBuffer, TRxAttr* pRxAttr);
100static void rxData_rcvPacketData (TI_HANDLE hRxData, void *pBuffer, TRxAttr* pRxAttr);
101
102static TI_STATUS rxData_enableDisableRxDataFilters(TI_HANDLE hRxData, TI_BOOL enabled);
103static TI_STATUS rxData_addRxDataFilter(TI_HANDLE hRxData, TRxDataFilterRequest* request);
104static TI_STATUS rxData_removeRxDataFilter(TI_HANDLE hRxData, TRxDataFilterRequest* request);
105
106
107#ifdef XCC_MODULE_INCLUDED
108static void rxData_rcvPacketIapp(TI_HANDLE hRxData, void *pBuffer, TRxAttr* pRxAttr);
109#endif
110#ifdef TI_DBG
111static void rxData_printRxThroughput(TI_HANDLE hRxData, TI_BOOL bTwdInitOccured);
112#endif
113
114static void rxData_StartReAuthActiveTimer(TI_HANDLE hRxData);
115static void reAuthTimeout(TI_HANDLE hRxData, TI_BOOL bTwdInitOccured);
116static void rxData_ReauthEnablePriority(TI_HANDLE hRxData);
117
118
119/*************************************************************************
120*                        rxData_create                                   *
121**************************************************************************
122* DESCRIPTION:  This function initializes the Rx data module.
123*
124* INPUT:        hOs - handle to Os Abstraction Layer
125*
126* OUTPUT:
127*
128* RETURN:       Handle to the allocated Rx data control block
129************************************************************************/
130TI_HANDLE rxData_create (TI_HANDLE hOs)
131{
132    rxData_t *pRxData;
133
134    /* check parameters validity */
135    if (hOs == NULL)
136    {
137        WLAN_OS_REPORT(("FATAL ERROR: rxData_create(): OS handle Error - Aborting\n"));
138        return NULL;
139    }
140
141
142    /* alocate Rx module control block */
143    pRxData = os_memoryAlloc(hOs, (sizeof(rxData_t)));
144
145    if (!pRxData)
146    {
147        WLAN_OS_REPORT(("FATAL ERROR: rxData_create(): Error Creating Rx Module - Aborting\n"));
148        return NULL;
149    }
150
151    /* reset Rx control block */
152    os_memoryZero (hOs, pRxData, (sizeof(rxData_t)));
153
154    pRxData->RxEventDistributor = DistributorMgr_Create (hOs, MAX_RX_NOTIF_REQ_ELMENTS);
155
156    pRxData->hOs = hOs;
157
158    return (TI_HANDLE)pRxData;
159}
160
161/***************************************************************************
162*                           rxData_config                                  *
163****************************************************************************
164* DESCRIPTION:  This function configures the Rx Data module
165*
166* INPUTS:       pStadHandles  - The driver modules handles
167*
168* OUTPUT:
169*
170* RETURNS:      void
171***************************************************************************/
172void rxData_init (TStadHandlesList *pStadHandles)
173{
174    rxData_t *pRxData = (rxData_t *)(pStadHandles->hRxData);
175
176    pRxData->hCtrlData  = pStadHandles->hCtrlData;
177    pRxData->hTWD       = pStadHandles->hTWD;
178    pRxData->hMlme      = pStadHandles->hMlmeSm;
179    pRxData->hRsn       = pStadHandles->hRsn;
180    pRxData->hSiteMgr   = pStadHandles->hSiteMgr;
181    pRxData->hOs        = pStadHandles->hOs;
182    pRxData->hReport    = pStadHandles->hReport;
183    pRxData->hXCCMgr    = pStadHandles->hXCCMngr;
184    pRxData->hEvHandler = pStadHandles->hEvHandler;
185    pRxData->hTimer     = pStadHandles->hTimer;
186    pRxData->hPowerMgr  = pStadHandles->hPowerMgr;
187
188    pRxData->rxDataExcludeUnencrypted = DEF_EXCLUDE_UNENCYPTED;
189    pRxData->rxDataExludeBroadcastUnencrypted = DEF_EXCLUDE_UNENCYPTED;
190    pRxData->rxDataEapolDestination = DEF_EAPOL_DESTINATION;
191    pRxData->rxDataPortStatus = DEF_RX_PORT_STATUS;
192	pRxData->genericEthertype = EAPOL_PACKET;
193
194    /*
195     * configure rx data dispatcher
196     */
197
198    /* port status close */
199    pRxData->rxData_dispatchBuffer[CLOSE][DATA_DATA_PACKET]  = &rxData_discardPacket;       /* data  */
200    pRxData->rxData_dispatchBuffer[CLOSE][DATA_EAPOL_PACKET] = &rxData_discardPacket;       /* eapol */
201    pRxData->rxData_dispatchBuffer[CLOSE][DATA_IAPP_PACKET]  = &rxData_discardPacket;       /* Iapp  */
202    pRxData->rxData_dispatchBuffer[CLOSE][DATA_VLAN_PACKET]  = &rxData_discardPacketVlan;   /* VLAN  */
203
204    /* port status open notify */
205    pRxData->rxData_dispatchBuffer[OPEN_NOTIFY][DATA_DATA_PACKET]  = &rxData_rcvPacketInOpenNotify; /* data  */
206    pRxData->rxData_dispatchBuffer[OPEN_NOTIFY][DATA_EAPOL_PACKET] = &rxData_rcvPacketInOpenNotify; /* eapol */
207    pRxData->rxData_dispatchBuffer[OPEN_NOTIFY][DATA_IAPP_PACKET]  = &rxData_rcvPacketInOpenNotify; /* Iapp  */
208    pRxData->rxData_dispatchBuffer[OPEN_NOTIFY][DATA_VLAN_PACKET]  = &rxData_discardPacketVlan;     /* VLAN  */
209
210    /* port status open eapol */
211    pRxData->rxData_dispatchBuffer[OPEN_EAPOL][DATA_DATA_PACKET]  = &rxData_discardPacket;      /* data  */
212    pRxData->rxData_dispatchBuffer[OPEN_EAPOL][DATA_EAPOL_PACKET] = &rxData_rcvPacketEapol;     /* eapol */
213    pRxData->rxData_dispatchBuffer[OPEN_EAPOL][DATA_IAPP_PACKET]  = &rxData_discardPacket;      /* Iapp  */
214    pRxData->rxData_dispatchBuffer[OPEN_EAPOL][DATA_VLAN_PACKET]  = &rxData_discardPacketVlan;  /* VLAN  */
215
216    /* port status open */
217    pRxData->rxData_dispatchBuffer[OPEN][DATA_DATA_PACKET]  = &rxData_rcvPacketData;    /* data  */
218    pRxData->rxData_dispatchBuffer[OPEN][DATA_EAPOL_PACKET] = &rxData_rcvPacketEapol;   /* eapol */
219#ifdef XCC_MODULE_INCLUDED
220    pRxData->rxData_dispatchBuffer[OPEN][DATA_IAPP_PACKET]  = &rxData_rcvPacketIapp;    /* Iapp  */
221#else
222    pRxData->rxData_dispatchBuffer[OPEN][DATA_IAPP_PACKET]  = &rxData_rcvPacketData;    /* Iapp  */
223#endif
224    pRxData->rxData_dispatchBuffer[OPEN][DATA_VLAN_PACKET]  = &rxData_discardPacketVlan;/* VLAN  */
225
226    /* register CB's for request buffer and receive CB to the lower layers */
227    TWD_RegisterCb (pRxData->hTWD,
228                    TWD_EVENT_RX_RECEIVE_PACKET,
229                    (void *)rxData_ReceivePacket,
230                    pStadHandles->hRxData);
231
232    TWD_RegisterCb (pRxData->hTWD,
233                    TWD_EVENT_RX_REQUEST_FOR_BUFFER,
234                    (void*)rxData_RequestForBuffer,
235                    pStadHandles->hRxData);
236}
237
238
239TI_STATUS rxData_SetDefaults (TI_HANDLE hRxData, rxDataInitParams_t * rxDataInitParams)
240{
241    rxData_t *pRxData = (rxData_t *)hRxData;
242    int i;
243
244    /* init rx data filters */
245    pRxData->filteringEnabled = rxDataInitParams->rxDataFiltersEnabled;
246    pRxData->filteringDefaultAction = rxDataInitParams->rxDataFiltersDefaultAction;
247    TWD_CfgEnableRxDataFilter (pRxData->hTWD, pRxData->filteringEnabled, pRxData->filteringDefaultAction);
248
249    for (i = 0; i < MAX_DATA_FILTERS; ++i)
250    {
251        if (rxDataInitParams->rxDataFilterRequests[i].maskLength > 0)
252        {
253            if (rxData_addRxDataFilter(hRxData, &rxDataInitParams->rxDataFilterRequests[i]) != TI_OK)
254            {
255                TRACE1(pRxData->hReport, REPORT_SEVERITY_ERROR, ": Invalid Rx Data Filter configured at init stage (at index %d)!\n", i);
256            }
257        }
258    }
259
260	pRxData->reAuthActiveTimer = tmr_CreateTimer (pRxData->hTimer);
261	if (pRxData->reAuthActiveTimer == NULL)
262	{
263        WLAN_OS_REPORT(("rxData_SetDefaults(): Failed to create reAuthActiveTimer!\n"));
264		return TI_NOK;
265	}
266
267    pRxData->reAuthActiveTimeout = rxDataInitParams->reAuthActiveTimeout;
268
269	rxData_SetReAuthInProgress(pRxData, TI_FALSE);
270
271#ifdef TI_DBG
272    /* reset counters */
273    rxData_resetCounters(pRxData);
274    rxData_resetDbgCounters(pRxData);
275
276    /* allocate timer for debug throughput */
277    pRxData->hThroughputTimer = tmr_CreateTimer (pRxData->hTimer);
278    if (pRxData->hThroughputTimer == NULL)
279    {
280        TRACE0(pRxData->hReport, REPORT_SEVERITY_ERROR, "rxData_SetDefaults(): Failed to create hThroughputTimer!\n");
281        return TI_NOK;
282    }
283    pRxData->rxThroughputTimerEnable = TI_FALSE;
284#endif
285
286
287    TRACE0(pRxData->hReport, REPORT_SEVERITY_INIT, ".....Rx Data configured successfully\n");
288
289    return TI_OK;
290}
291
292/***************************************************************************
293*                           rxData_unLoad                                  *
294****************************************************************************
295* DESCRIPTION:  This function unload the Rx data module.
296*
297* INPUTS:       hRxData - the object
298*
299* OUTPUT:
300*
301* RETURNS:      TI_OK - Unload succesfull
302*               TI_NOK - Unload unsuccesfull
303***************************************************************************/
304TI_STATUS rxData_unLoad(TI_HANDLE hRxData)
305{
306    rxData_t *pRxData = (rxData_t *)hRxData;
307
308    /* check parameters validity */
309    if (pRxData == NULL)
310    {
311        return TI_NOK;
312    }
313
314    DistributorMgr_Destroy(pRxData->RxEventDistributor);
315
316#ifdef TI_DBG
317    /* destroy periodic rx throughput timer */
318	if (pRxData->hThroughputTimer)
319	{
320		tmr_DestroyTimer (pRxData->hThroughputTimer);
321	}
322  #endif
323
324	if (pRxData->reAuthActiveTimer)
325	{
326		tmr_DestroyTimer (pRxData->reAuthActiveTimer);
327	}
328
329    /* free Rx Data controll block */
330    os_memoryFree(pRxData->hOs, pRxData, sizeof(rxData_t));
331
332    return TI_OK;
333}
334
335
336/***************************************************************************
337*                           rxData_stop                                    *
338****************************************************************************
339* DESCRIPTION:  this function stop the rx data.
340*
341* INPUTS:       hRxData - the object
342*
343* OUTPUT:
344*
345* RETURNS:      TI_OK - stop succesfull
346*               TI_NOK - stop unsuccesfull
347***************************************************************************/
348TI_STATUS rxData_stop (TI_HANDLE hRxData)
349{
350    rxData_t *pRxData = (rxData_t *)hRxData;
351
352    /* check parameters validity */
353    if (pRxData == NULL)
354    {
355        return TI_NOK;
356    }
357
358    pRxData->rxDataExcludeUnencrypted = DEF_EXCLUDE_UNENCYPTED;
359    pRxData->rxDataExludeBroadcastUnencrypted = DEF_EXCLUDE_UNENCYPTED;
360    pRxData->rxDataEapolDestination = DEF_EAPOL_DESTINATION;
361    pRxData->rxDataPortStatus = DEF_RX_PORT_STATUS;
362
363  #ifdef TI_DBG
364    /* reset counters */
365    /*rxData_resetCounters(pRxData);*/
366    /*rxData_resetDbgCounters(pRxData);*/
367
368    /* stop throughput timer */
369    if (pRxData->rxThroughputTimerEnable)
370    {
371        tmr_StopTimer (pRxData->hThroughputTimer);
372        pRxData->rxThroughputTimerEnable = TI_FALSE;
373    }
374  #endif
375
376    TRACE0(pRxData->hReport, REPORT_SEVERITY_INFORMATION, " rxData_stop() :  Succeeded.\n");
377
378    return TI_OK;
379
380}
381
382/***************************************************************************
383*                           rxData_getParam                                *
384****************************************************************************
385* DESCRIPTION:  get a specific parameter
386*
387* INPUTS:       hRxData - the object
388*
389* OUTPUT:       pParamInfo - structure which include the value of
390*               the requested parameter
391*
392* RETURNS:      TI_OK
393*               TI_NOK
394***************************************************************************/
395TI_STATUS rxData_getParam(TI_HANDLE hRxData, paramInfo_t *pParamInfo)
396{
397    rxData_t *pRxData = (rxData_t *)hRxData;
398
399    /* check handle validity */
400    if (pRxData == NULL)
401    {
402        return TI_NOK;
403    }
404
405    switch (pParamInfo->paramType)
406    {
407        case RX_DATA_EXCLUDE_UNENCRYPTED_PARAM:
408            pParamInfo->content.rxDataExcludeUnencrypted = pRxData->rxDataExcludeUnencrypted;
409            break;
410
411        case RX_DATA_EAPOL_DESTINATION_PARAM:
412            pParamInfo->content.rxDataEapolDestination = pRxData->rxDataEapolDestination;
413            break;
414
415        case RX_DATA_PORT_STATUS_PARAM:
416            pParamInfo->content.rxDataPortStatus = pRxData->rxDataPortStatus;
417            break;
418
419        case RX_DATA_COUNTERS_PARAM:
420            pParamInfo->content.siteMgrTiWlanCounters.RecvOk = pRxData->rxDataCounters.RecvOk;
421            pParamInfo->content.siteMgrTiWlanCounters.DirectedBytesRecv = pRxData->rxDataCounters.DirectedBytesRecv;
422            pParamInfo->content.siteMgrTiWlanCounters.DirectedFramesRecv = pRxData->rxDataCounters.DirectedFramesRecv;
423            pParamInfo->content.siteMgrTiWlanCounters.MulticastBytesRecv = pRxData->rxDataCounters.MulticastBytesRecv;
424            pParamInfo->content.siteMgrTiWlanCounters.MulticastFramesRecv = pRxData->rxDataCounters.MulticastFramesRecv;
425            pParamInfo->content.siteMgrTiWlanCounters.BroadcastBytesRecv = pRxData->rxDataCounters.BroadcastBytesRecv;
426            pParamInfo->content.siteMgrTiWlanCounters.BroadcastFramesRecv = pRxData->rxDataCounters.BroadcastFramesRecv;
427            break;
428
429        case RX_DATA_GET_RX_DATA_FILTERS_STATISTICS:
430            TWD_ItrDataFilterStatistics (pRxData->hTWD,
431                                         pParamInfo->content.interogateCmdCBParams.fCb,
432                                         pParamInfo->content.interogateCmdCBParams.hCb,
433                                         pParamInfo->content.interogateCmdCBParams.pCb);
434            break;
435
436        case RX_DATA_RATE_PARAM:
437            pParamInfo->content.siteMgrCurrentRxRate = pRxData->uLastDataPktRate;
438            break;
439
440        default:
441            TRACE0(pRxData->hReport, REPORT_SEVERITY_ERROR, " rxData_getParam() : PARAMETER NOT SUPPORTED \n");
442            return (PARAM_NOT_SUPPORTED);
443    }
444
445    return TI_OK;
446}
447
448/***************************************************************************
449*                           rxData_setParam                                *
450****************************************************************************
451* DESCRIPTION:  set a specific parameter
452*
453* INPUTS:       hRxData - the object
454*               pParamInfo - structure which include the value to set for
455*               the requested parameter
456*
457* OUTPUT:
458*
459* RETURNS:      TI_OK
460*               TI_NOK
461***************************************************************************/
462TI_STATUS rxData_setParam(TI_HANDLE hRxData, paramInfo_t *pParamInfo)
463{
464    rxData_t *pRxData = (rxData_t *)hRxData;
465
466    /* check handle validity */
467    if( pRxData == NULL  )
468    {
469        return TI_NOK;
470    }
471
472    switch (pParamInfo->paramType)
473    {
474        case RX_DATA_EXCLUDE_UNENCRYPTED_PARAM:
475            pRxData->rxDataExcludeUnencrypted = pParamInfo->content.rxDataExcludeUnencrypted;
476            break;
477        case RX_DATA_EXCLUDE_BROADCAST_UNENCRYPTED_PARAM:
478            pRxData->rxDataExludeBroadcastUnencrypted = pParamInfo->content.rxDataExcludeUnencrypted;
479            break;
480        case RX_DATA_EAPOL_DESTINATION_PARAM:
481            pRxData->rxDataEapolDestination = pParamInfo->content.rxDataEapolDestination;
482            break;
483
484        case RX_DATA_PORT_STATUS_PARAM:
485            pRxData->rxDataPortStatus = pParamInfo->content.rxDataPortStatus;
486            break;
487
488        case RX_DATA_ENABLE_DISABLE_RX_DATA_FILTERS:
489            return rxData_enableDisableRxDataFilters(hRxData, pParamInfo->content.rxDataFilterEnableDisable);
490
491        case RX_DATA_ADD_RX_DATA_FILTER:
492        {
493            TRxDataFilterRequest* pRequest = &pParamInfo->content.rxDataFilterRequest;
494
495            return rxData_addRxDataFilter(hRxData, pRequest);
496        }
497
498        case RX_DATA_REMOVE_RX_DATA_FILTER:
499        {
500            TRxDataFilterRequest* pRequest = &pParamInfo->content.rxDataFilterRequest;
501
502            return rxData_removeRxDataFilter(hRxData, pRequest);
503        }
504
505        case RX_DATA_GENERIC_ETHERTYPE_PARAM:
506            pRxData->genericEthertype = pParamInfo->content.rxGenericEthertype;
507            break;
508
509        default:
510            TRACE0(pRxData->hReport, REPORT_SEVERITY_ERROR, " rxData_setParam() : PARAMETER NOT SUPPORTED \n");
511            return (PARAM_NOT_SUPPORTED);
512    }
513
514    return TI_OK;
515}
516
517/***************************************************************************
518*                     rxData_enableDisableRxDataFilters                    *
519****************************************************************************
520* DESCRIPTION:
521*
522*
523* INPUTS:
524*
525*
526*
527* OUTPUT:
528*
529* RETURNS:
530*
531***************************************************************************/
532static TI_STATUS rxData_enableDisableRxDataFilters(TI_HANDLE hRxData, TI_BOOL enabled)
533{
534    rxData_t * pRxData = (rxData_t *) hRxData;
535
536    /* assert 0 or 1 */
537    if (enabled != TI_FALSE)
538        enabled = 1;
539
540    if (enabled == pRxData->filteringEnabled)
541        return TI_OK;
542
543    pRxData->filteringEnabled = enabled;
544
545    return TWD_CfgEnableRxDataFilter (pRxData->hTWD, pRxData->filteringEnabled, pRxData->filteringDefaultAction);
546}
547
548/***************************************************************************
549*                          findFilterRequest                               *
550****************************************************************************
551* DESCRIPTION:
552*
553*
554* INPUTS:
555*
556*
557*
558* OUTPUT:
559*
560* RETURNS:
561*
562***************************************************************************/
563static int findFilterRequest(TI_HANDLE hRxData, TRxDataFilterRequest* request)
564{
565    rxData_t * pRxData = (rxData_t *) hRxData;
566    int i;
567
568    for (i = 0; i < MAX_DATA_FILTERS; ++i)
569    {
570        if (pRxData->isFilterSet[i])
571        {
572            if ((pRxData->filterRequests[i].offset == request->offset) &&
573                (pRxData->filterRequests[i].maskLength == request->maskLength) &&
574                (pRxData->filterRequests[i].patternLength == request->patternLength))
575            {
576                if ((os_memoryCompare(pRxData->hOs, pRxData->filterRequests[i].mask, request->mask, request->maskLength) == 0) &&
577                    (os_memoryCompare(pRxData->hOs, pRxData->filterRequests[i].pattern, request->pattern, request->patternLength) == 0))
578                    return i;
579            }
580        }
581    }
582
583    return -1;
584}
585
586/***************************************************************************
587*                            closeFieldPattern                             *
588****************************************************************************
589* DESCRIPTION:
590*
591*
592* INPUTS:
593*
594*
595*
596* OUTPUT:
597*
598* RETURNS:
599*
600***************************************************************************/
601static void closeFieldPattern (rxData_t * pRxData, rxDataFilterFieldPattern_t * fieldPattern, TI_UINT8 * fieldPatterns, TI_UINT8 * lenFieldPatterns)
602{
603    //fieldPatterns[*lenFieldPatterns] = fieldPattern->offset;
604	os_memoryCopy(pRxData->hOs, fieldPatterns + *lenFieldPatterns, (TI_UINT8 *)&fieldPattern->offset, sizeof(fieldPattern->offset));
605    *lenFieldPatterns += sizeof(fieldPattern->offset);
606
607    fieldPatterns[*lenFieldPatterns] = fieldPattern->length;
608    *lenFieldPatterns += sizeof(fieldPattern->length);
609
610    fieldPatterns[*lenFieldPatterns] = fieldPattern->flag;
611    *lenFieldPatterns += sizeof(fieldPattern->flag);
612
613    os_memoryCopy(pRxData->hOs, fieldPatterns + *lenFieldPatterns, fieldPattern->pattern, fieldPattern->length);
614    *lenFieldPatterns += fieldPattern->length;
615
616    /* if the pattern bit mask is enabled add it to the end of the request */
617    if ((fieldPattern->flag & RX_DATA_FILTER_FLAG_USE_BIT_MASK) == RX_DATA_FILTER_FLAG_USE_BIT_MASK)
618    {
619        os_memoryCopy(pRxData->hOs, fieldPatterns + *lenFieldPatterns, fieldPattern->mask, fieldPattern->length);
620        *lenFieldPatterns += fieldPattern->length;
621    }
622
623    TRACE3(pRxData->hReport, REPORT_SEVERITY_INFORMATION, ": Closed field pattern, length = %d, total length = %d, pattern bit mask = %d.\n", fieldPattern->length, *lenFieldPatterns, ((fieldPattern->flag & RX_DATA_FILTER_FLAG_USE_BIT_MASK) == RX_DATA_FILTER_FLAG_USE_BIT_MASK));
624}
625
626
627/***************************************************************************
628*                         parseRxDataFilterRequest                         *
629****************************************************************************
630* DESCRIPTION:
631*
632*
633* INPUTS:
634*
635*
636*
637* OUTPUT:
638*
639* RETURNS:
640*
641***************************************************************************/
642static int parseRxDataFilterRequest(TI_HANDLE hRxData, TRxDataFilterRequest* request, TI_UINT8 * numFieldPatterns, TI_UINT8 * lenFieldPatterns, TI_UINT8 * fieldPatterns)
643{
644    rxData_t * pRxData = (rxData_t *) hRxData;
645
646    int maskIter;
647    int patternIter = 0;
648
649    /* used to store field patterns while they are built */
650    TI_BOOL isBuildingFieldPattern = TI_FALSE;
651    rxDataFilterFieldPattern_t fieldPattern;
652
653    for (maskIter = 0; maskIter < request->maskLength * 8; ++maskIter)
654    {
655        /* which byte in the mask and which bit in the byte we're at */
656        int bit = maskIter % 8;
657        int byte = maskIter / 8;
658
659        /* is the bit in the mask set */
660        TI_BOOL isSet = ((request->mask[byte] & (1 << bit)) == (1 << bit));
661
662        TRACE4(pRxData->hReport, REPORT_SEVERITY_INFORMATION, ": MaskIter = %d, Byte = %d, Bit = %d, isSet = %d\n", maskIter, byte, bit, isSet);
663
664        /* if we're in the midst of building a field pattern, we need to close in case */
665        /* the current bit is not set or we've reached the ethernet header boundary */
666        if (isBuildingFieldPattern)
667        {
668            if ((isSet == TI_FALSE) || (request->offset + maskIter == RX_DATA_FILTER_ETHERNET_HEADER_BOUNDARY))
669            {
670                closeFieldPattern(hRxData, &fieldPattern, fieldPatterns, lenFieldPatterns);
671
672                isBuildingFieldPattern = TI_FALSE;
673            }
674        }
675
676        /* nothing to do in case the bit is not set */
677        if (isSet)
678        {
679            /* if not already building a field pattern, create a new one */
680            if (isBuildingFieldPattern == TI_FALSE)
681            {
682                TRACE0(pRxData->hReport, REPORT_SEVERITY_INFORMATION, ": Creating a new field pattern.\n");
683
684                isBuildingFieldPattern = TI_TRUE;
685                ++(*numFieldPatterns);
686
687                if (*numFieldPatterns > RX_DATA_FILTER_MAX_FIELD_PATTERNS)
688                {
689                    TRACE1(pRxData->hReport, REPORT_SEVERITY_ERROR, ": Invalid filter, too many field patterns, maximum of %u is allowed!\n", RX_DATA_FILTER_MAX_FIELD_PATTERNS);
690
691                    return TI_NOK;
692                }
693
694                fieldPattern.offset = request->offset + maskIter;
695                fieldPattern.length = 0;
696
697                /* we don't support the mask per bit feature yet. */
698                fieldPattern.flag = RX_DATA_FILTER_FLAG_NO_BIT_MASK;
699
700                /* first 14 bits are used for the Ethernet header, rest for the IP header */
701                if (fieldPattern.offset < RX_DATA_FILTER_ETHERNET_HEADER_BOUNDARY)
702                {
703                    fieldPattern.flag |= RX_DATA_FILTER_FLAG_ETHERNET_HEADER;
704                }
705                else
706                {
707                    fieldPattern.flag |= RX_DATA_FILTER_FLAG_IP_HEADER;
708                    fieldPattern.offset -= RX_DATA_FILTER_ETHERNET_HEADER_BOUNDARY;
709                }
710
711                TRACE2(pRxData->hReport, REPORT_SEVERITY_INFORMATION, ": offset = %d, flag = %d.\n", fieldPattern.offset, fieldPattern.flag);
712            }
713
714            /* check that the pattern is long enough */
715            if (patternIter > request->patternLength)
716            {
717                TRACE0(pRxData->hReport, REPORT_SEVERITY_ERROR, ": Invalid filter, mask and pattern length are not consistent!\n");
718
719                return TI_NOK;
720            }
721
722            /* add the current pattern byte to the field pattern */
723            fieldPattern.pattern[fieldPattern.length++] = request->pattern[patternIter++];
724
725            /* check pattern matching boundary */
726            if (fieldPattern.offset + fieldPattern.length >= RX_DATA_FILTER_FILTER_BOUNDARY)
727            {
728                TRACE1(pRxData->hReport, REPORT_SEVERITY_ERROR, ": Invalid filter, pattern matching cannot exceed first %u characters.\n", RX_DATA_FILTER_FILTER_BOUNDARY);
729
730                return TI_NOK;
731            }
732        }
733    }
734
735    /* check that the pattern is long enough */
736    if (patternIter != request->patternLength)
737    {
738        TRACE0(pRxData->hReport, REPORT_SEVERITY_ERROR, ": Invalid filter, mask and pattern lengths are not consistent!\n");
739
740        return TI_NOK;
741    }
742
743    /* close the last field pattern if needed */
744    if (isBuildingFieldPattern)
745    {
746        closeFieldPattern (hRxData, &fieldPattern, fieldPatterns, lenFieldPatterns);
747    }
748
749    return TI_OK;
750}
751
752
753/***************************************************************************
754*                           rxData_setRxDataFilter                         *
755****************************************************************************
756* DESCRIPTION:
757*
758*
759* INPUTS:
760*
761*
762*
763* OUTPUT:
764*
765* RETURNS:
766*
767***************************************************************************/
768static TI_STATUS rxData_addRxDataFilter (TI_HANDLE hRxData, TRxDataFilterRequest* request)
769{
770    rxData_t * pRxData = (rxData_t *) hRxData;
771
772    /* firmware request fields */
773    TI_UINT8 index = 0;
774    TI_UINT8 numFieldPatterns = 0;
775    TI_UINT8 lenFieldPatterns = 0;
776    TI_UINT8 fieldPatterns[MAX_DATA_FILTER_SIZE];
777
778    /* does the filter already exist? */
779    if (findFilterRequest(hRxData, request) >= 0)
780    {
781        TRACE0(pRxData->hReport, REPORT_SEVERITY_INFORMATION, ": Filter already exists.\n");
782
783        return RX_FILTER_ALREADY_EXISTS;
784    }
785
786    /* find place for insertion */
787    for (index = 0; index < MAX_DATA_FILTERS; ++index)
788    {
789        if (pRxData->isFilterSet[index] == TI_FALSE)
790            break;
791    }
792
793    /* are all filter slots taken? */
794    if (index == MAX_DATA_FILTERS)
795    {
796        TRACE0(pRxData->hReport, REPORT_SEVERITY_ERROR, ": No place to insert filter!\n");
797
798        return RX_NO_AVAILABLE_FILTERS;
799    }
800
801    TRACE1(pRxData->hReport, REPORT_SEVERITY_INFORMATION, ": Inserting filter at index %d.\n", index);
802
803    /* parse the filter request into discrete field patterns */
804    if (parseRxDataFilterRequest(hRxData, request, &numFieldPatterns, &lenFieldPatterns, fieldPatterns) != TI_OK)
805        return TI_NOK;
806
807    if (numFieldPatterns == 0)
808        return TI_NOK;
809
810    /* Store configuration for future manipulation */
811    pRxData->isFilterSet[index] = TI_TRUE;
812    os_memoryCopy(pRxData->hOs, &pRxData->filterRequests[index], request, sizeof(pRxData->filterRequests[index]));
813
814    /* Send configuration to firmware */
815    return TWD_CfgRxDataFilter (pRxData->hTWD,
816                                index,
817                                ADD_FILTER,
818                                FILTER_SIGNAL,
819                                numFieldPatterns,
820                                lenFieldPatterns,
821                                fieldPatterns);
822
823}
824
825/***************************************************************************
826*                         rxData_removeRxDataFilter                        *
827****************************************************************************
828* DESCRIPTION:
829*
830*
831* INPUTS:
832*
833*
834*
835* OUTPUT:
836*
837* RETURNS:
838*
839***************************************************************************/
840static TI_STATUS rxData_removeRxDataFilter (TI_HANDLE hRxData, TRxDataFilterRequest* request)
841{
842    rxData_t * pRxData = (rxData_t *) hRxData;
843
844    int index = findFilterRequest(hRxData, request);
845
846    /* does the filter exist? */
847    if (index < 0)
848    {
849        TRACE0(pRxData->hReport, REPORT_SEVERITY_WARNING, ": Remove data filter request received but the specified filter was not found!");
850
851        return RX_FILTER_DOES_NOT_EXIST;
852    }
853
854    TRACE1(pRxData->hReport, REPORT_SEVERITY_INFORMATION, ": Removing filter at index %d.", index);
855
856    pRxData->isFilterSet[index] = TI_FALSE;
857
858    return TWD_CfgRxDataFilter (pRxData->hTWD,
859                                index,
860                                REMOVE_FILTER,
861                                FILTER_SIGNAL,
862                                0,
863                                0,
864                                NULL);
865}
866
867/***************************************************************************
868*                       rxData_DistributorRxEvent                          *
869****************************************************************************
870* DESCRIPTION:
871*
872*
873* INPUTS:
874*
875*
876*
877* OUTPUT:
878*
879* RETURNS:
880*
881***************************************************************************/
882static void rxData_DistributorRxEvent (rxData_t *pRxData, TI_UINT16 Mask, int DataLen)
883{
884    DistributorMgr_EventCall (pRxData->RxEventDistributor, Mask, DataLen);
885}
886
887/***************************************************************************
888*                       rxData_RegNotif                                    *
889****************************************************************************/
890TI_HANDLE rxData_RegNotif (TI_HANDLE hRxData, TI_UINT16 EventMask, GeneralEventCall_t CallBack, TI_HANDLE context, TI_UINT32 Cookie)
891{
892    rxData_t *pRxData = (rxData_t *)hRxData;
893
894    if (!hRxData)
895        return NULL;
896
897    return DistributorMgr_Reg (pRxData->RxEventDistributor, EventMask, (TI_HANDLE)CallBack, context, Cookie);
898}
899
900/***************************************************************************
901*                       rxData_AddToNotifMask                              *
902****************************************************************************/
903TI_STATUS rxData_AddToNotifMask (TI_HANDLE hRxData, TI_HANDLE Notifh, TI_UINT16 EventMask)
904{
905    rxData_t *pRxData = (rxData_t *)hRxData;
906
907    if (!hRxData)
908        return TI_NOK;
909
910    return DistributorMgr_AddToMask (pRxData->RxEventDistributor, Notifh, EventMask);
911}
912
913
914/***************************************************************************
915*                       rxData_UnRegNotif                                  *
916****************************************************************************/
917TI_STATUS rxData_UnRegNotif(TI_HANDLE hRxData,TI_HANDLE RegEventHandle)
918{
919    rxData_t *pRxData = (rxData_t *)hRxData;
920
921    if (!hRxData)
922        return TI_NOK;
923
924    return DistributorMgr_UnReg (pRxData->RxEventDistributor, RegEventHandle);
925}
926
927
928/***************************************************************************
929*                       rxData_receivePacketFromWlan                       *
930****************************************************************************
931* DESCRIPTION:  this function is called by the GWSI for each received Buffer.
932*               It filter and distribute the received Buffer.
933*
934* INPUTS:       hRxData - the object
935*               pBuffer - the received Buffer.
936*               pRxAttr - Rx attributes
937*
938* OUTPUT:
939*
940* RETURNS:
941***************************************************************************/
942void rxData_receivePacketFromWlan (TI_HANDLE hRxData, void *pBuffer, TRxAttr* pRxAttr)
943{
944    rxData_t        *pRxData    = (rxData_t *)hRxData;
945    TMacAddr        address3;
946    dot11_header_t  *pDot11Hdr;
947
948    TRACE1(pRxData->hReport, REPORT_SEVERITY_INFORMATION, " rxData_receivePacketFromWlan() : pRxAttr->packetType = %d\n", pRxAttr->ePacketType);
949
950    switch (pRxAttr->ePacketType)
951    {
952    case TAG_CLASS_MANAGEMENT:
953    case TAG_CLASS_BCN_PRBRSP:
954
955        TRACE1(pRxData->hReport, REPORT_SEVERITY_INFORMATION, "rxData_receivePacketFromWlan(): Received management Buffer len = %d\n", RX_BUF_LEN(pBuffer));
956
957        /* update siteMngr
958         *
959         * the BSSID in mgmt frames is always addr3 in the header
960         * must copy address3 since Buffer is freed in mlmeParser_recv
961         */
962        pDot11Hdr = (dot11_header_t*)RX_BUF_DATA(pBuffer);
963
964        os_memoryCopy(pRxData->hOs, &address3, &pDot11Hdr->address3, sizeof(address3));
965
966        /* distribute mgmt pBuffer to mlme */
967        if( mlmeParser_recv(pRxData->hMlme, pBuffer, pRxAttr) != TI_OK )
968        {
969            TRACE0(pRxData->hReport, REPORT_SEVERITY_ERROR, " rxData_receivePacketFromWlan() : MLME returned error \n");
970        }
971        break;
972
973    case TAG_CLASS_DATA:
974    case TAG_CLASS_QOS_DATA:
975    case TAG_CLASS_AMSDU:
976    case TAG_CLASS_EAPOL:
977        {
978            CL_TRACE_START_L3();
979            TRACE1(pRxData->hReport, REPORT_SEVERITY_INFORMATION, " rxData_receivePacketFromWlan() : Received Data Buffer len = %d\n", RX_BUF_LEN(pBuffer));
980
981            /* send pBuffer to data dispatcher */
982            rxData_dataPacketDisptcher(hRxData, pBuffer, pRxAttr);
983            CL_TRACE_END_L3("tiwlan_drv.ko", "INHERIT", "RX", ".DataPacket");
984            break;
985        }
986
987    default:
988        TRACE0(pRxData->hReport, REPORT_SEVERITY_INFORMATION, " rxData_receivePacketFromWlan(): Received unspecified packet type !!! \n");
989        RxBufFree(pRxData->hOs, pBuffer);
990        break;
991    }
992}
993
994/***************************************************************************
995*                       rxData_dataPacketDisptcher                         *
996****************************************************************************
997* DESCRIPTION:  this function is called upon receving data Buffer,
998*               it dispatches the packet to the approciate function according to
999*               data packet type and rx port status.
1000*
1001* INPUTS:       hRxData - the object
1002*               pBuffer - the received Buffer.
1003*               pRxAttr - Rx attributes
1004*
1005* OUTPUT:
1006*
1007* RETURNS:
1008***************************************************************************/
1009
1010static void rxData_dataPacketDisptcher (TI_HANDLE hRxData, void *pBuffer, TRxAttr* pRxAttr)
1011{
1012    rxData_t *pRxData = (rxData_t *)hRxData;
1013    portStatus_e DataPortStatus;
1014    rxDataPacketType_e DataPacketType;
1015
1016    /* get rx port status */
1017    DataPortStatus = pRxData->rxDataPortStatus;
1018
1019    /* discard data packets received while rx data port is closed */
1020    if (DataPortStatus == CLOSE)
1021    {
1022        TRACE0(pRxData->hReport, REPORT_SEVERITY_INFORMATION, " rxData_dataPacketDisptcher() : Received Data Buffer while Rx data port is closed \n");
1023
1024        rxData_discardPacket (hRxData, pBuffer, pRxAttr);
1025        return;
1026    }
1027
1028    /* get data packet type */
1029
1030    pRxData->uLastDataPktRate = pRxAttr->Rate;  /* save Rx packet rate for statistics */
1031
1032#ifdef XCC_MODULE_INCLUDED
1033    if (XCCMngr_isIappPacket (pRxData->hXCCMgr, pBuffer) == TI_TRUE)
1034    {
1035        TRACE0(pRxData->hReport, REPORT_SEVERITY_INFORMATION, " rxData_dataPacketDisptcher() : Received Iapp Buffer  \n");
1036
1037        DataPacketType = DATA_IAPP_PACKET;
1038
1039        /* dispatch Buffer according to packet type and current rx data port status */
1040        pRxData->rxData_dispatchBuffer[DataPortStatus][DataPacketType] (hRxData, pBuffer, pRxAttr);
1041    }
1042    else
1043#endif
1044    {
1045        /* A-MSDU ? */
1046        if (TAG_CLASS_AMSDU == pRxAttr->ePacketType)
1047        {
1048           rxData_ConvertAmsduToEthPackets (hRxData, pBuffer, pRxAttr);
1049        }
1050        else
1051        {
1052           TI_UINT16 etherType = 0;
1053           TEthernetHeader * pEthernetHeader;
1054
1055           /*
1056            * if Host processes received packets, the header translation
1057            * from WLAN to ETH is done here. The conversion has been moved
1058            * here so that IAPP packets aren't converted.
1059            */
1060           rxData_convertWlanToEthHeader (hRxData, pBuffer, &etherType);
1061
1062           pEthernetHeader = (TEthernetHeader *)RX_ETH_PKT_DATA(pBuffer);
1063
1064           if (etherType == ETHERTYPE_802_1D)
1065           {
1066               TRACE0(pRxData->hReport, REPORT_SEVERITY_INFORMATION, " rxData_dataPacketDisptcher() : Received VLAN packet  \n");
1067
1068               DataPacketType = DATA_VLAN_PACKET;
1069           }
1070           else if ((HTOWLANS(pEthernetHeader->type) == EAPOL_PACKET) ||
1071					(HTOWLANS(pEthernetHeader->type) == pRxData->genericEthertype))
1072           {
1073				TRACE0(pRxData->hReport, REPORT_SEVERITY_INFORMATION, " rxData_dataPacketDisptcher() : Received Eapol packet  \n");
1074
1075				if (rxData_IsReAuthInProgress(pRxData))
1076				{
1077					/* ReAuth already in progress, restart timer */
1078					rxData_StopReAuthActiveTimer(pRxData);
1079					rxData_StartReAuthActiveTimer(pRxData);
1080				}
1081				else
1082				{
1083					if (PowerMgr_getReAuthActivePriority(pRxData->hPowerMgr))
1084					{
1085						/* ReAuth not in progress yet, force active, set flag, restart timer, send event */
1086						rxData_SetReAuthInProgress(pRxData, TI_TRUE);
1087						rxData_StartReAuthActiveTimer(pRxData);
1088						rxData_ReauthEnablePriority(pRxData);
1089						EvHandlerSendEvent(pRxData->hEvHandler, IPC_EVENT_RE_AUTH_STARTED, NULL, 0);
1090					}
1091				}
1092
1093				DataPacketType = DATA_EAPOL_PACKET;
1094           }
1095           else
1096           {
1097               TRACE0(pRxData->hReport, REPORT_SEVERITY_INFORMATION, " rxData_dataPacketDisptcher() : Received Data packet  \n");
1098
1099               DataPacketType = DATA_DATA_PACKET;
1100           }
1101
1102           /* dispatch Buffer according to packet type and current rx data port status */
1103           pRxData->rxData_dispatchBuffer[DataPortStatus][DataPacketType] (hRxData, pBuffer, pRxAttr);
1104        }
1105    }
1106
1107}
1108
1109/***************************************************************************
1110*                       rxData_discardPacket                                   *
1111****************************************************************************
1112* DESCRIPTION:  this function is called to discard Buffer
1113*
1114* INPUTS:       hRxData - the object
1115*               pBuffer - the received Buffer.
1116*               pRxAttr - Rx attributes
1117*
1118* OUTPUT:
1119*
1120* RETURNS:
1121***************************************************************************/
1122static void rxData_discardPacket (TI_HANDLE hRxData, void *pBuffer, TRxAttr* pRxAttr)
1123{
1124    rxData_t *pRxData = (rxData_t *)hRxData;
1125
1126    TRACE2(pRxData->hReport, REPORT_SEVERITY_INFORMATION, " rxData_discardPacket: rx port status = %d , Buffer status = %d  \n", pRxData->rxDataPortStatus, pRxAttr->status);
1127
1128    pRxData->rxDataDbgCounters.excludedFrameCounter++;
1129
1130    /* free Buffer */
1131    RxBufFree(pRxData->hOs, pBuffer);
1132
1133}
1134
1135/***************************************************************************
1136*                       rxData_discardPacketVlan                                   *
1137****************************************************************************
1138* DESCRIPTION:  this function is called to discard Buffer
1139*
1140* INPUTS:       hRxData - the object
1141*               pBuffer - the received Buffer.
1142*               pRxAttr - Rx attributes
1143*
1144* OUTPUT:
1145*
1146* RETURNS:
1147***************************************************************************/
1148static void rxData_discardPacketVlan (TI_HANDLE hRxData, void *pBuffer, TRxAttr* pRxAttr)
1149{
1150    rxData_t *pRxData = (rxData_t *)hRxData;
1151
1152    TRACE0(pRxData->hReport, REPORT_SEVERITY_WARNING, " rxData_discardPacketVlan : drop packet that contains VLAN tag\n");
1153
1154    pRxData->rxDataDbgCounters.rxDroppedDueToVLANIncludedCnt++;
1155
1156    /* free Buffer */
1157    RxBufFree(pRxData->hOs, pBuffer);
1158}
1159
1160
1161/***************************************************************************
1162*                       rxData_rcvPacketInOpenNotify                         *
1163****************************************************************************
1164* DESCRIPTION:  this function is called upon receving data Eapol packet type
1165*               while rx port status is "open notify"
1166*
1167* INPUTS:       hRxData - the object
1168*               pBuffer - the received Buffer.
1169*               pRxAttr - Rx attributes
1170*
1171* OUTPUT:
1172*
1173* RETURNS:
1174***************************************************************************/
1175static void rxData_rcvPacketInOpenNotify (TI_HANDLE hRxData, void *pBuffer, TRxAttr* pRxAttr)
1176{
1177    rxData_t *pRxData = (rxData_t *)hRxData;
1178
1179    TRACE0(pRxData->hReport, REPORT_SEVERITY_ERROR, " rxData_rcvPacketInOpenNotify: receiving data packet while in rx port status is open notify\n");
1180
1181    pRxData->rxDataDbgCounters.rcvUnicastFrameInOpenNotify++;
1182
1183    /* free Buffer */
1184    RxBufFree(pRxData->hOs, pBuffer);
1185}
1186
1187
1188/***************************************************************************
1189*                       rxData_rcvPacketEapol                               *
1190****************************************************************************
1191* DESCRIPTION:  this function is called upon receving data Eapol packet type
1192*               while rx port status is "open  eapol"
1193*
1194* INPUTS:       hRxData - the object
1195*               pBuffer - the received Buffer.
1196*               pRxAttr - Rx attributes
1197*
1198* OUTPUT:
1199*
1200* RETURNS:
1201***************************************************************************/
1202static void rxData_rcvPacketEapol(TI_HANDLE hRxData, void *pBuffer, TRxAttr* pRxAttr)
1203{
1204    rxData_t *pRxData = (rxData_t *)hRxData;
1205
1206    TRACE0(pRxData->hReport, REPORT_SEVERITY_INFORMATION, " rxData_rcvPacketEapol() : Received an EAPOL frame tranferred to OS\n");
1207
1208    TRACE0(pRxData->hReport, REPORT_SEVERITY_INFORMATION, " rxData_rcvPacketEapol() : Received an EAPOL frame tranferred to OS\n");
1209
1210    EvHandlerSendEvent (pRxData->hEvHandler, IPC_EVENT_EAPOL, NULL, 0);
1211    os_receivePacket (pRxData->hOs, (struct RxIfDescriptor_t*)pBuffer, pBuffer, (TI_UINT16)RX_ETH_PKT_LEN(pBuffer));
1212
1213}
1214
1215/***************************************************************************
1216*                       rxData_rcvPacketData                                 *
1217****************************************************************************
1218* DESCRIPTION:  this function is called upon receving data "data" packet type
1219*               while rx port status is "open"
1220*
1221* INPUTS:       hRxData - the object
1222*               pBuffer - the received Buffer.
1223*               pRxAttr - Rx attributes
1224*
1225* OUTPUT:
1226*
1227* RETURNS:
1228***************************************************************************/
1229static void rxData_rcvPacketData(TI_HANDLE hRxData, void *pBuffer, TRxAttr* pRxAttr)
1230{
1231    rxData_t *pRxData = (rxData_t *)hRxData;
1232    TEthernetHeader *pEthernetHeader;
1233    TI_UINT16 EventMask = 0;
1234    TFwInfo *pFwInfo;
1235
1236    TRACE0(pRxData->hReport, REPORT_SEVERITY_INFORMATION, " rxData_rcvPacketData() : Received DATA frame tranferred to OS\n");
1237
1238    /* check encryption status */
1239    pEthernetHeader = (TEthernetHeader *)RX_ETH_PKT_DATA(pBuffer);
1240    if (!MAC_MULTICAST (pEthernetHeader->dst))
1241    {  /* unicast frame */
1242        if((pRxData->rxDataExcludeUnencrypted) && (!(pRxAttr->packetInfo & RX_DESC_ENCRYPT_MASK)))
1243        {
1244            pRxData->rxDataDbgCounters.excludedFrameCounter++;
1245            /* free Buffer */
1246            TRACE0(pRxData->hReport, REPORT_SEVERITY_WARNING, " rxData_rcvPacketData() : exclude unicast unencrypted is TI_TRUE & packet encryption is OFF\n");
1247
1248            RxBufFree(pRxData->hOs, pBuffer);
1249            return;
1250        }
1251    }
1252    else
1253    {  /* broadcast frame */
1254        if ((pRxData->rxDataExludeBroadcastUnencrypted) && (!(pRxAttr->packetInfo & RX_DESC_ENCRYPT_MASK)))
1255        {
1256            pRxData->rxDataDbgCounters.excludedFrameCounter++;
1257            /* free Buffer */
1258            TRACE0(pRxData->hReport, REPORT_SEVERITY_WARNING, " rxData_rcvPacketData() : exclude broadcast unencrypted is TI_TRUE & packet encryption is OFF\n");
1259
1260            RxBufFree(pRxData->hOs, pBuffer);
1261            return;
1262        }
1263
1264        /*
1265         * Discard multicast/broadcast frames that we sent ourselves.
1266         * Per IEEE 802.11-2007 section 9.2.7: "STAs shall filter out
1267         * broadcast/multicast messages that contain their address as
1268         * the source address."
1269         */
1270        pFwInfo = TWD_GetFWInfo (pRxData->hTWD);
1271        if (MAC_EQUAL(pFwInfo->macAddress, pEthernetHeader->src))
1272        {
1273            pRxData->rxDataDbgCounters.excludedFrameCounter++;
1274            /* free Buffer */
1275            RxBufFree(pRxData->hOs, pBuffer);
1276            return;
1277        }
1278    }
1279
1280    /* update traffic monitor parameters */
1281    pRxData->rxDataCounters.RecvOk++;
1282    EventMask |= RECV_OK;
1283
1284    if (!MAC_MULTICAST (pEthernetHeader->dst))
1285    {
1286        /* Directed frame */
1287        pRxData->rxDataCounters.DirectedFramesRecv++;
1288        pRxData->rxDataCounters.DirectedBytesRecv += RX_ETH_PKT_LEN(pBuffer);
1289        EventMask |= DIRECTED_BYTES_RECV;
1290        EventMask |= DIRECTED_FRAMES_RECV;
1291    }
1292    else if (MAC_BROADCAST (pEthernetHeader->dst))
1293    {
1294        /* Broadcast frame */
1295        pRxData->rxDataCounters.BroadcastFramesRecv++;
1296        pRxData->rxDataCounters.BroadcastBytesRecv += RX_ETH_PKT_LEN(pBuffer);
1297        EventMask |= BROADCAST_BYTES_RECV;
1298        EventMask |= BROADCAST_FRAMES_RECV;
1299    }
1300    else
1301    {
1302        /* Multicast Address */
1303        pRxData->rxDataCounters.MulticastFramesRecv++;
1304        pRxData->rxDataCounters.MulticastBytesRecv += RX_ETH_PKT_LEN(pBuffer);
1305        EventMask |= MULTICAST_BYTES_RECV;
1306        EventMask |= MULTICAST_FRAMES_RECV;
1307    }
1308    pRxData->rxDataCounters.LastSecBytesRecv += RX_ETH_PKT_LEN(pBuffer);
1309
1310    /*Handle PREAUTH_EAPOL_PACKET*/
1311    if (HTOWLANS(pEthernetHeader->type) == PREAUTH_EAPOL_PACKET)
1312    {
1313        TRACE0(pRxData->hReport, REPORT_SEVERITY_INFORMATION, " rxData_rcvPacketData() : Received an Pre-Auth EAPOL frame tranferred to OS\n");
1314    }
1315
1316    rxData_DistributorRxEvent (pRxData, EventMask, RX_ETH_PKT_LEN(pBuffer));
1317
1318    /* deliver packet to os */
1319    os_receivePacket (pRxData->hOs, (struct RxIfDescriptor_t*)pBuffer, pBuffer, (TI_UINT16)RX_ETH_PKT_LEN(pBuffer));
1320}
1321
1322
1323/***************************************************************************
1324*                       rxData_rcvPacketIapp                                 *
1325****************************************************************************
1326* DESCRIPTION:  this function is called upon receving data IAPP packet type
1327*               while rx port status is "open"
1328*
1329* INPUTS:       hRxData - the object
1330*               pBuffer - the received Buffer.
1331*               pRxAttr - Rx attributes
1332*
1333* OUTPUT:
1334*
1335* RETURNS:
1336***************************************************************************/
1337#ifdef XCC_MODULE_INCLUDED
1338
1339static void rxData_rcvPacketIapp(TI_HANDLE hRxData, void *pBuffer, TRxAttr* pRxAttr)
1340{
1341    rxData_t *pRxData = (rxData_t *)hRxData;
1342
1343    TRACE0(pRxData->hReport, REPORT_SEVERITY_INFORMATION, " rxData_rcvPacketIapp() : Received IAPP frame tranferred to XCCMgr\n");
1344
1345    TRACE0(pRxData->hReport, REPORT_SEVERITY_INFORMATION, " rxData_rcvPacketIapp() : Received IAPP frame tranferred to XCCMgr\n");
1346
1347    /* tranfer packet to XCCMgr */
1348    XCCMngr_recvIAPPPacket (pRxData->hXCCMgr, pBuffer, pRxAttr);
1349
1350    /* free Buffer */
1351    RxBufFree(pRxData->hOs, pBuffer);
1352}
1353
1354#endif
1355
1356
1357/****************************************************************************
1358*                       rxData_convertWlanToEthHeader                       *
1359*****************************************************************************
1360* DESCRIPTION:  this function convert the Packet header from 802.11 header
1361*               format to ethernet format
1362*
1363* INPUTS:       hRxData - the object
1364*               pBuffer - the received pBuffer in 802.11 format
1365*
1366* OUTPUT:       pEthPacket  - pointer to the received pBuffer in ethernet format
1367*               uEthLength - ethernet packet length
1368*
1369* RETURNS:      TI_OK/TI_NOK
1370***************************************************************************/
1371static TI_STATUS rxData_convertWlanToEthHeader (TI_HANDLE hRxData, void *pBuffer, TI_UINT16 * etherType)
1372{
1373    TEthernetHeader      EthHeader;
1374    Wlan_LlcHeader_T    *pWlanSnapHeader;
1375    TI_UINT8            *dataBuf;
1376    dot11_header_t      *pDot11Header;
1377    TI_UINT32            lengthDelta;
1378    TI_UINT16            swapedTypeLength;
1379    TI_UINT32            headerLength;
1380    TI_UINT8             createEtherIIHeader;
1381    rxData_t *pRxData = (rxData_t *)hRxData;
1382
1383    dataBuf = (TI_UINT8 *)RX_BUF_DATA(pBuffer);
1384
1385    /* Setting the mac header len according to the received FrameControl field in the Mac Header */
1386    GET_MAX_HEADER_SIZE (dataBuf, &headerLength);
1387    pDot11Header = (dot11_header_t*) dataBuf;
1388    pWlanSnapHeader = (Wlan_LlcHeader_T*)((TI_UINT32)dataBuf + (TI_UINT32)headerLength);
1389
1390    swapedTypeLength = WLANTOHS (pWlanSnapHeader->Type);
1391    *etherType = swapedTypeLength;
1392
1393    /* Prepare the Ethernet header. */
1394    if( ENDIAN_HANDLE_WORD(pDot11Header->fc) & DOT11_FC_FROM_DS)
1395    {   /* Infrastructure  bss */
1396        MAC_COPY (EthHeader.dst, pDot11Header->address1);
1397        MAC_COPY (EthHeader.src, pDot11Header->address3);
1398    }
1399    else
1400    {   /* Independent bss */
1401        MAC_COPY (EthHeader.dst, pDot11Header->address1);
1402        MAC_COPY (EthHeader.src, pDot11Header->address2);
1403    }
1404
1405    createEtherIIHeader = TI_FALSE;
1406	/* See if the LLC header in the frame shows the SAP SNAP... */
1407	if((SNAP_CHANNEL_ID == pWlanSnapHeader->DSAP) &&
1408	   (SNAP_CHANNEL_ID == pWlanSnapHeader->SSAP) &&
1409	   (LLC_CONTROL_UNNUMBERED_INFORMATION == pWlanSnapHeader->Control))
1410	{
1411		/* Check for the Bridge Tunnel OUI in the SNAP Header... */
1412		if((SNAP_OUI_802_1H_BYTE0 == pWlanSnapHeader->OUI[ 0 ]) &&
1413		   (SNAP_OUI_802_1H_BYTE1 == pWlanSnapHeader->OUI[ 1 ]) &&
1414		   (SNAP_OUI_802_1H_BYTE2 == pWlanSnapHeader->OUI[ 2 ]))
1415		{
1416			/* Strip the SNAP header by skipping over it.                  */
1417			/* Start moving data from the Ethertype field in the SNAP      */
1418			/* header.  Move to the TypeLength field in the 802.3 header.  */
1419			createEtherIIHeader = TI_TRUE;
1420		}
1421		/* Check for the RFC 1042 OUI in the SNAP Header   */
1422		else
1423		{
1424			/* Check for the RFC 1042 OUI in the SNAP Header   */
1425			if(	(SNAP_OUI_RFC1042_BYTE0 == pWlanSnapHeader->OUI[ 0 ]) &&
1426				(SNAP_OUI_RFC1042_BYTE1 == pWlanSnapHeader->OUI[ 1 ]) &&
1427				(SNAP_OUI_RFC1042_BYTE2 == pWlanSnapHeader->OUI[ 2 ]))
1428			{
1429			/* See if the Ethertype is in our selective translation table  */
1430			/* (Appletalk AARP and DIX II IPX are the two protocols in     */
1431			/* our 'table')                                                */
1432				if((ETHERTYPE_APPLE_AARP != swapedTypeLength) &&
1433					(ETHERTYPE_DIX_II_IPX != swapedTypeLength))
1434			{
1435				/* Strip the SNAP header by skipping over it. */
1436				createEtherIIHeader = TI_TRUE;
1437			}
1438		}
1439	}
1440    }
1441
1442    if( createEtherIIHeader == TI_TRUE )
1443    {
1444    /* The LEN/TYPE bytes are set to TYPE, the entire WLAN+SNAP is removed.*/
1445    lengthDelta = headerLength + WLAN_SNAP_HDR_LEN - ETHERNET_HDR_LEN;
1446    EthHeader.type = pWlanSnapHeader->Type;
1447    }
1448    else
1449    {
1450	/* The LEN/TYPE bytes are set to frame LEN, only the WLAN header is removed, */
1451	/* the entire 802.3 or 802.2 header is not removed.*/
1452	lengthDelta = headerLength - ETHERNET_HDR_LEN;
1453	EthHeader.type = WLANTOHS((TI_UINT16)(RX_BUF_LEN(pBuffer) - headerLength));
1454    }
1455
1456    /* Replace the 802.11 header and the LLC with Ethernet packet. */
1457    dataBuf += lengthDelta;
1458    os_memoryCopy (pRxData->hOs, dataBuf, (void*)&EthHeader, ETHERNET_HDR_LEN);
1459    RX_ETH_PKT_DATA(pBuffer) = dataBuf;
1460    RX_ETH_PKT_LEN(pBuffer)  = RX_BUF_LEN(pBuffer) - lengthDelta;
1461
1462    return TI_OK;
1463}
1464
1465
1466/**
1467 * \brief convert A-MSDU to several ethernet packets
1468 *
1469 * \param hRxData - the object
1470 * \param pBuffer - the received Buffer in A-MSDU 802.11n format
1471 * \param pRxAttr - Rx attributes
1472 * \return TI_OK on success or TI_NOK on failure
1473 *
1474 * \par Description
1475 * Static function
1476 * This function convert the A-MSDU Packet from A-MSDU 802.11n packet
1477 * format to several ethernet packets format and pass them to the OS layer
1478 *
1479 * \sa
1480 */
1481static TI_STATUS rxData_ConvertAmsduToEthPackets (TI_HANDLE hRxData, void *pBuffer, TRxAttr* pRxAttr)
1482{
1483
1484    TEthernetHeader     *pMsduEthHeader;
1485    TEthernetHeader     *pEthHeader;
1486    Wlan_LlcHeader_T    *pWlanSnapHeader;
1487    TI_UINT8            *pAmsduDataBuf;
1488    TI_UINT16            uAmsduDataLen;
1489    void                *pDataBuf;
1490    TI_UINT16            uDataLen;
1491    TI_UINT32            lengthDelta;
1492    TI_UINT16            swapedTypeLength;
1493    TI_UINT32            headerLength;
1494    rxDataPacketType_e   DataPacketType;
1495    rxData_t            *pRxData = (rxData_t *)hRxData;
1496
1497    /* total AMPDU header */
1498    pAmsduDataBuf = (TI_UINT8 *)RX_BUF_DATA(pBuffer);
1499    /* Setting the mac header len according to the received FrameControl field in the Mac Header */
1500    GET_MAX_HEADER_SIZE (pAmsduDataBuf, &headerLength);
1501
1502    /*
1503     * init loop setting
1504     */
1505    /* total AMPDU size */
1506    uAmsduDataLen = (TI_UINT16)(RX_BUF_LEN(pBuffer) - headerLength);
1507    /* ETH header */
1508    pMsduEthHeader = (TEthernetHeader *)(pAmsduDataBuf + headerLength);
1509    /* ETH length, in A-MSDU the MSDU header type contain the MSDU length and not the type */
1510    uDataLen = WLANTOHS(pMsduEthHeader->type);
1511
1512    TRACE1(pRxData->hReport, REPORT_SEVERITY_INFORMATION, "rxData_ConvertAmsduToEthPackets(): A-MSDU received in length %d \n",uAmsduDataLen);
1513
1514    /* if we have another packet at the AMSDU */
1515    while((uDataLen < uAmsduDataLen) && (uAmsduDataLen > ETHERNET_HDR_LEN + FCS_SIZE))
1516    {
1517        /* allocate a new buffer */
1518        /* RxBufAlloc() add an extra word for alignment the MAC payload */
1519        rxData_RequestForBuffer (hRxData, &pDataBuf, sizeof(RxIfDescriptor_t) + WLAN_SNAP_HDR_LEN + ETHERNET_HDR_LEN + uDataLen, 0, TAG_CLASS_AMSDU);
1520        if (NULL == pDataBuf)
1521        {
1522            TRACE1(pRxData->hReport, REPORT_SEVERITY_ERROR, "rxData_ConvertAmsduToEthPackets(): cannot alloc MSDU packet. length %d \n",uDataLen);
1523            rxData_discardPacket (hRxData, pBuffer, pRxAttr);
1524            return TI_NOK;
1525        }
1526
1527        /* read packet type from LLC */
1528        pWlanSnapHeader = (Wlan_LlcHeader_T*)((TI_UINT8*)pMsduEthHeader + ETHERNET_HDR_LEN);
1529        swapedTypeLength = WLANTOHS (pWlanSnapHeader->Type);
1530
1531        /* copy the RxIfDescriptor */
1532        os_memoryCopy (pRxData->hOs, pDataBuf, pBuffer, sizeof(RxIfDescriptor_t));
1533
1534        /* update length, in the RxIfDescriptor the Len in words (4B) */
1535        ((RxIfDescriptor_t *)pDataBuf)->length = (sizeof(RxIfDescriptor_t) + WLAN_SNAP_HDR_LEN + ETHERNET_HDR_LEN + uDataLen) >> 2;
1536        ((RxIfDescriptor_t *)pDataBuf)->extraBytes = 4 - ((sizeof(RxIfDescriptor_t) + WLAN_SNAP_HDR_LEN + ETHERNET_HDR_LEN + uDataLen) & 0x3);
1537
1538        /* Prepare the Ethernet header pointer. */
1539        /* add padding in the start of the buffer in order to align ETH payload */
1540        pEthHeader = (TEthernetHeader *)((TI_UINT8 *)(RX_BUF_DATA(pDataBuf)) +
1541                                         WLAN_SNAP_HDR_LEN +
1542                                         PADDING_ETH_PACKET_SIZE);
1543
1544        /* copy the Ethernet header */
1545        os_memoryCopy (pRxData->hOs, pEthHeader, pMsduEthHeader, ETHERNET_HDR_LEN);
1546
1547        /* The LEN/TYPE bytes are set to TYPE */
1548        pEthHeader->type = pWlanSnapHeader->Type;
1549
1550        /* Delta length for the next packet */
1551        lengthDelta = ETHERNET_HDR_LEN + uDataLen;
1552
1553        /* copy the packet payload */
1554        if (uDataLen > WLAN_SNAP_HDR_LEN)
1555            os_memoryCopy (pRxData->hOs,
1556                       (((TI_UINT8*)pEthHeader) + ETHERNET_HDR_LEN),
1557                       ((TI_UINT8*)pMsduEthHeader) + ETHERNET_HDR_LEN + WLAN_SNAP_HDR_LEN,
1558                       uDataLen - WLAN_SNAP_HDR_LEN);
1559
1560        /* set the packet type */
1561        if (swapedTypeLength == ETHERTYPE_802_1D)
1562        {
1563            TRACE0(pRxData->hReport, REPORT_SEVERITY_INFORMATION, " rxData_ConvertAmsduToEthPackets() : Received VLAN Buffer  \n");
1564
1565            DataPacketType = DATA_VLAN_PACKET;
1566        }
1567        else if (HTOWLANS(pEthHeader->type) == EAPOL_PACKET)
1568        {
1569            TRACE0(pRxData->hReport, REPORT_SEVERITY_INFORMATION, " rxData_ConvertAmsduToEthPackets() : Received Eapol pBuffer  \n");
1570
1571            DataPacketType = DATA_EAPOL_PACKET;
1572        }
1573        else
1574        {
1575            TRACE0(pRxData->hReport, REPORT_SEVERITY_INFORMATION, " rxData_ConvertAmsduToEthPackets() : Received Data pBuffer  \n");
1576
1577            DataPacketType = DATA_DATA_PACKET;
1578        }
1579
1580        /* update buffer setting */
1581        /* save the ETH packet address */
1582        RX_ETH_PKT_DATA(pDataBuf) = pEthHeader;
1583        /* save the ETH packet size */
1584        RX_ETH_PKT_LEN(pDataBuf) = uDataLen + ETHERNET_HDR_LEN - WLAN_SNAP_HDR_LEN;
1585
1586        /* star of MSDU packet always align acceding to 11n spec */
1587        lengthDelta = (lengthDelta + ALIGN_4BYTE_MASK) & ~ALIGN_4BYTE_MASK;
1588        pMsduEthHeader = (TEthernetHeader *)(((TI_UINT8*)pMsduEthHeader) + lengthDelta);
1589
1590        if(uAmsduDataLen > lengthDelta)
1591        {
1592            /* swich to the next MSDU */
1593            uAmsduDataLen = uAmsduDataLen - lengthDelta;
1594
1595            /* Clear the EndOfBurst flag for all packets except the last one */
1596            ((RxIfDescriptor_t *)pDataBuf)->driverFlags &= ~DRV_RX_FLAG_END_OF_BURST;
1597        }
1598        else
1599        {
1600            /* no more MSDU */
1601            uAmsduDataLen = 0;
1602        }
1603
1604
1605        /* in A-MSDU the MSDU header type contain the MSDU length and not the type */
1606        uDataLen = WLANTOHS(pMsduEthHeader->type);
1607
1608
1609        /* dispatch Buffer according to packet type and current rx data port status */
1610        pRxData->rxData_dispatchBuffer[pRxData->rxDataPortStatus][DataPacketType] (hRxData, pDataBuf, pRxAttr);
1611
1612    } /* while end */
1613
1614
1615    TRACE0(pRxData->hReport, REPORT_SEVERITY_INFORMATION, "rxData_ConvertAmsduToEthPackets(): A-MSDU Packe conversion done.\n");
1616
1617    /* free the A-MSDU packet */
1618    RxBufFree(pRxData->hOs, pBuffer);
1619
1620    return TI_OK;
1621}
1622
1623/****************************************************************************************
1624 *                        rxData_ReceivePacket                                              *
1625 ****************************************************************************************
1626DESCRIPTION:    receive packet CB from RxXfer.
1627                parse the status and other parameters and forward the frame to
1628                rxData_receivePacketFromWlan()
1629
1630INPUT:          Rx frame with its parameters
1631
1632OUTPUT:
1633
1634RETURN:
1635
1636************************************************************************/
1637static void rxData_ReceivePacket (TI_HANDLE   hRxData,
1638                                  void  *pBuffer)
1639{
1640    rxData_t            *pRxData    = (rxData_t *)hRxData;
1641
1642    TRACE1(pRxData->hReport, REPORT_SEVERITY_INFORMATION, "rxData_ReceivePacket: Received BUF %x\n", pBuffer);
1643
1644    if (pBuffer)
1645    {
1646        RxIfDescriptor_t    *pRxParams  = (RxIfDescriptor_t*)pBuffer;
1647        TRxAttr             RxAttr;
1648        ERate               appRate;
1649        dot11_header_t      *pHdr;
1650
1651        /*
1652         * First thing we do is getting the dot11_header, and than we check the status, since the header is
1653         * needed for RX_MIC_FAILURE_ERROR
1654         */
1655
1656        pHdr = (dot11_header_t *)RX_BUF_DATA(pBuffer);
1657
1658        /* Check status */
1659        switch (pRxParams->status & RX_DESC_STATUS_MASK)
1660        {
1661            case RX_DESC_STATUS_SUCCESS:
1662                break;
1663
1664            case RX_DESC_STATUS_DECRYPT_FAIL:
1665            {
1666                /* This error is not important before the Connection, so we ignore it when portStatus is not OPEN */
1667                if (pRxData->rxDataPortStatus == OPEN)
1668                {
1669                    TRACE0(pRxData->hReport, REPORT_SEVERITY_WARNING, "rxData_ReceivePacket: Received Packet with RX_DESC_DECRYPT_FAIL\n");
1670                }
1671
1672                RxBufFree(pRxData->hOs, pBuffer);
1673                return;
1674            }
1675            case RX_DESC_STATUS_MIC_FAIL:
1676            {
1677                TI_UINT8 uKeyType;
1678                paramInfo_t Param;
1679                TMacAddr* pMac = &pHdr->address1; /* hold the first mac address */
1680                /* Get BSS type */
1681                Param.paramType = SITE_MGR_CURRENT_BSS_TYPE_PARAM;
1682                siteMgr_getParam (pRxData->hSiteMgr, &Param);
1683
1684                /* For multicast/broadcast frames or in IBSS the key used is GROUP, else - it's Pairwise */
1685                if (MAC_MULTICAST(*pMac) || Param.content.siteMgrCurrentBSSType == BSS_INDEPENDENT)
1686                {
1687                    uKeyType = (TI_UINT8)KEY_TKIP_MIC_GROUP;
1688	                TRACE0(pRxData->hReport, REPORT_SEVERITY_ERROR, "rxData_ReceivePacket: Received Packet MIC failure. Type = Group\n");
1689                }
1690                /* Unicast on infrastructure */
1691                else
1692                {
1693                    uKeyType = (TI_UINT8)KEY_TKIP_MIC_PAIRWISE;
1694	                TRACE0(pRxData->hReport, REPORT_SEVERITY_ERROR, "rxData_ReceivePacket: Received Packet MIC failure. Type = Pairwise\n");
1695                }
1696
1697
1698                rsn_reportMicFailure (pRxData->hRsn, &uKeyType, sizeof(uKeyType));
1699                RxBufFree(pRxData->hOs, pBuffer);
1700                return;
1701            }
1702
1703            case RX_DESC_STATUS_DRIVER_RX_Q_FAIL:
1704            {
1705                /* Rx queue error - free packet and return */
1706                TRACE0(pRxData->hReport, REPORT_SEVERITY_ERROR, "rxData_ReceivePacket: Received Packet with Rx queue error \n");
1707
1708                RxBufFree(pRxData->hOs, pBuffer);
1709                return;
1710            }
1711
1712            default:
1713                    /* Unknown error - free packet and return */
1714                    TRACE1(pRxData->hReport, REPORT_SEVERITY_ERROR, "rxData_ReceivePacket: Received Packet with unknown status = %d\n", (pRxParams->status & RX_DESC_STATUS_MASK));
1715
1716                    RxBufFree(pRxData->hOs, pBuffer);
1717                    return;
1718            }
1719
1720        TRACE0(pRxData->hReport, REPORT_SEVERITY_INFORMATION , "Receive good Packet\n");
1721
1722        if (rate_PolicyToDrv ((ETxRateClassId)(pRxParams->rate), &appRate) != TI_OK)
1723        {
1724            TRACE1(pRxData->hReport, REPORT_SEVERITY_ERROR , "rxData_ReceivePacket: can't convert hwRate=0x%x\n", pRxParams->rate);
1725        }
1726
1727        /*
1728         * Set rx attributes
1729         */
1730        RxAttr.channel    = pRxParams->channel;
1731        RxAttr.packetInfo = pRxParams->flags;
1732        RxAttr.ePacketType= pRxParams->packet_class_tag;
1733        RxAttr.Rate       = appRate;
1734        RxAttr.Rssi       = pRxParams->rx_level;
1735        RxAttr.SNR        = pRxParams->rx_snr;
1736        RxAttr.status     = pRxParams->status & RX_DESC_STATUS_MASK;
1737        /* for now J band not implemented */
1738        RxAttr.band       = ((pRxParams->flags & RX_DESC_BAND_MASK) == RX_DESC_BAND_A) ?
1739                            RADIO_BAND_5_0_GHZ : RADIO_BAND_2_4_GHZ ;
1740        RxAttr.eScanTag   = (EScanResultTag)(pRxParams->proccess_id_tag);
1741        /* timestamp is 32 bit so do bytes copy to avoid exception in case the RxInfo is in 2 bytes offset */
1742        os_memoryCopy (pRxData->hOs,
1743                       (void *)&(RxAttr.TimeStamp),
1744                       (void *)&(pRxParams->timestamp),
1745                       sizeof(pRxParams->timestamp) );
1746        RxAttr.TimeStamp = ENDIAN_HANDLE_LONG(RxAttr.TimeStamp);
1747
1748        TRACE8(pRxData->hReport, REPORT_SEVERITY_INFORMATION, "rxData_ReceivePacket: channel=%d, info=0x%x, type=%d, rate=0x%x, RSSI=%d, SNR=%d, status=%d, scan tag=%d\n", RxAttr.channel, RxAttr.packetInfo, RxAttr.ePacketType, RxAttr.Rate, RxAttr.Rssi, RxAttr.SNR, RxAttr.status, RxAttr.eScanTag);
1749
1750        rxData_receivePacketFromWlan (hRxData, pBuffer, &RxAttr);
1751
1752        /*
1753         *  Buffer MUST be freed until now
1754         */
1755    }
1756    else
1757    {
1758        TRACE0(pRxData->hReport, REPORT_SEVERITY_ERROR , "rxData_ReceivePacket: null Buffer received");
1759    }
1760}
1761
1762
1763/****************************************************************************************
1764 *                        rxData_RequestForBuffer                                              *
1765 ****************************************************************************************
1766DESCRIPTION:     RX request for buffer
1767                uEncryptionflag API are for GWSI use.
1768INPUT:
1769
1770OUTPUT:
1771
1772RETURN:
1773
1774************************************************************************/
1775static ERxBufferStatus rxData_RequestForBuffer (TI_HANDLE   hRxData,
1776                                      void **pBuf,
1777                                      TI_UINT16 aLength,
1778                                      TI_UINT32 uEncryptionflag,
1779                                      PacketClassTag_e ePacketClassTag)
1780{
1781    rxData_t *pRxData = (rxData_t *)hRxData;
1782
1783    TRACE1(pRxData->hReport, REPORT_SEVERITY_INFORMATION , " RequestForBuffer, length = %d \n",aLength);
1784
1785    *pBuf = RxBufAlloc (pRxData->hOs, aLength, ePacketClassTag);
1786
1787    if (*pBuf)
1788    {
1789        return RX_BUF_ALLOC_COMPLETE;
1790    }
1791    else
1792    {
1793        return RX_BUF_ALLOC_OUT_OF_MEM;
1794    }
1795}
1796
1797
1798/*******************************************************************
1799*                        DEBUG FUNCTIONS                           *
1800*******************************************************************/
1801
1802#ifdef TI_DBG
1803
1804/***************************************************************************
1805*                        rxData_resetCounters                              *
1806****************************************************************************
1807* DESCRIPTION:  This function reset the Rx Data module counters
1808*
1809* INPUTS:       hRxData - the object
1810*
1811* OUTPUT:
1812*
1813* RETURNS:      void
1814***************************************************************************/
1815void rxData_resetCounters(TI_HANDLE hRxData)
1816{
1817    rxData_t *pRxData = (rxData_t *)hRxData;
1818
1819    os_memoryZero(pRxData->hOs, &pRxData->rxDataCounters, sizeof(rxDataCounters_t));
1820}
1821
1822/***************************************************************************
1823*                        rxData_resetDbgCounters                           *
1824****************************************************************************
1825* DESCRIPTION:  This function reset the Rx Data module debug counters
1826*
1827* INPUTS:       hRxData - the object
1828*
1829* OUTPUT:
1830*
1831* RETURNS:      void
1832***************************************************************************/
1833
1834void rxData_resetDbgCounters(TI_HANDLE hRxData)
1835{
1836    rxData_t *pRxData = (rxData_t *)hRxData;
1837
1838    os_memoryZero(pRxData->hOs, &pRxData->rxDataDbgCounters, sizeof(rxDataDbgCounters_t));
1839}
1840
1841
1842/***************************************************************************
1843*                            test functions                                *
1844***************************************************************************/
1845void rxData_printRxCounters (TI_HANDLE hRxData)
1846{
1847#ifdef REPORT_LOG
1848    rxData_t *pRxData = (rxData_t *)hRxData;
1849
1850    if (pRxData)
1851    {
1852        WLAN_OS_REPORT(("RecvOk = %d\n", pRxData->rxDataCounters.RecvOk));
1853        WLAN_OS_REPORT(("DirectedBytesRecv = %d\n", pRxData->rxDataCounters.DirectedBytesRecv));
1854        WLAN_OS_REPORT(("DirectedFramesRecv = %d\n", pRxData->rxDataCounters.DirectedFramesRecv));
1855        WLAN_OS_REPORT(("MulticastBytesRecv = %d\n", pRxData->rxDataCounters.MulticastBytesRecv));
1856        WLAN_OS_REPORT(("MulticastFramesRecv = %d\n", pRxData->rxDataCounters.MulticastFramesRecv));
1857        WLAN_OS_REPORT(("BroadcastBytesRecv = %d\n", pRxData->rxDataCounters.BroadcastBytesRecv));
1858        WLAN_OS_REPORT(("BroadcastFramesRecv = %d\n", pRxData->rxDataCounters.BroadcastFramesRecv));
1859
1860        /* debug counters */
1861        WLAN_OS_REPORT(("excludedFrameCounter = %d\n", pRxData->rxDataDbgCounters.excludedFrameCounter));
1862        WLAN_OS_REPORT(("rxDroppedDueToVLANIncludedCnt = %d\n", pRxData->rxDataDbgCounters.rxDroppedDueToVLANIncludedCnt));
1863        WLAN_OS_REPORT(("rxWrongBssTypeCounter = %d\n", pRxData->rxDataDbgCounters.rxWrongBssTypeCounter));
1864        WLAN_OS_REPORT(("rxWrongBssIdCounter = %d\n", pRxData->rxDataDbgCounters.rxWrongBssIdCounter));
1865        WLAN_OS_REPORT(("rcvUnicastFrameInOpenNotify = %d\n", pRxData->rxDataDbgCounters.rcvUnicastFrameInOpenNotify));
1866    }
1867#endif
1868}
1869
1870
1871void rxData_printRxBlock(TI_HANDLE hRxData)
1872{
1873#ifdef REPORT_LOG
1874    rxData_t *pRxData = (rxData_t *)hRxData;
1875
1876    WLAN_OS_REPORT(("hCtrlData = 0x%X\n", pRxData->hCtrlData));
1877    WLAN_OS_REPORT(("hMlme = 0x%X\n", pRxData->hMlme));
1878    WLAN_OS_REPORT(("hOs = 0x%X\n", pRxData->hOs));
1879    WLAN_OS_REPORT(("hReport = 0x%X\n", pRxData->hReport));
1880    WLAN_OS_REPORT(("hRsn = 0x%X\n", pRxData->hRsn));
1881    WLAN_OS_REPORT(("hSiteMgr = 0x%X\n", pRxData->hSiteMgr));
1882
1883    WLAN_OS_REPORT(("hCtrlData = 0x%X\n", pRxData->hCtrlData));
1884    WLAN_OS_REPORT(("hMlme = 0x%X\n", pRxData->hMlme));
1885    WLAN_OS_REPORT(("hOs = 0x%X\n", pRxData->hOs));
1886    WLAN_OS_REPORT(("hReport = 0x%X\n", pRxData->hReport));
1887    WLAN_OS_REPORT(("hRsn = 0x%X\n", pRxData->hRsn));
1888    WLAN_OS_REPORT(("hSiteMgr = 0x%X\n", pRxData->hSiteMgr));
1889
1890    WLAN_OS_REPORT(("rxDataPortStatus = %d\n", pRxData->rxDataPortStatus));
1891    WLAN_OS_REPORT(("rxDataExcludeUnencrypted = %d\n", pRxData->rxDataExcludeUnencrypted));
1892    WLAN_OS_REPORT(("rxDataEapolDestination = %d\n", pRxData->rxDataEapolDestination));
1893#endif
1894}
1895
1896
1897void rxData_startRxThroughputTimer (TI_HANDLE hRxData)
1898{
1899    rxData_t *pRxData = (rxData_t *)hRxData;
1900
1901    if (!pRxData->rxThroughputTimerEnable)
1902    {
1903        /* reset throughput counter */
1904        pRxData->rxDataCounters.LastSecBytesRecv = 0;
1905        pRxData->rxThroughputTimerEnable = TI_TRUE;
1906
1907        /* start 1 sec throughput timer */
1908        tmr_StartTimer (pRxData->hThroughputTimer,
1909                        rxData_printRxThroughput,
1910                        (TI_HANDLE)pRxData,
1911                        1000,
1912                        TI_TRUE);
1913    }
1914}
1915
1916
1917void rxData_stopRxThroughputTimer (TI_HANDLE hRxData)
1918{
1919
1920    rxData_t *pRxData = (rxData_t *)hRxData;
1921
1922    if (pRxData->rxThroughputTimerEnable)
1923    {
1924        tmr_StopTimer (pRxData->hThroughputTimer);
1925        pRxData->rxThroughputTimerEnable = TI_FALSE;
1926    }
1927}
1928
1929
1930static void rxData_printRxThroughput (TI_HANDLE hRxData, TI_BOOL bTwdInitOccured)
1931{
1932    rxData_t *pRxData = (rxData_t *)hRxData;
1933
1934    WLAN_OS_REPORT (("\n"));
1935    WLAN_OS_REPORT (("-------------- Rx Throughput Statistics ---------------\n"));
1936    WLAN_OS_REPORT (("Throughput = %d KBits/sec\n", pRxData->rxDataCounters.LastSecBytesRecv * 8 / 1024));
1937
1938    /* reset throughput counter */
1939    pRxData->rxDataCounters.LastSecBytesRecv = 0;
1940}
1941
1942void rxData_printRxDataFilter (TI_HANDLE hRxData)
1943{
1944    TI_UINT32 index;
1945    rxData_t *pRxData = (rxData_t *)hRxData;
1946
1947    for (index=0; index<MAX_DATA_FILTERS; index++)
1948     {
1949        if (pRxData->isFilterSet[index])
1950        {
1951            WLAN_OS_REPORT (("index=%d, pattern & mask\n", index));
1952            report_PrintDump(pRxData->filterRequests[index].pattern, pRxData->filterRequests[index].patternLength);
1953            report_PrintDump(pRxData->filterRequests[index].mask, pRxData->filterRequests[index].maskLength);
1954        }
1955        else
1956        {
1957            WLAN_OS_REPORT (("No Filter defined for index-%d\n", index));
1958        }
1959     }
1960}
1961
1962#endif /*TI_DBG*/
1963
1964/****************************************************************************
1965 *                      rxData_SetReAuthInProgress()
1966 ****************************************************************************
1967 * DESCRIPTION:	Sets the ReAuth flag value
1968 *
1969 * INPUTS: hRxData - the object
1970 *		   value - value to set the flag to
1971 *
1972 * OUTPUT:	None
1973 *
1974 * RETURNS:	OK or NOK
1975 ****************************************************************************/
1976void rxData_SetReAuthInProgress(TI_HANDLE hRxData, TI_BOOL	value)
1977{
1978	rxData_t *pRxData = (rxData_t *)hRxData;
1979
1980	TRACE1(pRxData->hReport, REPORT_SEVERITY_INFORMATION , "Set ReAuth flag to %d\n", value);
1981
1982	pRxData->reAuthInProgress = value;
1983}
1984
1985/****************************************************************************
1986 *                      rxData_IsReAuthInProgress()
1987 ****************************************************************************
1988 * DESCRIPTION:	Returns the ReAuth flag value
1989 *
1990 * INPUTS: hRxData - the object
1991 *
1992 * OUTPUT:	None
1993 *
1994 * RETURNS:	ReAuth flag value
1995 ****************************************************************************/
1996TI_BOOL rxData_IsReAuthInProgress(TI_HANDLE hRxData)
1997{
1998	rxData_t *pRxData = (rxData_t *)hRxData;
1999	return pRxData->reAuthInProgress;
2000}
2001
2002/****************************************************************************
2003*						rxData_StartReAuthActiveTimer   	                *
2004*****************************************************************************
2005* DESCRIPTION:	this function starts the ReAuthActive timer
2006*
2007* INPUTS:		hRxData - the object
2008*
2009* OUTPUT:		None
2010*
2011* RETURNS:		None
2012***************************************************************************/
2013static void rxData_StartReAuthActiveTimer(TI_HANDLE hRxData)
2014{
2015	rxData_t *pRxData = (rxData_t *)hRxData;
2016    TRACE0(pRxData->hReport, REPORT_SEVERITY_INFORMATION , "Start ReAuth Active Timer\n");
2017    tmr_StartTimer (pRxData->reAuthActiveTimer,
2018                    reAuthTimeout,
2019                    (TI_HANDLE)pRxData,
2020                    pRxData->reAuthActiveTimeout,
2021                    TI_FALSE);
2022}
2023
2024/****************************************************************************
2025*						rxData_StopReAuthActiveTimer   						*
2026*****************************************************************************
2027* DESCRIPTION:	this function stops the ReAuthActive timer
2028*
2029* INPUTS:		hRxData - the object
2030*
2031* OUTPUT:		None
2032*
2033* RETURNS:		None
2034***************************************************************************/
2035void rxData_StopReAuthActiveTimer(TI_HANDLE hRxData)
2036{
2037	rxData_t *pRxData = (rxData_t *)hRxData;
2038    TRACE0(pRxData->hReport, REPORT_SEVERITY_INFORMATION , "Stop ReAuth Active Timer\n");
2039    tmr_StopTimer (pRxData->reAuthActiveTimer);
2040}
2041
2042/****************************************************************************
2043*						reAuthTimeout   									*
2044*****************************************************************************
2045* DESCRIPTION:	this function ia called when the ReAuthActive timer elapses
2046*				It resets the Reauth flag and restore the PS state.
2047*				It also sends RE_AUTH_TERMINATED event to upper layer.
2048*
2049* INPUTS:		hRxData - the object
2050*
2051* OUTPUT:		None
2052*
2053* RETURNS:		None
2054***************************************************************************/
2055static void reAuthTimeout(TI_HANDLE hRxData, TI_BOOL bTwdInitOccured)
2056{
2057	rxData_t *pRxData = (rxData_t *)hRxData;
2058
2059    TRACE0(pRxData->hReport, REPORT_SEVERITY_INFORMATION , "ReAuth Active Timeout\n");
2060	rxData_SetReAuthInProgress(pRxData, TI_FALSE);
2061	rxData_ReauthDisablePriority(pRxData);
2062    EvHandlerSendEvent(pRxData->hEvHandler, IPC_EVENT_RE_AUTH_TERMINATED, NULL, 0);
2063}
2064
2065void rxData_ReauthEnablePriority(TI_HANDLE hRxData)
2066{
2067	rxData_t *pRxData = (rxData_t *)hRxData;
2068	paramInfo_t param;
2069
2070    param.paramType = POWER_MGR_ENABLE_PRIORITY;
2071    param.content.powerMngPriority = POWER_MANAGER_REAUTH_PRIORITY;
2072    powerMgr_setParam(pRxData->hPowerMgr,&param);
2073}
2074
2075void rxData_ReauthDisablePriority(TI_HANDLE hRxData)
2076{
2077	rxData_t *pRxData = (rxData_t *)hRxData;
2078    paramInfo_t param;
2079
2080    param.paramType = POWER_MGR_DISABLE_PRIORITY;
2081    param.content.powerMngPriority = POWER_MANAGER_REAUTH_PRIORITY;
2082    powerMgr_setParam(pRxData->hPowerMgr,&param);
2083}
2084