Home | History | Annotate | Download | only in Tx_Ctrl_Blk
      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 
     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 
     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 
     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 
     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 
     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 
    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 
    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 
    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 *************************************************************************/
    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 *************************************************************************/
    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 *************************************************************************/
    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
    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  ****************************************************************************/
    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  ****************************************************************************/
    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