Home | History | Annotate | Download | only in Data_Service
      1 /*
      2  * txCtrlBlk.c
      3  *
      4  * Copyright(c) 1998 - 2009 Texas Instruments. All rights reserved.
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  *
     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
     16  *    distribution.
     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.
     20  *
     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.
     32  */
     33 
     34 
     35 /****************************************************************************
     36  *
     37  *   MODULE:  txCtrlBlk.c
     38  *
     39  *   PURPOSE: Maintains active packets Tx attributes table (including descriptor).
     40  *
     41  *	 DESCRIPTION:
     42  *   ============
     43  *		This module allocates and frees table entry for each packet in the Tx
     44  *		process (from sendPkt by upper driver until Tx-complete).
     45  *
     46  ****************************************************************************/
     47 #define __FILE_ID__  FILE_ID_99
     48 #include "osApi.h"
     49 #include "tidef.h"
     50 #include "report.h"
     51 #include "context.h"
     52 #include "TWDriver.h"
     53 #include "txCtrlBlk_api.h"
     54 
     55 
     56 /* The TxCtrlBlk module object - contains the control-block table. */
     57 typedef struct
     58 {
     59 	TI_HANDLE   hOs;
     60 	TI_HANDLE   hReport;
     61 	TI_HANDLE   hContext;
     62 
     63 	TTxCtrlBlk  aTxCtrlBlkTbl[CTRL_BLK_ENTRIES_NUM]; /* The table of control-block entries. */
     64 
     65 #ifdef TI_DBG  /* Just for debug. */
     66 	TI_UINT32	uNumUsedEntries;
     67 #endif
     68 
     69 } TTxCtrlBlkObj;
     70 
     71 
     72 /****************************************************************************
     73  *                      txCtrlBlk_Create()
     74  ****************************************************************************
     75  * DESCRIPTION:	Create the Tx control block table object
     76  *
     77  * INPUTS:	hOs
     78  *
     79  * OUTPUT:	None
     80  *
     81  * RETURNS:	The Created object
     82  ****************************************************************************/
     83 TI_HANDLE txCtrlBlk_Create (TI_HANDLE hOs)
     84 {
     85 	TTxCtrlBlkObj *pTxCtrlBlk;
     86 
     87 	pTxCtrlBlk = os_memoryAlloc (hOs, sizeof(TTxCtrlBlkObj));
     88 	if (pTxCtrlBlk == NULL)
     89 		return NULL;
     90 
     91 	os_memoryZero (hOs, pTxCtrlBlk, sizeof(TTxCtrlBlkObj));
     92 
     93 	pTxCtrlBlk->hOs = hOs;
     94 
     95 	return( (TI_HANDLE)pTxCtrlBlk );
     96 }
     97 
     98 
     99 /****************************************************************************
    100  *                      txCtrlBlk_Destroy()
    101  ****************************************************************************
    102  * DESCRIPTION:	Destroy the Tx control block table object
    103  *
    104  * INPUTS:	hTxCtrlBlk - The object to free
    105  *
    106  * OUTPUT:	None
    107  *
    108  * RETURNS:	TI_OK or TI_NOK
    109  ****************************************************************************/
    110 TI_STATUS txCtrlBlk_Destroy (TI_HANDLE hTxCtrlBlk)
    111 {
    112 	TTxCtrlBlkObj *pTxCtrlBlk = (TTxCtrlBlkObj *)hTxCtrlBlk;
    113 
    114 	if (pTxCtrlBlk)
    115 		os_memoryFree(pTxCtrlBlk->hOs, pTxCtrlBlk, sizeof(TTxCtrlBlkObj));
    116 
    117 	return TI_OK;
    118 }
    119 
    120 
    121 /****************************************************************************
    122  *               txCtrlBlk_Init()
    123  ****************************************************************************
    124    DESCRIPTION:	 Initialize the Tx control block module.
    125  ****************************************************************************/
    126 TI_STATUS txCtrlBlk_Init (TI_HANDLE hTxCtrlBlk, TI_HANDLE hReport, TI_HANDLE hContext)
    127 {
    128 	TTxCtrlBlkObj *pTxCtrlBlk = (TTxCtrlBlkObj *)hTxCtrlBlk;
    129 	TTxnStruct    *pTxn;
    130 	TI_UINT8       entry;
    131 
    132 	pTxCtrlBlk->hReport  = hReport;
    133 	pTxCtrlBlk->hContext = hContext;
    134 
    135 	/* For all entries, write the entry index in the descriptor and the next entry address
    136 		 in the next free entery pointer. Init also some other fields. */
    137 	for(entry = 0; entry < CTRL_BLK_ENTRIES_NUM; entry++)
    138 	{
    139 		pTxCtrlBlk->aTxCtrlBlkTbl[entry].tTxDescriptor.descID = entry;
    140 		pTxCtrlBlk->aTxCtrlBlkTbl[entry].pNextFreeEntry       = &(pTxCtrlBlk->aTxCtrlBlkTbl[entry + 1]);
    141 		pTxCtrlBlk->aTxCtrlBlkTbl[entry].tTxDescriptor.aid    = 1;  /* The value for infrastructure BSS */
    142 		pTxCtrlBlk->aTxCtrlBlkTbl[entry].tTxDescriptor.reserved  = 0;
    143 
    144         /* Prepare the Txn fields to the host-slave register (fixed address) */
    145         pTxn = &(pTxCtrlBlk->aTxCtrlBlkTbl[entry].tTxnStruct);
    146         TXN_PARAM_SET(pTxn, TXN_LOW_PRIORITY, TXN_FUNC_ID_WLAN, TXN_DIRECTION_WRITE, TXN_FIXED_ADDR)
    147 	}
    148 
    149 	/* Write null in the next-free index of the last entry. */
    150 	pTxCtrlBlk->aTxCtrlBlkTbl[CTRL_BLK_ENTRIES_NUM - 1].pNextFreeEntry = NULL;
    151 
    152   #ifdef TI_DBG
    153 	pTxCtrlBlk->uNumUsedEntries = 0;
    154   #endif
    155 
    156 	return TI_OK;
    157 }
    158 
    159 
    160 /****************************************************************************
    161  *					txCtrlBlk_Alloc()
    162  ****************************************************************************
    163  * DESCRIPTION:
    164 	Allocate a free control-block entry for the current Tx packet's parameters
    165 	  (including the descriptor structure).
    166 	Note that entry 0 in the list is never allocated and points to the
    167 	  first free entry.
    168  ****************************************************************************/
    169 TTxCtrlBlk *txCtrlBlk_Alloc (TI_HANDLE hTxCtrlBlk)
    170 {
    171 	TTxCtrlBlkObj   *pTxCtrlBlk = (TTxCtrlBlkObj *)hTxCtrlBlk;
    172 	TTxCtrlBlk      *pCurrentEntry; /* The pointer of the new entry allocated for the packet. */
    173 	TTxCtrlBlk      *pFirstFreeEntry; /* The first entry just points to the first free entry. */
    174 
    175 	pFirstFreeEntry = &(pTxCtrlBlk->aTxCtrlBlkTbl[0]);
    176 
    177     /* Protect block allocation from preemption (may be called from external context) */
    178     context_EnterCriticalSection (pTxCtrlBlk->hContext);
    179 
    180     pCurrentEntry = pFirstFreeEntry->pNextFreeEntry; /* Get free entry. */
    181 
    182 #ifdef TI_DBG
    183 	/* If no free entries, print error (not expected to happen) and return NULL. */
    184 	if (pCurrentEntry->pNextFreeEntry == NULL)
    185 	{
    186 TRACE1(pTxCtrlBlk->hReport, REPORT_SEVERITY_ERROR, "txCtrlBlk_alloc():  No free entry,  UsedEntries=%d\n", pTxCtrlBlk->uNumUsedEntries);
    187         context_LeaveCriticalSection (pTxCtrlBlk->hContext);
    188 		return NULL;
    189 	}
    190 	pTxCtrlBlk->uNumUsedEntries++;
    191 #endif
    192 
    193 	/* Link the first entry to the next free entry. */
    194 	pFirstFreeEntry->pNextFreeEntry = pCurrentEntry->pNextFreeEntry;
    195 
    196     context_LeaveCriticalSection (pTxCtrlBlk->hContext);
    197 
    198 	/* Clear the next-free-entry index just as an indication that our entry is not free. */
    199 	pCurrentEntry->pNextFreeEntry = 0;
    200 
    201     pCurrentEntry->tTxPktParams.uFlags = 0;
    202     pCurrentEntry->tTxPktParams.uHeadroomSize = 0;
    203 
    204 	return pCurrentEntry;
    205 }
    206 
    207 
    208 /****************************************************************************
    209  *					txCtrlBlk_Free()
    210  ****************************************************************************
    211  * DESCRIPTION:
    212 	Link the freed entry after entry 0, so now it is the first free entry to
    213 	  be allocated.
    214  ****************************************************************************/
    215 void txCtrlBlk_Free (TI_HANDLE hTxCtrlBlk, TTxCtrlBlk *pCurrentEntry)
    216 {
    217 	TTxCtrlBlkObj   *pTxCtrlBlk = (TTxCtrlBlkObj *)hTxCtrlBlk;
    218 	TTxCtrlBlk *pFirstFreeEntry = &(pTxCtrlBlk->aTxCtrlBlkTbl[0]);
    219 
    220 	if (!pTxCtrlBlk)
    221     {
    222 		return;
    223 	}
    224 
    225 #ifdef TI_DBG
    226 	/* If the pointed entry is already free, print error and exit (not expected to happen). */
    227 	if (pCurrentEntry->pNextFreeEntry != 0)
    228 	{
    229 		TRACE2(pTxCtrlBlk->hReport, REPORT_SEVERITY_ERROR, "txCtrlBlk_free(): Entry %d alredy free, UsedEntries=%d\n", 			pCurrentEntry->tTxDescriptor.descID, pTxCtrlBlk->uNumUsedEntries);
    230 		return;
    231 	}
    232 	pTxCtrlBlk->uNumUsedEntries--;
    233 #endif
    234 
    235 	/* Protect block freeing from preemption (may be called from external context) */
    236 	context_EnterCriticalSection (pTxCtrlBlk->hContext);
    237 
    238 	/* Link the freed entry between entry 0 and the next free entry. */
    239 	pCurrentEntry->pNextFreeEntry   = pFirstFreeEntry->pNextFreeEntry;
    240 	pFirstFreeEntry->pNextFreeEntry = pCurrentEntry;
    241 
    242 	context_LeaveCriticalSection (pTxCtrlBlk->hContext);
    243 }
    244 
    245 
    246 /****************************************************************************
    247  *					txCtrlBlk_GetPointer()
    248  ****************************************************************************
    249  * DESCRIPTION:
    250 	Return a pointer to the control block entry of the requested packet.
    251 	Used upon tx-complete to retrieve info after getting the descId from the FW.
    252  ****************************************************************************/
    253 TTxCtrlBlk *txCtrlBlk_GetPointer (TI_HANDLE hTxCtrlBlk, TI_UINT8 descId)
    254 {
    255 	TTxCtrlBlkObj *pTxCtrlBlk = (TTxCtrlBlkObj *)hTxCtrlBlk;
    256 	return ( &(pTxCtrlBlk->aTxCtrlBlkTbl[descId]) );
    257 }
    258 
    259 
    260 /****************************************************************************
    261  *                      txCtrlBlk_PrintTable()
    262  ****************************************************************************
    263  * DESCRIPTION:	 Print the txCtrlBlk table main fields.
    264  ****************************************************************************/
    265 #ifdef TI_DBG
    266 void txCtrlBlk_PrintTable (TI_HANDLE hTxCtrlBlk)
    267 {
    268 #ifdef REPORT_LOG
    269 	TTxCtrlBlkObj *pTxCtrlBlk = (TTxCtrlBlkObj *)hTxCtrlBlk;
    270 	TI_UINT8 entry;
    271 
    272 	WLAN_OS_REPORT((" Tx-Control-Block Information,  UsedEntries=%d\n", pTxCtrlBlk->uNumUsedEntries));
    273 	WLAN_OS_REPORT(("==============================================\n"));
    274 
    275 	for(entry = 0; entry < CTRL_BLK_ENTRIES_NUM; entry++)
    276 	{
    277 		WLAN_OS_REPORT(("Entry %d: DescID=%d, Next=0x%x, Len=%d, StartTime=%d, TID=%d, ExtraBlks=%d, TotalBlks=%d, Flags=0x%x\n",
    278 			entry,
    279 			pTxCtrlBlk->aTxCtrlBlkTbl[entry].tTxDescriptor.descID,
    280 			pTxCtrlBlk->aTxCtrlBlkTbl[entry].pNextFreeEntry,
    281 			ENDIAN_HANDLE_WORD(pTxCtrlBlk->aTxCtrlBlkTbl[entry].tTxDescriptor.length),
    282 			ENDIAN_HANDLE_LONG(pTxCtrlBlk->aTxCtrlBlkTbl[entry].tTxDescriptor.startTime),
    283             pTxCtrlBlk->aTxCtrlBlkTbl[entry].tTxDescriptor.tid,
    284 			pTxCtrlBlk->aTxCtrlBlkTbl[entry].tTxDescriptor.extraMemBlks,
    285             pTxCtrlBlk->aTxCtrlBlkTbl[entry].tTxDescriptor.totalMemBlks,
    286             pTxCtrlBlk->aTxCtrlBlkTbl[entry].tTxPktParams.uFlags));
    287 	}
    288 #endif
    289 }
    290 #endif /* TI_DBG */
    291 
    292