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