diff options
Diffstat (limited to 'wl1271/TWD/FW_Transfer/RxXfer.c')
-rw-r--r-- | wl1271/TWD/FW_Transfer/RxXfer.c | 909 |
1 files changed, 0 insertions, 909 deletions
diff --git a/wl1271/TWD/FW_Transfer/RxXfer.c b/wl1271/TWD/FW_Transfer/RxXfer.c deleted file mode 100644 index 9e82964..0000000 --- a/wl1271/TWD/FW_Transfer/RxXfer.c +++ /dev/null @@ -1,909 +0,0 @@ -/* - * RxXfer.c - * - * Copyright(c) 1998 - 2010 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. - * - ****************************************************************************/ - -#define __FILE_ID__ FILE_ID_106 -#include "tidef.h" -#include "osApi.h" -#include "report.h" -#include "rxXfer_api.h" -#include "FwEvent_api.h" -#include "TWDriverInternal.h" -#include "RxQueue_api.h" -#include "TwIf.h" -#include "public_host_int.h" -#include "bmtrace_api.h" - -#define RX_DRIVER_COUNTER_ADDRESS 0x300538 -#define PLCP_HEADER_LENGTH 8 -#define WORD_SIZE 4 -#define UNALIGNED_PAYLOAD 0x1 -#define RX_DESCRIPTOR_SIZE (sizeof(RxIfDescriptor_t)) -#define MAX_PACKETS_NUMBER 8 -#define MAX_CONSECUTIVE_READ_TXN 16 -#define MAX_PACKET_SIZE 8192 /* Max Txn size */ - -#ifdef PLATFORM_SYMBIAN /* UMAC is using only one buffer and therefore we can't use consecutive reads */ - #define MAX_CONSECUTIVE_READS 1 -#else - #define MAX_CONSECUTIVE_READS 8 -#endif - -#define SLV_MEM_CP_VALUE(desc, offset) (((RX_DESC_GET_MEM_BLK(desc) << 8) + offset)) -#define ALIGNMENT_SIZE(desc) ((RX_DESC_GET_UNALIGNED(desc) & UNALIGNED_PAYLOAD) ? 2 : 0) - -#if (NUM_RX_PKT_DESC & (NUM_RX_PKT_DESC - 1)) - #error NUM_RX_PKT_DESC is not a power of 2 which may degrade performance when we calculate modulo!! -#endif - - -#ifdef TI_DBG -typedef struct -{ - TI_UINT32 uCountFwEvents; - TI_UINT32 uCountPktsForward; - TI_UINT32 uCountBufPend; - TI_UINT32 uCountBufNoMem; - TI_UINT32 uCountPktAggreg[MAX_XFER_BUFS]; - -} TRxXferDbgStat; -#endif - -typedef struct -{ - TTxnStruct tTxnStruct; - TI_UINT32 uRegData; - TI_UINT32 uRegAdata; - -} TRegTxn; - -typedef struct -{ - TTxnStruct tTxnStruct; - TI_UINT32 uCounter; - -} TCounterTxn; - -typedef struct -{ - TI_HANDLE hOs; - TI_HANDLE hReport; - TI_HANDLE hTwIf; - TI_HANDLE hFwEvent; - TI_HANDLE hRxQueue; - - TI_UINT32 aRxPktsDesc[NUM_RX_PKT_DESC]; /* Save Rx packets short descriptors from FwStatus */ - TI_UINT32 uFwRxCntr; /* Save last FW packets counter from FwStatus */ - TI_UINT32 uDrvRxCntr; /* The current driver processed packets counter */ - TI_UINT32 uPacketMemoryPoolStart; /* The FW mem-blocks area base address */ - TI_UINT32 uMaxAggregLen; /* The max length in bytes of aggregated packets transaction */ - TI_UINT32 uMaxAggregPkts; /* The max number of packets that may be aggregated in one transaction */ - TRequestForBufferCb RequestForBufferCB; /* Upper layer CB for allocating buffers for packets */ - TI_HANDLE RequestForBufferCB_handle; /* The upper later CB handle */ - TI_BOOL bPendingBuffer; /* If TRUE, we exited the Rx handler upon pending-buffer */ - - TI_UINT32 uCurrTxnIndex; /* The current Txn structures index to use */ - TI_UINT32 uAvailableTxn; /* Number of Txn structures currently available */ - TRegTxn aSlaveRegTxn[MAX_CONSECUTIVE_READ_TXN]; /* Txn structures for writing mem-block address reg */ - TTxnStruct aTxnStruct[MAX_CONSECUTIVE_READ_TXN]; /* Txn structures for reading the Rx packets */ - TCounterTxn aCounterTxn[MAX_CONSECUTIVE_READ_TXN]; /* Txn structures for writing the driver counter workaround */ - - TI_UINT8 aTempBuffer[MAX_PACKET_SIZE]; /* Dummy buffer to use if we couldn't get a buffer for the packet (so drop the packet) */ - TFailureEventCb fErrCb; /* The upper layer CB function for error handling */ - TI_HANDLE hErrCb; /* The CB function handle */ - -#ifdef TI_DBG - TRxXferDbgStat tDbgStat; -#endif - -} TRxXfer; - - -/************************ static function declaration *****************************/ -static TI_STATUS rxXfer_Handle(TI_HANDLE hRxXfer); -static void rxXfer_TxnDoneCb (TI_HANDLE hRxXfer, TTxnStruct* pTxn); -static void rxXfer_PktDropTxnDoneCb (TI_HANDLE hRxXfer, TTxnStruct *pTxn); -static ETxnStatus rxXfer_IssueTxn (TI_HANDLE hRxXfer, TI_UINT32 uFirstMemBlkAddr); -static void rxXfer_ForwardPacket (TRxXfer* 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) -{ - TRxXfer *pRxXfer; - - pRxXfer = os_memoryAlloc (hOs, sizeof(TRxXfer)); - if (pRxXfer == NULL) - return NULL; - - /* For all the counters */ - os_memoryZero (hOs, pRxXfer, sizeof(TRxXfer)); - - 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) -{ - TRxXfer *pRxXfer = (TRxXfer *)hRxXfer; - - if (pRxXfer) - { - os_memoryFree (pRxXfer->hOs, pRxXfer, sizeof(TRxXfer)); - } -} - - -/**************************************************************************** - * rxXfer_init() - **************************************************************************** - * DESCRIPTION: Init the module object - * - * INPUTS: hRxXfer - module handle; - * other modules handles. - * - * OUTPUT: None - * - * RETURNS: None - ****************************************************************************/ -void rxXfer_Init(TI_HANDLE hRxXfer, - TI_HANDLE hFwEvent, - TI_HANDLE hReport, - TI_HANDLE hTwIf, - TI_HANDLE hRxQueue) -{ - TRxXfer *pRxXfer = (TRxXfer *)hRxXfer; - pRxXfer->hFwEvent = hFwEvent; - pRxXfer->hReport = hReport; - pRxXfer->hTwIf = hTwIf; - pRxXfer->hRxQueue = hRxQueue; - - rxXfer_Restart (hRxXfer); - -#ifdef TI_DBG - rxXfer_ClearStats (pRxXfer); -#endif -} - - -/**************************************************************************** - * rxXfer_SetDefaults() - **************************************************************************** - * DESCRIPTION: Set module parameters default setting - * - * INPUTS: hRxXfer - module handle; - * - * OUTPUT: None - * - * RETURNS: None - ****************************************************************************/ -void rxXfer_SetDefaults (TI_HANDLE hRxXfer, TTwdInitParams *pInitParams) -{ - TRxXfer *pRxXfer = (TRxXfer *)hRxXfer; - - pRxXfer->uMaxAggregPkts = pInitParams->tGeneral.uRxAggregPktsLimit; -} - - -/**************************************************************************** - * rxXfer_SetBusParams() - **************************************************************************** - * DESCRIPTION: Configure bus driver DMA-able buffer length to be used as a limit to the aggragation length. - * - * INPUTS: hRxXfer - module handle - * uDmaBufLen - The bus driver DMA-able buffer length - * - * OUTPUT: None - * - * RETURNS: None - ****************************************************************************/ -void rxXfer_SetBusParams (TI_HANDLE hRxXfer, TI_UINT32 uDmaBufLen) -{ - TRxXfer *pRxXfer = (TRxXfer *)hRxXfer; - - pRxXfer->uMaxAggregLen = uDmaBufLen; -} - - -/**************************************************************************** - * 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) -{ - TRxXfer *pRxXfer = (TRxXfer *)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(s) to the upper layers. - * - * INPUTS: - * - * OUTPUT: - * - * RETURNS: - ****************************************************************************/ -static void rxXfer_ForwardPacket (TRxXfer *pRxXfer, TTxnStruct *pTxn) -{ - TI_UINT32 uBufNum; - RxIfDescriptor_t *pRxInfo = (RxIfDescriptor_t*)(pTxn->aBuf[0]); -#ifdef TI_DBG /* for packet sanity check */ - TI_UINT16 uLenFromRxInfo; -#endif - - /* Go over all occupied Txn buffers and forward their Rx packets upward */ - for (uBufNum = 0; uBufNum < MAX_XFER_BUFS; uBufNum++) - { - /* If no more buffers, exit the loop */ - if (pTxn->aLen[uBufNum] == 0) - { - break; - } - -#ifdef TI_DBG /* Packet sanity check */ - /* Get length from RxInfo, handle endianess and convert to length in bytes */ - pRxInfo = (RxIfDescriptor_t*)(pTxn->aBuf[uBufNum]); - 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[uBufNum] != uLenFromRxInfo) - { - TRACE3(pRxXfer->hReport, REPORT_SEVERITY_ERROR , "rxXfer_ForwardPacket: Bad Length!! RxInfoLength=%d, ShortDescLen=%d, RxInfoStatus=0x%x\n", uLenFromRxInfo, pTxn->aLen[uBufNum], pRxInfo->status); - - pRxInfo->status &= ~RX_DESC_STATUS_MASK; - pRxInfo->status |= RX_DESC_STATUS_DRIVER_RX_Q_FAIL; - pRxInfo->length = ENDIAN_HANDLE_WORD(pTxn->aLen[uBufNum] >> 2); - - /* If error CB available, trigger recovery !! */ - if (pRxXfer->fErrCb) - { - pRxXfer->fErrCb (pRxXfer->hErrCb, RX_XFER_FAILURE); - } - } - else - { - TRACE2(pRxXfer->hReport, REPORT_SEVERITY_INFORMATION , "rxXfer_ForwardPacket: RxInfoLength=%d, RxInfoStatus=0x%x\n", uLenFromRxInfo, pRxInfo->status); - } - pRxXfer->tDbgStat.uCountPktsForward++; -#endif - - /* This is the last packet in the Burst so mark its EndOfBurst flag */ - if (TXN_PARAM_GET_END_OF_BURST(pTxn) && (uBufNum == (MAX_XFER_BUFS - 1) || pTxn->aLen[uBufNum + 1] == 0)) - { - TXN_PARAM_SET_END_OF_BURST(pTxn, 0); - pRxInfo->driverFlags |= DRV_RX_FLAG_END_OF_BURST; - } - /* Forward received packet to the upper layers */ - RxQueue_ReceivePacket (pRxXfer->hRxQueue, (const void *)pTxn->aBuf[uBufNum]); - } - - /* 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 - * - ****************************************************************************/ -ETxnStatus rxXfer_RxEvent (TI_HANDLE hRxXfer, FwStatus_t *pFwStatus) -{ - TRxXfer *pRxXfer = (TRxXfer *)hRxXfer; - TI_UINT32 uTempCounters; - FwStatCntrs_t *pFwStatusCounters; - TI_UINT32 i; - TI_STATUS rc; - CL_TRACE_START_L2(); - - uTempCounters = ENDIAN_HANDLE_LONG (pFwStatus->counters); - pFwStatusCounters = (FwStatCntrs_t*)(&uTempCounters); - - TRACE2(pRxXfer->hReport, REPORT_SEVERITY_INFORMATION , "rxXfer_RxEvent: NewFwCntr=%d, OldFwCntr=%d\n", pFwStatusCounters->fwRxCntr, pRxXfer->uFwRxCntr); - - /* If no new Rx packets - exit */ - if ((pFwStatusCounters->fwRxCntr % NUM_RX_PKT_DESC) == (pRxXfer->uFwRxCntr % NUM_RX_PKT_DESC)) - { - CL_TRACE_END_L2("tiwlan_drv.ko", "CONTEXT", "RX", ""); - return TXN_STATUS_COMPLETE; - } - -#ifdef TI_DBG - pRxXfer->tDbgStat.uCountFwEvents++; -#endif - - /* Save current FW counter and Rx packets short descriptors for processing */ - pRxXfer->uFwRxCntr = pFwStatusCounters->fwRxCntr; - for (i = 0; i < NUM_RX_PKT_DESC; i++) - { - pRxXfer->aRxPktsDesc[i] = ENDIAN_HANDLE_LONG (pFwStatus->rxPktsDesc[i]); - } - - /* Handle all new Rx packets */ - rc = rxXfer_Handle (pRxXfer); - - CL_TRACE_END_L2("tiwlan_drv.ko", "CONTEXT", "RX", ""); - return TXN_STATUS_COMPLETE; -} - - -/**************************************************************************** - * rxXfer_Handle() - **************************************************************************** - * DESCRIPTION: - * - * INPUTS: hRxXfer - RxXfer handle; - * - * OUTPUT: - * - * RETURNS: - ****************************************************************************/ -static TI_STATUS rxXfer_Handle(TI_HANDLE hRxXfer) -{ -#ifndef _VLCT_ - TRxXfer * pRxXfer = (TRxXfer *)hRxXfer; - TI_BOOL bIssueTxn = TI_FALSE; /* If TRUE transact current aggregated packets */ - TI_BOOL bDropLastPkt = TI_FALSE; /* If TRUE, need to drop last packet (RX_BUF_ALLOC_OUT_OF_MEM) */ - TI_BOOL bExit = TI_FALSE; /* If TRUE, can't process further packets so exit (after serving the other flags) */ - TI_UINT32 uAggregPktsNum = 0; /* Number of aggregated packets */ - TI_UINT32 uFirstMemBlkAddr = 0; - TI_UINT32 uRxDesc = 0; - TI_UINT32 uBuffSize = 0; - TI_UINT32 uTotalAggregLen = 0; - TI_UINT32 uDrvIndex; - TI_UINT32 uFwIndex; - TI_UINT8 * pHostBuf; - TTxnStruct * pTxn = NULL; - ETxnStatus eTxnStatus; - ERxBufferStatus eBufStatus; - PacketClassTag_e eRxPacketType; - CL_TRACE_START_L2(); - - - /* If no Txn structures available exit!! (fatal error - not expected to happen) */ - if (pRxXfer->uAvailableTxn == 0 ) - { - TRACE0(pRxXfer->hReport, REPORT_SEVERITY_ERROR, "rxXfer_Handle: No available Txn structures left!\n"); - CL_TRACE_END_L2("tiwlan_drv.ko", "CONTEXT", "RX", ""); - return TI_NOK; - } - - uFwIndex = pRxXfer->uFwRxCntr % NUM_RX_PKT_DESC; - - /* Loop while Rx packets can be transfered from the FW */ - while (1) - { - uDrvIndex = pRxXfer->uDrvRxCntr % NUM_RX_PKT_DESC; - - /* If there are unprocessed Rx packets */ - if (uDrvIndex != uFwIndex) - { - /* Get next packte info */ - uRxDesc = pRxXfer->aRxPktsDesc[uDrvIndex]; - uBuffSize = RX_DESC_GET_LENGTH(uRxDesc) << 2; - eRxPacketType = (PacketClassTag_e)RX_DESC_GET_PACKET_CLASS_TAG (uRxDesc); - - /* If new packet exceeds max aggregation length, set flag to send previous packets (postpone it to next loop) */ - if ((uTotalAggregLen + uBuffSize) > pRxXfer->uMaxAggregLen) - { - bIssueTxn = TI_TRUE; - } - - /* No length limit so try to aggregate new packet */ - else - { - /* Allocate host read buffer */ - /* The RxBufAlloc() add an extra word for MAC header alignment in case of QoS MSDU */ - eBufStatus = pRxXfer->RequestForBufferCB(pRxXfer->RequestForBufferCB_handle, - (void**)&pHostBuf, - uBuffSize, - (TI_UINT32)NULL, - eRxPacketType); - - TRACE6(pRxXfer->hReport, REPORT_SEVERITY_INFORMATION , "rxXfer_Handle: Index=%d, RxDesc=0x%x, DrvCntr=%d, FwCntr=%d, BufStatus=%d, BuffSize=%d\n", uDrvIndex, uRxDesc, pRxXfer->uDrvRxCntr, pRxXfer->uFwRxCntr, eBufStatus, uBuffSize); - - /* If buffer allocated, add it to current Txn (up to 4 packets aggregation) */ - if (eBufStatus == RX_BUF_ALLOC_COMPLETE) - { - /* If first aggregated packet prepare the next Txn struct */ - if (uAggregPktsNum == 0) - { - pTxn = (TTxnStruct*)&(pRxXfer->aTxnStruct[pRxXfer->uCurrTxnIndex]); - pTxn->uHwAddr = SLV_MEM_DATA; - - /* Save first mem-block of first aggregated packet! */ - uFirstMemBlkAddr = SLV_MEM_CP_VALUE(uRxDesc, pRxXfer->uPacketMemoryPoolStart); - } - pTxn->aBuf[uAggregPktsNum] = pHostBuf + ALIGNMENT_SIZE(uRxDesc); - pTxn->aLen[uAggregPktsNum] = uBuffSize; - uAggregPktsNum++; - uTotalAggregLen += uBuffSize; - if (uAggregPktsNum >= pRxXfer->uMaxAggregPkts) - { - bIssueTxn = TI_TRUE; - } - pRxXfer->uDrvRxCntr++; - } - - /* If buffer pending until freeing previous buffer, set Exit flag and if needed set IssueTxn flag. */ - else if (eBufStatus == RX_BUF_ALLOC_PENDING) - { - bExit = TI_TRUE; - pRxXfer->bPendingBuffer = TI_TRUE; - if (uAggregPktsNum > 0) - { - bIssueTxn = TI_TRUE; - } -#ifdef TI_DBG - pRxXfer->tDbgStat.uCountBufPend++; -#endif - } - - /* If no buffer due to out-of-memory, set DropLastPkt flag and if needed set IssueTxn flag. */ - else - { - bDropLastPkt = TI_TRUE; - if (uAggregPktsNum > 0) - { - bIssueTxn = TI_TRUE; - } -#ifdef TI_DBG - pRxXfer->tDbgStat.uCountBufNoMem++; -#endif - } - } - } - - /* If no more packets, set Exit flag and if needed set IssueTxn flag. */ - else - { - bExit = TI_TRUE; - if (uAggregPktsNum > 0) - { - bIssueTxn = TI_TRUE; - } - } - - - /* If required to send Rx packet(s) transaction */ - if (bIssueTxn) - { - if (bExit) - { - TXN_PARAM_SET_END_OF_BURST(pTxn, 1); - } - /* If not all 4 Txn buffers are used, reset first unused buffer length for indication */ - if (uAggregPktsNum < MAX_XFER_BUFS) - { - pTxn->aLen[uAggregPktsNum] = 0; - } - - eTxnStatus = rxXfer_IssueTxn (pRxXfer, uFirstMemBlkAddr); - - if (eTxnStatus == TXN_STATUS_COMPLETE) - { - /* Forward received packet to the upper layers */ - rxXfer_ForwardPacket (pRxXfer, pTxn); - } - else if (eTxnStatus == TXN_STATUS_PENDING) - { - /* Decrease the number of available txn structures */ - pRxXfer->uAvailableTxn--; - } - else - { - TRACE3(pRxXfer->hReport, REPORT_SEVERITY_ERROR , "rxXfer_Handle: Status=%d, DrvCntr=%d, RxDesc=0x%x\n", eTxnStatus, pRxXfer->uDrvRxCntr, uRxDesc); - } - -#ifdef TI_DBG - pRxXfer->tDbgStat.uCountPktAggreg[uAggregPktsNum - 1]++; -#endif - - uAggregPktsNum = 0; - uTotalAggregLen = 0; - bIssueTxn = TI_FALSE; - pRxXfer->uCurrTxnIndex = (pRxXfer->uCurrTxnIndex + 1) % MAX_CONSECUTIVE_READ_TXN; - } - - /* If last packet should be dropped (no memory for host buffer) */ - if (bDropLastPkt) - { - /* Increment driver packets counter before calling rxXfer_IssueTxn() */ - pRxXfer->uDrvRxCntr++; - - /* Read packet to dummy buffer and ignore it (no callback needed) */ - uFirstMemBlkAddr = SLV_MEM_CP_VALUE(uRxDesc, pRxXfer->uPacketMemoryPoolStart); - pTxn = (TTxnStruct*)&pRxXfer->aTxnStruct[pRxXfer->uCurrTxnIndex]; - BUILD_TTxnStruct(pTxn, SLV_MEM_DATA, pRxXfer->aTempBuffer, uBuffSize, (TTxnDoneCb)rxXfer_PktDropTxnDoneCb, hRxXfer) - eTxnStatus = rxXfer_IssueTxn (pRxXfer, uFirstMemBlkAddr); - if (eTxnStatus == TXN_STATUS_PENDING) - { - pRxXfer->uAvailableTxn--; - } - pRxXfer->uCurrTxnIndex = (pRxXfer->uCurrTxnIndex + 1) % MAX_CONSECUTIVE_READ_TXN; - bDropLastPkt = TI_FALSE; - } - - /* Can't process more packets so exit */ - if (bExit) - { - CL_TRACE_END_L2("tiwlan_drv.ko", "CONTEXT", "RX", ""); - return TI_OK; - } - - } /* End of while(1) */ - - /* Unreachable code */ - -#endif -} - - -/**************************************************************************** - * rxXfer_IssueTxn() - **************************************************************************** - * DESCRIPTION: - * - * INPUTS: - * - * OUTPUT: - * - * RETURNS: - ****************************************************************************/ -static ETxnStatus rxXfer_IssueTxn (TI_HANDLE hRxXfer, TI_UINT32 uFirstMemBlkAddr) -{ - TRxXfer *pRxXfer = (TRxXfer *)hRxXfer; - TI_UINT32 uIndex = pRxXfer->uCurrTxnIndex; - TTxnStruct *pTxn; - ETxnStatus eStatus; - - /* Write the next mem block that we want to read */ - pTxn = &pRxXfer->aSlaveRegTxn[uIndex].tTxnStruct; - pTxn->uHwAddr = SLV_REG_DATA; - pRxXfer->aSlaveRegTxn[uIndex].uRegData = ENDIAN_HANDLE_LONG(uFirstMemBlkAddr); - pRxXfer->aSlaveRegTxn[uIndex].uRegAdata = ENDIAN_HANDLE_LONG(uFirstMemBlkAddr + 4); - twIf_Transact(pRxXfer->hTwIf, pTxn); - - /* Issue the packet(s) read transaction (prepared in rxXfer_Handle) */ - pTxn = &pRxXfer->aTxnStruct[uIndex]; - eStatus = twIf_Transact(pRxXfer->hTwIf, pTxn); - - /* Write driver packets counter to FW. This write automatically generates interrupt to FW */ - /* Note: Workaround for WL6-PG1.0 is still needed for PG2.0 ==> if (pRxXfer->bChipIs1273Pg10) */ - pTxn = &pRxXfer->aCounterTxn[uIndex].tTxnStruct; - pTxn->uHwAddr = RX_DRIVER_COUNTER_ADDRESS; - pRxXfer->aCounterTxn[uIndex].uCounter = ENDIAN_HANDLE_LONG(pRxXfer->uDrvRxCntr); - twIf_Transact(pRxXfer->hTwIf, pTxn); - - TRACE5(pRxXfer->hReport, REPORT_SEVERITY_INFORMATION , "rxXfer_IssueTxn: Counter-Txn: HwAddr=0x%x, Len0=%d, Data0=%d, DrvCount=%d, TxnParams=0x%x\n", pTxn->uHwAddr, pTxn->aLen[0], *(TI_UINT32 *)(pTxn->aBuf[0]), pRxXfer->uDrvRxCntr, pTxn->uTxnParams); - - /* Return the status of the packet(s) transaction - COMPLETE, PENDING or ERROR */ - return eStatus; -} - - -/**************************************************************************** - * rxXfer_SetRxDirectAccessParams() - **************************************************************************** - * DESCRIPTION: - * - * INPUTS: - * - * OUTPUT: - * - * RETURNS: - ****************************************************************************/ -void rxXfer_SetRxDirectAccessParams (TI_HANDLE hRxXfer, TDmaParams *pDmaParams) -{ - TRxXfer *pRxXfer = (TRxXfer *)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) -{ - TRxXfer *pRxXfer = (TRxXfer *)hRxXfer; - CL_TRACE_START_L2(); - - /* Increase the number of available txn structures */ - pRxXfer->uAvailableTxn++; - - /* Forward received packet to the upper layers */ - rxXfer_ForwardPacket (pRxXfer, pTxn); - - /* If we exited the handler upon pending-buffer, call it again to handle further packets if any */ - if (pRxXfer->bPendingBuffer) - { - pRxXfer->bPendingBuffer = TI_FALSE; - rxXfer_Handle (hRxXfer); - } - - CL_TRACE_END_L2("tiwlan_drv.ko", "INHERIT", "RX", ""); -} - - -/**************************************************************************** - * rxXfer_PktDropTxnDoneCb() - **************************************************************************** - * DESCRIPTION: Dummy CB for case of dropping a packet due to out-of-memory. - * - * INPUTS: - * - * OUTPUT: - * - * RETURNS: - ****************************************************************************/ -static void rxXfer_PktDropTxnDoneCb (TI_HANDLE hRxXfer, TTxnStruct *pTxn) -{ - TRxXfer *pRxXfer = (TRxXfer *)hRxXfer; - - /* Increase the number of available txn structures */ - pRxXfer->uAvailableTxn++; - - /* Restore the regular TxnDone callback to the used structure */ - pTxn->fTxnDoneCb = (TTxnDoneCb)rxXfer_TxnDoneCb; - pTxn->hCbHandle = 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) -{ - TRxXfer *pRxXfer = (TRxXfer *)hRxXfer; - TTxnStruct* pTxn; - TI_UINT8 i; - - pRxXfer->uFwRxCntr = 0; - pRxXfer->uDrvRxCntr = 0; - pRxXfer->uCurrTxnIndex = 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->aTxnStruct[i]); - - /* Check if buffer allocated and not the dummy one (has a different callback) */ - if ((pTxn->aBuf[0] != 0) && (pTxn->fTxnDoneCb == (TTxnDoneCb)rxXfer_TxnDoneCb)) - { - TI_UINT32 uBufNum; - RxIfDescriptor_t *pRxParams; - - /* Go over the Txn occupied buffers and mark them as TAG_CLASS_UNKNOWN to be freed */ - for (uBufNum = 0; uBufNum < MAX_XFER_BUFS; uBufNum++) - { - /* If no more buffers, exit the loop */ - if (pTxn->aLen[uBufNum] == 0) - { - break; - } - - pRxParams = (RxIfDescriptor_t *)(pTxn->aBuf[uBufNum]); - pRxParams->packet_class_tag = TAG_CLASS_UNKNOWN; - } - - /* Call upper layer only to release the allocated buffer */ - rxXfer_ForwardPacket (pRxXfer, pTxn); - } - } - - /* Fill the transaction structures fields that have constant values */ - for (i = 0; i < MAX_CONSECUTIVE_READ_TXN; i++) - { - /* First mem-block address (two consecutive registers) */ - 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].uRegData, REGISTER_SIZE*2, NULL, NULL) - - /* The packet(s) read transaction */ - pTxn = &(pRxXfer->aTxnStruct[i]); - TXN_PARAM_SET(pTxn, TXN_LOW_PRIORITY, TXN_FUNC_ID_WLAN, TXN_DIRECTION_READ, TXN_FIXED_ADDR) - pTxn->fTxnDoneCb = (TTxnDoneCb)rxXfer_TxnDoneCb; - pTxn->hCbHandle = hRxXfer; - - /* The driver packets counter */ - pTxn = &(pRxXfer->aCounterTxn[i].tTxnStruct); - 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[i].uCounter, REGISTER_SIZE, NULL, NULL) - } - -} - - -/**************************************************************************** - * rxXfer_RegisterErrCb() - **************************************************************************** - * DESCRIPTION: Register Error CB - * - * INPUTS: - * hRxXfer - The object - * ErrCb - The upper layer CB function for error handling - * hErrCb - The CB function handle - * - * OUTPUT: None - * - * RETURNS: void - ****************************************************************************/ -void rxXfer_RegisterErrCb (TI_HANDLE hRxXfer, void *fErrCb, TI_HANDLE hErrCb) -{ - TRxXfer *pRxXfer = (TRxXfer *)hRxXfer; - - /* Save upper layer (health monitor) CB for recovery from fatal error */ - pRxXfer->fErrCb = (TFailureEventCb)fErrCb; - pRxXfer->hErrCb = hErrCb; -} - - -#ifdef TI_DBG -/**************************************************************************** - * rxXfer_ClearStats() - **************************************************************************** - * DESCRIPTION: - * - * INPUTS: - * pRxXfer The object - * - * OUTPUT: None - * - * RETURNS: TI_OK. - ****************************************************************************/ -void rxXfer_ClearStats (TI_HANDLE hRxXfer) -{ - TRxXfer *pRxXfer = (TRxXfer *)hRxXfer; - - os_memoryZero (pRxXfer->hOs, &pRxXfer->tDbgStat, sizeof(TRxXferDbgStat)); -} - - -/**************************************************************************** - * rxXfer_PrintStats() - **************************************************************************** - * DESCRIPTION: . - * - * INPUTS: - * pRxXfer The object - * - * OUTPUT: None - * - * RETURNS: TI_OK. - ****************************************************************************/ -void rxXfer_PrintStats (TI_HANDLE hRxXfer) -{ -#ifdef REPORT_LOG - TRxXfer *pRxXfer = (TRxXfer *)hRxXfer; - - WLAN_OS_REPORT(("Print RX Xfer module info\n")); - WLAN_OS_REPORT(("=========================\n")); - WLAN_OS_REPORT(("uMaxAggregPkts = %d\n", pRxXfer->uMaxAggregPkts)); - WLAN_OS_REPORT(("uMaxAggregLen = %d\n", pRxXfer->uMaxAggregLen)); - WLAN_OS_REPORT(("FW counter = %d\n", pRxXfer->uFwRxCntr)); - WLAN_OS_REPORT(("Drv counter = %d\n", pRxXfer->uDrvRxCntr)); - WLAN_OS_REPORT(("AvailableTxn = %d\n", pRxXfer->uAvailableTxn)); - WLAN_OS_REPORT(("uCountFwEvents = %d\n", pRxXfer->tDbgStat.uCountFwEvents)); - WLAN_OS_REPORT(("uCountPktsForward = %d\n", pRxXfer->tDbgStat.uCountPktsForward)); - WLAN_OS_REPORT(("uCountBufPend = %d\n", pRxXfer->tDbgStat.uCountBufPend)); - WLAN_OS_REPORT(("uCountBufNoMem = %d\n", pRxXfer->tDbgStat.uCountBufNoMem)); - WLAN_OS_REPORT(("uCountPktAggreg-1 = %d\n", pRxXfer->tDbgStat.uCountPktAggreg[0])); - WLAN_OS_REPORT(("uCountPktAggreg-2 = %d\n", pRxXfer->tDbgStat.uCountPktAggreg[1])); - WLAN_OS_REPORT(("uCountPktAggreg-3 = %d\n", pRxXfer->tDbgStat.uCountPktAggreg[2])); - WLAN_OS_REPORT(("uCountPktAggreg-4 = %d\n", pRxXfer->tDbgStat.uCountPktAggreg[3])); -#endif -} -#endif |