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 */ 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 ************************************************************************/ 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 ***************************************************************************/ 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 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 239 TI_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 ***************************************************************************/ 304 TI_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 ***************************************************************************/ 348 TI_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 ***************************************************************************/ 395 TI_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 ***************************************************************************/ 462 TI_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 ***************************************************************************/ 532 static 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 ***************************************************************************/ 563 static 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 ***************************************************************************/ 601 static 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 ***************************************************************************/ 642 static 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 ***************************************************************************/ 768 static 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 ***************************************************************************/ 840 static 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 ***************************************************************************/ 882 static 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 ****************************************************************************/ 890 TI_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 ****************************************************************************/ 903 TI_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 ****************************************************************************/ 917 TI_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 ***************************************************************************/ 942 void 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 1010 static 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, ðerType); 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 ***************************************************************************/ 1122 static 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 ***************************************************************************/ 1148 static 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 ***************************************************************************/ 1175 static 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 ***************************************************************************/ 1202 static 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 ***************************************************************************/ 1229 static 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 1339 static 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 ***************************************************************************/ 1371 static 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 */ 1481 static 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 **************************************************************************************** 1626 DESCRIPTION: receive packet CB from RxXfer. 1627 parse the status and other parameters and forward the frame to 1628 rxData_receivePacketFromWlan() 1629 1630 INPUT: Rx frame with its parameters 1631 1632 OUTPUT: 1633 1634 RETURN: 1635 1636 ************************************************************************/ 1637 static 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 **************************************************************************************** 1766 DESCRIPTION: RX request for buffer 1767 uEncryptionflag API are for GWSI use. 1768 INPUT: 1769 1770 OUTPUT: 1771 1772 RETURN: 1773 1774 ************************************************************************/ 1775 static 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 ***************************************************************************/ 1815 void 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 1834 void 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 ***************************************************************************/ 1845 void 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 1871 void 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 1897 void 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 1917 void 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 1930 static 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 1942 void 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 ****************************************************************************/ 1976 void 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 ****************************************************************************/ 1996 TI_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 ***************************************************************************/ 2013 static 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 ***************************************************************************/ 2035 void 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 ***************************************************************************/ 2055 static 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 2065 void 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,¶m); 2073 } 2074 2075 void 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,¶m); 2083 } 2084