4 * Copyright(c) 1998 - 2009 Texas Instruments. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name Texas Instruments nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 /****************************************************************************
39 * PURPOSE: Handle Tx frame transfer to the firmware.
43 * This module gets the upper driver's Tx packets after FW resources were
44 * allocated for it, and handles its transfer to the FW via the
45 * host slave (indirect) interface, using the TwIf Transaction API.
47 ****************************************************************************/
49 #define __FILE_ID__ FILE_ID_108
55 #include "FwEvent_api.h"
56 #include "txXfer_api.h"
59 /* remove workaround when WL6-PG1.0 becomes obsolete */
62 TTxnStruct tTxnStruct;
67 /* The TxXfer module object. */
74 TSendPacketTranferCb fSendPacketTransferCb; /* Upper layer Xfer-Complete callback */
75 TI_HANDLE hSendPacketTransferHndl; /* Upper layer Xfer-Complete callback handle */
77 /* remove workaround when WL6-PG1.0 becomes obsolete */
78 TI_BOOL bChipIs1273Pg10;
80 TPktsCntrTxn aPktsCntrTxn[CTRL_BLK_ENTRIES_NUM];
84 static void txXfer_TransferDoneCb (TI_HANDLE hTxXfer, TTxnStruct *pTxn);
88 /****************************************************************************
90 ****************************************************************************
91 * DESCRIPTION: Create the Xfer module object
97 * RETURNS: The Created object
98 ****************************************************************************/
99 TI_HANDLE txXfer_Create(TI_HANDLE hOs)
103 pTxXfer = os_memoryAlloc (hOs, sizeof(TTxXferObj));
109 os_memoryZero (hOs, pTxXfer, sizeof(TTxXferObj));
113 return (TI_HANDLE)pTxXfer;
117 /****************************************************************************
119 ****************************************************************************
120 * DESCRIPTION: Destroy the Xfer module object
122 * INPUTS: hTxXfer - The object to free
126 * RETURNS: TI_OK or TI_NOK
127 ****************************************************************************/
128 TI_STATUS txXfer_Destroy(TI_HANDLE hTxXfer)
130 TTxXferObj *pTxXfer = (TTxXferObj *)hTxXfer;
134 os_memoryFree (pTxXfer->hOs, pTxXfer, sizeof(TTxXferObj));
141 /****************************************************************************
143 ****************************************************************************
146 Initialize the Xfer module.
147 ****************************************************************************/
148 TI_STATUS txXfer_Init (TI_HANDLE hTxXfer, TI_HANDLE hReport, TI_HANDLE hTwIf)
150 TTxXferObj *pTxXfer = (TTxXferObj *)hTxXfer;
154 pTxXfer->hReport = hReport;
155 pTxXfer->hTwIf = hTwIf;
156 pTxXfer->fSendPacketTransferCb = NULL;
158 /* remove workaround when WL6-PG1.0 becomes obsolete */
159 pTxXfer->uPktsCntr = 0;
160 for (i = 0; i < CTRL_BLK_ENTRIES_NUM; i++)
162 pTxn = &(pTxXfer->aPktsCntrTxn[i].tTxnStruct);
163 TXN_PARAM_SET(pTxn, TXN_LOW_PRIORITY, TXN_FUNC_ID_WLAN, TXN_DIRECTION_WRITE, TXN_INC_ADDR)
164 BUILD_TTxnStruct(pTxn, HOST_WR_ACCESS_REG, &pTxXfer->aPktsCntrTxn[i].uPktsCntr, REGISTER_SIZE, NULL, NULL)
167 return txXfer_Restart(hTxXfer, TI_TRUE);
171 /****************************************************************************
173 ****************************************************************************
176 Restart the Xfer module.
177 ****************************************************************************/
178 TI_STATUS txXfer_Restart (TI_HANDLE hTxXfer, TI_BOOL bChipIs1273Pg10)
180 TTxXferObj *pTxXfer = (TTxXferObj *)hTxXfer;
182 /* remove the counter transactions workaround when WL6-PG1.0 becomes obsolete */
183 pTxXfer->bChipIs1273Pg10 = bChipIs1273Pg10;
184 pTxXfer->uPktsCntr = 0;
190 /****************************************************************************
191 * txXfer_sendPacket()
192 ****************************************************************************
195 Send packet to the transaction queue.
196 Return the transfer status:
197 TXN_STATUS_COMPLETE - if completed, i.e. Synchronous mode.
198 TXN_STATUS_PENDING - if pending, i.e. Asynchronous mode.
199 Note that in case of PENDING, a callback function will be called
200 only if registered (needed for WHA).
201 ****************************************************************************/
202 ETxnStatus txXfer_SendPacket (TI_HANDLE hTxXfer, TTxCtrlBlk *pPktCtrlBlk)
204 TTxXferObj *pTxXfer = (TTxXferObj *)hTxXfer;
205 TTxnStruct *pTxn = (TTxnStruct *)pPktCtrlBlk;
207 TPktsCntrTxn *pPktsCntrTxn;
209 /* Prepare the Txn fields to the host-slave register (fixed address) */
210 TXN_PARAM_SET(pTxn, TXN_LOW_PRIORITY, TXN_FUNC_ID_WLAN, TXN_DIRECTION_WRITE, TXN_FIXED_ADDR)
211 pTxn->uHwAddr = SLV_MEM_DATA;
213 /* Fill the TxnDone CB only if registered by the upper layers */
214 if (pTxXfer->fSendPacketTransferCb == NULL)
216 pTxn->fTxnDoneCb = NULL;
220 pTxn->fTxnDoneCb = (TTxnDoneCb)txXfer_TransferDoneCb;
221 pTxn->hCbHandle = hTxXfer;
224 /* Send the transaction */
225 eStatus = twIf_Transact (pTxXfer->hTwIf, pTxn);
229 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);
231 if (eStatus == TXN_STATUS_ERROR)
234 for (i = 0; i < MAX_XFER_BUFS; i++)
236 if (pPktCtrlBlk->tTxnStruct.aLen[i] == 0)
240 TRACE1(pTxXfer->hReport, REPORT_SEVERITY_CONSOLE, "txXfer_SendPacket(): Tx Buffer %d:\n", i);
241 WLAN_OS_REPORT (("txXfer_SendPacket(): Tx Buffer %d:\n", i));
242 report_PrintDump(pPktCtrlBlk->tTxnStruct.aBuf[i], pPktCtrlBlk->tTxnStruct.aLen[i]);
249 /* remove workaround when WL6-PG1.0 becomes obsolete */
250 if (1) /* restore -> if (pTxXfer->bChipIs1273Pg10) */
252 pTxXfer->uPktsCntr++;
253 pPktsCntrTxn = &(pTxXfer->aPktsCntrTxn[pTxXfer->uPktsCntr % CTRL_BLK_ENTRIES_NUM]);
254 pPktsCntrTxn->uPktsCntr = ENDIAN_HANDLE_LONG(pTxXfer->uPktsCntr);
255 pPktsCntrTxn->tTxnStruct.uHwAddr = HOST_WR_ACCESS_REG;
256 twIf_Transact(pTxXfer->hTwIf, &pPktsCntrTxn->tTxnStruct);
259 /* Return the Txn result - COMPLETE or PENDING. */
260 /* Note: For PENDING, a callback function will be called only if registered (needed for WHA) */
265 /****************************************************************************
266 * txXfer_TransferDoneCb()
267 ****************************************************************************
268 * DESCRIPTION: Call the upper layers TranferDone callback, providing the TxCtrlBlk
269 ****************************************************************************/
270 static void txXfer_TransferDoneCb (TI_HANDLE hTxXfer, TTxnStruct *pTxn)
272 TTxXferObj *pTxXfer = (TTxXferObj*)hTxXfer;
274 TRACE1(pTxXfer->hReport, REPORT_SEVERITY_INFORMATION, ": pTxn=0x%x\n", pTxn);
276 /* Call the upper layers TranferDone callback, providing the TxCtrlBlk. */
277 /* Note: If this CB was called it means that the upper CB exists (see in txXfer_SendPacket) */
278 pTxXfer->fSendPacketTransferCb (pTxXfer->hSendPacketTransferHndl, (TTxCtrlBlk *)pTxn);
282 /****************************************************************************
283 * txXfer_RegisterCb()
284 ****************************************************************************
285 * DESCRIPTION: Register the upper driver Xfer callback functions.
286 ****************************************************************************/
287 void txXfer_RegisterCb (TI_HANDLE hTxXfer, TI_UINT32 CallBackID, void *CBFunc, TI_HANDLE CBObj)
289 TTxXferObj* pTxXfer = (TTxXferObj*)hTxXfer;
291 TRACE3(pTxXfer->hReport, REPORT_SEVERITY_INFORMATION, ": CallBackID=%d, CBFunc=0x%x, CBObj=0x%x\n", CallBackID, CBFunc, CBObj);
295 /* Save upper layers Transfer-Done callback */
296 case TWD_INT_SEND_PACKET_TRANSFER:
297 pTxXfer->fSendPacketTransferCb = (TSendPacketTranferCb)CBFunc;
298 pTxXfer->hSendPacketTransferHndl = CBObj;
302 TRACE0(pTxXfer->hReport, REPORT_SEVERITY_ERROR, " - Illegal value\n");