summaryrefslogtreecommitdiff
path: root/wl1271/TWD/FW_Transfer/txXfer.c
diff options
context:
space:
mode:
Diffstat (limited to 'wl1271/TWD/FW_Transfer/txXfer.c')
-rw-r--r--wl1271/TWD/FW_Transfer/txXfer.c444
1 files changed, 0 insertions, 444 deletions
diff --git a/wl1271/TWD/FW_Transfer/txXfer.c b/wl1271/TWD/FW_Transfer/txXfer.c
deleted file mode 100644
index 1497a09..0000000
--- a/wl1271/TWD/FW_Transfer/txXfer.c
+++ /dev/null
@@ -1,444 +0,0 @@
-/*
- * txXfer.c
- *
- * Copyright(c) 1998 - 2009 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.
- */
-
-
-/** \file txXfer.c
- * \brief Handle Tx packets transfer to the firmware.
- *
- * This module gets the upper driver's Tx packets after FW resources were
- * allocated for them, aggregates them if possible, and handles their transfer
- * to the FW via the host slave (indirect) interface, using the TwIf Transaction API.
- * The aggregation processing is completed by the BusDrv where the packets are combined
- * and sent to the FW in one transaction.
- *
- * \see
- */
-
-
-#define __FILE_ID__ FILE_ID_108
-#include "tidef.h"
-#include "osApi.h"
-#include "report.h"
-#include "TwIf.h"
-#include "TWDriver.h"
-#include "txXfer_api.h"
-
-
-#ifdef TI_DBG
-#define DBG_MAX_AGGREG_PKTS 16
-#endif
-
-typedef struct
-{
- TTxnStruct tTxnStruct;
- TI_UINT32 uPktsCntr;
-} TPktsCntrTxn;
-
-/* The TxXfer module object. */
-typedef struct
-{
- TI_HANDLE hOs;
- TI_HANDLE hReport;
- TI_HANDLE hTwIf;
-
- TI_UINT32 uAggregMaxPkts; /* Max number of packets that may be aggregated */
- TI_UINT32 uAggregMaxLen; /* Max length in bytes of a single aggregation */
- TI_UINT32 uAggregPktsNum; /* Number of packets in current aggregation */
- TI_UINT32 uAggregPktsLen; /* Aggregated length of current aggregation */
- TTxCtrlBlk * pAggregFirstPkt; /* Pointer to the first packet of current aggregation */
- TTxCtrlBlk * pAggregLastPkt; /* Pointer to the last packet of current aggregation */
- TSendPacketTranferCb fSendPacketTransferCb; /* Upper layer Xfer-Complete callback */
- TI_HANDLE hSendPacketTransferHndl; /* Upper layer Xfer-Complete callback handle */
- TTxnDoneCb fXferCompleteLocalCb; /* TxXfer local CB for pkt transfer completion (NULL is not needed!) */
- TI_UINT32 uPktsCntr; /* Counts all Tx packets. Written to FW after each packet transaction */
- TI_UINT32 uPktsCntrTxnIndex; /* The current indext of the aPktsCntrTxn[] used for the counter workaround transactions */
- TPktsCntrTxn aPktsCntrTxn[CTRL_BLK_ENTRIES_NUM]; /* Transaction structures for sending the packets counter */
-#ifdef TI_DBG
- TI_UINT32 aDbgCountPktAggreg[DBG_MAX_AGGREG_PKTS];
-#endif
-
-} TTxXferObj;
-
-static ETxnStatus txXfer_SendAggregatedPkts (TTxXferObj *pTxXfer, TI_BOOL bLastPktSentNow);
-static void txXfer_TransferDoneCb (TI_HANDLE hTxXfer, TTxnStruct *pTxn);
-
-
-/********************************************************************************
-* *
-* PUBLIC FUNCTIONS IMPLEMENTATION *
-* *
-*********************************************************************************/
-
-
-TI_HANDLE txXfer_Create(TI_HANDLE hOs)
-{
- TTxXferObj *pTxXfer;
-
- pTxXfer = os_memoryAlloc (hOs, sizeof(TTxXferObj));
- if (pTxXfer == NULL)
- {
- return NULL;
- }
-
- os_memoryZero (hOs, pTxXfer, sizeof(TTxXferObj));
-
- pTxXfer->hOs = hOs;
-
- return (TI_HANDLE)pTxXfer;
-}
-
-
-TI_STATUS txXfer_Destroy(TI_HANDLE hTxXfer)
-{
- TTxXferObj *pTxXfer = (TTxXferObj *)hTxXfer;
-
- if (pTxXfer)
- {
- os_memoryFree (pTxXfer->hOs, pTxXfer, sizeof(TTxXferObj));
- }
-
- return TI_OK;
-}
-
-
-TI_STATUS txXfer_Init (TI_HANDLE hTxXfer, TI_HANDLE hReport, TI_HANDLE hTwIf)
-{
- TTxXferObj *pTxXfer = (TTxXferObj *)hTxXfer;
- TTxnStruct *pTxn;
- TI_UINT8 i;
-
- pTxXfer->hReport = hReport;
- pTxXfer->hTwIf = hTwIf;
- pTxXfer->fSendPacketTransferCb = NULL;
- pTxXfer->fXferCompleteLocalCb = NULL;
-
- for (i = 0; i < CTRL_BLK_ENTRIES_NUM; i++)
- {
- pTxn = &(pTxXfer->aPktsCntrTxn[i].tTxnStruct);
- TXN_PARAM_SET(pTxn, TXN_LOW_PRIORITY, TXN_FUNC_ID_WLAN, TXN_DIRECTION_WRITE, TXN_INC_ADDR)
- BUILD_TTxnStruct(pTxn, HOST_WR_ACCESS_REG, &pTxXfer->aPktsCntrTxn[i].uPktsCntr, REGISTER_SIZE, NULL, NULL)
- }
-
- return txXfer_Restart(hTxXfer);
-}
-
-
-TI_STATUS txXfer_Restart (TI_HANDLE hTxXfer)
-{
- TTxXferObj *pTxXfer = (TTxXferObj *)hTxXfer;
-
- pTxXfer->uPktsCntr = 0;
- pTxXfer->uPktsCntrTxnIndex = 0;
- pTxXfer->uAggregPktsNum = 0;
-
- return TI_OK;
-}
-
-
-void txXfer_SetDefaults (TI_HANDLE hTxXfer, TTwdInitParams *pInitParams)
-{
- TTxXferObj *pTxXfer = (TTxXferObj *)hTxXfer;
-
- pTxXfer->uAggregMaxPkts = pInitParams->tGeneral.uTxAggregPktsLimit;
-}
-
-
-void txXfer_SetBusParams (TI_HANDLE hTxXfer, TI_UINT32 uDmaBufLen)
-{
- TTxXferObj *pTxXfer = (TTxXferObj *)hTxXfer;
-
- pTxXfer->uAggregMaxLen = uDmaBufLen;
-}
-
-
-void txXfer_RegisterCb (TI_HANDLE hTxXfer, TI_UINT32 CallBackID, void *CBFunc, TI_HANDLE CBObj)
-{
- TTxXferObj* pTxXfer = (TTxXferObj*)hTxXfer;
-
- TRACE3(pTxXfer->hReport, REPORT_SEVERITY_INFORMATION, "txXfer_RegisterCb: CallBackID=%d, CBFunc=0x%x, CBObj=0x%x\n", CallBackID, CBFunc, CBObj);
-
- switch(CallBackID)
- {
- /* Save upper layers Transfer-Done callback */
- case TWD_INT_SEND_PACKET_TRANSFER:
- pTxXfer->fSendPacketTransferCb = (TSendPacketTranferCb)CBFunc;
- pTxXfer->hSendPacketTransferHndl = CBObj;
- /* Set also the local CB so we are called upon Async transaction completion to call the upper CB */
- pTxXfer->fXferCompleteLocalCb = (TTxnDoneCb)txXfer_TransferDoneCb;
- break;
-
- default:
- TRACE0(pTxXfer->hReport, REPORT_SEVERITY_ERROR, " - Illegal value\n");
- break;
- }
-}
-
-
-ETxnStatus txXfer_SendPacket (TI_HANDLE hTxXfer, TTxCtrlBlk *pPktCtrlBlk)
-{
- TTxXferObj *pTxXfer = (TTxXferObj *)hTxXfer;
- TI_UINT32 uPktLen = ENDIAN_HANDLE_WORD(pPktCtrlBlk->tTxDescriptor.length << 2); /* swap back for endianess if needed */
- ETxnStatus eStatus;
-
- /* If starting a new aggregation, prepare it, and send packet if aggregation is disabled. */
- if (pTxXfer->uAggregPktsNum == 0)
- {
- pTxXfer->uAggregPktsNum = 1;
- pTxXfer->uAggregPktsLen = uPktLen;
- pTxXfer->pAggregFirstPkt = pPktCtrlBlk;
- pTxXfer->pAggregLastPkt = pPktCtrlBlk;
- pPktCtrlBlk->pNextAggregEntry = pPktCtrlBlk; /* First packet points to itself */
- if (pTxXfer->uAggregMaxPkts <= 1)
- {
- eStatus = txXfer_SendAggregatedPkts (pTxXfer, TI_TRUE);
- pTxXfer->uAggregPktsNum = 0;
- }
- else
- {
- eStatus = TXN_STATUS_PENDING;
- }
- }
-
- /* Else, if new packet can be added to aggregation, add it and set status as Pending. */
- else if ((pTxXfer->uAggregPktsNum + 1 <= pTxXfer->uAggregMaxPkts) &&
- (pTxXfer->uAggregPktsLen + uPktLen <= pTxXfer->uAggregMaxLen))
- {
- pTxXfer->uAggregPktsNum++;
- pTxXfer->uAggregPktsLen += uPktLen;
- pTxXfer->pAggregLastPkt->pNextAggregEntry = pPktCtrlBlk; /* Link new packet to last */
- pTxXfer->pAggregLastPkt = pPktCtrlBlk; /* Save new packet as last */
- pPktCtrlBlk->pNextAggregEntry = pTxXfer->pAggregFirstPkt; /* Point from last to first */
- eStatus = TXN_STATUS_PENDING;
- }
-
- /* Else, we can't add the new packet, so send current aggregation and start a new one */
- else
- {
- txXfer_SendAggregatedPkts (pTxXfer, TI_FALSE);
- eStatus = TXN_STATUS_PENDING; /* The current packet is not sent yet so return Pending */
- pTxXfer->uAggregPktsNum = 1;
- pTxXfer->uAggregPktsLen = uPktLen;
- pTxXfer->pAggregFirstPkt = pPktCtrlBlk;
- pTxXfer->pAggregLastPkt = pPktCtrlBlk;
- pPktCtrlBlk->pNextAggregEntry = pPktCtrlBlk; /* First packet points to itself */
- }
-
-
- /* Return the Txn result - COMPLETE or PENDING. */
- /* Note: For PENDING, a callback function will be called only if registered (needed for WHA) */
- return eStatus;
-}
-
-
-void txXfer_EndOfBurst (TI_HANDLE hTxXfer)
-{
- TTxXferObj *pTxXfer = (TTxXferObj *)hTxXfer;
-
- if (pTxXfer->uAggregPktsNum > 0)
- {
- /* No more packets from TxDataQ so send any aggregated packets and clear aggregation */
- txXfer_SendAggregatedPkts (pTxXfer, TI_FALSE);
- pTxXfer->uAggregPktsNum = 0;
- }
-}
-
-
-/********************************************************************************
-* *
-* INTERNAL FUNCTIONS IMPLEMENTATION *
-* *
-*********************************************************************************/
-
-/**
- * \fn txXfer_SendAggregatedPkts
- * \brief Send aggregated Tx packets to bus Txn layer
- *
- * Send aggregated Tx packets to bus Txn layer one by one.
- * Increase the packets counter by the number of packets and send it to the FW (generates an interrupt).
- * If xfer completion CB is registered and status is Complete, call CB for all packets (except last one if inseted now).
- *
- * \note The BusDrv combines the packets and sends them in one transaction.
- * \param pTxXfer - The module's object
- * \param bLastPktSentNow - If TRUE, last packet in the aggregation was inserted in current call to txXfer_SendPacket.
- * \return COMPLETE if transaction completed in this context, PENDING if not, ERROR if failed
- * \sa
- */
-static ETxnStatus txXfer_SendAggregatedPkts (TTxXferObj *pTxXfer, TI_BOOL bLastPktSentNow)
-{
- TTxCtrlBlk *pCurrPkt;
- TTxnStruct *pTxn;
- TPktsCntrTxn *pPktsCntrTxn;
- ETxnStatus eStatus = TXN_STATUS_COMPLETE;
- TI_UINT32 i;
-
- /* Prepare and send all aggregated packets (combined and sent in one transaction by the BusDrv) */
- pCurrPkt = pTxXfer->pAggregFirstPkt;
- for (i = 0; i < pTxXfer->uAggregPktsNum; i++)
- {
- pTxn = (TTxnStruct *)pCurrPkt;
-
- /* If not last packet, set aggregation flag, clear completion CB and progress to next packet */
- if (i < pTxXfer->uAggregPktsNum - 1)
- {
- TXN_PARAM_SET_AGGREGATE(pTxn, TXN_AGGREGATE_ON);
- pTxn->fTxnDoneCb = NULL;
- pCurrPkt = pCurrPkt->pNextAggregEntry;
- }
- /* If last packet, clear aggregation flag and set completion CB (exist only if registered) */
- else
- {
- TXN_PARAM_SET_AGGREGATE(pTxn, TXN_AGGREGATE_OFF);
- pTxn->fTxnDoneCb = pTxXfer->fXferCompleteLocalCb;
- pTxn->hCbHandle = (TI_HANDLE)pTxXfer;
- }
-
- /* Send packet */
- pTxn->uHwAddr = SLV_MEM_DATA;
- eStatus = twIf_Transact (pTxXfer->hTwIf, pTxn);
- }
-
-#ifdef TI_DBG
- pTxXfer->aDbgCountPktAggreg[pTxXfer->uAggregPktsNum]++;
- TRACE5(pTxXfer->hReport, REPORT_SEVERITY_INFORMATION, "txXfer_SendAggregatedPkts: Status=%d, NumPkts=%d, AggregLen=%d, pFirstPkt=0x%x, pLastPkt=0x%x\n", eStatus, pTxXfer->uAggregPktsNum, pTxXfer->uAggregPktsLen, pTxXfer->pAggregFirstPkt, pTxXfer->pAggregLastPkt);
- if (eStatus == TXN_STATUS_ERROR)
- {
- TRACE5(pTxXfer->hReport, REPORT_SEVERITY_ERROR, "txXfer_SendAggregatedPkts: Status=%d, NumPkts=%d, AggregLen=%d, pFirstPkt=0x%x, pLastPkt=0x%x\n", eStatus, pTxXfer->uAggregPktsNum, pTxXfer->uAggregPktsLen, pTxXfer->pAggregFirstPkt, pTxXfer->pAggregLastPkt);
- return eStatus;
- }
-#endif /* TI_DBG */
-
- /* Write packet counter to FW (generates an interrupt).
- Note: This may be removed once the host-slave HW counter functionality is verified */
- pTxXfer->uPktsCntr += pTxXfer->uAggregPktsNum;
- pTxXfer->uPktsCntrTxnIndex++;
- if (pTxXfer->uPktsCntrTxnIndex == CTRL_BLK_ENTRIES_NUM)
- {
- pTxXfer->uPktsCntrTxnIndex = 0;
- }
- pPktsCntrTxn = &(pTxXfer->aPktsCntrTxn[pTxXfer->uPktsCntrTxnIndex]);
- pPktsCntrTxn->uPktsCntr = ENDIAN_HANDLE_LONG(pTxXfer->uPktsCntr);
- pPktsCntrTxn->tTxnStruct.uHwAddr = HOST_WR_ACCESS_REG;
- twIf_Transact(pTxXfer->hTwIf, &pPktsCntrTxn->tTxnStruct);
-
- /* If xfer completion CB is registered and last packet status is Complete, call the CB for all
- * packets except the input one (covered by the return code).
- */
- if (pTxXfer->fSendPacketTransferCb && (eStatus == TXN_STATUS_COMPLETE))
- {
- /* Don't call CB for last packet if inserted in current Tx */
- TI_UINT32 uNumCbCalls = bLastPktSentNow ? (pTxXfer->uAggregPktsNum - 1) : pTxXfer->uAggregPktsNum;
-
- pCurrPkt = pTxXfer->pAggregFirstPkt;
- for (i = 0; i < uNumCbCalls; i++)
- {
- pTxXfer->fSendPacketTransferCb (pTxXfer->hSendPacketTransferHndl, pCurrPkt);
- pCurrPkt = pCurrPkt->pNextAggregEntry;
- }
- }
-
- /* Return the Txn result - COMPLETE or PENDING. */
- /* Note: For PENDING, a callback function will be called only if registered (needed for WHA) */
- return eStatus;
-}
-
-
-/**
- * \fn txXfer_TransferDoneCb
- * \brief Send aggregated Tx packets to bus Txn layer
- *
- * Call the upper layers TranferDone CB for all packets of the completed aggregation
- * This function is called only if the upper layers registered their CB (used only by WHA)
- *
- * \note
- * \param pTxXfer - The module's object
- * \return COMPLETE if completed in this context, PENDING if not, ERROR if failed
- * \sa
- */
-static void txXfer_TransferDoneCb (TI_HANDLE hTxXfer, TTxnStruct *pTxn)
-{
- TTxXferObj *pTxXfer = (TTxXferObj*)hTxXfer;
- TTxCtrlBlk *pInputPkt = (TTxCtrlBlk *)pTxn; /* This is the last packet of the aggregation */
- TTxCtrlBlk *pCurrPkt;
- TI_UINT32 i;
-
- /* Call the upper layers TranferDone CB for all packets of the completed aggregation */
- /* Note: If this CB was called it means that the upper CB exists */
- pCurrPkt = pInputPkt->pNextAggregEntry; /* The last packet of the aggregation point to the first one */
- for (i = 0; i < pTxXfer->uAggregMaxPkts; i++)
- {
- pTxXfer->fSendPacketTransferCb (pTxXfer->hSendPacketTransferHndl, pCurrPkt);
-
- /* If we got back to the input packet we went over all the aggregation */
- if (pCurrPkt == pInputPkt)
- {
- break;
- }
-
- pCurrPkt = pCurrPkt->pNextAggregEntry;
- }
-
- TRACE3(pTxXfer->hReport, REPORT_SEVERITY_INFORMATION, "txXfer_TransferDoneCb: NumPkts=%d, pInputPkt=0x%x, pCurrPkt=0x%x\n", i + 1, pInputPkt, pCurrPkt);
-}
-
-
-#ifdef TI_DBG
-
-void txXfer_ClearStats (TI_HANDLE hTxXfer)
-{
- TTxXferObj *pTxXfer = (TTxXferObj*)hTxXfer;
-
- os_memoryZero (pTxXfer->hOs, &pTxXfer->aDbgCountPktAggreg, sizeof(pTxXfer->aDbgCountPktAggreg));
-}
-
-void txXfer_PrintStats (TI_HANDLE hTxXfer)
-{
-#ifdef REPORT_LOG
- TTxXferObj *pTxXfer = (TTxXferObj*)hTxXfer;
- TI_UINT32 i;
-
- WLAN_OS_REPORT(("Print Tx Xfer module info\n"));
- WLAN_OS_REPORT(("=========================\n"));
- WLAN_OS_REPORT(("uAggregMaxPkts = %d\n", pTxXfer->uAggregMaxPkts));
- WLAN_OS_REPORT(("uAggregMaxLen = %d\n", pTxXfer->uAggregMaxLen));
- WLAN_OS_REPORT(("uAggregPktsNum = %d\n", pTxXfer->uAggregPktsNum));
- WLAN_OS_REPORT(("uAggregPktsLen = %d\n", pTxXfer->uAggregPktsLen));
- WLAN_OS_REPORT(("uPktsCntr = %d\n", pTxXfer->uPktsCntr));
- WLAN_OS_REPORT(("uPktsCntrTxnIndex = %d\n", pTxXfer->uPktsCntrTxnIndex));
- for (i = 1; i < DBG_MAX_AGGREG_PKTS; i++)
- {
- WLAN_OS_REPORT(("uCountPktAggreg-%2d = %d\n", i, pTxXfer->aDbgCountPktAggreg[i]));
- }
-#endif
-}
-
-#endif /* TI_DBG */