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 ****************************************************************************/
txCtrlBlk_Create(TI_HANDLE hOs)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 ****************************************************************************/
txCtrlBlk_Destroy(TI_HANDLE hTxCtrlBlk)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 ****************************************************************************/
txCtrlBlk_init(TI_HANDLE hTxCtrlBlk,TI_HANDLE hReport)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 ****************************************************************************/
txCtrlBlk_restart(TI_HANDLE hTxCtrlBlk)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 ****************************************************************************/
txCtrlBlk_alloc(TI_HANDLE hTxCtrlBlk)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 ****************************************************************************/
txCtrlBlk_free(TI_HANDLE hTxCtrlBlk,txCtrlBlkEntry_t * pCurrentEntry)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 ****************************************************************************/
txCtrlBlk_GetPointer(TI_HANDLE hTxCtrlBlk,UINT8 descId)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 ****************************************************************************/
txCtrlBlk_printTable(TI_HANDLE hTxCtrlBlk)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