TWD/Data_Service/txCtrlBlk.c
changeset 0 10c42ec6c05f
--- /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 */
+