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