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 ****************************************************************************/
rxXfer_Create(TI_HANDLE hOs)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 ****************************************************************************/
rxXfer_Destroy(TI_HANDLE hRxXfer)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 ****************************************************************************/
rxXfer_Config(TI_HANDLE hRxXfer,TI_HANDLE hFwEvent,TI_HANDLE hMemMgr,TI_HANDLE hReport,TI_HANDLE hTNETWIF)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 ****************************************************************************/
rxXfer_Register_CB(TI_HANDLE hRxXfer,tiUINT32 CallBackID,void * CBFunc,TI_HANDLE CBObj)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 ****************************************************************************/
rxXfer_SetDoubleBufferAddr(TI_HANDLE hRxXfer,ACXDataPathParamsResp_t * pDataPathParams)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 ****************************************************************************/
rxXfer_RxEvent(TI_HANDLE hRxXfer)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 ****************************************************************************/
rxXfer_StateMachine(TI_HANDLE hRxXfer,UINT8 module_id,TI_STATUS status)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 ****************************************************************************/
rxXfer_ReadHeader(RxXfer_t * pRxXfer)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 ****************************************************************************/
rxXfer_ReadBody(RxXfer_t * pRxXfer)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 ****************************************************************************/
rxXfer_ForwardCB(RxXfer_t * pRxXfer)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 ****************************************************************************/
rxXfer_AckRx(RxXfer_t * pRxXfer)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 ****************************************************************************/
rxXfer_ConvertDescFlagsToAppFlags(UINT16 descRxFlags,UINT32 * aFlags,TI_STATUS * pPacketStatus)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 ****************************************************************************/
rxXfer_ClearStats(TI_HANDLE hRxXfer)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 ****************************************************************************/
rxXfer_PrintStats(TI_HANDLE hRxXfer)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
RxXfer_ReStart(TI_HANDLE hRxXfer)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