1 /**************************************************************************** 2 **+-----------------------------------------------------------------------+** 3 **| |** 4 **| Copyright(c) 1998 - 2008 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 /**************************************************************************** 37 * 38 * MODULE: rxXfer.c 39 * 40 * PURPOSE: Rx Xfer module implementation.Responsible for reading Rx from the FW 41 * and forward it to the upper layers. 42 * 43 ****************************************************************************/ 44 45 #include "RxXfer.h" 46 #include "utils.h" 47 #include "report.h" 48 #include "shmUtils.h" 49 #include "FwEvent_api.h" 50 #include "tnetwCommon.h" 51 #include "whalBus_Defs.h" 52 53 #define PLCP_HEADER_LENGTH 8 54 55 /************************ static function declaration *****************************/ 56 57 static void rxXfer_StateMachine (TI_HANDLE hRxXfer, UINT8 module_id, TI_STATUS status); 58 static TI_STATUS rxXfer_ReadHeader (RxXfer_t *pRxXfer); 59 static TI_STATUS rxXfer_ReadBody (RxXfer_t *pRxXfer); 60 static void rxXfer_ForwardCB (RxXfer_t *pRxXfer); 61 static TI_STATUS rxXfer_AckRx (RxXfer_t *pRxXfer); 62 static void rxXfer_ConvertDescFlagsToAppFlags (UINT16 descRxFlags, UINT32 *aFlags, TI_STATUS *pPacketStatus); 63 64 65 /**************************************************************************** 66 * RxXfer_Create() 67 **************************************************************************** 68 * DESCRIPTION: Create the RxXfer module object 69 * 70 * INPUTS: None 71 * 72 * OUTPUT: None 73 * 74 * RETURNS: The Created object 75 ****************************************************************************/ 76 TI_HANDLE rxXfer_Create (TI_HANDLE hOs) 77 { 78 RxXfer_t *pRxXfer; 79 80 pRxXfer = os_memoryAlloc (hOs, sizeof(RxXfer_t)); 81 if (pRxXfer == NULL) 82 return NULL; 83 84 /* For all the counters */ 85 os_memoryZero (hOs, pRxXfer, sizeof(RxXfer_t)); 86 87 pRxXfer->hOs = hOs; 88 89 return (TI_HANDLE)pRxXfer; 90 } 91 92 93 /**************************************************************************** 94 * RxXfer_Destroy() 95 **************************************************************************** 96 * DESCRIPTION: Destroy the RxXfer module object 97 * 98 * INPUTS: hRxXfer - The object to free 99 * 100 * OUTPUT: None 101 * 102 * RETURNS: 103 ****************************************************************************/ 104 void rxXfer_Destroy (TI_HANDLE hRxXfer) 105 { 106 RxXfer_t *pRxXfer = (RxXfer_t *)hRxXfer; 107 108 if (pRxXfer) 109 { 110 os_memoryFree (pRxXfer->hOs, pRxXfer, sizeof(RxXfer_t)); 111 } 112 } /* RxXfer_Destroy() */ 113 114 115 /**************************************************************************** 116 * RxXfer_Config() 117 **************************************************************************** 118 * DESCRIPTION: Destroy the FwEvent module object 119 * 120 * INPUTS: hRxXfer - FwEvent handle; 121 * 122 * OUTPUT: None 123 * 124 * RETURNS: None 125 ****************************************************************************/ 126 void rxXfer_Config(TI_HANDLE hRxXfer, 127 TI_HANDLE hFwEvent, 128 TI_HANDLE hMemMgr, 129 TI_HANDLE hReport, 130 TI_HANDLE hTNETWIF) 131 { 132 RxXfer_t *pRxXfer = (RxXfer_t *)hRxXfer; 133 134 pRxXfer->hFwEvent = hFwEvent; 135 pRxXfer->hMemMgr = hMemMgr; 136 pRxXfer->hReport = hReport; 137 pRxXfer->hTNETWIF = hTNETWIF; 138 139 pRxXfer->state = RX_XFER_STATE_IDLE; 140 pRxXfer->currBuffer = 0; /* first buffer to read from */ 141 pRxXfer->lastPacketId = 0; 142 143 FwEvent_Enable (pRxXfer->hFwEvent, ACX_INTR_RX0_DATA); 144 FwEvent_Enable (pRxXfer->hFwEvent, ACX_INTR_RX1_DATA); 145 146 #ifdef TI_DBG 147 rxXfer_ClearStats (pRxXfer); 148 #endif 149 } 150 151 152 /**************************************************************************** 153 * rxXfer_Register_CB() 154 **************************************************************************** 155 * DESCRIPTION: Register the function to be called for received Rx 156 * or the function to be called for request for buffer 157 * 158 * INPUTS: hRxXfer - RxXfer handle; 159 * 160 * OUTPUT: None 161 * 162 * RETURNS: None 163 ****************************************************************************/ 164 void rxXfer_Register_CB (TI_HANDLE hRxXfer, tiUINT32 CallBackID, void *CBFunc, TI_HANDLE CBObj) 165 { 166 RxXfer_t* pRxXfer = (RxXfer_t *)hRxXfer; 167 168 WLAN_REPORT_INFORMATION (pRxXfer->hReport, HAL_RX_MODULE_LOG, ("rxXfer_Register_CB (Value = 0x%x)\n", CallBackID)); 169 170 switch(CallBackID) 171 { 172 case HAL_INT_RECEIVE_PACKET: 173 pRxXfer->ReceivePacketCB = (packetReceiveCB_t)CBFunc; 174 pRxXfer->ReceivePacketCB_handle = CBObj; 175 break; 176 177 case HAL_INT_REQUEST_FOR_BUFFER: 178 pRxXfer->RequestForBufferCB = (requestForBufferCB_t)CBFunc; 179 pRxXfer->RequestForBufferCB_handle = CBObj; 180 break; 181 182 default: 183 WLAN_REPORT_ERROR(pRxXfer->hReport, HAL_RX_MODULE_LOG, ("rxXfer_Register_CB - Illegal value\n")); 184 return; 185 } 186 } 187 188 189 /**************************************************************************** 190 * rxXfer_SetDoubleBufferAddr() 191 **************************************************************************** 192 * DESCRIPTION: Store the addresses of the Double Buffer 193 * 194 * INPUTS: hRxXfer - RxXfer handle; 195 * 196 * OUTPUT: None 197 * 198 * RETURNS: None 199 ****************************************************************************/ 200 void rxXfer_SetDoubleBufferAddr (TI_HANDLE hRxXfer, ACXDataPathParamsResp_t *pDataPathParams) 201 { 202 RxXfer_t* pRxXfer = (RxXfer_t *)hRxXfer; 203 204 pRxXfer->doubleBuffer[0] = pDataPathParams->rxPacketRingAddr; 205 pRxXfer->doubleBuffer[1] = pDataPathParams->rxPacketRingAddr + pDataPathParams->rxPacketRingChunkSize; 206 } 207 208 209 /**************************************************************************** 210 * rxXfer_RxEvent() 211 **************************************************************************** 212 * DESCRIPTION: Called upon Rx event from the FW.calls the SM 213 * 214 * INPUTS: hRxXfer - RxXfer handle; 215 * 216 * OUTPUT: None 217 * 218 * RETURNS: TNETWIF_OK in case of Synch mode, or TNETWIF_PENDING in case of Asynch mode 219 * (when returning TNETWIF_PENDING, FwEvent module expects the FwEvent_EventComplete() 220 * function call to finish the Rx Client handling 221 * 222 ****************************************************************************/ 223 TI_STATUS rxXfer_RxEvent (TI_HANDLE hRxXfer) 224 { 225 RxXfer_t* pRxXfer = (RxXfer_t *)hRxXfer; 226 227 if (RX_XFER_STATE_IDLE != pRxXfer->state) 228 { 229 WLAN_REPORT_ERROR(pRxXfer->hReport,HAL_RX_MODULE_LOG, 230 ("rxXfer_RxEvent called in state %d !!!\n",pRxXfer->state)); 231 return TNETWIF_ERROR; 232 } 233 234 WLAN_REPORT_INFORMATION (pRxXfer->hReport, HAL_RX_MODULE_LOG, 235 ("rxXfer_RxEvent Calling rxXfer_StateMachine : currBuffer = %d \n", 236 pRxXfer->currBuffer)); 237 238 #ifdef TI_DBG 239 if (pRxXfer->currBuffer == 0) 240 pRxXfer->DbgStats.numIrq0 ++; 241 else 242 pRxXfer->DbgStats.numIrq1 ++; 243 #endif 244 245 /* Assume that we are in synch bus until otherwise is proven */ 246 pRxXfer->bSync = TRUE; 247 /* The packet status is OK unless we receive error */ 248 pRxXfer->packetStatus = OK; 249 250 rxXfer_StateMachine (hRxXfer, 0, OK); 251 252 return pRxXfer->returnValue; 253 } 254 255 256 /**************************************************************************** 257 * rxXfer_StateMachine() 258 **************************************************************************** 259 * DESCRIPTION: SM for handling Synch & Asynch read of RX from the HW. 260 * The flow of the SM is by that order: 261 * IDLE -> READING_HDR -> READING_PKT -> EXIT 262 * On synch mode - each state is called in the same context in the while loop. 263 * On Asynch mode - each state returns TNETWIF_PENDING and exits the SM.The CB of 264 * each Asynch is the SM, that will continue the Rx handling. 265 * 266 * INPUTS: hRxXfer - RxXfer handle; 267 * 268 * OUTPUT: pRxXfer->returnValue is TNETWIF_OK in synch mode and TNETWIF_PENDING in Asynch mode. 269 * 270 * RETURNS: 271 ****************************************************************************/ 272 static void rxXfer_StateMachine (TI_HANDLE hRxXfer, UINT8 module_id, TI_STATUS status) 273 { 274 RxXfer_t* pRxXfer = (RxXfer_t *)hRxXfer; 275 276 pRxXfer->returnValue = OK; 277 278 /* 279 * This while loop will continue till the exit or when waiting for the CB due to 280 * memory transfer operation pending for DMA to complete 281 */ 282 while (TNETWIF_PENDING != pRxXfer->returnValue) 283 { 284 WLAN_REPORT_DEBUG_RX (pRxXfer->hReport, ("Rx SM: state = %d, rc = %d\n", 285 pRxXfer->state, pRxXfer->returnValue)); 286 287 switch(pRxXfer->state) 288 { 289 case RX_XFER_STATE_IDLE: 290 pRxXfer->state = RX_XFER_STATE_READING_HDR; 291 pRxXfer->returnValue = rxXfer_ReadHeader (pRxXfer); 292 break; 293 294 case RX_XFER_STATE_READING_HDR: 295 pRxXfer->state = RX_XFER_STATE_READING_PKT; 296 pRxXfer->returnValue = rxXfer_ReadBody (pRxXfer); 297 break; 298 299 case RX_XFER_STATE_READING_PKT: 300 pRxXfer->state = RX_XFER_STATE_EXITING; 301 rxXfer_ForwardCB(pRxXfer); 302 pRxXfer->returnValue = rxXfer_AckRx (pRxXfer); 303 break; 304 305 case RX_XFER_STATE_EXITING: 306 pRxXfer->state = RX_XFER_STATE_IDLE; 307 if (FALSE == pRxXfer->bSync) 308 { 309 /* Async bus - call FwEvent for notifying the completion */ 310 FwEvent_EventComplete (pRxXfer->hFwEvent, TNETWIF_OK); 311 } 312 else 313 { 314 /* This is the sync case - we should return TNETWIF_OK */ 315 pRxXfer->returnValue = TNETWIF_OK; 316 } 317 318 return; 319 320 default: 321 WLAN_REPORT_ERROR (pRxXfer->hReport, HAL_RX_MODULE_LOG, 322 ("rxXfer_StateMachine Unknown state = %d\n", 323 pRxXfer->state)); 324 } 325 326 if (TNETWIF_ERROR == pRxXfer->returnValue) 327 { 328 WLAN_REPORT_ERROR (pRxXfer->hReport, HAL_RX_MODULE_LOG, 329 ("rxXfer_StateMachine returning TNETWIF_ERROR in state %d. Next packet will be discarded!!!\n",pRxXfer->state)); 330 331 /* Next packet will be marked as NOK and will be discarded */ 332 pRxXfer->packetStatus = NOK; 333 } 334 } 335 336 /* If we are here - we got TNETWIF_PENDING, so we are in Async mode */ 337 pRxXfer->bSync = FALSE; 338 } 339 340 341 /**************************************************************************** 342 * rxXfer_ReadHeader() 343 **************************************************************************** 344 * DESCRIPTION: Read the packet header (descriptor) 345 * 346 * INPUTS: pRxXfer - RxXfer handle; 347 * 348 * OUTPUT: 349 * 350 * RETURNS: TNETWIF_OK in synch mode and TNETWIF_PENDING in Asynch mode. 351 ****************************************************************************/ 352 TI_STATUS rxXfer_ReadHeader(RxXfer_t *pRxXfer) 353 { 354 WLAN_REPORT_DEBUG_RX(pRxXfer->hReport, 355 ("rxXfer_readHeader: Before Read Memory Addr from DB No %d Addr %x !!!! \n",pRxXfer->currBuffer,pRxXfer->doubleBuffer[pRxXfer->currBuffer])); 356 357 return TNETWIF_ReadMemOpt (pRxXfer->hTNETWIF, 358 pRxXfer->doubleBuffer[pRxXfer->currBuffer], 359 PADREAD (&pRxXfer->rxDescriptor), 360 RX_DESCRIPTOR_SIZE, 361 FW_EVENT_MODULE_ID, 362 rxXfer_StateMachine, 363 (TI_HANDLE)pRxXfer); 364 } 365 366 367 /**************************************************************************** 368 * rxXfer_ReadBody() 369 **************************************************************************** 370 * DESCRIPTION: Read the packet body 371 * 372 * INPUTS: pRxXfer - RxXfer handle; 373 * 374 * OUTPUT: 375 * 376 * RETURNS: TNETWIF_OK in synch mode and TNETWIF_PENDING in Asynch mode. 377 ****************************************************************************/ 378 TI_STATUS rxXfer_ReadBody (RxXfer_t *pRxXfer) 379 { 380 UINT32 uCurrPacketId; /* Current packet ID */ 381 UINT32 uLastPacketIdIncremented; /* The last received packet-ID incremented with modulo */ 382 UINT32 uAlignToWord; /* Used to align the length of the packet to a WORD */ 383 384 /* Check for correct length of Rx Descriptor */ 385 if (pRxXfer->rxDescriptor.length <= PLCP_HEADER_LENGTH || 386 pRxXfer->rxDescriptor.length > (MAX_DATA_BODY_LENGTH + PLCP_HEADER_LENGTH)) 387 { 388 WLAN_REPORT_ERROR (pRxXfer->hReport, HAL_RX_MODULE_LOG, 389 ("rxXfer_ReadBody: RxLength not correct! rxDescriptor.length=%d\n", 390 pRxXfer->rxDescriptor.length)); 391 return TNETWIF_ERROR; 392 } 393 394 pRxXfer->rxDescriptor.length = pRxXfer->rxDescriptor.length - PLCP_HEADER_LENGTH; 395 396 uCurrPacketId = (pRxXfer->rxDescriptor.flags & RX_DESC_SEQNUM_MASK) >> RX_DESC_PACKETID_SHIFT; 397 398 uLastPacketIdIncremented = (pRxXfer->lastPacketId + 1) % (RX_MAX_PACKET_ID + 1); 399 400 if (uCurrPacketId == uLastPacketIdIncremented) 401 { 402 pRxXfer->lastPacketId = uLastPacketIdIncremented; 403 404 #ifdef GWSI_RECORDING 405 WLAN_REPORT_GWSI_RECORDING(pRxXfer->hReport, ("GWSI Recording, rxXfer_ReadBody (request for buffer), Length = 0x%x\n", pRxXfer->rxDescriptor.length)); 406 #endif /* GWSI_RECORDING */ 407 } 408 else 409 { 410 WLAN_REPORT_ERROR (pRxXfer->hReport, HAL_RX_MODULE_LOG, 411 ("rxXfer_ReadBody: Packet ID mismatch! CurrPacketId=%d, lastPacketId=%d\n", 412 uCurrPacketId, pRxXfer->lastPacketId)); 413 #ifdef TI_DBG 414 pRxXfer->DbgStats.numPacketsDroppedPacketIDMismatch++; 415 rxXfer_PrintStats ((TI_HANDLE)pRxXfer); 416 #endif 417 /* Reset the lastPacketId to be synchronized on the Current Packet ID read from the FW */ 418 pRxXfer->lastPacketId = uCurrPacketId; 419 } 420 421 /* 422 * Add uAlignToWord to the body length since we have to read buffers from the FW in 4 bytes chunks. 423 * NOTE: The size of the buffer is aligned to 4, but the packet itself is not. 424 * Releasing the memory must be done with the actual size allocated and not the size of the packet 425 */ 426 uAlignToWord = 4 - (pRxXfer->rxDescriptor.length & 0x3); /* (&0x3) is equal to (% 4) */ 427 uAlignToWord = (uAlignToWord == 4) ? 0 : uAlignToWord; 428 429 /* 430 * Requesting buffer from the upper layer memory manager. 431 * Add the align to word and offset for the access to the bus 432 * Also send the encryption status of the packet. It is used only for GWSI alignment. 433 */ 434 pRxXfer->pPacketBuffer = (void *)pRxXfer->RequestForBufferCB ( 435 pRxXfer->RequestForBufferCB_handle, 436 pRxXfer->rxDescriptor.length + uAlignToWord + TNETWIF_READ_OFFSET_BYTES, 437 ((pRxXfer->rxDescriptor.flags & RX_DESC_ENCRYPTION_MASK) >> RX_DESC_FLAGS_ENCRYPTION)); 438 439 if (pRxXfer->pPacketBuffer != NULL) 440 { 441 WLAN_REPORT_DEBUG_RX (pRxXfer->hReport, 442 (" rxXfer_ReadBody() : packetLength %d uAligntoWord = %d\n", 443 pRxXfer->rxDescriptor.length, uAlignToWord)); 444 445 #ifdef TI_DBG 446 pRxXfer->DbgStats.numPacketsRead++; 447 pRxXfer->DbgStats.numBytesRead += pRxXfer->rxDescriptor.length; 448 #endif 449 450 /* Read the packet and return TNETWIF_OK or TNETWIF_PENDING */ 451 return TNETWIF_ReadMemOpt (pRxXfer->hTNETWIF, 452 pRxXfer->doubleBuffer[pRxXfer->currBuffer] + RX_DESCRIPTOR_SIZE + 20, 453 (UINT8 *)pRxXfer->pPacketBuffer, 454 (UINT32)pRxXfer->rxDescriptor.length + uAlignToWord, 455 FW_EVENT_MODULE_ID, 456 rxXfer_StateMachine, 457 (TI_HANDLE)pRxXfer); 458 459 } 460 /* If no buffer could be allocated */ 461 else 462 { 463 WLAN_REPORT_ERROR (pRxXfer->hReport, HAL_RX_MODULE_LOG, 464 ("rxXfer_RecvOnePacket: pRxXfer->rxDescriptor %x NULL !!!! \n",pRxXfer->pPacketBuffer)); 465 466 #ifdef TI_DBG 467 pRxXfer->DbgStats.numPacketsDroppedNoMem++; 468 #endif 469 } 470 471 return TNETWIF_ERROR; 472 } 473 474 475 /**************************************************************************** 476 * rxXfer_ForwardCB() 477 **************************************************************************** 478 * DESCRIPTION: Parse the Packet with the descriptor and forward the results and 479 * the packet to the registered CB 480 * 481 * INPUTS: pRxXfer - RxXfer handle; 482 * 483 * OUTPUT: 484 * 485 * RETURNS: 486 ****************************************************************************/ 487 void rxXfer_ForwardCB (RxXfer_t *pRxXfer) 488 { 489 UINT32 aFlags = 0; 490 rate_e eRate = DRV_RATE_AUTO; 491 rxXfer_Reserved_t Reserved; 492 RxIfDescriptor_t *pRxParams = &pRxXfer->rxDescriptor; 493 494 WLAN_REPORT_DEBUG_RX (pRxXfer->hReport, ("rxXfer_ForwardCB ENTERING\n")); 495 496 eRate = ConvertHwRateToDrvRate(pRxParams->rate, (BOOL)(OFDM_RATE_BIT & pRxParams->modPre)); 497 498 WLAN_REPORT_DEBUG_RX (pRxXfer->hReport, 499 (" rxXfer_ForwardCB() HwRate = %d, modPre = %d eRate = %d:\n",pRxParams->rate,pRxParams->modPre,eRate)); 500 501 if ( eRate == DRV_RATE_AUTO) 502 { 503 WLAN_REPORT_ERROR (pRxXfer->hReport, HAL_RX_MODULE_LOG, 504 ("rxXfer_ForwardCB: Received wrong rate from Hw = 0x%x, modPre = 0x%x\n", 505 pRxParams->rate,pRxParams->modPre)); 506 } 507 508 Reserved.packetType = (rxPacketType_e)pRxParams->type; 509 Reserved.rssi = pRxParams->rssi; 510 Reserved.SNR = pRxParams->snr; 511 Reserved.band = pRxParams->band; 512 Reserved.TimeStamp = pRxParams->timestamp; 513 514 if (pRxXfer->packetStatus == OK) 515 { 516 /* Get the mac header from the TNETWIF_READ_OFFSET_BYTES in the packet Buffer */ 517 dot11_header_t *pMacHdr = (dot11_header_t *)((UINT8*)pRxXfer->pPacketBuffer + TNETWIF_READ_OFFSET_BYTES); 518 #ifdef GWSI_RECORDING 519 static char TempString[(1600 * 2) + 1]; 520 #endif /* GWSI_RECORDING */ 521 522 /* Handle endian for the frame control fields */ 523 pMacHdr->fc = ENDIAN_HANDLE_WORD(pMacHdr->fc); 524 pMacHdr->duration = ENDIAN_HANDLE_WORD(pMacHdr->duration); 525 pMacHdr->seqCtrl = ENDIAN_HANDLE_WORD(pMacHdr->seqCtrl); 526 527 rxXfer_ConvertDescFlagsToAppFlags (pRxParams->flags, &aFlags, &pRxXfer->packetStatus); 528 529 #ifdef GWSI_RECORDING 530 convert_hex_to_string ((UINT8*)pRxXfer->pPacketBuffer + TNETWIF_READ_OFFSET_BYTES, TempString, pRxParams->length); 531 532 WLAN_REPORT_GWSI_RECORDING (pRxXfer->hReport, 533 ("GWSI Recording, rxXfer_RecvPacketCB, aStatus = 0x%x, aRate = 0x%x, aRCPI = 0x%x, aFlags = 0x%x\n", 534 pRxXfer->packetStatus, aRate, pRxParams->rcpi, aFlags)); 535 WLAN_REPORT_GWSI_RECORDING (pRxXfer->hReport, 536 ("GWSI Recording, rxXfer_RecvPacketCB, aLength = 0x%x, aFrame = %s\n", 537 pRxParams->length, TempString)); 538 #endif /* GWSI_RECORDING */ 539 } 540 541 /* Set the packet to upper layer. packet is starting after TNETWIF_READ_OFFSET_BYTES bytes */ 542 pRxXfer->ReceivePacketCB (pRxXfer->ReceivePacketCB_handle, 543 pRxXfer->packetStatus, 544 (const void*)pRxXfer->pPacketBuffer, 545 pRxParams->length, 546 (UINT32)eRate, 547 pRxParams->rcpi, 548 pRxParams->chanNum, 549 (void *)&Reserved, 550 aFlags); 551 } 552 553 554 /**************************************************************************** 555 * rxXfer_AckRx() 556 **************************************************************************** 557 * DESCRIPTION: Set Ack to the FW that the buffer was read 558 * 559 * INPUTS: pRxXfer - RxXfer handle; 560 * 561 * OUTPUT: 562 * 563 * RETURNS: TNETWIF_OK in synch mode and TNETWIF_PENDING in Asynch mode. 564 ****************************************************************************/ 565 TI_STATUS rxXfer_AckRx (RxXfer_t *pRxXfer) 566 { 567 TI_STATUS status; 568 569 /* Ack on the opposite buffer since we changed it in rxXfer_ForwardCB() */ 570 if (pRxXfer->currBuffer == 0) 571 { 572 WLAN_REPORT_DEBUG_RX (pRxXfer->hReport, ("Ack on Rx 0\n")); 573 574 #ifdef TI_DBG 575 pRxXfer->DbgStats.numAck0 ++; 576 #endif 577 578 status = TNETWIF_WriteRegOpt (pRxXfer->hTNETWIF, 579 ACX_REG_INTERRUPT_TRIG, 580 INTR_TRIG_RX_PROC0, 581 FW_EVENT_MODULE_ID, 582 rxXfer_StateMachine, 583 (TI_HANDLE)pRxXfer); 584 } 585 else 586 { 587 WLAN_REPORT_DEBUG_RX (pRxXfer->hReport, ("Ack on Rx 1\n")); 588 589 #ifdef TI_DBG 590 pRxXfer->DbgStats.numAck1 ++; 591 #endif 592 593 status = TNETWIF_WriteRegOpt (pRxXfer->hTNETWIF, 594 ACX_REG_INTERRUPT_TRIG_H, 595 INTR_TRIG_RX_PROC1, 596 FW_EVENT_MODULE_ID, 597 rxXfer_StateMachine, 598 (TI_HANDLE)pRxXfer); 599 } 600 601 /* Calculate the next buffer to read from (0 or 1) */ 602 pRxXfer->currBuffer = 1 - pRxXfer->currBuffer; 603 604 return status; 605 } 606 607 608 /**************************************************************************** 609 * rxXfer_ConvertDescFlagsToAppFlags() 610 **************************************************************************** 611 * DESCRIPTION: Add some spacing before capital letters and you'll figure it out ... 612 * 613 * INPUTS: descRxFlags - Bits as received from Fw 614 * 615 * OUTPUT: aFlags - converted bits to our definition 616 * pPacketStatus - changed status if an error was indicated 617 * RETURNS: 618 ****************************************************************************/ 619 static void rxXfer_ConvertDescFlagsToAppFlags (UINT16 descRxFlags, UINT32 *aFlags, TI_STATUS *pPacketStatus) 620 { 621 UINT32 flags = 0; 622 623 if (descRxFlags & RX_DESC_MATCH_RXADDR1) 624 { 625 flags |= RX_PACKET_FLAGS_MATCH_RXADDR1; 626 } 627 628 if (descRxFlags & RX_DESC_MCAST) 629 { 630 flags |= RX_PACKET_FLAGS_GROUP_ADDR; 631 } 632 633 if (descRxFlags & RX_DESC_STAINTIM) 634 { 635 flags |= RX_PACKET_FLAGS_STAINTIM; 636 } 637 638 if (descRxFlags & RX_DESC_VIRTUAL_BM) 639 { 640 flags |= RX_PACKET_FLAGS_VIRTUAL_BM; 641 } 642 643 if (descRxFlags & RX_DESC_BCAST) 644 { 645 flags |= RX_PACKET_FLAGS_BCAST; 646 } 647 648 if (descRxFlags & RX_DESC_MATCH_SSID) 649 { 650 flags |= RX_PACKET_FLAGS_MATCH_SSID; 651 } 652 653 if (descRxFlags & RX_DESC_MATCH_BSSID) 654 { 655 flags |= RX_PACKET_FLAGS_MATCH_BSSID; 656 } 657 658 flags |= (descRxFlags & RX_DESC_ENCRYPTION_MASK) << RX_PACKET_FLAGS_ENCRYPTION_SHIFT_FROM_DESC; 659 660 if (descRxFlags & RX_DESC_MEASURMENT) 661 { 662 flags |= RX_PACKET_FLAGS_MEASURMENT; 663 } 664 665 if (descRxFlags & RX_DESC_MIC_FAIL) 666 { 667 *pPacketStatus = RX_MIC_FAILURE_ERROR; 668 } 669 670 if (descRxFlags & RX_DESC_DECRYPT_FAIL) 671 { 672 *pPacketStatus = RX_DECRYPT_FAILURE; 673 } 674 675 *aFlags = flags; 676 } 677 678 #ifdef TI_DBG 679 /**************************************************************************** 680 * rxXfer_ClearStats() 681 **************************************************************************** 682 * DESCRIPTION: 683 * 684 * INPUTS: 685 * pRxXfer The object 686 * 687 * OUTPUT: None 688 * 689 * RETURNS: OK. 690 ****************************************************************************/ 691 void rxXfer_ClearStats (TI_HANDLE hRxXfer) 692 { 693 RxXfer_t * pRxXfer = (RxXfer_t *)hRxXfer; 694 695 os_memoryZero (pRxXfer->hOs, &pRxXfer->DbgStats, sizeof(RxXferStats_T)); 696 } 697 698 699 /**************************************************************************** 700 * rxXfer_PrintStats() 701 **************************************************************************** 702 * DESCRIPTION: . 703 * 704 * INPUTS: 705 * pRxXfer The object 706 * 707 * OUTPUT: None 708 * 709 * RETURNS: OK. 710 ****************************************************************************/ 711 void rxXfer_PrintStats (TI_HANDLE hRxXfer) 712 { 713 RxXfer_t * pRxXfer = (RxXfer_t *)hRxXfer; 714 715 WLAN_OS_REPORT(("Number of packets read: %d, number of bytes read:%d\n", 716 pRxXfer->DbgStats.numPacketsRead, pRxXfer->DbgStats.numBytesRead)); 717 WLAN_OS_REPORT(("Number of frames dropped due to no memory:%d, Number of frames dropped due to packet ID mismatch:%d\n", 718 pRxXfer->DbgStats.numPacketsDroppedNoMem, pRxXfer->DbgStats.numPacketsDroppedPacketIDMismatch)); 719 WLAN_OS_REPORT(("Number of irq0:%u, ack0:%d\n", 720 pRxXfer->DbgStats.numIrq0, pRxXfer->DbgStats.numAck0)); 721 WLAN_OS_REPORT(("Number of irq1:%u, ack1:%d\n", 722 pRxXfer->DbgStats.numIrq1, pRxXfer->DbgStats.numAck1)); 723 } 724 #endif 725 726 /**************************************************************************** 727 * RxXfer_ReStart() 728 **************************************************************************** 729 * DESCRIPTION: RxXfer_ReStart the RxXfer module object (called by the recovery) 730 * 731 * INPUTS: hRxXfer - The object to free 732 * 733 * OUTPUT: None 734 * 735 * RETURNS: NONE 736 ****************************************************************************/ 737 738 VOID RxXfer_ReStart(TI_HANDLE hRxXfer) 739 { 740 RxXfer_t * pRxXfer = (RxXfer_t *)hRxXfer; 741 742 pRxXfer->state = RX_XFER_STATE_IDLE; 743 pRxXfer->currBuffer = 0; /* first buffer to read from */ 744 pRxXfer->lastPacketId = 0; 745 746 } /* RxXfer_ReStart() */ 747 748