diff -r 000000000000 -r 10c42ec6c05f TWD/Data_Service/txCtrlBlk.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TWD/Data_Service/txCtrlBlk.c Tue Jun 29 12:34:26 2010 +0100 @@ -0,0 +1,284 @@ +/* + * txCtrlBlk.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: txCtrlBlk.c + * + * PURPOSE: Maintains active packets Tx attributes table (including descriptor). + * + * DESCRIPTION: + * ============ + * This module allocates and frees table entry for each packet in the Tx + * process (from sendPkt by upper driver until Tx-complete). + * + ****************************************************************************/ +#define __FILE_ID__ FILE_ID_99 +#include "osApi.h" +#include "tidef.h" +#include "report.h" +#include "context.h" +#include "TWDriver.h" +#include "txCtrlBlk_api.h" + + +/* The TxCtrlBlk module object - contains the control-block table. */ +typedef struct +{ + TI_HANDLE hOs; + TI_HANDLE hReport; + TI_HANDLE hContext; + + TTxCtrlBlk aTxCtrlBlkTbl[CTRL_BLK_ENTRIES_NUM]; /* The table of control-block entries. */ + +#ifdef TI_DBG /* Just for debug. */ + TI_UINT32 uNumUsedEntries; +#endif + +} TTxCtrlBlkObj; + + +/**************************************************************************** + * txCtrlBlk_Create() + **************************************************************************** + * DESCRIPTION: Create the Tx control block table object + * + * INPUTS: hOs + * + * OUTPUT: None + * + * RETURNS: The Created object + ****************************************************************************/ +TI_HANDLE txCtrlBlk_Create (TI_HANDLE hOs) +{ + TTxCtrlBlkObj *pTxCtrlBlk; + + pTxCtrlBlk = os_memoryAlloc (hOs, sizeof(TTxCtrlBlkObj),MemoryNormal); + if (pTxCtrlBlk == NULL) + return NULL; + + os_memoryZero (hOs, pTxCtrlBlk, sizeof(TTxCtrlBlkObj)); + + pTxCtrlBlk->hOs = hOs; + + return( (TI_HANDLE)pTxCtrlBlk ); +} + + +/**************************************************************************** + * txCtrlBlk_Destroy() + **************************************************************************** + * DESCRIPTION: Destroy the Tx control block table object + * + * INPUTS: hTxCtrlBlk - The object to free + * + * OUTPUT: None + * + * RETURNS: TI_OK or TI_NOK + ****************************************************************************/ +TI_STATUS txCtrlBlk_Destroy (TI_HANDLE hTxCtrlBlk) +{ + TTxCtrlBlkObj *pTxCtrlBlk = (TTxCtrlBlkObj *)hTxCtrlBlk; + + if (pTxCtrlBlk) + os_memoryFree(pTxCtrlBlk->hOs, pTxCtrlBlk, sizeof(TTxCtrlBlkObj)); + + return TI_OK; +} + + +/**************************************************************************** + * txCtrlBlk_Init() + **************************************************************************** + DESCRIPTION: Initialize the Tx control block module. + ****************************************************************************/ +TI_STATUS txCtrlBlk_Init (TI_HANDLE hTxCtrlBlk, TI_HANDLE hReport, TI_HANDLE hContext) +{ + TTxCtrlBlkObj *pTxCtrlBlk = (TTxCtrlBlkObj *)hTxCtrlBlk; + TI_UINT8 entry; + + pTxCtrlBlk->hReport = hReport; + pTxCtrlBlk->hContext = hContext; + + /* For all entries, write the entry index in the descriptor and the next entry address + in the next free entery pointer. Init also some other fields. */ + for(entry = 0; entry < CTRL_BLK_ENTRIES_NUM; entry++) + { + pTxCtrlBlk->aTxCtrlBlkTbl[entry].tTxDescriptor.descID = entry; + pTxCtrlBlk->aTxCtrlBlkTbl[entry].pNextFreeEntry = &(pTxCtrlBlk->aTxCtrlBlkTbl[entry + 1]); + pTxCtrlBlk->aTxCtrlBlkTbl[entry].tTxDescriptor.aid = 1; /* The value for infrastructure BSS */ + pTxCtrlBlk->aTxCtrlBlkTbl[entry].tTxDescriptor.reserved = 0; + } + + /* Write null in the next-free index of the last entry. */ + pTxCtrlBlk->aTxCtrlBlkTbl[CTRL_BLK_ENTRIES_NUM - 1].pNextFreeEntry = NULL; + + #ifdef TI_DBG + pTxCtrlBlk->uNumUsedEntries = 0; + #endif + + return TI_OK; +} + + +/**************************************************************************** + * txCtrlBlk_Alloc() + **************************************************************************** + * DESCRIPTION: + Allocate a free control-block entry for the current Tx packet's parameters + (including the descriptor structure). + Note that entry 0 in the list is never allocated and points to the + first free entry. + ****************************************************************************/ +TTxCtrlBlk *txCtrlBlk_Alloc (TI_HANDLE hTxCtrlBlk) +{ + TTxCtrlBlkObj *pTxCtrlBlk = (TTxCtrlBlkObj *)hTxCtrlBlk; + TTxCtrlBlk *pCurrentEntry; /* The pointer of the new entry allocated for the packet. */ + TTxCtrlBlk *pFirstFreeEntry; /* The first entry just points to the first free entry. */ + + pFirstFreeEntry = &(pTxCtrlBlk->aTxCtrlBlkTbl[0]); + + /* Protect block allocation from preemption (may be called from external context) */ + CONTEXT_ENTER_CRITICAL_SECTION (pTxCtrlBlk->hContext); + + pCurrentEntry = pFirstFreeEntry->pNextFreeEntry; /* Get free entry. */ + +#ifdef TI_DBG + /* If no free entries, print error (not expected to happen) and return NULL. */ + if (pCurrentEntry->pNextFreeEntry == NULL) + { +TRACE1(pTxCtrlBlk->hReport, REPORT_SEVERITY_ERROR, "txCtrlBlk_alloc(): No free entry, UsedEntries=%d\n", pTxCtrlBlk->uNumUsedEntries); + CONTEXT_LEAVE_CRITICAL_SECTION (pTxCtrlBlk->hContext); + return NULL; + } + pTxCtrlBlk->uNumUsedEntries++; +#endif + + /* Link the first entry to the next free entry. */ + pFirstFreeEntry->pNextFreeEntry = pCurrentEntry->pNextFreeEntry; + + CONTEXT_LEAVE_CRITICAL_SECTION (pTxCtrlBlk->hContext); + + /* Clear the next-free-entry index just as an indication that our entry is not free. */ + pCurrentEntry->pNextFreeEntry = 0; + + pCurrentEntry->tTxPktParams.uFlags = 0; + pCurrentEntry->tTxPktParams.uHeadroomSize = 0; + + return pCurrentEntry; +} + + +/**************************************************************************** + * txCtrlBlk_Free() + **************************************************************************** + * DESCRIPTION: + Link the freed entry after entry 0, so now it is the first free entry to + be allocated. + ****************************************************************************/ +void txCtrlBlk_Free (TI_HANDLE hTxCtrlBlk, TTxCtrlBlk *pCurrentEntry) +{ + TTxCtrlBlkObj *pTxCtrlBlk = (TTxCtrlBlkObj *)hTxCtrlBlk; + TTxCtrlBlk *pFirstFreeEntry = &(pTxCtrlBlk->aTxCtrlBlkTbl[0]); + +#ifdef TI_DBG + /* If the pointed entry is already free, print error and exit (not expected to happen). */ + if (pCurrentEntry->pNextFreeEntry != 0) + { +TRACE2(pTxCtrlBlk->hReport, REPORT_SEVERITY_ERROR, "txCtrlBlk_free(): Entry %d alredy free, UsedEntries=%d\n", pCurrentEntry->tTxDescriptor.descID, pTxCtrlBlk->uNumUsedEntries); + return; + } + pTxCtrlBlk->uNumUsedEntries--; +#endif + + /* Protect block freeing from preemption (may be called from external context) */ + CONTEXT_ENTER_CRITICAL_SECTION (pTxCtrlBlk->hContext); + + /* Link the freed entry between entry 0 and the next free entry. */ + pCurrentEntry->pNextFreeEntry = pFirstFreeEntry->pNextFreeEntry; + pFirstFreeEntry->pNextFreeEntry = pCurrentEntry; + + CONTEXT_LEAVE_CRITICAL_SECTION (pTxCtrlBlk->hContext); +} + + +/**************************************************************************** + * txCtrlBlk_GetPointer() + **************************************************************************** + * DESCRIPTION: + Return a pointer to the control block entry of the requested packet. + Used upon tx-complete to retrieve info after getting the descId from the FW. + ****************************************************************************/ +TTxCtrlBlk *txCtrlBlk_GetPointer (TI_HANDLE hTxCtrlBlk, TI_UINT8 descId) +{ + TTxCtrlBlkObj *pTxCtrlBlk = (TTxCtrlBlkObj *)hTxCtrlBlk; + return ( &(pTxCtrlBlk->aTxCtrlBlkTbl[descId]) ); +} + + +/**************************************************************************** + * txCtrlBlk_PrintTable() + **************************************************************************** + * DESCRIPTION: Print the txCtrlBlk table main fields. + ****************************************************************************/ +#ifdef TI_DBG +void txCtrlBlk_PrintTable (TI_HANDLE hTxCtrlBlk) +{ + TTxCtrlBlkObj *pTxCtrlBlk = (TTxCtrlBlkObj *)hTxCtrlBlk; + TI_UINT8 entry; + + WLAN_OS_REPORT((" Tx-Control-Block Information, UsedEntries=%d\n", pTxCtrlBlk->uNumUsedEntries)); + WLAN_OS_REPORT(("==============================================\n")); + + for(entry = 0; entry < CTRL_BLK_ENTRIES_NUM; entry++) + { + WLAN_OS_REPORT(("Entry %d: DescID=%d, Next=0x%x, Len=%d, StartTime=%d, TID=%d, ExtraBlks=%d, TotalBlks=%d, Flags=0x%x\n", + entry, + pTxCtrlBlk->aTxCtrlBlkTbl[entry].tTxDescriptor.descID, + pTxCtrlBlk->aTxCtrlBlkTbl[entry].pNextFreeEntry, + ENDIAN_HANDLE_WORD(pTxCtrlBlk->aTxCtrlBlkTbl[entry].tTxDescriptor.length), + ENDIAN_HANDLE_LONG(pTxCtrlBlk->aTxCtrlBlkTbl[entry].tTxDescriptor.startTime), + pTxCtrlBlk->aTxCtrlBlkTbl[entry].tTxDescriptor.tid, + pTxCtrlBlk->aTxCtrlBlkTbl[entry].tTxDescriptor.extraMemBlks, + pTxCtrlBlk->aTxCtrlBlkTbl[entry].tTxDescriptor.totalMemBlks, + pTxCtrlBlk->aTxCtrlBlkTbl[entry].tTxPktParams.uFlags)); + } +} +#endif /* TI_DBG */ +