OSDN Git Service

original
[gb-231r1-is01/GB_2.3_IS01.git] / system / wlan / ti / sta_dk_4_0_4_32 / common / src / TNETW_Driver / FW_Transfer / Rx_Xfer / RxXfer.c
diff --git a/system/wlan/ti/sta_dk_4_0_4_32/common/src/TNETW_Driver/FW_Transfer/Rx_Xfer/RxXfer.c b/system/wlan/ti/sta_dk_4_0_4_32/common/src/TNETW_Driver/FW_Transfer/Rx_Xfer/RxXfer.c
new file mode 100644 (file)
index 0000000..564a56c
--- /dev/null
@@ -0,0 +1,747 @@
+/****************************************************************************
+**+-----------------------------------------------------------------------+**
+**|                                                                       |**
+**| Copyright(c) 1998 - 2008 Texas Instruments. All rights reserved.      |**
+**| All rights reserved.                                                  |**
+**|                                                                       |**
+**| Redistribution and use in source and binary forms, with or without    |**
+**| modification, are permitted provided that the following conditions    |**
+**| are met:                                                              |**
+**|                                                                       |**
+**|  * Redistributions of source code must retain the above copyright     |**
+**|    notice, this list of conditions and the following disclaimer.      |**
+**|  * Redistributions in binary form must reproduce the above copyright  |**
+**|    notice, this list of conditions and the following disclaimer in    |**
+**|    the documentation and/or other materials provided with the         |**
+**|    distribution.                                                      |**
+**|  * Neither the name Texas Instruments nor the names of its            |**
+**|    contributors may be used to endorse or promote products derived    |**
+**|    from this software without specific prior written permission.      |**
+**|                                                                       |**
+**| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS   |**
+**| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT     |**
+**| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |**
+**| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT  |**
+**| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |**
+**| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT      |**
+**| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |**
+**| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |**
+**| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT   |**
+**| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |**
+**| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  |**
+**|                                                                       |**
+**+-----------------------------------------------------------------------+**
+****************************************************************************/
+
+/****************************************************************************
+ *
+ *   MODULE:  rxXfer.c
+ *
+ *   PURPOSE: Rx Xfer module implementation.Responsible for reading Rx from the FW
+ *              and forward it to the upper layers.
+ * 
+ ****************************************************************************/
+
+#include "RxXfer.h"
+#include "utils.h"
+#include "report.h"
+#include "shmUtils.h"
+#include "FwEvent_api.h"
+#include "tnetwCommon.h"
+#include "whalBus_Defs.h"
+
+#define PLCP_HEADER_LENGTH 8
+
+/************************ static function declaration *****************************/
+
+static void      rxXfer_StateMachine (TI_HANDLE hRxXfer, UINT8 module_id, TI_STATUS status);
+static TI_STATUS rxXfer_ReadHeader (RxXfer_t *pRxXfer);
+static TI_STATUS rxXfer_ReadBody (RxXfer_t *pRxXfer);
+static void      rxXfer_ForwardCB (RxXfer_t *pRxXfer);
+static TI_STATUS rxXfer_AckRx (RxXfer_t *pRxXfer);
+static void      rxXfer_ConvertDescFlagsToAppFlags (UINT16 descRxFlags, UINT32 *aFlags, TI_STATUS *pPacketStatus);
+
+
+/****************************************************************************
+ *                      RxXfer_Create()
+ ****************************************************************************
+ * DESCRIPTION: Create the RxXfer module object 
+ * 
+ * INPUTS:  None
+ * 
+ * OUTPUT:  None
+ * 
+ * RETURNS: The Created object
+ ****************************************************************************/
+TI_HANDLE rxXfer_Create (TI_HANDLE hOs)
+{
+    RxXfer_t *pRxXfer;
+
+    pRxXfer = os_memoryAlloc (hOs, sizeof(RxXfer_t));
+    if (pRxXfer == NULL)
+        return NULL;
+
+    /* For all the counters */
+    os_memoryZero (hOs, pRxXfer, sizeof(RxXfer_t));
+
+    pRxXfer->hOs = hOs;
+
+    return (TI_HANDLE)pRxXfer;
+}
+
+
+/****************************************************************************
+ *                      RxXfer_Destroy()
+ ****************************************************************************
+ * DESCRIPTION: Destroy the RxXfer module object 
+ * 
+ * INPUTS:  hRxXfer - The object to free
+ * 
+ * OUTPUT:  None
+ * 
+ * RETURNS: 
+ ****************************************************************************/
+void rxXfer_Destroy (TI_HANDLE hRxXfer)
+{
+    RxXfer_t *pRxXfer = (RxXfer_t *)hRxXfer;
+
+    if (pRxXfer)
+    {
+        os_memoryFree (pRxXfer->hOs, pRxXfer, sizeof(RxXfer_t));
+    }
+} /* RxXfer_Destroy() */
+
+
+/****************************************************************************
+ *                      RxXfer_Config()
+ ****************************************************************************
+ * DESCRIPTION: Destroy the FwEvent module object 
+ * 
+ * INPUTS:      hRxXfer       - FwEvent handle;
+ * 
+ * OUTPUT:  None
+ * 
+ * RETURNS: None
+ ****************************************************************************/
+void rxXfer_Config(TI_HANDLE hRxXfer,
+                   TI_HANDLE hFwEvent, 
+                   TI_HANDLE hMemMgr,
+                   TI_HANDLE hReport,
+                   TI_HANDLE hTNETWIF)
+{
+    RxXfer_t  *pRxXfer      = (RxXfer_t *)hRxXfer;
+
+    pRxXfer->hFwEvent       = hFwEvent;
+    pRxXfer->hMemMgr        = hMemMgr;
+    pRxXfer->hReport        = hReport;
+    pRxXfer->hTNETWIF       = hTNETWIF;
+
+    pRxXfer->state          = RX_XFER_STATE_IDLE;
+    pRxXfer->currBuffer     = 0;        /* first buffer to read from */
+    pRxXfer->lastPacketId   = 0;
+
+    FwEvent_Enable (pRxXfer->hFwEvent, ACX_INTR_RX0_DATA);
+    FwEvent_Enable (pRxXfer->hFwEvent, ACX_INTR_RX1_DATA);
+    
+#ifdef TI_DBG   
+    rxXfer_ClearStats (pRxXfer);
+#endif
+}
+
+
+/****************************************************************************
+ *                      rxXfer_Register_CB()
+ ****************************************************************************
+ * DESCRIPTION: Register the function to be called for received Rx
+ *              or the function to be called for request for buffer
+ * 
+ * INPUTS:      hRxXfer       - RxXfer handle;
+ * 
+ * OUTPUT:  None
+ * 
+ * RETURNS: None
+ ****************************************************************************/
+void rxXfer_Register_CB (TI_HANDLE hRxXfer, tiUINT32 CallBackID, void *CBFunc, TI_HANDLE CBObj)
+{
+    RxXfer_t* pRxXfer = (RxXfer_t *)hRxXfer;
+
+    WLAN_REPORT_INFORMATION (pRxXfer->hReport, HAL_RX_MODULE_LOG, ("rxXfer_Register_CB (Value = 0x%x)\n", CallBackID));
+
+    switch(CallBackID)
+    {
+    case HAL_INT_RECEIVE_PACKET:
+        pRxXfer->ReceivePacketCB = (packetReceiveCB_t)CBFunc;
+        pRxXfer->ReceivePacketCB_handle = CBObj;
+        break;
+
+    case HAL_INT_REQUEST_FOR_BUFFER:       
+        pRxXfer->RequestForBufferCB = (requestForBufferCB_t)CBFunc;
+        pRxXfer->RequestForBufferCB_handle = CBObj;
+        break;
+
+    default:
+        WLAN_REPORT_ERROR(pRxXfer->hReport, HAL_RX_MODULE_LOG, ("rxXfer_Register_CB - Illegal value\n"));
+        return;
+    }
+}
+
+
+/****************************************************************************
+ *                      rxXfer_SetDoubleBufferAddr()
+ ****************************************************************************
+ * DESCRIPTION: Store the addresses of the Double Buffer 
+ * 
+ * INPUTS:      hRxXfer       - RxXfer handle;
+ * 
+ * OUTPUT:  None
+ * 
+ * RETURNS: None
+ ****************************************************************************/
+void rxXfer_SetDoubleBufferAddr (TI_HANDLE hRxXfer, ACXDataPathParamsResp_t *pDataPathParams)
+{
+    RxXfer_t* pRxXfer = (RxXfer_t *)hRxXfer;
+
+    pRxXfer->doubleBuffer[0] = pDataPathParams->rxPacketRingAddr;
+    pRxXfer->doubleBuffer[1] = pDataPathParams->rxPacketRingAddr + pDataPathParams->rxPacketRingChunkSize;
+} 
+
+
+/****************************************************************************
+ *                      rxXfer_RxEvent()
+ ****************************************************************************
+ * DESCRIPTION: Called upon Rx event from the FW.calls the SM  
+ * 
+ * INPUTS:      hRxXfer       - RxXfer handle;
+ * 
+ * OUTPUT:  None
+ * 
+ * RETURNS: TNETWIF_OK in case of Synch mode, or TNETWIF_PENDING in case of Asynch mode
+ *          (when returning TNETWIF_PENDING, FwEvent module expects the FwEvent_EventComplete()
+ *          function call to finish the Rx Client handling 
+ *
+ ****************************************************************************/
+TI_STATUS rxXfer_RxEvent (TI_HANDLE hRxXfer)
+{
+    RxXfer_t* pRxXfer = (RxXfer_t *)hRxXfer;
+
+    if (RX_XFER_STATE_IDLE != pRxXfer->state)
+    {
+        WLAN_REPORT_ERROR(pRxXfer->hReport,HAL_RX_MODULE_LOG,
+            ("rxXfer_RxEvent called in state %d !!!\n",pRxXfer->state));
+        return TNETWIF_ERROR;
+    }
+
+    WLAN_REPORT_INFORMATION (pRxXfer->hReport, HAL_RX_MODULE_LOG,
+        ("rxXfer_RxEvent Calling rxXfer_StateMachine : currBuffer = %d \n",
+        pRxXfer->currBuffer));
+
+  #ifdef TI_DBG
+    if (pRxXfer->currBuffer == 0)     
+        pRxXfer->DbgStats.numIrq0 ++;
+    else
+        pRxXfer->DbgStats.numIrq1 ++;
+  #endif
+
+    /* Assume that we are in synch bus until otherwise is proven */
+    pRxXfer->bSync = TRUE;
+    /* The packet status is OK unless we receive error */
+    pRxXfer->packetStatus = OK;
+
+    rxXfer_StateMachine (hRxXfer, 0, OK);
+    
+    return pRxXfer->returnValue;
+}
+
+
+/****************************************************************************
+ *                      rxXfer_StateMachine()
+ ****************************************************************************
+ * DESCRIPTION: SM for handling Synch & Asynch read of RX from the HW.
+ *              The flow of the SM is by that order:
+ *              IDLE -> READING_HDR -> READING_PKT -> EXIT
+ *              On synch mode - each state is called in the same context in the while loop.
+ *              On Asynch mode - each state returns TNETWIF_PENDING and exits the SM.The CB of
+ *              each Asynch is the SM, that will continue the Rx handling.
+ *
+ * INPUTS:      hRxXfer       - RxXfer handle;
+ * 
+ * OUTPUT:      pRxXfer->returnValue is TNETWIF_OK in synch mode and TNETWIF_PENDING in Asynch mode.
+ * 
+ * RETURNS: 
+ ****************************************************************************/
+static void rxXfer_StateMachine (TI_HANDLE hRxXfer, UINT8 module_id, TI_STATUS status)
+{
+    RxXfer_t* pRxXfer = (RxXfer_t *)hRxXfer;
+
+    pRxXfer->returnValue = OK;
+    
+    /*
+     * This while loop will continue till the exit or when waiting for the CB due to
+     * memory transfer operation pending for DMA to complete   
+     */
+    while (TNETWIF_PENDING != pRxXfer->returnValue)
+    {
+        WLAN_REPORT_DEBUG_RX (pRxXfer->hReport, ("Rx SM: state = %d, rc = %d\n",
+            pRxXfer->state, pRxXfer->returnValue));
+    
+        switch(pRxXfer->state) 
+        {
+        case RX_XFER_STATE_IDLE:
+            pRxXfer->state = RX_XFER_STATE_READING_HDR;
+            pRxXfer->returnValue = rxXfer_ReadHeader (pRxXfer);
+            break;
+
+        case RX_XFER_STATE_READING_HDR:
+            pRxXfer->state = RX_XFER_STATE_READING_PKT;
+            pRxXfer->returnValue = rxXfer_ReadBody (pRxXfer);
+            break;
+
+        case RX_XFER_STATE_READING_PKT:
+            pRxXfer->state = RX_XFER_STATE_EXITING;
+            rxXfer_ForwardCB(pRxXfer);
+            pRxXfer->returnValue = rxXfer_AckRx (pRxXfer);
+            break;
+
+        case RX_XFER_STATE_EXITING:
+            pRxXfer->state = RX_XFER_STATE_IDLE;
+            if (FALSE == pRxXfer->bSync)
+            {   
+                /* Async bus - call FwEvent for notifying the completion */
+                FwEvent_EventComplete (pRxXfer->hFwEvent, TNETWIF_OK);
+            }
+            else    
+            {
+                /* This is the sync case - we should return TNETWIF_OK */
+                pRxXfer->returnValue = TNETWIF_OK;
+            }
+
+            return;
+
+        default:
+            WLAN_REPORT_ERROR (pRxXfer->hReport, HAL_RX_MODULE_LOG,
+                               ("rxXfer_StateMachine Unknown state = %d\n",
+                               pRxXfer->state));
+        }
+
+        if (TNETWIF_ERROR == pRxXfer->returnValue)
+        {   
+            WLAN_REPORT_ERROR (pRxXfer->hReport, HAL_RX_MODULE_LOG,
+                ("rxXfer_StateMachine returning TNETWIF_ERROR in state %d. Next packet will be discarded!!!\n",pRxXfer->state));
+
+            /* Next packet will be marked as NOK and will be discarded */
+            pRxXfer->packetStatus = NOK;
+        }
+    }
+
+    /* If we are here - we got TNETWIF_PENDING, so we are in Async mode */
+    pRxXfer->bSync = FALSE;
+}
+
+
+/****************************************************************************
+ *                      rxXfer_ReadHeader()
+ ****************************************************************************
+ * DESCRIPTION: Read the packet header (descriptor)
+ *
+ * INPUTS:      pRxXfer       - RxXfer handle;
+ * 
+ * OUTPUT:      
+ * 
+ * RETURNS:     TNETWIF_OK in synch mode and TNETWIF_PENDING in Asynch mode.
+ ****************************************************************************/
+TI_STATUS rxXfer_ReadHeader(RxXfer_t *pRxXfer)
+{
+    WLAN_REPORT_DEBUG_RX(pRxXfer->hReport, 
+                        ("rxXfer_readHeader: Before Read Memory Addr from DB No %d Addr %x !!!! \n",pRxXfer->currBuffer,pRxXfer->doubleBuffer[pRxXfer->currBuffer]));
+
+    return TNETWIF_ReadMemOpt (pRxXfer->hTNETWIF, 
+                               pRxXfer->doubleBuffer[pRxXfer->currBuffer], 
+                               PADREAD (&pRxXfer->rxDescriptor),
+                               RX_DESCRIPTOR_SIZE,
+                               FW_EVENT_MODULE_ID,
+                               rxXfer_StateMachine,
+                               (TI_HANDLE)pRxXfer);
+}
+
+
+/****************************************************************************
+ *                      rxXfer_ReadBody()
+ ****************************************************************************
+ * DESCRIPTION: Read the packet body
+ *
+ * INPUTS:      pRxXfer       - RxXfer handle;
+ * 
+ * OUTPUT:      
+ * 
+ * RETURNS:     TNETWIF_OK in synch mode and TNETWIF_PENDING in Asynch mode.
+ ****************************************************************************/
+TI_STATUS rxXfer_ReadBody (RxXfer_t *pRxXfer)
+{
+    UINT32  uCurrPacketId;             /* Current packet ID */
+    UINT32  uLastPacketIdIncremented;  /* The last received packet-ID incremented with modulo */
+    UINT32  uAlignToWord;              /* Used to align the length of the packet to a WORD */ 
+
+       /* Check for correct length of Rx Descriptor */
+    if (pRxXfer->rxDescriptor.length <= PLCP_HEADER_LENGTH || 
+        pRxXfer->rxDescriptor.length > (MAX_DATA_BODY_LENGTH + PLCP_HEADER_LENGTH))
+    {
+        WLAN_REPORT_ERROR (pRxXfer->hReport, HAL_RX_MODULE_LOG,
+             ("rxXfer_ReadBody: RxLength not correct! rxDescriptor.length=%d\n",         
+             pRxXfer->rxDescriptor.length));
+        return TNETWIF_ERROR;
+    }
+
+    pRxXfer->rxDescriptor.length = pRxXfer->rxDescriptor.length - PLCP_HEADER_LENGTH;
+
+    uCurrPacketId = (pRxXfer->rxDescriptor.flags & RX_DESC_SEQNUM_MASK) >> RX_DESC_PACKETID_SHIFT;
+
+    uLastPacketIdIncremented = (pRxXfer->lastPacketId + 1) % (RX_MAX_PACKET_ID + 1);
+
+    if (uCurrPacketId == uLastPacketIdIncremented)
+    {
+        pRxXfer->lastPacketId = uLastPacketIdIncremented;
+
+#ifdef GWSI_RECORDING
+        WLAN_REPORT_GWSI_RECORDING(pRxXfer->hReport, ("GWSI Recording, rxXfer_ReadBody (request for buffer), Length = 0x%x\n", pRxXfer->rxDescriptor.length));
+#endif /* GWSI_RECORDING */
+    }
+    else
+    {
+       WLAN_REPORT_ERROR (pRxXfer->hReport, HAL_RX_MODULE_LOG,
+            ("rxXfer_ReadBody: Packet ID mismatch! CurrPacketId=%d, lastPacketId=%d\n",         
+            uCurrPacketId, pRxXfer->lastPacketId));
+#ifdef TI_DBG
+        pRxXfer->DbgStats.numPacketsDroppedPacketIDMismatch++;
+        rxXfer_PrintStats ((TI_HANDLE)pRxXfer);
+#endif
+        /* Reset the lastPacketId to be synchronized on the Current Packet ID read from the FW */
+        pRxXfer->lastPacketId = uCurrPacketId;
+    }
+
+    /*
+     * Add uAlignToWord to the body length since we have to read buffers from the FW in 4 bytes chunks.
+     * NOTE: The size of the buffer is aligned to 4, but the packet itself is not.
+     * Releasing the memory must be done with the actual size allocated and not the size of the packet 
+     */
+    uAlignToWord = 4 - (pRxXfer->rxDescriptor.length & 0x3); /* (&0x3) is equal to (% 4) */
+    uAlignToWord = (uAlignToWord == 4) ? 0 : uAlignToWord;
+
+    /* 
+     * Requesting buffer from the upper layer memory manager. 
+     * Add the align to word and offset for the access to the bus 
+        * Also send the encryption status of the packet. It is used only for GWSI alignment.
+     */
+    pRxXfer->pPacketBuffer = (void *)pRxXfer->RequestForBufferCB (
+        pRxXfer->RequestForBufferCB_handle,
+        pRxXfer->rxDescriptor.length + uAlignToWord + TNETWIF_READ_OFFSET_BYTES,
+               ((pRxXfer->rxDescriptor.flags & RX_DESC_ENCRYPTION_MASK) >> RX_DESC_FLAGS_ENCRYPTION));
+
+    if (pRxXfer->pPacketBuffer != NULL)
+    {
+        WLAN_REPORT_DEBUG_RX (pRxXfer->hReport,
+            (" rxXfer_ReadBody() : packetLength %d uAligntoWord = %d\n",
+                         pRxXfer->rxDescriptor.length, uAlignToWord));
+
+#ifdef TI_DBG
+        pRxXfer->DbgStats.numPacketsRead++;
+        pRxXfer->DbgStats.numBytesRead += pRxXfer->rxDescriptor.length;
+#endif
+
+        /* Read the packet and return TNETWIF_OK or TNETWIF_PENDING */
+        return TNETWIF_ReadMemOpt (pRxXfer->hTNETWIF,
+                                   pRxXfer->doubleBuffer[pRxXfer->currBuffer] + RX_DESCRIPTOR_SIZE + 20,
+                                   (UINT8 *)pRxXfer->pPacketBuffer,
+                                   (UINT32)pRxXfer->rxDescriptor.length + uAlignToWord,
+                                   FW_EVENT_MODULE_ID,
+                                   rxXfer_StateMachine,
+                                   (TI_HANDLE)pRxXfer);
+    
+    }
+    /* If no buffer could be allocated */
+    else   
+    {
+        WLAN_REPORT_ERROR (pRxXfer->hReport, HAL_RX_MODULE_LOG,
+            ("rxXfer_RecvOnePacket:  pRxXfer->rxDescriptor %x NULL !!!! \n",pRxXfer->pPacketBuffer));
+
+#ifdef TI_DBG
+        pRxXfer->DbgStats.numPacketsDroppedNoMem++;
+#endif
+    }
+    
+    return TNETWIF_ERROR;
+}
+
+
+/****************************************************************************
+ *                      rxXfer_ForwardCB()
+ ****************************************************************************
+ * DESCRIPTION: Parse the Packet with the descriptor and forward the results and
+ *              the packet to the registered CB
+ *
+ * INPUTS:      pRxXfer       - RxXfer handle;
+ * 
+ * OUTPUT:      
+ * 
+ * RETURNS:     
+ ****************************************************************************/
+void rxXfer_ForwardCB (RxXfer_t *pRxXfer)
+{
+    UINT32            aFlags = 0;
+    rate_e            eRate = DRV_RATE_AUTO;
+    rxXfer_Reserved_t Reserved;
+    RxIfDescriptor_t *pRxParams = &pRxXfer->rxDescriptor;
+
+    WLAN_REPORT_DEBUG_RX (pRxXfer->hReport, ("rxXfer_ForwardCB ENTERING\n"));
+   
+    eRate = ConvertHwRateToDrvRate(pRxParams->rate, (BOOL)(OFDM_RATE_BIT & pRxParams->modPre));
+
+    WLAN_REPORT_DEBUG_RX (pRxXfer->hReport,
+        (" rxXfer_ForwardCB() HwRate = %d, modPre = %d eRate = %d:\n",pRxParams->rate,pRxParams->modPre,eRate));
+
+    if ( eRate == DRV_RATE_AUTO)
+    {
+        WLAN_REPORT_ERROR (pRxXfer->hReport, HAL_RX_MODULE_LOG,
+            ("rxXfer_ForwardCB:  Received wrong rate from Hw = 0x%x, modPre = 0x%x\n",
+            pRxParams->rate,pRxParams->modPre));
+    }
+    
+    Reserved.packetType = (rxPacketType_e)pRxParams->type;
+    Reserved.rssi       = pRxParams->rssi;
+    Reserved.SNR        = pRxParams->snr;
+    Reserved.band       = pRxParams->band;
+    Reserved.TimeStamp  = pRxParams->timestamp;
+
+    if (pRxXfer->packetStatus == OK)
+    {
+        /* Get the mac header from the TNETWIF_READ_OFFSET_BYTES in the packet Buffer */
+        dot11_header_t *pMacHdr = (dot11_header_t *)((UINT8*)pRxXfer->pPacketBuffer + TNETWIF_READ_OFFSET_BYTES);
+      #ifdef GWSI_RECORDING
+        static  char TempString[(1600 * 2) + 1];
+      #endif /* GWSI_RECORDING */
+
+        /* Handle endian for the frame control fields */
+        pMacHdr->fc       = ENDIAN_HANDLE_WORD(pMacHdr->fc);
+        pMacHdr->duration = ENDIAN_HANDLE_WORD(pMacHdr->duration);
+        pMacHdr->seqCtrl  = ENDIAN_HANDLE_WORD(pMacHdr->seqCtrl);
+
+        rxXfer_ConvertDescFlagsToAppFlags (pRxParams->flags, &aFlags, &pRxXfer->packetStatus);
+
+      #ifdef GWSI_RECORDING
+        convert_hex_to_string ((UINT8*)pRxXfer->pPacketBuffer + TNETWIF_READ_OFFSET_BYTES, TempString, pRxParams->length);
+
+        WLAN_REPORT_GWSI_RECORDING (pRxXfer->hReport, 
+                                    ("GWSI Recording, rxXfer_RecvPacketCB, aStatus = 0x%x, aRate = 0x%x, aRCPI = 0x%x, aFlags = 0x%x\n", 
+                                    pRxXfer->packetStatus, aRate, pRxParams->rcpi, aFlags));
+        WLAN_REPORT_GWSI_RECORDING (pRxXfer->hReport, 
+                                    ("GWSI Recording, rxXfer_RecvPacketCB, aLength = 0x%x, aFrame = %s\n", 
+                                    pRxParams->length, TempString));    
+      #endif /* GWSI_RECORDING */
+    }
+
+    /* Set the packet to upper layer. packet is starting after TNETWIF_READ_OFFSET_BYTES bytes */
+    pRxXfer->ReceivePacketCB (pRxXfer->ReceivePacketCB_handle,
+                              pRxXfer->packetStatus,
+                              (const void*)pRxXfer->pPacketBuffer,
+                              pRxParams->length,
+                              (UINT32)eRate,
+                              pRxParams->rcpi,
+                              pRxParams->chanNum,
+                              (void *)&Reserved,
+                              aFlags);
+}
+
+
+/****************************************************************************
+ *                      rxXfer_AckRx()
+ ****************************************************************************
+ * DESCRIPTION: Set Ack to the FW that the buffer was read
+ *
+ * INPUTS:      pRxXfer       - RxXfer handle;
+ * 
+ * OUTPUT:      
+ * 
+ * RETURNS:     TNETWIF_OK in synch mode and TNETWIF_PENDING in Asynch mode.
+ ****************************************************************************/
+TI_STATUS rxXfer_AckRx (RxXfer_t *pRxXfer)
+{
+    TI_STATUS status;
+
+    /* Ack on the opposite buffer since we changed it in rxXfer_ForwardCB() */
+    if (pRxXfer->currBuffer == 0)
+    {
+        WLAN_REPORT_DEBUG_RX (pRxXfer->hReport, ("Ack on Rx 0\n"));
+      
+      #ifdef TI_DBG
+        pRxXfer->DbgStats.numAck0 ++;
+      #endif
+
+        status = TNETWIF_WriteRegOpt (pRxXfer->hTNETWIF, 
+                                      ACX_REG_INTERRUPT_TRIG, 
+                                      INTR_TRIG_RX_PROC0,
+                                      FW_EVENT_MODULE_ID,
+                                      rxXfer_StateMachine,
+                                      (TI_HANDLE)pRxXfer);
+    }
+    else 
+    {
+        WLAN_REPORT_DEBUG_RX (pRxXfer->hReport, ("Ack on Rx 1\n"));
+
+      #ifdef TI_DBG
+        pRxXfer->DbgStats.numAck1 ++;
+      #endif
+
+        status = TNETWIF_WriteRegOpt (pRxXfer->hTNETWIF, 
+                                      ACX_REG_INTERRUPT_TRIG_H, 
+                                      INTR_TRIG_RX_PROC1,
+                                      FW_EVENT_MODULE_ID,
+                                      rxXfer_StateMachine,
+                                      (TI_HANDLE)pRxXfer);
+    }
+
+    /* Calculate the next buffer to read from (0 or 1) */
+    pRxXfer->currBuffer = 1 - pRxXfer->currBuffer;
+
+    return status;
+}
+
+
+/****************************************************************************
+ *                      rxXfer_ConvertDescFlagsToAppFlags()
+ ****************************************************************************
+ * DESCRIPTION: Add some spacing before capital letters and you'll figure it out ...
+ *
+ * INPUTS:      descRxFlags   - Bits as received from Fw
+ * 
+ * OUTPUT:      aFlags        - converted bits to our definition    
+ *              pPacketStatus - changed status if an error was indicated
+ * RETURNS:     
+ ****************************************************************************/
+static void  rxXfer_ConvertDescFlagsToAppFlags (UINT16 descRxFlags, UINT32 *aFlags, TI_STATUS *pPacketStatus)
+{
+    UINT32 flags = 0;
+
+    if (descRxFlags & RX_DESC_MATCH_RXADDR1)
+    {
+        flags |= RX_PACKET_FLAGS_MATCH_RXADDR1;
+    }
+
+    if (descRxFlags & RX_DESC_MCAST)
+    {
+        flags |= RX_PACKET_FLAGS_GROUP_ADDR;
+    }
+
+    if (descRxFlags & RX_DESC_STAINTIM)
+    {
+        flags |= RX_PACKET_FLAGS_STAINTIM;
+    }
+
+    if (descRxFlags & RX_DESC_VIRTUAL_BM)
+    {
+        flags |= RX_PACKET_FLAGS_VIRTUAL_BM;
+    }
+
+    if (descRxFlags & RX_DESC_BCAST)
+    {
+        flags |= RX_PACKET_FLAGS_BCAST;
+    }
+
+    if (descRxFlags & RX_DESC_MATCH_SSID)
+    {
+        flags |= RX_PACKET_FLAGS_MATCH_SSID;
+    }
+
+    if (descRxFlags & RX_DESC_MATCH_BSSID)
+    {
+        flags |= RX_PACKET_FLAGS_MATCH_BSSID;
+    }
+
+    flags |= (descRxFlags & RX_DESC_ENCRYPTION_MASK) << RX_PACKET_FLAGS_ENCRYPTION_SHIFT_FROM_DESC;
+
+    if (descRxFlags & RX_DESC_MEASURMENT)
+    {
+        flags |= RX_PACKET_FLAGS_MEASURMENT;
+    }
+
+    if (descRxFlags & RX_DESC_MIC_FAIL)
+    {
+        *pPacketStatus = RX_MIC_FAILURE_ERROR;
+    }
+
+    if (descRxFlags & RX_DESC_DECRYPT_FAIL)
+    {
+        *pPacketStatus = RX_DECRYPT_FAILURE;
+    }
+
+    *aFlags = flags;
+}
+
+#ifdef TI_DBG
+/****************************************************************************
+ *                      rxXfer_ClearStats()
+ ****************************************************************************
+ * DESCRIPTION: 
+ *
+ * INPUTS:  
+ *          pRxXfer The object
+ * 
+ * OUTPUT:  None
+ * 
+ * RETURNS: OK. 
+ ****************************************************************************/
+void rxXfer_ClearStats (TI_HANDLE hRxXfer)
+{
+    RxXfer_t * pRxXfer = (RxXfer_t *)hRxXfer;
+
+    os_memoryZero (pRxXfer->hOs, &pRxXfer->DbgStats, sizeof(RxXferStats_T));
+}
+
+
+/****************************************************************************
+ *                      rxXfer_PrintStats()
+ ****************************************************************************
+ * DESCRIPTION: .
+ *
+ * INPUTS:  
+ *          pRxXfer The object
+ * 
+ * OUTPUT:  None
+ * 
+ * RETURNS: OK. 
+ ****************************************************************************/
+void rxXfer_PrintStats (TI_HANDLE hRxXfer)
+{
+    RxXfer_t * pRxXfer = (RxXfer_t *)hRxXfer;
+    
+    WLAN_OS_REPORT(("Number of packets read: %d, number of bytes read:%d\n",
+                    pRxXfer->DbgStats.numPacketsRead, pRxXfer->DbgStats.numBytesRead));
+    WLAN_OS_REPORT(("Number of frames dropped due to no memory:%d, Number of frames dropped due to packet ID mismatch:%d\n",
+                    pRxXfer->DbgStats.numPacketsDroppedNoMem, pRxXfer->DbgStats.numPacketsDroppedPacketIDMismatch));
+    WLAN_OS_REPORT(("Number of irq0:%u, ack0:%d\n",
+                    pRxXfer->DbgStats.numIrq0, pRxXfer->DbgStats.numAck0));
+    WLAN_OS_REPORT(("Number of irq1:%u, ack1:%d\n",
+                    pRxXfer->DbgStats.numIrq1, pRxXfer->DbgStats.numAck1));
+}
+#endif
+
+/****************************************************************************
+ *                      RxXfer_ReStart()
+ ****************************************************************************
+ * DESCRIPTION:        RxXfer_ReStart the RxXfer module object (called by the recovery)
+ * 
+ * INPUTS:     hRxXfer - The object to free
+ * 
+ * OUTPUT:     None
+ * 
+ * RETURNS:    NONE 
+ ****************************************************************************/
+
+VOID RxXfer_ReStart(TI_HANDLE hRxXfer)
+{
+       RxXfer_t * pRxXfer = (RxXfer_t *)hRxXfer;
+
+       pRxXfer->state          = RX_XFER_STATE_IDLE;
+       pRxXfer->currBuffer     = 0;        /* first buffer to read from */
+       pRxXfer->lastPacketId   = 0;
+       
+} /* RxXfer_ReStart() */
+