--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/TWD/FW_Transfer/txXfer.c Tue Jun 29 12:34:26 2010 +0100
@@ -0,0 +1,328 @@
+/*
+ * txXfer.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: txXfer.c
+ *
+ * PURPOSE: Handle Tx frame transfer to the firmware.
+ *
+ * DESCRIPTION:
+ * ============
+ * This module gets the upper driver's Tx packets after FW resources were
+ * allocated for it, and handles its transfer to the FW via the
+ * host slave (indirect) interface, using the TwIf Transaction API.
+ *
+ ****************************************************************************/
+
+#define __FILE_ID__ FILE_ID_108
+#include "tidef.h"
+#include "osApi.h"
+#include "report.h"
+#include "TwIf.h"
+#include "TWDriver.h"
+#include "FwEvent_api.h"
+#include "txXfer_api.h"
+
+
+
+typedef struct
+{
+ TTxnStruct tTxnStruct;
+ TI_UINT8 *pPktsCntr;
+} TPktsCntrTxn;
+
+
+/* The TxXfer module object. */
+typedef struct
+{
+ TI_HANDLE hOs;
+ TI_HANDLE hReport;
+ TI_HANDLE hTwIf;
+
+ TSendPacketTranferCb fSendPacketTransferCb; /* Upper layer Xfer-Complete callback */
+ TI_HANDLE hSendPacketTransferHndl; /* Upper layer Xfer-Complete callback handle */
+
+ TI_UINT32 uPktsCntr;
+ TPktsCntrTxn aPktsCntrTxn[CTRL_BLK_ENTRIES_NUM];
+
+} TTxXferObj;
+
+static void txXfer_TransferDoneCb (TI_HANDLE hTxXfer, TTxnStruct *pTxn);
+
+
+
+/****************************************************************************
+ * txXfer_Create()
+ ****************************************************************************
+ * DESCRIPTION: Create the Xfer module object
+ *
+ * INPUTS: None
+ *
+ * OUTPUT: None
+ *
+ * RETURNS: The Created object
+ ****************************************************************************/
+TI_HANDLE txXfer_Create(TI_HANDLE hOs)
+{
+ TTxXferObj *pTxXfer;
+ int i;
+
+ pTxXfer = os_memoryAlloc (hOs, sizeof(TTxXferObj), MemoryNormal);
+ if (pTxXfer == NULL)
+ {
+ return NULL;
+ }
+
+ os_memoryZero (hOs, pTxXfer, sizeof(TTxXferObj));
+
+ for (i = 0; i < CTRL_BLK_ENTRIES_NUM; i++)
+ {
+ pTxXfer->aPktsCntrTxn[i].pPktsCntr = os_memoryAlloc (hOs, sizeof(TI_UINT32) + WSPI_PAD_LEN_READ, MemoryDMA);
+ if (pTxXfer->aPktsCntrTxn[i].pPktsCntr == NULL)
+ {
+ return NULL;
+ }
+ os_memoryZero (hOs, pTxXfer->aPktsCntrTxn[i].pPktsCntr, sizeof(TI_UINT32) + WSPI_PAD_LEN_READ);
+ pTxXfer->aPktsCntrTxn[i].pPktsCntr += WSPI_PAD_LEN_READ;
+ }
+
+ pTxXfer->hOs = hOs;
+
+ return (TI_HANDLE)pTxXfer;
+}
+
+
+/****************************************************************************
+ * txXfer_Destroy()
+ ****************************************************************************
+ * DESCRIPTION: Destroy the Xfer module object
+ *
+ * INPUTS: hTxXfer - The object to free
+ *
+ * OUTPUT: None
+ *
+ * RETURNS: TI_OK or TI_NOK
+ ****************************************************************************/
+TI_STATUS txXfer_Destroy(TI_HANDLE hTxXfer)
+{
+ TTxXferObj *pTxXfer = (TTxXferObj *)hTxXfer;
+ int i;
+
+ if (pTxXfer)
+ {
+ for (i = 0; i < CTRL_BLK_ENTRIES_NUM; i++)
+ {
+ if (pTxXfer->aPktsCntrTxn[i].pPktsCntr)
+ {
+ os_memoryFree (pTxXfer->hOs, ((TI_UINT8*)pTxXfer->aPktsCntrTxn[i].pPktsCntr) - WSPI_PAD_LEN_READ, sizeof(TI_UINT32) + WSPI_PAD_LEN_READ);
+ }
+ }
+
+ os_memoryFree (pTxXfer->hOs, pTxXfer, sizeof(TTxXferObj));
+ }
+
+ return TI_OK;
+}
+
+
+/****************************************************************************
+ * txXfer_init()
+ ****************************************************************************
+ DESCRIPTION:
+ ============
+ Initialize the Xfer module.
+ ****************************************************************************/
+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->uPktsCntr = 0;
+ 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].pPktsCntr, REGISTER_SIZE, NULL, NULL)
+ }
+
+ return txXfer_Restart(hTxXfer);
+}
+
+
+/****************************************************************************
+ * txXfer_Restart()
+ ****************************************************************************
+ DESCRIPTION:
+ ============
+ Restart the Xfer module.
+ ****************************************************************************/
+TI_STATUS txXfer_Restart (TI_HANDLE hTxXfer)
+{
+ TTxXferObj *pTxXfer = (TTxXferObj *)hTxXfer;
+
+ pTxXfer->uPktsCntr = 0;
+
+ return TI_OK;
+}
+
+
+/****************************************************************************
+ * txXfer_sendPacket()
+ ****************************************************************************
+ * DESCRIPTION:
+ ============
+ Send packet to the transaction queue.
+ Return the transfer status:
+ TXN_STATUS_COMPLETE - if completed, i.e. Synchronous mode.
+ TXN_STATUS_PENDING - if pending, i.e. Asynchronous mode.
+ Note that in case of PENDING, a callback function will be called
+ only if registered (needed for WHA).
+ ****************************************************************************/
+ETxnStatus txXfer_SendPacket (TI_HANDLE hTxXfer, TTxCtrlBlk *pPktCtrlBlk)
+{
+ TTxXferObj *pTxXfer = (TTxXferObj *)hTxXfer;
+ TTxnStruct *pTxn = (TTxnStruct *)pPktCtrlBlk;
+ ETxnStatus eStatus;
+ TPktsCntrTxn *pPktsCntrTxn;
+
+ /* Prepare the Txn fields to the host-slave register (fixed address) */
+ TXN_PARAM_SET(pTxn, TXN_LOW_PRIORITY, TXN_FUNC_ID_WLAN, TXN_DIRECTION_WRITE, TXN_FIXED_ADDR)
+ pTxn->uHwAddr = SLV_MEM_DATA;
+
+ /* Fill the TxnDone CB only if registered by the upper layers */
+ if (pTxXfer->fSendPacketTransferCb == NULL)
+ {
+ pTxn->fTxnDoneCb = NULL;
+ }
+ else
+ {
+ pTxn->fTxnDoneCb = (TTxnDoneCb)txXfer_TransferDoneCb;
+ pTxn->hCbHandle = hTxXfer;
+ }
+
+ /* Send the transaction */
+ eStatus = twIf_Transact (pTxXfer->hTwIf, pTxn);
+
+#ifdef TI_DBG
+
+ TRACE11(pTxXfer->hReport, REPORT_SEVERITY_INFORMATION, ": Status=%d, PktType=%d, Len0=%d, Len1=%d, Length=%d, ExtraBlks=%d, TotalBlks=%d, TxAttr=0x%x, TID=%d, DescID=%d, StartTime=%d\n", eStatus, pPktCtrlBlk->tTxPktParams.uPktType, pPktCtrlBlk->tTxnStruct.aLen[0], pPktCtrlBlk->tTxnStruct.aLen[1], pPktCtrlBlk->tTxDescriptor.length, pPktCtrlBlk->tTxDescriptor.extraMemBlks, pPktCtrlBlk->tTxDescriptor.totalMemBlks, pPktCtrlBlk->tTxDescriptor.txAttr, pPktCtrlBlk->tTxDescriptor.tid, pPktCtrlBlk->tTxDescriptor.descID, pPktCtrlBlk->tTxDescriptor.startTime);
+
+ if (eStatus == TXN_STATUS_ERROR)
+ {
+ TI_UINT32 i;
+ for (i = 0; i < MAX_XFER_BUFS; i++)
+ {
+ if (pPktCtrlBlk->tTxnStruct.aLen[i] == 0)
+ {
+ break;
+ }
+ TRACE1(pTxXfer->hReport, REPORT_SEVERITY_CONSOLE, "txXfer_SendPacket(): Tx Buffer %d:\n", i);
+ WLAN_OS_REPORT (("txXfer_SendPacket(): Tx Buffer %d:\n", i));
+ report_PrintDump(pPktCtrlBlk->tTxnStruct.aBuf[i], pPktCtrlBlk->tTxnStruct.aLen[i]);
+ }
+ }
+
+#endif /* TI_DBG */
+
+
+ pTxXfer->uPktsCntr++;
+ pPktsCntrTxn = &(pTxXfer->aPktsCntrTxn[pTxXfer->uPktsCntr % CTRL_BLK_ENTRIES_NUM]);
+ *((TI_UINT32*)(pPktsCntrTxn->pPktsCntr)) = ENDIAN_HANDLE_LONG(pTxXfer->uPktsCntr);
+ pPktsCntrTxn->tTxnStruct.uHwAddr = HOST_WR_ACCESS_REG;
+ twIf_Transact(pTxXfer->hTwIf, &pPktsCntrTxn->tTxnStruct);
+
+ /* Return the Txn result - COMPLETE or PENDING. */
+ /* Note: For PENDING, a callback function will be called only if registered (needed for WHA) */
+ return eStatus;
+}
+
+
+/****************************************************************************
+ * txXfer_TransferDoneCb()
+ ****************************************************************************
+ * DESCRIPTION: Call the upper layers TranferDone callback, providing the TxCtrlBlk
+ ****************************************************************************/
+static void txXfer_TransferDoneCb (TI_HANDLE hTxXfer, TTxnStruct *pTxn)
+{
+ TTxXferObj *pTxXfer = (TTxXferObj*)hTxXfer;
+
+ TRACE1(pTxXfer->hReport, REPORT_SEVERITY_INFORMATION, ": pTxn=0x%x\n", pTxn);
+
+ /* Call the upper layers TranferDone callback, providing the TxCtrlBlk. */
+ /* Note: If this CB was called it means that the upper CB exists (see in txXfer_SendPacket) */
+ pTxXfer->fSendPacketTransferCb (pTxXfer->hSendPacketTransferHndl, (TTxCtrlBlk *)pTxn);
+}
+
+
+/****************************************************************************
+ * txXfer_RegisterCb()
+ ****************************************************************************
+ * DESCRIPTION: Register the upper driver Xfer callback functions.
+ ****************************************************************************/
+void txXfer_RegisterCb (TI_HANDLE hTxXfer, TI_UINT32 CallBackID, void *CBFunc, TI_HANDLE CBObj)
+{
+ TTxXferObj* pTxXfer = (TTxXferObj*)hTxXfer;
+
+ TRACE3(pTxXfer->hReport, REPORT_SEVERITY_INFORMATION, ": 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;
+ break;
+
+ default:
+ TRACE0(pTxXfer->hReport, REPORT_SEVERITY_ERROR, " - Illegal value\n");
+ break;
+ }
+}
+
+
+
+
+