--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/TWD/FW_Transfer/RxXfer.c Tue Jun 29 12:34:26 2010 +0100
@@ -0,0 +1,677 @@
+/*
+ * RxXfer.c
+ *
+ * Copyright(c) 1998 - 2010 Texas Instruments. All rights reserved.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 or BSD License which accompanies
+ * this distribution. The Eclipse Public License is available at
+ * http://www.eclipse.org/legal/epl-v10.html and the BSD License is as below.
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+#define __FILE_ID__ FILE_ID_106
+#include "tidef.h"
+#include "osApi.h"
+#include "report.h"
+#include "RxXfer.h"
+#include "FwEvent_api.h"
+#include "TWDriverInternal.h"
+#include "RxQueue_api.h"
+#include "TwIf.h"
+#include "public_host_int.h"
+
+#define RX_DRIVER_COUNTER_ADDRESS 0x300538
+#define RX_DRIVER_DUMMY_WRITE_ADDRESS 0x300534
+#define PLCP_HEADER_LENGTH 8
+#define WORD_SIZE 4
+#define UNALIGNED_PAYLOAD 0x1
+
+#define SLV_MEM_ADDR_VALUE(desc, offset)((RX_DESC_GET_MEM_BLK(desc)<<8)+ offset + 4)
+#define SLV_MEM_CP_VALUE(desc, offset) (((RX_DESC_GET_MEM_BLK(desc)<<8)+ offset))
+/* Add an extra word for alignment the MAC payload in case of QoS MSDU */
+#define ALIGNMENT_SIZE(desc) ((RX_DESC_GET_UNALIGNED(desc) & UNALIGNED_PAYLOAD)? 2 : 0)
+/*QOS definitions*/
+#define QOS_HW_ADDRESS 0x14FDA
+#define QOS_SHIF_BACK_BUFFER 2
+#define QOS_LENGTH_DIFF 2
+#define QOS_SHIF_IN_BUFFER 4
+/************************ static function declaration *****************************/
+
+static void rxXfer_TxnDoneCb (TI_HANDLE hRxXfer, TTxnStruct* pTxn);
+static void rxXfer_IssueTxn (TI_HANDLE hRxXfer, TI_UINT32 uRxDesc, TI_UINT8 *pHostBuf, TI_UINT32 uBuffSize, TI_BOOL bDropPacket);
+static void rxXfer_ForwardPacket (RxXfer_t* pRxXfer, TTxnStruct* pTxn);
+
+/****************************************************************************
+ * 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;
+ int i;
+
+ pRxXfer = os_memoryAlloc (hOs, sizeof(RxXfer_t),MemoryNormal);
+ if (pRxXfer == NULL)
+ return NULL;
+
+ /* For all the counters */
+ os_memoryZero (hOs, pRxXfer, sizeof(RxXfer_t));
+
+ pRxXfer->pTempBuffer = os_memoryAlloc (hOs, MAX_PACKET_SIZE + WSPI_PAD_LEN_READ,MemoryDMA);
+ if (pRxXfer->pTempBuffer == NULL)
+ {
+ return NULL;
+ }
+ os_memoryZero (hOs, pRxXfer->pTempBuffer, MAX_PACKET_SIZE + WSPI_PAD_LEN_READ);
+ pRxXfer->pTempBuffer += WSPI_PAD_LEN_READ;
+
+ for (i = 0; i < MAX_CONSECUTIVE_READ_TXN; i++)
+ {
+ pRxXfer->aSlaveRegTxn[i].pRegData = os_memoryAlloc (hOs, 2*REGISTER_SIZE + WSPI_PAD_LEN_READ,MemoryDMA);
+ if (pRxXfer->aSlaveRegTxn[i].pRegData == NULL)
+ {
+ return NULL;
+ }
+ os_memoryZero (hOs, pRxXfer->aSlaveRegTxn[i].pRegData, 2*REGISTER_SIZE + WSPI_PAD_LEN_READ);
+ pRxXfer->aSlaveRegTxn[i].pRegData += WSPI_PAD_LEN_READ;
+ }
+
+ for (i = 0; i < MAX_CONSECUTIVE_READ_TXN; i++)
+ {
+ pRxXfer->aCounterTxn[i].pCounter = os_memoryAlloc (hOs, REGISTER_SIZE + WSPI_PAD_LEN_READ,MemoryDMA);
+ if (pRxXfer->aCounterTxn[i].pCounter == NULL)
+ {
+ return NULL;
+ }
+ os_memoryZero (hOs, pRxXfer->aCounterTxn[i].pCounter, REGISTER_SIZE + WSPI_PAD_LEN_READ);
+ pRxXfer->aCounterTxn[i].pCounter += WSPI_PAD_LEN_READ;
+ }
+
+ for (i = 0; i < MAX_CONSECUTIVE_READ_TXN; i++)
+ {
+ pRxXfer->aDummyTxn[i].pData = os_memoryAlloc (hOs, REGISTER_SIZE + WSPI_PAD_LEN_READ,MemoryDMA);
+ if (pRxXfer->aDummyTxn[i].pData == NULL)
+ {
+ return NULL;
+ }
+ os_memoryZero (hOs, pRxXfer->aDummyTxn[i].pData, REGISTER_SIZE + WSPI_PAD_LEN_READ);
+ pRxXfer->aDummyTxn[i].pData += WSPI_PAD_LEN_READ;
+ }
+
+
+ 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;
+ int i;
+
+ if (pRxXfer)
+ {
+ if (pRxXfer->pTempBuffer)
+ {
+ os_memoryFree (pRxXfer->hOs, pRxXfer->pTempBuffer - WSPI_PAD_LEN_READ, MAX_PACKET_SIZE + WSPI_PAD_LEN_READ);
+ }
+
+ for (i = 0; i < MAX_CONSECUTIVE_READ_TXN; i++)
+ {
+ if (pRxXfer->aSlaveRegTxn[i].pRegData)
+ {
+ os_memoryFree (pRxXfer->hOs, pRxXfer->aSlaveRegTxn[i].pRegData - WSPI_PAD_LEN_READ, 2*REGISTER_SIZE + WSPI_PAD_LEN_READ);
+ }
+ }
+
+ for (i = 0; i < MAX_CONSECUTIVE_READ_TXN; i++)
+ {
+ if (pRxXfer->aCounterTxn[i].pCounter)
+ {
+ os_memoryFree (pRxXfer->hOs, pRxXfer->aCounterTxn[i].pCounter - WSPI_PAD_LEN_READ, REGISTER_SIZE + WSPI_PAD_LEN_READ);
+ }
+ }
+
+ for (i = 0; i < MAX_CONSECUTIVE_READ_TXN; i++)
+ {
+ if (pRxXfer->aDummyTxn[i].pData)
+ {
+ os_memoryFree (pRxXfer->hOs, pRxXfer->aDummyTxn[i].pData - WSPI_PAD_LEN_READ, REGISTER_SIZE + WSPI_PAD_LEN_READ);
+ }
+ }
+
+ os_memoryFree (pRxXfer->hOs, pRxXfer, sizeof(RxXfer_t));
+ }
+}
+
+
+/****************************************************************************
+ * rxXfer_init()
+ ****************************************************************************
+ * DESCRIPTION: Init the FwEvent module object
+ *
+ * INPUTS: hRxXfer - FwEvent handle;
+ *
+ * OUTPUT: None
+ *
+ * RETURNS: None
+ ****************************************************************************/
+void rxXfer_Init(TI_HANDLE hRxXfer,
+ TI_HANDLE hFwEvent,
+ TI_HANDLE hReport,
+ TI_HANDLE hTwIf,
+ TI_HANDLE hRxQueue)
+{
+ RxXfer_t *pRxXfer = (RxXfer_t *)hRxXfer;
+
+ pRxXfer->hFwEvent = hFwEvent;
+ pRxXfer->hReport = hReport;
+ pRxXfer->hTwIf = hTwIf;
+ pRxXfer->hRxQueue = hRxQueue;
+ pRxXfer->uDrvRxCntr = 0;
+
+ RxXfer_ReStart (hRxXfer);
+
+#ifdef TI_DBG
+ rxXfer_ClearStats (pRxXfer);
+#endif
+}
+
+
+/****************************************************************************
+ * rxXfer_Register_CB()
+ ****************************************************************************
+ * DESCRIPTION: Register the function to be called for request for buffer.
+ *
+ * INPUTS: hRxXfer - RxXfer handle;
+ *
+ * OUTPUT: None
+ *
+ * RETURNS: None
+ ****************************************************************************/
+void rxXfer_Register_CB (TI_HANDLE hRxXfer, TI_UINT32 CallBackID, void *CBFunc, TI_HANDLE CBObj)
+{
+ RxXfer_t* pRxXfer = (RxXfer_t *)hRxXfer;
+
+ TRACE1(pRxXfer->hReport, REPORT_SEVERITY_INFORMATION , "rxXfer_Register_CB (Value = 0x%x)\n", CallBackID);
+
+ switch(CallBackID)
+ {
+ case TWD_INT_REQUEST_FOR_BUFFER:
+ pRxXfer->RequestForBufferCB = (TRequestForBufferCb)CBFunc;
+ pRxXfer->RequestForBufferCB_handle = CBObj;
+ break;
+
+ default:
+ TRACE0(pRxXfer->hReport, REPORT_SEVERITY_ERROR, "rxXfer_Register_CB - Illegal value\n");
+ return;
+ }
+}
+
+
+/****************************************************************************
+ * rxXfer_ForwardPacket()
+ ****************************************************************************
+ * DESCRIPTION: Forward received packet to the upper layers.
+ *
+ * INPUTS:
+ *
+ * OUTPUT:
+ *
+ * RETURNS:
+ ****************************************************************************/
+static void rxXfer_ForwardPacket (RxXfer_t* pRxXfer, TTxnStruct* pTxn)
+{
+ RxIfDescriptor_t *pRxInfo;
+ TI_UINT16 uLenFromRxInfo;
+
+ if (pTxn->uHwAddr == QOS_HW_ADDRESS)/*in case of QOS*/
+ {
+ pTxn->aBuf[0]-= QOS_SHIF_BACK_BUFFER;
+ pRxInfo = (RxIfDescriptor_t*)(pTxn->aBuf[0]);
+ /*in case of QOS we ask to read the data with 2 bytes shift so the packet will be alignd.
+ as a result we asked to read 2 bytes less,
+ since we are adding the mising 2 bytes (length)
+ we need to add those 2 bytes to the length*/
+ pTxn->aLen[0]+= QOS_LENGTH_DIFF;
+ /*devide by 4 to have the value in word (from byte)*/
+ pRxInfo->length = pTxn->aLen[0] >> 2;
+ /*fix back the endianaty and setting the missing value from the shor descriptor*/
+ pRxInfo->length = ENDIAN_HANDLE_WORD(pRxInfo->length);
+ /*now we have the a regular Rx info with all parameters */
+ pRxInfo = (RxIfDescriptor_t*)(pTxn->aBuf[0]);
+
+ }
+ else
+ {
+ /*in case of regular packet*/
+ pRxInfo = (RxIfDescriptor_t*)(pTxn->aBuf[0]);
+ }
+
+
+#ifdef TI_DBG /* packet sanity check */
+ /* Get length from RxInfo, handle endianess and convert to length in bytes */
+ uLenFromRxInfo = ENDIAN_HANDLE_WORD(pRxInfo->length) << 2;
+
+ /* If the length in the RxInfo is different than in the short descriptor, set error status */
+ if (pTxn->aLen[0] != uLenFromRxInfo)
+ {
+ TRACE3(pRxXfer->hReport, REPORT_SEVERITY_ERROR , ": Bad Length!! RxInfoLength=%d, ShortDescLen=%d, RxInfoStatus=0x%x\n", uLenFromRxInfo, pTxn->aLen[0], pRxInfo->status);
+ report_PrintDump(pTxn->aBuf[0], pTxn->aLen[0]);
+ pRxInfo->status &= ~RX_DESC_STATUS_MASK;
+ pRxInfo->status |= RX_DESC_STATUS_DRIVER_RX_Q_FAIL;
+ pRxInfo->length = ENDIAN_HANDLE_WORD(pTxn->aLen[0] >> 2);
+ }
+#endif
+
+ /* Forward received packet to the upper layers */
+ RxQueue_ReceivePacket (pRxXfer->hRxQueue, (const void *)pTxn->aBuf[0]);
+
+ /* reset the aBuf field for clean on recovery purpose */
+ pTxn->aBuf[0] = 0;
+}
+
+
+/****************************************************************************
+ * rxXfer_RxEvent()
+ ****************************************************************************
+ * DESCRIPTION: Called upon Rx event from the FW.calls the SM
+ *
+ * INPUTS: hRxXfer - RxXfer handle;
+ *
+ * OUTPUT: None
+ *
+ * RETURNS: TWIF_OK in case of Synch mode, or TWIF_PENDING in case of Asynch mode
+ * (when returning TWIF_PENDING, FwEvent module expects the FwEvent_EventComplete()
+ * function call to finish the Rx Client handling
+ *
+ ****************************************************************************/
+TI_STATUS rxXfer_RxEvent (TI_HANDLE hRxXfer, FwStatus_t *pFwStatus)
+{
+ RxXfer_t *pRxXfer = (RxXfer_t *)hRxXfer;
+ TI_UINT32 uTempCounters;
+ FwStatCntrs_t *pFwStatusCounters;
+ TI_UINT32 i;
+ TI_STATUS rc;
+
+
+ uTempCounters = ENDIAN_HANDLE_LONG (pFwStatus->counters);
+#ifdef TI_DBG
+ pRxXfer->DbgStats.counters = uTempCounters;
+#endif
+ pFwStatusCounters = (FwStatCntrs_t*)(&uTempCounters);
+
+ TRACE2(pRxXfer->hReport, REPORT_SEVERITY_INFORMATION , ": NewFwCntr=%d, OldFwCntr=%d\n", pFwStatusCounters->fwRxCntr, pRxXfer->uFwRxCntr);
+
+ if (pFwStatusCounters->fwRxCntr%8 == pRxXfer->uFwRxCntr%8)
+ {
+ return TI_OK;
+ }
+ pRxXfer->uFwRxCntr = pFwStatusCounters->fwRxCntr;
+
+ for (i = 0; i < NUM_RX_PKT_DESC; i++)
+ {
+ pRxXfer->aRxPktsDesc[i] = ENDIAN_HANDLE_LONG (pFwStatus->rxPktsDesc[i]);
+ }
+
+ rc = rxXfer_Handle (pRxXfer);
+
+ return rc;
+}
+
+
+/****************************************************************************
+ * rxXfer_Handle()
+ ****************************************************************************
+ * DESCRIPTION:
+ *
+ * INPUTS: hRxXfer - RxXfer handle;
+ *
+ * OUTPUT:
+ *
+ * RETURNS:
+ ****************************************************************************/
+TI_STATUS rxXfer_Handle(TI_HANDLE hRxXfer)
+{
+#ifndef _VLCT_
+ RxXfer_t* pRxXfer = (RxXfer_t *)hRxXfer;
+ TI_UINT32 uRxDesc, uPacketIndex, uBuffSize, uSecurity;
+ TI_UINT8 *pHostBuf;
+ ERxBufferStatus eBufStatus;
+
+
+ if (pRxXfer->uAvailableTxn == 0 )
+ {
+ TRACE0(pRxXfer->hReport, REPORT_SEVERITY_ERROR, "(): No available Txn structures left!\n");
+ return TI_NOK;
+ }
+
+ while (pRxXfer->uFwRxCntr%8 != pRxXfer->uDrvRxCntr%8)
+ {
+ uPacketIndex = pRxXfer->uDrvRxCntr % NUM_RX_PKT_DESC;
+
+ uRxDesc = pRxXfer->aRxPktsDesc[uPacketIndex];
+
+ uBuffSize = RX_DESC_GET_LENGTH(uRxDesc) << 2;
+
+ uSecurity = RX_DESC_GET_SECURITY(uRxDesc);
+
+ /* prepare the read buffer */
+ /* the RxBufAlloc() add an extra word for alignment the MAC payload in case of QoS MSDU */
+ eBufStatus = pRxXfer->RequestForBufferCB(pRxXfer->RequestForBufferCB_handle,
+ (void**)&pHostBuf,
+ uBuffSize,
+ uSecurity);
+
+ TRACE6(pRxXfer->hReport, REPORT_SEVERITY_INFORMATION , ": Index=%d, RxDesc=0x%x, DrvCntr=%d, FwCntr=%d, BufStatus=%d, BuffSize=%d\n", uPacketIndex, uRxDesc, pRxXfer->uDrvRxCntr, pRxXfer->uFwRxCntr, eBufStatus, uBuffSize);
+
+ switch (eBufStatus)
+ {
+ case RX_BUF_ALLOC_PENDING:
+ return TI_OK;
+
+ case RX_BUF_ALLOC_COMPLETE:
+ rxXfer_IssueTxn (pRxXfer, uRxDesc, pHostBuf, uBuffSize, TI_FALSE);
+ break;
+
+ case RX_BUF_ALLOC_OUT_OF_MEM:
+ /* In case the allocation failed, we read the packet to a temporary buffer and ignore it */
+ rxXfer_IssueTxn (pRxXfer, uRxDesc, pRxXfer->pTempBuffer, uBuffSize, TI_TRUE);
+ break;
+ }
+
+ /* End of while */
+ }
+#endif
+ return TI_OK;
+/* End of rxXfer_Handle() */
+}
+
+
+/****************************************************************************
+ * rxXfer_IssueTxn()
+ ****************************************************************************
+ * DESCRIPTION:
+ *
+ * INPUTS:
+ *
+ * OUTPUT:
+ *
+ * RETURNS:
+ ****************************************************************************/
+static void rxXfer_IssueTxn (TI_HANDLE hRxXfer, TI_UINT32 uRxDesc, TI_UINT8 *pHostBuf, TI_UINT32 uBuffSize, TI_BOOL bDropPacket)
+{
+ RxXfer_t *pRxXfer = (RxXfer_t *)hRxXfer;
+ TI_UINT32 uIndex = pRxXfer->uDrvRxCntr % MAX_CONSECUTIVE_READ_TXN;
+ TTxnStruct *pTxn;
+ ETxnStatus eStatus;
+
+ /* Write the next mem block that we want to read */
+ pRxXfer->aSlaveRegTxn[uIndex].tTxnStruct.uHwAddr = SLV_REG_DATA;
+ ((TI_UINT32*)(pRxXfer->aSlaveRegTxn[uIndex].pRegData))[0] = SLV_MEM_CP_VALUE(uRxDesc, pRxXfer->uPacketMemoryPoolStart);
+ ((TI_UINT32*)(pRxXfer->aSlaveRegTxn[uIndex].pRegData))[1] = SLV_MEM_ADDR_VALUE(uRxDesc, pRxXfer->uPacketMemoryPoolStart);
+ twIf_Transact(pRxXfer->hTwIf, &pRxXfer->aSlaveRegTxn[uIndex].tTxnStruct);
+
+ /* prepare the read transaction */
+ pTxn = (TTxnStruct*)&pRxXfer->aTxnStruct[uIndex];
+
+ if (!bDropPacket)
+ {
+
+ if (ALIGNMENT_SIZE(uRxDesc))
+ {
+ /*because the DMA requiers a 4 bytes alingned buffer and in the case of QOS we have
+ 2 more bytes in the WLAN header,we will give a 4 byte shifted buffer for the read.
+ in addition we will ask to read the data with 2 bytes shift, in this way we will
+ packet aligned. because of this 2 bytes shif the lenght for the read should be 2
+ bytes shorter.
+ we will loose the first 2 bytes in the read (length in the RX info),
+ */
+ BUILD_TTxnStruct(pTxn, SLV_MEM_QOS_DATA, pHostBuf +QOS_SHIF_IN_BUFFER , uBuffSize-QOS_LENGTH_DIFF, (TTxnDoneCb)rxXfer_TxnDoneCb, hRxXfer)
+ }
+ else
+ {
+ BUILD_TTxnStruct(pTxn, SLV_MEM_DATA, pHostBuf, uBuffSize, (TTxnDoneCb)rxXfer_TxnDoneCb, hRxXfer)
+ }
+
+ }
+ else
+ {
+ TRACE0(pRxXfer->hReport, REPORT_SEVERITY_WARNING, "Request for Rx buffer failed! \n");
+ BUILD_TTxnStruct(pTxn, SLV_MEM_DATA, pHostBuf, uBuffSize, NULL, NULL)
+ }
+
+ eStatus = twIf_Transact(pRxXfer->hTwIf, pTxn);
+
+ pRxXfer->uDrvRxCntr++;
+
+
+
+ pTxn = &pRxXfer->aCounterTxn[uIndex].tTxnStruct;
+ *((TI_UINT32*)(pRxXfer->aCounterTxn[uIndex].pCounter)) = ENDIAN_HANDLE_LONG(pRxXfer->uDrvRxCntr);
+ TXN_PARAM_SET(pTxn, TXN_LOW_PRIORITY, TXN_FUNC_ID_WLAN, TXN_DIRECTION_WRITE, TXN_INC_ADDR)
+ BUILD_TTxnStruct(pTxn, RX_DRIVER_COUNTER_ADDRESS, pRxXfer->aCounterTxn[uIndex].pCounter, REGISTER_SIZE, NULL, NULL)
+ twIf_Transact(pRxXfer->hTwIf, pTxn);
+
+ TRACE6(pRxXfer->hReport, REPORT_SEVERITY_INFORMATION , ": Counter-Txn: HwAddr=0x%x, Len0=%d, Data0=%d, DrvCount=%d, TxnParams=0x%x, RxDesc=0x%x\n", pTxn->uHwAddr, pTxn->aLen[0], *(TI_UINT32 *)(pTxn->aBuf[0]), pRxXfer->uDrvRxCntr, pTxn->uTxnParams, uRxDesc);
+
+
+ if (!bDropPacket)
+ {
+ if (eStatus == TXN_STATUS_COMPLETE)
+ {
+ /* Forward received packet to the upper layers */
+ rxXfer_ForwardPacket (pRxXfer, &(pRxXfer->aTxnStruct[uIndex]));
+ }
+ else if (eStatus == TXN_STATUS_PENDING)
+ {
+ /* Decrease the number of available txn structures */
+ pRxXfer->uAvailableTxn--;
+ }
+ else
+ {
+ TRACE3(pRxXfer->hReport, REPORT_SEVERITY_ERROR , ": Status=%d, DrvCntr=%d, RxDesc=0x%x\n", eStatus, pRxXfer->uDrvRxCntr, uRxDesc);
+ }
+ }
+}
+
+
+/****************************************************************************
+ * rxXfer_SetRxDirectAccessParams()
+ ****************************************************************************
+ * DESCRIPTION:
+ *
+ * INPUTS:
+ *
+ * OUTPUT:
+ *
+ * RETURNS:
+ ****************************************************************************/
+void rxXfer_SetRxDirectAccessParams (TI_HANDLE hRxXfer, TDmaParams *pDmaParams)
+{
+ RxXfer_t* pRxXfer = (RxXfer_t *)hRxXfer;
+
+ pRxXfer->uPacketMemoryPoolStart = pDmaParams->PacketMemoryPoolStart;
+}
+
+
+/****************************************************************************
+ * rxXfer_TxnDoneCb()
+ ****************************************************************************
+ * DESCRIPTION: Forward the packet to the registered CB
+ *
+ * INPUTS:
+ *
+ * OUTPUT:
+ *
+ * RETURNS:
+ ****************************************************************************/
+static void rxXfer_TxnDoneCb (TI_HANDLE hRxXfer, TTxnStruct* pTxn)
+{
+ RxXfer_t* pRxXfer = (RxXfer_t *)hRxXfer;
+
+ /* Increase the number of available txn structures */
+ pRxXfer->uAvailableTxn++;
+
+ /* Forward received packet to the upper layers */
+ rxXfer_ForwardPacket (pRxXfer, pTxn);
+
+ /* Handle further packets if any */
+ rxXfer_Handle(hRxXfer);
+}
+
+
+/****************************************************************************
+ * 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;
+ TTxnStruct* pTxn;
+ TI_UINT8 i;
+
+ pRxXfer->uFwRxCntr = 0;
+ pRxXfer->uDrvRxCntr = 0;
+ pRxXfer->uAvailableTxn = MAX_CONSECUTIVE_READ_TXN - 1;
+
+ /* Scan all transaction array and release only pending transaction */
+ for (i = 0; i < MAX_CONSECUTIVE_READ_TXN; i++)
+ {
+ pTxn = &(pRxXfer->aSlaveRegTxn[i].tTxnStruct);
+ /* Check if buffer allocated and not the local one (signed by no callback) */
+ if ((pTxn->hCbHandle != NULL) && (pTxn->aBuf[0] != 0))
+ {
+ RxIfDescriptor_t *pRxParams = (RxIfDescriptor_t*)pTxn->aBuf[0];
+
+ WLAN_OS_REPORT (("RxXfer_ReStart: clean, in loop call RxQueue_ReceivePacket with TAG_CLASS_UNKNOWN\n"));
+ /* Set TAG_CLASS_UNKNOWN and call upper layer only to release the allocated buffer */
+ pRxParams->packet_class_tag = TAG_CLASS_UNKNOWN;
+ RxQueue_ReceivePacket (pRxXfer->hRxQueue, (const void *)pTxn->aBuf[0]);
+ pTxn->aBuf[0] = 0;
+ }
+ }
+
+ for (i = 0; i < MAX_CONSECUTIVE_READ_TXN; i++)
+ {
+ pTxn = &(pRxXfer->aSlaveRegTxn[i].tTxnStruct);
+ TXN_PARAM_SET(pTxn, TXN_LOW_PRIORITY, TXN_FUNC_ID_WLAN, TXN_DIRECTION_WRITE, TXN_INC_ADDR)
+ BUILD_TTxnStruct(pTxn, SLV_REG_DATA, pRxXfer->aSlaveRegTxn[i].pRegData, REGISTER_SIZE*2, NULL, NULL)
+
+ pTxn = &pRxXfer->aTxnStruct[i];
+ TXN_PARAM_SET(pTxn, TXN_LOW_PRIORITY, TXN_FUNC_ID_WLAN, TXN_DIRECTION_READ, TXN_FIXED_ADDR)
+ }
+
+} /* RxXfer_ReStart() */
+
+
+#ifdef TI_DBG
+/****************************************************************************
+ * rxXfer_ClearStats()
+ ****************************************************************************
+ * DESCRIPTION:
+ *
+ * INPUTS:
+ * pRxXfer The object
+ *
+ * OUTPUT: None
+ *
+ * RETURNS: TI_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: TI_OK.
+ ****************************************************************************/
+void rxXfer_PrintStats (TI_HANDLE hRxXfer)
+{
+ RxXfer_t * pRxXfer = (RxXfer_t *)hRxXfer;
+
+ WLAN_OS_REPORT(("Print RX Xfer module info\n"));
+ WLAN_OS_REPORT(("=========================\n"));
+ WLAN_OS_REPORT(("Rx counter = 0x%x\n", pRxXfer->uFwRxCntr));
+ WLAN_OS_REPORT(("Drv counter = 0x%x\n", pRxXfer->uDrvRxCntr));
+ WLAN_OS_REPORT(("Fw Counters = 0x%x\n", pRxXfer->DbgStats.counters));
+ WLAN_OS_REPORT(("AvailableTxn = 0x%x\n", pRxXfer->uAvailableTxn));
+}
+#endif
+
+