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: TNETW_Driver_Tx.c
39 *
40 * PURPOSE: TNETW_Driver Tx API functions needed externally to the driver.
41 *
42 ****************************************************************************/
43
44 #include "whalParams.h"
45 #include "report.h"
46 #include "TNETW_Driver_api.h"
47 #include "txCtrlBlk_api.h"
48 #include "txHwQueue_api.h"
49 #include "txXfer_api.h"
50 #include "txResult_api.h"
51 #include "TNETW_Driver.h"
52
53
54 static systemStatus_e ConvertTxResultStatus(TxDescStatus_enum txResultStatus);
55
56
57 /****************************************************************************
58 * Tx Control Block API functions *
59 ****************************************************************************/
60
TnetwDrv_txCtrlBlk_alloc(TI_HANDLE hTnetwDrv)61 txCtrlBlkEntry_t *TnetwDrv_txCtrlBlk_alloc(TI_HANDLE hTnetwDrv)
62 {
63 TnetwDrv_t *pTnetwDrv = (TnetwDrv_t *)hTnetwDrv;
64
65 return txCtrlBlk_alloc(pTnetwDrv->hTxCtrlBlk);
66 }
67
68
TnetwDrv_txCtrlBlk_free(TI_HANDLE hTnetwDrv,txCtrlBlkEntry_t * pCurrentEntry)69 void TnetwDrv_txCtrlBlk_free(TI_HANDLE hTnetwDrv, txCtrlBlkEntry_t *pCurrentEntry)
70 {
71 TnetwDrv_t *pTnetwDrv = (TnetwDrv_t *)hTnetwDrv;
72
73 txCtrlBlk_free(pTnetwDrv->hTxCtrlBlk, pCurrentEntry);
74 }
75
76
TnetwDrv_txCtrlBlk_GetPointer(TI_HANDLE hTnetwDrv,UINT8 descId)77 txCtrlBlkEntry_t *TnetwDrv_txCtrlBlk_GetPointer(TI_HANDLE hTnetwDrv, UINT8 descId)
78 {
79 TnetwDrv_t *pTnetwDrv = (TnetwDrv_t *)hTnetwDrv;
80
81 return txCtrlBlk_GetPointer(pTnetwDrv->hTxCtrlBlk, descId);
82 }
83
84
85
86 /****************************************************************************
87 * Tx HW Queue API functions *
88 ****************************************************************************/
89
TnetwDrv_txHwQueue_alloc(TI_HANDLE hTnetwDrv,txCtrlBlkEntry_t * pPktCtrlBlk)90 TI_STATUS TnetwDrv_txHwQueue_alloc(TI_HANDLE hTnetwDrv, txCtrlBlkEntry_t *pPktCtrlBlk)
91 {
92 TnetwDrv_t *pTnetwDrv = (TnetwDrv_t *)hTnetwDrv;
93
94 return txHwQueue_alloc(pTnetwDrv->hTxHwQueue, pPktCtrlBlk);
95 }
96
97
TnetwDrv_txHwQueue_free(TI_HANDLE hTnetwDrv,txCtrlBlkEntry_t * pPktCtrlBlk)98 TI_STATUS TnetwDrv_txHwQueue_free(TI_HANDLE hTnetwDrv, txCtrlBlkEntry_t *pPktCtrlBlk)
99 {
100 TnetwDrv_t *pTnetwDrv = (TnetwDrv_t *)hTnetwDrv;
101
102 return txHwQueue_free(pTnetwDrv->hTxHwQueue, pPktCtrlBlk);
103 }
104
105
TnetwDrv_txHwQueue_GetUsedHwBlks(TI_HANDLE hTnetwDrv,int TxQid)106 UINT8 TnetwDrv_txHwQueue_GetUsedHwBlks(TI_HANDLE hTnetwDrv, int TxQid)
107 {
108 TnetwDrv_t *pTnetwDrv = (TnetwDrv_t *)hTnetwDrv;
109
110 return txHwQueue_GetUsedHwBlks(pTnetwDrv->hTxHwQueue, TxQid);
111 }
112
113
114
115 /****************************************************************************
116 * Tx Xfer API functions *
117 ****************************************************************************/
118
TnetwDrv_txXfer_sendPacket(TI_HANDLE hTnetwDrv,const void * aFrame,UINT16 aLength,UINT8 aQueueId,UINT8 aTxRateClassId,UINT16 aMaxTransmitRate,BOOL aMore,UINT32 aPacketId,UINT8 aPowerLevel,UINT32 aExpiryTime,void * aReserved)119 systemStatus_e TnetwDrv_txXfer_sendPacket(TI_HANDLE hTnetwDrv,
120 const void *aFrame, /* Pointer to the packet content. points to */
121 /* the place that the actual packet begins. */
122 /* a size of TX_TOTAL_OFFSET_BEFORE_DATA */
123 /* must be saved before that pointer */
124 UINT16 aLength, /* MSDU length from first byte of MAC */
125 /* header to last byteof frame body. */
126 UINT8 aQueueId, /* Tx queue as defined in ConfigureQueue. */
127 UINT8 aTxRateClassId, /* Tx rate class ID defined in txRatePolicy.*/
128 UINT16 aMaxTransmitRate,/* A bit mask that specifies the initial */
129 /* (highest) rate to use. */
130 BOOL aMore, /* Tells if there is another packet coming */
131 /* shortly after this one. */
132 UINT32 aPacketId, /* Packet identifier used as a context by */
133 /* the host driver. */
134 UINT8 aPowerLevel, /* Transmission power level. */
135 UINT32 aExpiryTime, /* Time left for this MSDU to live. */
136 void *aReserved) /* Optional parameters pointer. */
137
138 {
139 TnetwDrv_t *pTnetwDrv = (TnetwDrv_t *)hTnetwDrv;
140 TxDescCtrl_t txAttr, *pTxAttr = &txAttr; /* A union for setting the txAttr bit fields. */
141 dot11_header_t *pDot11Hdr;
142 systemStatus_e status;
143 txCtrlBlkEntry_t *pPktCtrlBlk;
144 WhalParams_T *pWhalParams = (WhalParams_T *)(pTnetwDrv->hWhalParams);
145 BOOL bIsMultiCastAndIBSS; /* used for the Ack policy */
146
147 #ifdef TI_DBG
148 /* If queue number is invalid return ERROR. */
149 if (aQueueId >= MAX_NUM_OF_TX_QUEUES)
150 {
151 WLAN_REPORT_ERROR(pTnetwDrv->hReport, TNETW_DRV_MODULE_LOG,
152 ("TnetwDrv_txXfer_sendPacket(): Invalid aQueueId = %d !!!\n", aQueueId));
153 return SEND_PACKET_ERROR;
154 }
155 #endif
156
157 /*****************************************************************************************/
158 /* 1) Allocates a Control-Block for the packet Tx parameters and descriptor. */
159 /*****************************************************************************************/
160
161 pPktCtrlBlk = TnetwDrv_txCtrlBlk_alloc(pTnetwDrv);
162
163 #ifdef TI_DBG
164 pTnetwDrv->dbgCountSentPackets[aQueueId]++; /* Count packets sent from upper driver. */
165 #endif
166 /* If null entry (not expected to happen) return ERROR. */
167 if (!pPktCtrlBlk)
168 {
169 #ifdef TI_DBG
170 WLAN_REPORT_ERROR(pTnetwDrv->hReport, TNETW_DRV_MODULE_LOG,
171 ("TnetwDrv_txXfer_sendPacket(): Tx Ctrl-Blk allocation failed!!!\n"));
172 #endif
173 return SEND_PACKET_ERROR;
174 }
175
176 /*****************************************************************************************/
177 /* 2) Set the packet control block parameters (including descriptor structure). */
178 /*****************************************************************************************/
179
180 /* Note that the following params are currently not used: aMore, aPowerLevel, aReserved. */
181
182 /* Note that the following descriptor params are for future use, so they are left zeroed:
183 pktType and xferPadding fields in txAttr, and tid. */
184
185 /* Note that the other params are set later in the Tx process (e.g. fragThresh and numMemBlks). */
186
187 /* aFrame points to the start of the data, but we need to reserve place for descriptor + TNETWIF_WRITE_OFFSET_BYTES */
188 pPktCtrlBlk->txPktParams.pFrame = (void*)((UINT8 *)aFrame - TX_TOTAL_OFFSET_BEFORE_DATA);
189
190 pPktCtrlBlk->txDescriptor.length = aLength;
191 pPktCtrlBlk->txDescriptor.xmitQueue = aQueueId;
192 pPktCtrlBlk->txDescriptor.rate = aMaxTransmitRate;
193 pPktCtrlBlk->txPktParams.packetId = aPacketId;
194 pPktCtrlBlk->txDescriptor.expiryTime = aExpiryTime << SHIFT_BETWEEN_TU_AND_USEC; /* Convert TUs to microseconds. */
195
196 pDot11Hdr = (dot11_header_t*)(aFrame); /* aFrame points to the start of the data */
197 pPktCtrlBlk->txPktParams.headerFrameCtrl = pDot11Hdr->fc; /* Save frame-control field from MAC header. */
198
199 /* Set descriptor control bit-mask fields and write the whole word to the descriptor. */
200 *(uint16 *)pTxAttr = 0; /* Clear temporary union. */
201 txAttr.ratePolicy = aTxRateClassId;
202
203 /* Configure the Ack policy */
204 bIsMultiCastAndIBSS = ((BSS_INDEPENDENT == (bssType_e)(whal_ParamsGetReqBssType(pWhalParams)))
205 && (MAC_MULTICAST(GET_DA_FROM_DOT11_HEADER_T(pDot11Hdr))));
206 txAttr.ackPolicy = TnetwDrv_txGetAckPolicy(pTnetwDrv, aQueueId , bIsMultiCastAndIBSS);
207
208 if (IS_QOS_FRAME(pDot11Hdr->fc)) /* Check if frame is QoS-Data or QoS-Null. */
209 txAttr.qosFrame = 1;
210
211 /* if this is a management frame, request immediate TX complete indication */
212 if ( (pDot11Hdr->fc & DOT11_FC_TYPE_MASK) == DOT11_FC_TYPE_MGMT )
213 {
214 txAttr.txCmpltRequired = 1;
215 }
216
217 pPktCtrlBlk->txDescriptor.txAttr = *(uint16 *)pTxAttr;
218
219 pPktCtrlBlk->txPktParams.flags = 0;
220
221
222 /************************************************************************************************/
223 /* 3) Call HwQueue for Hw resources allocation. If not available free CtrlBlk and return BUSY. */
224 /************************************************************************************************/
225
226 /* Note that the HwQueue calls first the fragThreshold and numMemBlks calculation. */
227
228 if ( TnetwDrv_txHwQueue_alloc(pTnetwDrv, pPktCtrlBlk) != OK )
229 {
230 TnetwDrv_txCtrlBlk_free(pTnetwDrv, pPktCtrlBlk);
231 return SEND_PACKET_BUSY;
232 }
233
234 #ifdef TI_DBG
235 /* Just for debug, write per queue sequence number to packet ctrl-blk (after allocation success!). */
236 pTnetwDrv->dbgPktSeqNum[aQueueId]++;
237 pPktCtrlBlk->txPktParams.dbgPktSeqNum = pTnetwDrv->dbgPktSeqNum[aQueueId];
238
239 pTnetwDrv->dbgCountQueueAvailable[aQueueId]++; /* Count packets sent and queue not busy. */
240 #endif
241
242
243 /*****************************************************************************************/
244 /* 4) Copy the descriptor to the frame . */
245 /*****************************************************************************************/
246
247 os_memoryCopy(pTnetwDrv->hOs, (void *)((UINT8*)aFrame - sizeof(DbTescriptor)), &(pPktCtrlBlk->txDescriptor), sizeof(DbTescriptor));
248
249
250 /*****************************************************************************************/
251 /* 5) Call the Tx-Xfer to start packet transfer to the FW and return its result. */
252 /*****************************************************************************************/
253
254 status = txXfer_sendPacket(pTnetwDrv->hTxXfer, pPktCtrlBlk);
255
256 /* If the packet was transfered in this context and Tx-complete already occured, free the ctrl-blk. */
257 if (status == SEND_PACKET_XFER_DONE)
258 {
259 if (pPktCtrlBlk->txPktParams.flags & TX_CTRL_BLK_FLAGS_TX_COMPLETE_ISSUED)
260 TnetwDrv_txCtrlBlk_free(pTnetwDrv, pPktCtrlBlk);
261 else
262 pPktCtrlBlk->txPktParams.flags |= TX_CTRL_BLK_FLAGS_XFER_DONE_ISSUED;
263 }
264
265 #ifdef TI_DBG
266 if (status == SEND_PACKET_XFER_DONE)
267 pTnetwDrv->dbgCountXferDone[aQueueId]++;
268 else if (status == SEND_PACKET_SUCCESS)
269 pTnetwDrv->dbgCountXferSuccess[aQueueId]++;
270 else if (status == SEND_PACKET_PENDING)
271 pTnetwDrv->dbgCountXferPending[aQueueId]++;
272 else
273 pTnetwDrv->dbgCountXferError[aQueueId]++;
274 #endif
275
276
277 return status;
278 }
279
280
281
282
283 /****************************************************************************
284 * Tx API functions needed for GWSI interface *
285 ****************************************************************************/
286
TnetwDrv_txGetAckPolicy(TI_HANDLE hTnetwDrv,int TxQid,BOOL bIsMultiCastAndIBSS)287 UINT8 TnetwDrv_txGetAckPolicy(TI_HANDLE hTnetwDrv, int TxQid , BOOL bIsMultiCastAndIBSS)
288 {
289 TnetwDrv_t *pTnetwDrv = (TnetwDrv_t *)hTnetwDrv;
290 WhalParams_T *pWhalParams = (WhalParams_T *)(pTnetwDrv->hWhalParams);
291
292 /* If we are in IBSS and we are transmitting a Multicast/Broadcast frame -> we don't expect an Ack packet */
293 if (bIsMultiCastAndIBSS)
294 {
295 return ACK_POLICY_NO_ACK;
296 }
297
298 return (pWhalParams->QueuesParams.queues[TxQid].ackPolicy);
299 }
300
301 /*************************************************************************
302 * TnetwDrv_TxXferDone *
303 **************************************************************************
304 * DESCRIPTION:
305 ============
306 Called upon Xfer-Done of transmitted packet.
307 Calls the upper driver's Xfer-Done handler.
308
309 *
310 * INPUT: hDummyHandle - Just to support the CB API.
311 * pPktCtrlBlk - The packet's control block pointer.
312 *
313 * OUTPUT:
314 *
315 * RETURN:
316
317 *************************************************************************/
TnetwDrv_TxXferDone(TI_HANDLE hTnetwDrv,txCtrlBlkEntry_t * pPktCtrlBlk)318 void TnetwDrv_TxXferDone(TI_HANDLE hTnetwDrv, txCtrlBlkEntry_t *pPktCtrlBlk)
319 {
320 /* Make a working copy of TNETDriver Handle */
321 TnetwDrv_t *pTnetwDrv = (TnetwDrv_t *)hTnetwDrv;
322
323
324 #ifdef TI_DBG
325 pTnetwDrv->dbgCountXferDoneCB[pPktCtrlBlk->txDescriptor.xmitQueue]++;
326 #endif
327 /* If the pointed entry is already free, print error and exit (not expected to happen). */
328 if (pPktCtrlBlk->pNextFreeEntry != NULL)
329 {
330 #ifdef TI_DBG
331 WLAN_REPORT_ERROR(pTnetwDrv->hReport, TNETW_DRV_MODULE_LOG,
332 ("TnetwDrv_TxXferDone(): Pkt already free!!, DescID=%d, dbgPktSeqNum=%d, flags=%d, packetId=0x%x, Queue=%d\n",
333 pPktCtrlBlk->txDescriptor.descID, pPktCtrlBlk->txPktParams.dbgPktSeqNum, pPktCtrlBlk->txPktParams.flags,
334 pPktCtrlBlk->txPktParams.packetId, pPktCtrlBlk->txDescriptor.xmitQueue));
335 #endif
336 return;
337 }
338
339 /* If Tx-complete already occurred, free the ctrl-blk. */
340 /* Note that this may happen when the Xfer-SM delays the Xfer-Done (for pipeline sequence). */
341 if (pPktCtrlBlk->txPktParams.flags & TX_CTRL_BLK_FLAGS_TX_COMPLETE_ISSUED)
342 TnetwDrv_txCtrlBlk_free(pTnetwDrv, pPktCtrlBlk);
343 else
344 pPktCtrlBlk->txPktParams.flags |= TX_CTRL_BLK_FLAGS_XFER_DONE_ISSUED;
345
346 /* Call the upper driver's Xfer-Done handler with the packet-ID. */
347 /* Note that depending on the type of compilation, the upper layers vary: */
348 /* It may be either CoreAdaptTx or GWSIAdaptTx */
349 /* Both functions are called the same */
350 SendPacketTransfer (pTnetwDrv->hUser, pPktCtrlBlk->txPktParams.packetId);
351 }
352
353
354
355 /*************************************************************************
356 * TnetwDrv_TxComplete *
357 **************************************************************************
358 * DESCRIPTION:
359 ============
360 Called upon Tx-complete of transmitted packet.
361 Handles it as follows:
362 1) Update the HwQueue to free queue resources.
363 2) Call the upper driver's tx-complete handler.
364 3) Free the packet's Control-Block if Xfer-Done already occured.
365
366 *
367 * INPUT: hDummyHandle - Just to support the CB API.
368 * pTxResultInfo - The packet's Tx result information.
369 *
370 * OUTPUT:
371 *
372 * RETURN:
373
374 *************************************************************************/
TnetwDrv_TxComplete(TI_HANDLE hTnetwDrv,TxResultDescriptor_t * pTxResultInfo)375 void TnetwDrv_TxComplete(TI_HANDLE hTnetwDrv, TxResultDescriptor_t *pTxResultInfo)
376 {
377 txCtrlBlkEntry_t *pPktCtrlBlk;
378 /* Make a working copy of TNETDriver Handle */
379 TnetwDrv_t *pTnetwDrv = (TnetwDrv_t *)hTnetwDrv;
380
381 /* Get the packet's control block pointer by the descId index. */
382 pPktCtrlBlk = TnetwDrv_txCtrlBlk_GetPointer(pTnetwDrv, pTxResultInfo->descID);
383
384 #ifdef TI_DBG
385 WLAN_REPORT_INFORMATION(pTnetwDrv->hReport, TNETW_DRV_MODULE_LOG,
386 ("TnetwDrv_TxComplete(): DescID=%d, dbgPktSeqNum=%d, flags=%d, packetId=0x%x, Queue=%d\n",
387 pTxResultInfo->descID, pPktCtrlBlk->txPktParams.dbgPktSeqNum, pPktCtrlBlk->txPktParams.flags,
388 pPktCtrlBlk->txPktParams.packetId, pPktCtrlBlk->txDescriptor.xmitQueue));
389
390 pTnetwDrv->dbgCountTxCompleteCB[pPktCtrlBlk->txDescriptor.xmitQueue]++;
391 #endif
392 /* If the pointed entry is already free, print error and exit (not expected to happen). */
393 if (pPktCtrlBlk->pNextFreeEntry != NULL)
394 {
395 #ifdef TI_DBG
396 WLAN_REPORT_ERROR(pTnetwDrv->hReport, TNETW_DRV_MODULE_LOG,
397 ("TnetwDrv_TxComplete(): Pkt already free!!, DescID=%d, dbgPktSeqNum=%d, flags=%d, packetId=0x%x, Queue=%d\n",
398 pTxResultInfo->descID, pPktCtrlBlk->txPktParams.dbgPktSeqNum, pPktCtrlBlk->txPktParams.flags,
399 pPktCtrlBlk->txPktParams.packetId, pPktCtrlBlk->txDescriptor.xmitQueue));
400 #endif
401 return;
402 }
403
404 /* Update the HwQueue to free queue resources. */
405 TnetwDrv_txHwQueue_free(pTnetwDrv, pPktCtrlBlk);
406
407 /* @@@ Note: Add Security Sequence Number handling. */
408 /* Update the TKIP/AES sequence-number according to the Tx data packet security-seq-num. */
409 /* Note: The FW always provides the last used seq-num so no need to check if the current
410 packet is data and WEP is on. */
411 whalCtrl_updateSecuritySeqNum(pTnetwDrv->hHalCtrl, pTxResultInfo->lsbSecuritySequenceNumber);
412
413 /* Call the upper driver's tx-complete handler. */
414 /* Note that depending on the type of compilation, the upper layeres varry: */
415 /* It may be either CoreAdaptTx or GWSIAdaptTx */
416 /* Both functions are called the same */
417 SendPacketComplete (pTnetwDrv->hUser,
418 ConvertTxResultStatus((TxDescStatus_enum)pTxResultInfo->status),
419 pPktCtrlBlk->txPktParams.packetId,
420 pTxResultInfo->actualRate,
421 pTxResultInfo->ackFailures,
422 (UINT32)pTxResultInfo->mediumUsage,
423 pTxResultInfo->fwHandlingTime,
424 pTxResultInfo->mediumDelay);
425
426 /* If Xfer-Done already occured, free the ctrl-blk (otherwise Xfer-Done will do it). */
427 /* Note that the Xfer-SM may delay the Xfer-Done (for pipeline sequence). */
428 if (pPktCtrlBlk->txPktParams.flags & TX_CTRL_BLK_FLAGS_XFER_DONE_ISSUED)
429 TnetwDrv_txCtrlBlk_free(pTnetwDrv, pPktCtrlBlk);
430 else
431 pPktCtrlBlk->txPktParams.flags |= TX_CTRL_BLK_FLAGS_TX_COMPLETE_ISSUED;
432 }
433
434
435 /*************************************************************************
436 * TnetwDrv_RecoveryCtrlBlk *
437 **************************************************************************
438 * DESCRIPTION:
439 ============
440 Called upon recovery.
441 Handles it as follows:
442 1) Update the HwQueue to free queue resources.
443 3) Free the packet's Control-Block if Xfer-Done already occured.
444
445 *
446 * INPUT: hDummyHandle - Just to support the CB API.
447 *
448 * OUTPUT:
449 *
450 * RETURN:
451
452 *************************************************************************/
TnetwDrv_RecoveryCtrlBlk(TI_HANDLE hTnetwDrv)453 void TnetwDrv_RecoveryCtrlBlk(TI_HANDLE hTnetwDrv)
454 {
455 txCtrlBlkEntry_t *pPktCtrlBlk;
456 /* Make a working copy of TNETDriver Handle */
457 TnetwDrv_t *pTnetwDrv = (TnetwDrv_t *)hTnetwDrv;
458 UINT32 entry;
459 const UINT32 MAX_CTRL_BLK_ENTRY = 64;
460
461 for (entry = 0; entry < MAX_CTRL_BLK_ENTRY-1; entry++)
462 {
463 /* Get the packet's control block pointer by the descId index. */
464 pPktCtrlBlk = TnetwDrv_txCtrlBlk_GetPointer(pTnetwDrv, entry);
465 if (pPktCtrlBlk->pNextFreeEntry == NULL)
466 {
467 TnetwDrv_txHwQueue_free(pTnetwDrv, pPktCtrlBlk);
468 TnetwDrv_txCtrlBlk_free(pTnetwDrv, pPktCtrlBlk);
469 }
470 }
471 }
472
473
474 /*************************************************************************
475 * TnetwDrv_TxXferDebug *
476 **************************************************************************
477 * DESCRIPTION:
478 ============
479 Called upon issuing interrupt to firmware.
480 Calls the upper driver's Xfer-Debug handler.
481
482 *
483 * INPUT: hDummyHandle - Just to support the CB API.
484 * pPktCtrlBlk - The packet's control block pointer.
485 uDebugInfo - Additional debug info
486 *
487 * OUTPUT:
488 *
489 * RETURN:
490
491 *************************************************************************/
492 #ifdef TI_DBG
TnetwDrv_TxXferDebug(TI_HANDLE hTnetwDrv,txCtrlBlkEntry_t * pPktCtrlBlk,UINT32 uDebugInfo)493 void TnetwDrv_TxXferDebug (TI_HANDLE hTnetwDrv, txCtrlBlkEntry_t *pPktCtrlBlk, UINT32 uDebugInfo)
494 {
495 TnetwDrv_t *pTnetwDrv = (TnetwDrv_t *)hTnetwDrv;
496 /* Call the upper driver's Xfer-Done handler with the packet-ID. */
497 /* Note that depending on the type of compilation, the upper layeres varry: */
498 /* It may be either CoreAdaptTx or GWSIAdaptTx */
499 /* Both functions are called the same */
500 SendPacketDebug (pTnetwDrv->hUser, pPktCtrlBlk->txPktParams.packetId, uDebugInfo);
501 }
502 #endif
503
504
505 /****************************************************************************
506 * ConvertTxResultStatus
507 ****************************************************************************
508 * DESCRIPTION: Convert the status bit field in the TxDone descriptor, indexed
509 * by the given index, to a driver status bit field
510 *
511 * INPUTS: txResultStatus - Status value received from the FW
512 *
513 * OUTPUT: None
514 *
515 * RETURNS: The converted value
516 ****************************************************************************/
ConvertTxResultStatus(TxDescStatus_enum txResultStatus)517 systemStatus_e ConvertTxResultStatus(TxDescStatus_enum txResultStatus)
518 {
519 /* Convert Tx-Result from FW to GWSI values. */
520 /* Note: only 1 bit in the entire status field should be set */
521 switch (txResultStatus)
522 {
523 case TX_SUCCESS:
524 return SEND_COMPLETE_SUCCESS;
525
526 case TX_RETRY_EXCEEDED:
527 return SEND_COMPLETE_RETRY_EXCEEDED;
528
529 case TX_TIMEOUT:
530 return SEND_COMPLETE_LIFETIME_EXCEEDED;
531
532 default:
533 return SEND_COMPLETE_NO_LINK;
534 }
535 }
536
537
538 /****************************************************************************
539 * TnetwDrv_printInfo()
540 ****************************************************************************
541 * DESCRIPTION: Print the txXfer object main fields.
542 ****************************************************************************/
TnetwDrv_printInfo(TI_HANDLE hTnetwDrv)543 void TnetwDrv_printInfo(TI_HANDLE hTnetwDrv)
544 {
545 #ifdef TI_DBG
546 TnetwDrv_t *pTnetwDrv = (TnetwDrv_t *)hTnetwDrv;
547 int qIndex;
548
549 WLAN_OS_REPORT(("TNETW Driver Tx Counters per Queue:\n"));
550 WLAN_OS_REPORT(("===========================\n"));
551
552 WLAN_OS_REPORT(("-------------- packets sent from upper driver ---------------\n"));
553 for(qIndex = 0; qIndex < MAX_NUM_OF_TX_QUEUES; qIndex++)
554 WLAN_OS_REPORT(("Queue %d = %d\n",qIndex, pTnetwDrv->dbgCountSentPackets[qIndex]));
555
556 WLAN_OS_REPORT(("-------------- packets sent and queue not busy ---------------\n"));
557 for(qIndex = 0; qIndex < MAX_NUM_OF_TX_QUEUES; qIndex++)
558 WLAN_OS_REPORT(("Queue %d = %d\n",qIndex, pTnetwDrv->dbgCountQueueAvailable[qIndex]));
559
560 WLAN_OS_REPORT(("-------------- XferDone value returned from Xfer ---------------\n"));
561 for(qIndex = 0; qIndex < MAX_NUM_OF_TX_QUEUES; qIndex++)
562 WLAN_OS_REPORT(("Queue %d = %d\n",qIndex, pTnetwDrv->dbgCountXferDone[qIndex]));
563
564 WLAN_OS_REPORT(("-------------- Success value returned from Xfer ---------------\n"));
565 for(qIndex = 0; qIndex < MAX_NUM_OF_TX_QUEUES; qIndex++)
566 WLAN_OS_REPORT(("Queue %d = %d\n",qIndex, pTnetwDrv->dbgCountXferSuccess[qIndex]));
567
568 WLAN_OS_REPORT(("-------------- Pending value returned from Xfer ---------------\n"));
569 for(qIndex = 0; qIndex < MAX_NUM_OF_TX_QUEUES; qIndex++)
570 WLAN_OS_REPORT(("Queue %d = %d\n",qIndex, pTnetwDrv->dbgCountXferPending[qIndex]));
571
572 WLAN_OS_REPORT(("-------------- Error value returned from Xfer ---------------\n"));
573 for(qIndex = 0; qIndex < MAX_NUM_OF_TX_QUEUES; qIndex++)
574 WLAN_OS_REPORT(("Queue %d = %d\n",qIndex, pTnetwDrv->dbgCountXferError[qIndex]));
575
576 WLAN_OS_REPORT(("-------------- XferDone callback calls ---------------\n"));
577 for(qIndex = 0; qIndex < MAX_NUM_OF_TX_QUEUES; qIndex++)
578 WLAN_OS_REPORT(("Queue %d = %d\n",qIndex, pTnetwDrv->dbgCountXferDoneCB[qIndex]));
579
580 WLAN_OS_REPORT(("-------------- TxComplete callback calls ---------------\n"));
581 for(qIndex = 0; qIndex < MAX_NUM_OF_TX_QUEUES; qIndex++)
582 WLAN_OS_REPORT(("Queue %d = %d\n",qIndex, pTnetwDrv->dbgCountTxCompleteCB[qIndex]));
583 #endif /* TI_DBG */
584 }
585