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. */ 57typedef 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 ****************************************************************************/ 83TI_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 ****************************************************************************/ 110TI_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 ****************************************************************************/ 126TI_STATUS txCtrlBlk_Init (TI_HANDLE hTxCtrlBlk, TI_HANDLE hReport, TI_HANDLE hContext) 127{ 128 TTxCtrlBlkObj *pTxCtrlBlk = (TTxCtrlBlkObj *)hTxCtrlBlk; 129 TI_UINT8 entry; 130 131 pTxCtrlBlk->hReport = hReport; 132 pTxCtrlBlk->hContext = hContext; 133 134 /* For all entries, write the entry index in the descriptor and the next entry address 135 in the next free entery pointer. Init also some other fields. */ 136 for(entry = 0; entry < CTRL_BLK_ENTRIES_NUM; entry++) 137 { 138 pTxCtrlBlk->aTxCtrlBlkTbl[entry].tTxDescriptor.descID = entry; 139 pTxCtrlBlk->aTxCtrlBlkTbl[entry].pNextFreeEntry = &(pTxCtrlBlk->aTxCtrlBlkTbl[entry + 1]); 140 pTxCtrlBlk->aTxCtrlBlkTbl[entry].tTxDescriptor.aid = 1; /* The value for infrastructure BSS */ 141 pTxCtrlBlk->aTxCtrlBlkTbl[entry].tTxDescriptor.reserved = 0; 142 } 143 144 /* Write null in the next-free index of the last entry. */ 145 pTxCtrlBlk->aTxCtrlBlkTbl[CTRL_BLK_ENTRIES_NUM - 1].pNextFreeEntry = NULL; 146 147 #ifdef TI_DBG 148 pTxCtrlBlk->uNumUsedEntries = 0; 149 #endif 150 151 return TI_OK; 152} 153 154 155/**************************************************************************** 156 * txCtrlBlk_Alloc() 157 **************************************************************************** 158 * DESCRIPTION: 159 Allocate a free control-block entry for the current Tx packet's parameters 160 (including the descriptor structure). 161 Note that entry 0 in the list is never allocated and points to the 162 first free entry. 163 ****************************************************************************/ 164TTxCtrlBlk *txCtrlBlk_Alloc (TI_HANDLE hTxCtrlBlk) 165{ 166 TTxCtrlBlkObj *pTxCtrlBlk = (TTxCtrlBlkObj *)hTxCtrlBlk; 167 TTxCtrlBlk *pCurrentEntry; /* The pointer of the new entry allocated for the packet. */ 168 TTxCtrlBlk *pFirstFreeEntry; /* The first entry just points to the first free entry. */ 169 170 pFirstFreeEntry = &(pTxCtrlBlk->aTxCtrlBlkTbl[0]); 171 172 /* Protect block allocation from preemption (may be called from external context) */ 173 context_EnterCriticalSection (pTxCtrlBlk->hContext); 174 175 pCurrentEntry = pFirstFreeEntry->pNextFreeEntry; /* Get free entry. */ 176 177#ifdef TI_DBG 178 /* If no free entries, print error (not expected to happen) and return NULL. */ 179 if (pCurrentEntry->pNextFreeEntry == NULL) 180 { 181TRACE1(pTxCtrlBlk->hReport, REPORT_SEVERITY_ERROR, "txCtrlBlk_alloc(): No free entry, UsedEntries=%d\n", pTxCtrlBlk->uNumUsedEntries); 182 context_LeaveCriticalSection (pTxCtrlBlk->hContext); 183 return NULL; 184 } 185 pTxCtrlBlk->uNumUsedEntries++; 186#endif 187 188 /* Link the first entry to the next free entry. */ 189 pFirstFreeEntry->pNextFreeEntry = pCurrentEntry->pNextFreeEntry; 190 191 context_LeaveCriticalSection (pTxCtrlBlk->hContext); 192 193 /* Clear the next-free-entry index just as an indication that our entry is not free. */ 194 pCurrentEntry->pNextFreeEntry = 0; 195 196 pCurrentEntry->tTxPktParams.uFlags = 0; 197 pCurrentEntry->tTxPktParams.uHeadroomSize = 0; 198 199 return pCurrentEntry; 200} 201 202 203/**************************************************************************** 204 * txCtrlBlk_Free() 205 **************************************************************************** 206 * DESCRIPTION: 207 Link the freed entry after entry 0, so now it is the first free entry to 208 be allocated. 209 ****************************************************************************/ 210void txCtrlBlk_Free (TI_HANDLE hTxCtrlBlk, TTxCtrlBlk *pCurrentEntry) 211{ 212 TTxCtrlBlkObj *pTxCtrlBlk = (TTxCtrlBlkObj *)hTxCtrlBlk; 213 TTxCtrlBlk *pFirstFreeEntry = &(pTxCtrlBlk->aTxCtrlBlkTbl[0]); 214 215 if (!pTxCtrlBlk) { 216 return; 217 } 218 219#ifdef TI_DBG 220 /* If the pointed entry is already free, print error and exit (not expected to happen). */ 221 if (pCurrentEntry->pNextFreeEntry != 0) 222 { 223 TRACE2(pTxCtrlBlk->hReport, REPORT_SEVERITY_ERROR, "txCtrlBlk_free(): Entry %d alredy free, UsedEntries=%d\n", pCurrentEntry->tTxDescriptor.descID, pTxCtrlBlk->uNumUsedEntries); 224 return; 225 } 226 pTxCtrlBlk->uNumUsedEntries--; 227#endif 228 229 /* Protect block freeing from preemption (may be called from external context) */ 230 context_EnterCriticalSection (pTxCtrlBlk->hContext); 231 232 /* Link the freed entry between entry 0 and the next free entry. */ 233 pCurrentEntry->pNextFreeEntry = pFirstFreeEntry->pNextFreeEntry; 234 pFirstFreeEntry->pNextFreeEntry = pCurrentEntry; 235 236 context_LeaveCriticalSection (pTxCtrlBlk->hContext); 237} 238 239 240/**************************************************************************** 241 * txCtrlBlk_GetPointer() 242 **************************************************************************** 243 * DESCRIPTION: 244 Return a pointer to the control block entry of the requested packet. 245 Used upon tx-complete to retrieve info after getting the descId from the FW. 246 ****************************************************************************/ 247TTxCtrlBlk *txCtrlBlk_GetPointer (TI_HANDLE hTxCtrlBlk, TI_UINT8 descId) 248{ 249 TTxCtrlBlkObj *pTxCtrlBlk = (TTxCtrlBlkObj *)hTxCtrlBlk; 250 return ( &(pTxCtrlBlk->aTxCtrlBlkTbl[descId]) ); 251} 252 253 254/**************************************************************************** 255 * txCtrlBlk_PrintTable() 256 **************************************************************************** 257 * DESCRIPTION: Print the txCtrlBlk table main fields. 258 ****************************************************************************/ 259#ifdef TI_DBG 260void txCtrlBlk_PrintTable (TI_HANDLE hTxCtrlBlk) 261{ 262#ifdef REPORT_LOG 263 TTxCtrlBlkObj *pTxCtrlBlk = (TTxCtrlBlkObj *)hTxCtrlBlk; 264 TI_UINT8 entry; 265 266 WLAN_OS_REPORT((" Tx-Control-Block Information, UsedEntries=%d\n", pTxCtrlBlk->uNumUsedEntries)); 267 WLAN_OS_REPORT(("==============================================\n")); 268 269 for(entry = 0; entry < CTRL_BLK_ENTRIES_NUM; entry++) 270 { 271 WLAN_OS_REPORT(("Entry %d: DescID=%d, Next=0x%x, Len=%d, StartTime=%d, TID=%d, ExtraBlks=%d, TotalBlks=%d, Flags=0x%x\n", 272 entry, 273 pTxCtrlBlk->aTxCtrlBlkTbl[entry].tTxDescriptor.descID, 274 pTxCtrlBlk->aTxCtrlBlkTbl[entry].pNextFreeEntry, 275 ENDIAN_HANDLE_WORD(pTxCtrlBlk->aTxCtrlBlkTbl[entry].tTxDescriptor.length), 276 ENDIAN_HANDLE_LONG(pTxCtrlBlk->aTxCtrlBlkTbl[entry].tTxDescriptor.startTime), 277 pTxCtrlBlk->aTxCtrlBlkTbl[entry].tTxDescriptor.tid, 278 pTxCtrlBlk->aTxCtrlBlkTbl[entry].tTxDescriptor.extraMemBlks, 279 pTxCtrlBlk->aTxCtrlBlkTbl[entry].tTxDescriptor.totalMemBlks, 280 pTxCtrlBlk->aTxCtrlBlkTbl[entry].tTxPktParams.uFlags)); 281 } 282#endif 283} 284#endif /* TI_DBG */ 285 286