1 /**************************************************************************** 2 **+-----------------------------------------------------------------------+** 3 **| |** 4 **| Copyright(c) 1998 - 2008 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 * 38 * MODULE: txCtrlBlk.c 39 * 40 * PURPOSE: Maintains active packets Tx attributes table (including descriptor). 41 * 42 * DESCRIPTION: 43 * ============ 44 * This module allocates and frees table entry for each packet in the Tx 45 * process (from sendPkt by upper driver until Tx-complete). 46 * 47 ****************************************************************************/ 48 49 #include "osTIType.h" 50 #include "whalCommon.h" 51 #include "whalHwDefs.h" 52 #include "txCtrlBlk_api.h" 53 54 #include "txCtrlBlk.h" /* Local definitions */ 55 56 57 58 /**************************************************************************** 59 * txCtrlBlk_Create() 60 **************************************************************************** 61 * DESCRIPTION: Create the Tx control block table object 62 * 63 * INPUTS: hOs 64 * 65 * OUTPUT: None 66 * 67 * RETURNS: The Created object 68 ****************************************************************************/ 69 TI_HANDLE txCtrlBlk_Create(TI_HANDLE hOs) 70 { 71 txCtrlBlkObj_t *pTxCtrlBlk; 72 73 pTxCtrlBlk = os_memoryAlloc(hOs, sizeof(txCtrlBlkObj_t)); 74 if (pTxCtrlBlk == NULL) 75 return NULL; 76 77 os_memoryZero(hOs, pTxCtrlBlk, sizeof(txCtrlBlkObj_t)); 78 79 pTxCtrlBlk->hOs = hOs; 80 81 return( (TI_HANDLE)pTxCtrlBlk ); 82 } 83 84 85 86 87 /**************************************************************************** 88 * txCtrlBlk_Destroy() 89 **************************************************************************** 90 * DESCRIPTION: Destroy the Tx control block table object 91 * 92 * INPUTS: hTxCtrlBlk - The object to free 93 * 94 * OUTPUT: None 95 * 96 * RETURNS: OK or NOK 97 ****************************************************************************/ 98 TI_STATUS txCtrlBlk_Destroy(TI_HANDLE hTxCtrlBlk) 99 { 100 txCtrlBlkObj_t *pTxCtrlBlk = (txCtrlBlkObj_t *)hTxCtrlBlk; 101 102 if (pTxCtrlBlk) 103 os_memoryFree(pTxCtrlBlk->hOs, pTxCtrlBlk, sizeof(txCtrlBlkObj_t)); 104 105 return OK; 106 } 107 108 109 110 111 /**************************************************************************** 112 * txCtrlBlk_init() 113 **************************************************************************** 114 DESCRIPTION: Initialize the Tx control block module. 115 ****************************************************************************/ 116 TI_STATUS txCtrlBlk_init(TI_HANDLE hTxCtrlBlk, TI_HANDLE hReport) 117 { 118 txCtrlBlkObj_t *pTxCtrlBlk = (txCtrlBlkObj_t *)hTxCtrlBlk; 119 120 pTxCtrlBlk->hReport = hReport; 121 122 txCtrlBlk_restart(hTxCtrlBlk); 123 124 return OK; 125 } 126 127 128 129 130 /**************************************************************************** 131 * txCtrlBlk_restart() 132 **************************************************************************** 133 DESCRIPTION: 134 ============ 135 Restarts the Tx-control-block table. 136 Should be called upon init, disconnect and recovery!! 137 ****************************************************************************/ 138 TI_STATUS txCtrlBlk_restart(TI_HANDLE hTxCtrlBlk) 139 { 140 UINT8 entry; 141 txCtrlBlkObj_t *pTxCtrlBlk = (txCtrlBlkObj_t *)hTxCtrlBlk; 142 143 /* For all entries, write the entry index in the descriptor and the next entry address 144 in the next free entery pointer. */ 145 for(entry = 0; entry < CTRL_BLK_ENTRIES_NUM; entry++) 146 { 147 pTxCtrlBlk->TxCtrlBlkTbl[entry].txDescriptor.descID = entry; 148 pTxCtrlBlk->TxCtrlBlkTbl[entry].pNextFreeEntry = &(pTxCtrlBlk->TxCtrlBlkTbl[entry + 1]); 149 } 150 151 /* Write null in the next-free index of the last entry. */ 152 pTxCtrlBlk->TxCtrlBlkTbl[CTRL_BLK_ENTRIES_NUM - 1].pNextFreeEntry = NULL; 153 154 #ifdef TI_DBG 155 pTxCtrlBlk->numUsedEntries = 0; 156 #endif 157 158 return OK; 159 } 160 161 162 163 164 165 /**************************************************************************** 166 * txCtrlBlk_alloc() 167 **************************************************************************** 168 * DESCRIPTION: 169 Allocate a free control-block entry for the current Tx packet's parameters 170 (including the descriptor structure). 171 Note that entry 0 in the list is never allocated and points to the 172 first free entry. 173 ****************************************************************************/ 174 txCtrlBlkEntry_t *txCtrlBlk_alloc(TI_HANDLE hTxCtrlBlk) 175 { 176 txCtrlBlkObj_t *pTxCtrlBlk = (txCtrlBlkObj_t *)hTxCtrlBlk; 177 txCtrlBlkEntry_t *pCurrentEntry; /* The pointer of the new entry allocated for the packet. */ 178 txCtrlBlkEntry_t *pFirstFreeEntry; /* The first entry just points to the first free entry. */ 179 180 pFirstFreeEntry = &(pTxCtrlBlk->TxCtrlBlkTbl[0]); 181 pCurrentEntry = pFirstFreeEntry->pNextFreeEntry; /* Get free entry. */ 182 183 /* If no free entries, print error (not expected to happen) and return NULL. */ 184 if (pCurrentEntry == NULL) 185 { 186 #ifdef TI_DBG 187 WLAN_REPORT_ERROR(pTxCtrlBlk->hReport, TX_CTRL_BLK_MODULE_LOG, 188 ("txCtrlBlk_alloc(): No free entry, UsedEntries=%d\n", pTxCtrlBlk->numUsedEntries)); 189 #endif 190 return NULL; 191 } 192 #ifdef TI_DBG 193 pTxCtrlBlk->numUsedEntries++; 194 #endif 195 196 /* Link the first entry to the next free entry. */ 197 pFirstFreeEntry->pNextFreeEntry = pCurrentEntry->pNextFreeEntry; 198 199 /* Clear the next-free-entry index just as an indication that our entry is not free. */ 200 pCurrentEntry->pNextFreeEntry = 0; 201 202 return pCurrentEntry; 203 } 204 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, txCtrlBlkEntry_t *pCurrentEntry) 216 { 217 txCtrlBlkObj_t *pTxCtrlBlk = (txCtrlBlkObj_t *)hTxCtrlBlk; 218 txCtrlBlkEntry_t *pFirstFreeEntry = &(pTxCtrlBlk->TxCtrlBlkTbl[0]); 219 220 /* If the pointed entry is already free, print error and exit (not expected to happen). */ 221 if (pCurrentEntry->pNextFreeEntry != 0) 222 { 223 #ifdef TI_DBG 224 WLAN_REPORT_ERROR(pTxCtrlBlk->hReport, TX_CTRL_BLK_MODULE_LOG, 225 ("txCtrlBlk_free(): Entry %d alredy free, UsedEntries=%d\n", 226 pCurrentEntry->txDescriptor.descID, pTxCtrlBlk->numUsedEntries)); 227 #endif 228 return; 229 } 230 #ifdef TI_DBG 231 pTxCtrlBlk->numUsedEntries--; 232 #endif 233 234 /* Link the freed entry between entry 0 and the next free entry. */ 235 pCurrentEntry->pNextFreeEntry = pFirstFreeEntry->pNextFreeEntry; 236 pFirstFreeEntry->pNextFreeEntry = pCurrentEntry; 237 } 238 239 240 241 242 /**************************************************************************** 243 * txCtrlBlk_GetPointer() 244 **************************************************************************** 245 * DESCRIPTION: 246 Return a pointer to the control block entry of the requested packet. 247 Used upon tx-complete to retrieve info after getting the descId from the FW. 248 ****************************************************************************/ 249 txCtrlBlkEntry_t *txCtrlBlk_GetPointer(TI_HANDLE hTxCtrlBlk, UINT8 descId) 250 { 251 txCtrlBlkObj_t *pTxCtrlBlk = (txCtrlBlkObj_t *)hTxCtrlBlk; 252 return ( &(pTxCtrlBlk->TxCtrlBlkTbl[descId]) ); 253 } 254 255 256 257 258 /**************************************************************************** 259 * txCtrlBlk_printTable() 260 **************************************************************************** 261 * DESCRIPTION: Print the txCtrlBlk table main fields. 262 ****************************************************************************/ 263 void txCtrlBlk_printTable(TI_HANDLE hTxCtrlBlk) 264 { 265 #ifdef TI_DBG 266 txCtrlBlkObj_t *pTxCtrlBlk = (txCtrlBlkObj_t *)hTxCtrlBlk; 267 UINT8 entry; 268 269 WLAN_OS_REPORT((" Tx-Control-Block Information, UsedEntries=%d\n", pTxCtrlBlk->numUsedEntries)); 270 WLAN_OS_REPORT(("==============================================\n")); 271 272 for(entry = 0; entry < CTRL_BLK_ENTRIES_NUM; entry++) 273 { 274 WLAN_OS_REPORT(("Entry %d: DescID=%d, NextEntry=0x%x, PktID=0x%x, PktLen=%d, FragThresh=%d, NumBlks=%d, FC=0x%x, Flags=0x%x\n", 275 entry, 276 pTxCtrlBlk->TxCtrlBlkTbl[entry].txDescriptor.descID, 277 pTxCtrlBlk->TxCtrlBlkTbl[entry].pNextFreeEntry, 278 pTxCtrlBlk->TxCtrlBlkTbl[entry].txPktParams.packetId, 279 pTxCtrlBlk->TxCtrlBlkTbl[entry].txDescriptor.length, 280 pTxCtrlBlk->TxCtrlBlkTbl[entry].txDescriptor.fragThreshold, 281 pTxCtrlBlk->TxCtrlBlkTbl[entry].txDescriptor.numMemBlks, 282 pTxCtrlBlk->TxCtrlBlkTbl[entry].txPktParams.headerFrameCtrl, 283 pTxCtrlBlk->TxCtrlBlkTbl[entry].txPktParams.flags)); 284 } 285 #endif /* TI_DBG */ 286 } 287