diff options
Diffstat (limited to 'wl1271/TWD/FW_Transfer/txXfer.c')
-rw-r--r-- | wl1271/TWD/FW_Transfer/txXfer.c | 444 |
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 */ |