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: txHwQueue.c
39 *
40 * PURPOSE: manage the wlan hardware Tx memory blocks allocation per queue.
41 *
42 * DESCRIPTION:
43 * ============
44 * This module is responsible for the HW Tx resources allocation (except
45 * the HW double buffer).
46 * The HW Tx resources are allocated and freed in the driver by pure
47 * calculations without accessing the FW. This is done by tracking the
48 * resources allocation and freeing, and checking against thresholds before
49 * each allocation.
50 ****************************************************************************/
51
52 #ifdef _WINDOWS
53 #endif
54
55 #include "whalCommon.h"
56 #include "whalHwDefs.h"
57 #include "whalCtrl_api.h"
58 #include "whalParams.h"
59 #include "txCtrlBlk_api.h"
60 #include "txHwQueue_api.h"
61
62 #include "txHwQueue.h" /* Local definitions */
63
64
65
66
67
68 /****************************************************************************
69 * txHwQueue_Create()
70 ****************************************************************************
71 * DESCRIPTION: Create the Tx buffers pool object
72 *
73 * INPUTS: None
74 *
75 * OUTPUT: None
76 *
77 * RETURNS: The Created object
78 ****************************************************************************/
txHwQueue_Create(TI_HANDLE hOs)79 TI_HANDLE txHwQueue_Create(TI_HANDLE hOs)
80 {
81 TxHwQueueObj_t *pTxHwQueue;
82
83 pTxHwQueue = os_memoryAlloc(hOs, sizeof(TxHwQueueObj_t));
84 if (pTxHwQueue == NULL)
85 return NULL;
86
87 os_memoryZero(hOs, pTxHwQueue, sizeof(TxHwQueueObj_t));
88
89 pTxHwQueue->hOs = hOs;
90
91 return( (TI_HANDLE)pTxHwQueue );
92 }
93
94 /****************************************************************************
95 * txHwQueue_Destroy()
96 ****************************************************************************
97 * DESCRIPTION: Destroy the Tx buffers pool object
98 *
99 * INPUTS: hTxHwQueue - The object to free
100 *
101 * OUTPUT: None
102 *
103 * RETURNS: OK or NOK
104 ****************************************************************************/
txHwQueue_Destroy(TI_HANDLE hTxHwQueue)105 TI_STATUS txHwQueue_Destroy(TI_HANDLE hTxHwQueue)
106 {
107 TxHwQueueObj_t *pTxHwQueue = (TxHwQueueObj_t *)hTxHwQueue;
108
109 if (pTxHwQueue)
110 os_memoryFree(pTxHwQueue->hOs, pTxHwQueue, sizeof(TxHwQueueObj_t));
111
112 return OK;
113 }
114
115
116
117
118 /****************************************************************************
119 * txHwQueue_init()
120 ****************************************************************************
121
122 DESCRIPTION: Initialize module handles.
123
124 ****************************************************************************/
txHwQueue_init(TI_HANDLE hTxHwQueue,TI_HANDLE hReport,TI_HANDLE hWhalParams)125 TI_STATUS txHwQueue_init(TI_HANDLE hTxHwQueue, TI_HANDLE hReport, TI_HANDLE hWhalParams)
126 {
127 TxHwQueueObj_t *pTxHwQueue = (TxHwQueueObj_t *)hTxHwQueue;
128
129 pTxHwQueue->hReport = hReport;
130 pTxHwQueue->pWhalParams = (WhalParams_T *)hWhalParams;
131
132 return OK;
133 }
134
135 /****************************************************************************
136 * txHwQueue_Config()
137 ****************************************************************************
138 * DESCRIPTION: Configure the Tx buffers pool object
139 *
140 * INPUTS: None
141 *
142 * OUTPUT: None
143 *
144 * RETURNS:
145 ****************************************************************************/
txHwQueue_Config(TI_HANDLE hTxHwQueue,TnetwDrv_InitParams_t * pInitParams)146 TI_STATUS txHwQueue_Config(TI_HANDLE hTxHwQueue, TnetwDrv_InitParams_t *pInitParams)
147 {
148 UINT8 acID;
149
150 /* Configure queue parameters to Tx-HW queue module */
151 for(acID = 0 ; acID < MAX_NUM_OF_AC ; acID++)
152 {
153 txHwQueue_configQueue( hTxHwQueue,
154 acID,
155 pInitParams->whalCtrl_init.TxBlocksLowPercentPerAc[acID],
156 pInitParams->whalCtrl_init.TxBlocksHighPercentPerAc[acID]);
157 }
158
159 return OK;
160 }
161
162
163 /****************************************************************************
164 * txHwQueue_setHwInfo()
165 ****************************************************************************
166
167 DESCRIPTION:
168
169 Called after the HW configuration in the driver init or recovery process.
170 Configure Tx HW information, including Tx-HW-blocks number, and per queue
171 Tx-descriptors number. Than, restart the module variables.
172
173 ****************************************************************************/
txHwQueue_setHwInfo(TI_HANDLE hTxHwQueue,DmaParams_T * pDmaParams)174 TI_STATUS txHwQueue_setHwInfo(TI_HANDLE hTxHwQueue, DmaParams_T *pDmaParams)
175 {
176 TxHwQueueObj_t *pTxHwQueue = (TxHwQueueObj_t *)hTxHwQueue;
177 int TxQid;
178
179 pTxHwQueue->NumBlocks = pDmaParams->NumTxBlocks - 1; /* One block must be always free for FW use. */
180
181 /* Get the Tx descriptors number per queue. */
182 for(TxQid = 0; TxQid < MAX_NUM_OF_TX_QUEUES ; TxQid++)
183 pTxHwQueue->TxHwQueueInfo[TxQid].numDescriptors = pDmaParams->TxNumDesc[TxQid];
184
185 /* Restart the module variables. */
186 txHwQueue_restart(hTxHwQueue);
187
188 return OK;
189 }
190
191
192
193
194 /****************************************************************************
195 * txHwQueue_configQueue()
196 ****************************************************************************
197 DESCRIPTION:
198
199 Configure Tx HW queue blocks accounting parameters used in the allocate and free
200 procedures in this module.
201
202 Two thresholds are defined per queue:
203 a) TxBlocksLowPercentPerQueue[queue] - The lower threshold is the minimal number of
204 Tx blocks guaranteed for each queue.
205 The sum of all low thresholds should be less than 100%.
206 b) TxBlocksHighPercentPerQueue[queue] - The higher threshold is the maximal number of
207 Tx blocks that may be allocated to the queue.
208 The extra blocks above the low threshold can be allocated when needed only
209 if they are currently available and are not needed in order to guarantee
210 the other queues low threshold.
211 The sum of all high thresholds should be more than 100%.
212
213 ****************************************************************************/
txHwQueue_configQueue(TI_HANDLE hTxHwQueue,UINT8 TxQid,UINT16 percentOfBlockLowThreshold,UINT16 percentOfBlockHighThreshold)214 TI_STATUS txHwQueue_configQueue(TI_HANDLE hTxHwQueue, UINT8 TxQid,
215 UINT16 percentOfBlockLowThreshold, UINT16 percentOfBlockHighThreshold)
216 {
217 TxHwQueueObj_t *pTxHwQueue = (TxHwQueueObj_t *)hTxHwQueue;
218 txHwQueueInfo_t *pQueueInfo = &(pTxHwQueue->TxHwQueueInfo[TxQid]);
219
220 /* Calculate queue's blocks high threshold: maximum number that may be allocated to it. */
221 pQueueInfo->numBlocksHighThreshold = percentOfBlockHighThreshold * pTxHwQueue->NumBlocks / 100;
222
223 /* Calculate queue's blocks low threshold: minimum number that must be reserved for it. */
224 pQueueInfo->numBlocksLowThreshold = percentOfBlockLowThreshold * pTxHwQueue->NumBlocks / 100;
225
226 /* Set the threshold for low block resources: when the next packet may not have enough blocks. */
227 if (pQueueInfo->numBlocksLowThreshold > MAX_BLKS_PER_PKT)
228 pQueueInfo->lowResourceThresh = pQueueInfo->numBlocksLowThreshold - MAX_BLKS_PER_PKT;
229 else
230 pQueueInfo->lowResourceThresh = 0;
231
232 pQueueInfo->numBlocksUsed = 0;
233 pQueueInfo->numPackets = 0;
234
235 /* Since no blocks are used yet, reserved blocks number equals to the low threshold. */
236 pQueueInfo->numBlocksReserved = pQueueInfo->numBlocksLowThreshold;
237
238 /* Accumulate total reserved blocks. */
239 pTxHwQueue->TotalBlocksReserved += pQueueInfo->numBlocksReserved;
240
241 WLAN_REPORT_INIT(pTxHwQueue->hReport, TX_HW_QUEUE_MODULE_LOG,
242 ("txHwQueue_configQueue(): HighThresh=%d, LowThresh=%d, LowRsrcThresh=%d, TotalReserved=%d\n",
243 pQueueInfo->numBlocksHighThreshold, pQueueInfo->numBlocksLowThreshold,
244 pQueueInfo->lowResourceThresh, pTxHwQueue->TotalBlocksReserved));
245
246 return OK;
247 }
248
249
250
251
252 /****************************************************************************
253 * txHwQueue_restart()
254 ****************************************************************************
255 DESCRIPTION:
256 ============
257 Restarts the Tx-HW-Queue module.
258 Should be called upon disconnect and recovery!!
259 ****************************************************************************/
txHwQueue_restart(TI_HANDLE hTxHwQueue)260 TI_STATUS txHwQueue_restart(TI_HANDLE hTxHwQueue)
261 {
262 TxHwQueueObj_t *pTxHwQueue = (TxHwQueueObj_t *)hTxHwQueue;
263 txHwQueueInfo_t *pQueueInfo;
264 int TxQid;
265
266 /* All blocks are free at restart.
267 Note that free means all blocks that are currently not in use,
268 while reserved are a part of the free blocks that are the summary of all queues reserved blocks.
269 Each queue may take from the reserved part only up to its own reservation (according to
270 its low threshold). */
271
272 pTxHwQueue->NumFree = pTxHwQueue->NumBlocks;
273 pTxHwQueue->TotalBlocksReserved = 0;
274
275 for(TxQid = 0; TxQid < MAX_NUM_OF_TX_QUEUES ; TxQid++)
276 {
277 pQueueInfo = &(pTxHwQueue->TxHwQueueInfo[TxQid]);
278 pQueueInfo->numBlocksUsed = 0;
279 pQueueInfo->numPackets = 0;
280
281 /* Since no blocks are used yet, reserved blocks number equals to the low threshold. */
282 pQueueInfo->numBlocksReserved = pQueueInfo->numBlocksLowThreshold;
283
284 /* Accumulate total reserved blocks. */
285 pTxHwQueue->TotalBlocksReserved += pQueueInfo->numBlocksReserved;
286 }
287
288 return OK;
289 }
290
291
292
293
294 /****************************************************************************
295 * txHwQueue_alloc()
296 ****************************************************************************
297 * DESCRIPTION:
298 ============
299 If the required blocks are available for the queue and there is an available
300 descriptor, update the blocks and descriptor allocation and return OK.
301 Else, return NOK.
302 If the queue's reaources (blocks) are low, indicate in the descriptor to get
303 Tx-complete from FW immediately.
304 ****************************************************************************/
txHwQueue_alloc(TI_HANDLE hTxHwQueue,txCtrlBlkEntry_t * pPktCtrlBlk)305 TI_STATUS txHwQueue_alloc(TI_HANDLE hTxHwQueue, txCtrlBlkEntry_t *pPktCtrlBlk)
306 {
307 TxHwQueueObj_t *pTxHwQueue = (TxHwQueueObj_t *)hTxHwQueue;
308 UINT8 numBlksToAlloc; /* The number of blocks required for the current packet. */
309 UINT8 maxAllowed; /* Max blocks that may be currently allocated to this Queue to obey the high threshold.*/
310 UINT8 maxAvailable; /* Max blocks that are currently free and not reserved for other Queues. */
311 UINT8 reserved; /* How many blocks are reserved to this Queue before this allocation. */
312 txHwQueueInfo_t *pQueueInfo = &(pTxHwQueue->TxHwQueueInfo[pPktCtrlBlk->txDescriptor.xmitQueue]);
313
314
315 /***********************************************************************/
316 /* Calculate packet fragmentation threshold and required HW blocks. */
317 /***********************************************************************/
318
319 txHwQueueCalc_BlocksNum(hTxHwQueue, pPktCtrlBlk);
320
321
322 /***********************************************************************/
323 /* Check if the required resources are available */
324 /***********************************************************************/
325
326 /* If all queue's descriptors are occupied, return BUSY. */
327 if (pQueueInfo->numPackets == pQueueInfo->numDescriptors)
328 {
329 WLAN_REPORT_INFORMATION(pTxHwQueue->hReport, TX_HW_QUEUE_MODULE_LOG,
330 ("txHwQueue_alloc(): No Descriptors, Queue=%d, Descriptors=%d, Packets=%d\n",
331 pPktCtrlBlk->txDescriptor.xmitQueue, pQueueInfo->numDescriptors, pQueueInfo->numPackets));
332 return NOK;
333 }
334
335 reserved = pQueueInfo->numBlocksReserved;
336 numBlksToAlloc = pPktCtrlBlk->txDescriptor.numMemBlks;
337
338 /* Calculate how far we are from this Queue's high threshold limit (allowed = highThresh - used). */
339 maxAllowed = pQueueInfo->numBlocksHighThreshold - pQueueInfo->numBlocksUsed;
340
341 /* Calculate how many buffers are available for this Queue: the total free buffers minus the buffers
342 that are reserved for other Queues (all reserved minus this Queue's reserved). */
343 maxAvailable = pTxHwQueue->NumFree - (pTxHwQueue->TotalBlocksReserved - reserved);
344
345 /* If we need more blocks than are allowed or available, return BUSY. */
346 if (numBlksToAlloc > min(maxAllowed, maxAvailable))
347 {
348 WLAN_REPORT_INFORMATION(pTxHwQueue->hReport, TX_HW_QUEUE_MODULE_LOG,
349 ("txHwQueue_alloc(): No Hw-Blocks, Queue=%d, Req-blks=%d , Free=%d, Used=%d, available=%d\n",
350 pPktCtrlBlk->txDescriptor.xmitQueue, numBlksToAlloc, pTxHwQueue->NumFree, pQueueInfo->numBlocksUsed, maxAvailable));
351 return NOK;
352 }
353
354 /***********************************************************************/
355 /* Allocate required resources */
356 /***********************************************************************/
357
358 /* Update number of packets in FW (for descriptors allocation check). */
359 pQueueInfo->numPackets++;
360
361
362 /* If we are currently using less than the low threshold (i.e. we have some reserved blocks),
363 blocks allocation should reduce the reserved blocks number as follows:
364 */
365 if (reserved)
366 {
367
368 /* If adding the allocated blocks to the used blocks will pass the low-threshold,
369 only the part up to the low-threshold is subtracted from the reserved blocks.
370 This is because blocks are reserved for the Queue only up to its low-threshold.
371
372 0 old used low new used high
373 |######| | | |
374 |######| | | |
375 <------------ allocated ----------->
376 <----- old reserved ---->
377 new reserved = 0 (we passed the low threshold)
378 */
379 if (numBlksToAlloc > reserved)
380 {
381 pQueueInfo->numBlocksReserved = 0;
382 pTxHwQueue->TotalBlocksReserved -= reserved; /* reduce change from total reserved.*/
383 }
384
385
386 /* Else, if allocating less than reserved,
387 the allocated blocks are subtracted from the reserved blocks:
388
389 0 old used new used low high
390 |######| | | |
391 |######| | | |
392 <- allocated ->
393 <--------- old reserved ---------->
394 <-- new reserved -->
395 */
396 else
397 {
398 pQueueInfo->numBlocksReserved -= numBlksToAlloc;
399 pTxHwQueue->TotalBlocksReserved -= numBlksToAlloc; /* reduce change from total reserved.*/
400 }
401 }
402
403
404 /* Update total free blocks and Queue used blocks with the allocated blocks number. */
405 pTxHwQueue->NumFree -= numBlksToAlloc;
406 pQueueInfo->numBlocksUsed += numBlksToAlloc;
407
408 /* If this queue has low resources (blocks or descriptors), set descriptor flag to get Tx-Complete from FW. */
409 if ( (pQueueInfo->numBlocksUsed > pQueueInfo->lowResourceThresh) ||
410 (pQueueInfo->numPackets == pQueueInfo->numDescriptors - 1) )
411 {
412 #ifdef _WINDOWS
413 #else
414 pPktCtrlBlk->txDescriptor.txAttr |= TX_COMPLETE_REQUIRED_BIT;
415 #endif
416 }
417
418 WLAN_REPORT_INFORMATION(pTxHwQueue->hReport, TX_HW_QUEUE_MODULE_LOG,
419 ("txHwQueue_alloc(): SUCCESS, Queue=%d, Req-blks=%d , Free=%d, Used=%d, LowResources=%d\n",
420 pPktCtrlBlk->txDescriptor.xmitQueue, numBlksToAlloc, pTxHwQueue->NumFree,
421 pQueueInfo->numBlocksUsed, (pQueueInfo->numBlocksUsed > pQueueInfo->lowResourceThresh)));
422
423 return OK;
424 }
425
426
427
428
429 /****************************************************************************
430 * txHwQueue_free()
431 ****************************************************************************
432 * DESCRIPTION: Decrement the number of used descriptors and used data blks
433 for the specific queue.
434 ****************************************************************************/
txHwQueue_free(TI_HANDLE hTxHwQueue,txCtrlBlkEntry_t * pPktCtrlBlk)435 TI_STATUS txHwQueue_free(TI_HANDLE hTxHwQueue, txCtrlBlkEntry_t *pPktCtrlBlk)
436 {
437 TxHwQueueObj_t *pTxHwQueue = (TxHwQueueObj_t *)hTxHwQueue;
438 UINT8 numBlksToFree; /* The number of blocks freed by the current packet. */
439 UINT8 lowThreshold; /* Minimum blocks that are guaranteed for this Queue. */
440 UINT8 newUsed; /* Blocks that are used by this Queue after freeing these blocks. */
441 UINT8 newReserved; /* How many blocks are reserved to this Queue after freeing. */
442 txHwQueueInfo_t *pQueueInfo = &(pTxHwQueue->TxHwQueueInfo[pPktCtrlBlk->txDescriptor.xmitQueue]);
443
444 numBlksToFree = pPktCtrlBlk->txDescriptor.numMemBlks;
445
446 /* Update number of packets in FW (for descriptors allocation check). */
447 pQueueInfo->numPackets--;
448
449 #ifdef TI_DBG /* Debug Counters */
450 /* Sanity check: make sure we don't free more blocks than are in use. */
451 if (numBlksToFree > pQueueInfo->numBlocksUsed)
452 {
453 WLAN_REPORT_ERROR(pTxHwQueue->hReport, TX_HW_QUEUE_MODULE_LOG,
454 ("txHwQueue_free(): Try to free more blks than used: Queue %d, free %d, used %d\n",
455 pPktCtrlBlk->txDescriptor.xmitQueue, numBlksToFree, pQueueInfo->numBlocksUsed));
456 return NOK;
457 }
458 #endif
459
460 /* Update total free blocks and Queue used blocks with the freed blocks number. */
461 pTxHwQueue->NumFree += numBlksToFree;
462 pQueueInfo->numBlocksUsed -= numBlksToFree;
463
464
465 lowThreshold = pQueueInfo->numBlocksLowThreshold;
466 newUsed = pQueueInfo->numBlocksUsed;
467
468
469 /* If after freeing the blocks we are using less than the low threshold,
470 update total reserved blocks number as follows:
471 (note: if we are above the low threshold after freeing the blocks we still have no reservation.)
472 */
473 if (newUsed < lowThreshold)
474 {
475 newReserved = lowThreshold - newUsed;
476 pQueueInfo->numBlocksReserved = newReserved;
477
478
479 /* If freeing the blocks reduces the used blocks from above to below the low-threshold,
480 only the part from the low-threshold to the new used number is added to the
481 reserved blocks (because blocks are reserved for the Queue only up to its low-threshold):
482
483 0 new used low old used high
484 |###########|####################|################| |
485 |###########|####################|################| |
486 <-------------- freed -------------->
487 <-- new reserved -->
488 old reserved = 0
489 */
490 if (numBlksToFree > newReserved)
491 pTxHwQueue->TotalBlocksReserved += newReserved; /* Add change to total reserved.*/
492
493
494 /* Else, if we were under the low-threshold before freeing these blocks,
495 all freed blocks are added to the reserved blocks:
496
497 0 new used old used low high
498 |################|#################| | |
499 |################|#################| | |
500 <---- freed ---->
501 <- old reserved ->
502 <---------- new reserved ---------->
503 */
504 else
505 pTxHwQueue->TotalBlocksReserved += numBlksToFree; /* Add change to total reserved.*/
506 }
507
508 return OK;
509 }
510
511
512
513
514 /****************************************************************************
515 * txHwQueue_GetUsedHwBlks()
516 ****************************************************************************
517 * DESCRIPTION: Provide the number of used HW Tx blocks of the given Queue.
518 ****************************************************************************/
txHwQueue_GetUsedHwBlks(TI_HANDLE hTxHwQueue,int TxQid)519 UINT8 txHwQueue_GetUsedHwBlks(TI_HANDLE hTxHwQueue, int TxQid)
520 {
521 TxHwQueueObj_t *pTxHwQueue = (TxHwQueueObj_t *)hTxHwQueue;
522 return (pTxHwQueue->TxHwQueueInfo[TxQid].numBlocksUsed);
523 }
524
525
526
527
528 /****************************************************************************
529 * txHwQueue_printInfo()
530 ****************************************************************************
531 * DESCRIPTION: Print the Hw Queue current information
532 ****************************************************************************/
txHwQueue_printInfo(TI_HANDLE hTxHwQueue)533 void txHwQueue_printInfo(TI_HANDLE hTxHwQueue)
534 {
535 #ifdef TI_DBG
536 TxHwQueueObj_t *pTxHwQueue = (TxHwQueueObj_t *)hTxHwQueue;
537 int TxQid;
538
539 /* Print the Tx-HW-Queue information: */
540 WLAN_OS_REPORT(("Hw-Queues Information:\n"));
541 WLAN_OS_REPORT(("======================\n"));
542 WLAN_OS_REPORT(("Total Blocks: %d\n", pTxHwQueue->NumBlocks));
543 WLAN_OS_REPORT(("Total Free Blocks: %d\n", pTxHwQueue->NumFree));
544 WLAN_OS_REPORT(("Total Reserved Blocks: %d\n\n", pTxHwQueue->TotalBlocksReserved));
545
546 for(TxQid = 0; TxQid < MAX_NUM_OF_TX_QUEUES; TxQid++)
547 {
548 WLAN_OS_REPORT(("Queue %d: Used=%d, Reserved=%d, LowThresh=%d, HighThresh=%d, LowRsrcThresh=%d, NumDesc=%d, UsedDesc=%d\n",
549 TxQid,
550 pTxHwQueue->TxHwQueueInfo[TxQid].numBlocksUsed,
551 pTxHwQueue->TxHwQueueInfo[TxQid].numBlocksReserved,
552 pTxHwQueue->TxHwQueueInfo[TxQid].numBlocksLowThreshold,
553 pTxHwQueue->TxHwQueueInfo[TxQid].numBlocksHighThreshold,
554 pTxHwQueue->TxHwQueueInfo[TxQid].lowResourceThresh,
555 pTxHwQueue->TxHwQueueInfo[TxQid].numDescriptors,
556 pTxHwQueue->TxHwQueueInfo[TxQid].numPackets));
557 }
558 #endif /* TI_DBG */
559 }
560
561