/******************************************************************************
 *
 * This file is provided under a dual license.  When you use or
 * distribute this software, you may choose to be licensed under
 * version 2 of the GNU General Public License ("GPLv2 License")
 * or BSD License.
 *
 * GPLv2 License
 *
 * Copyright(C) 2016 MediaTek Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2 of the GNU General Public License as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
 *
 * BSD LICENSE
 *
 * Copyright(C) 2016 MediaTek Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name of the copyright holder nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *****************************************************************************/
/*
** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/nic_tx.c#2
*/

/*! \file   nic_tx.c
*    \brief  Functions that provide TX operation in NIC Layer.
*
*    This file provides TX functions which are responsible for both Hardware and
*    Software Resource Management and keep their Synchronization.
*/


/*******************************************************************************
*                         C O M P I L E R   F L A G S
********************************************************************************
*/

/*******************************************************************************
*                    E X T E R N A L   R E F E R E N C E S
********************************************************************************
*/
#include "precomp.h"
#include "que_mgt.h"

#ifdef UDP_SKT_WIFI
#include <linux/ftrace_event.h>
#endif

/*******************************************************************************
*                              C O N S T A N T S
********************************************************************************
*/

/*******************************************************************************
*                             D A T A   T Y P E S
********************************************************************************
*/

/*******************************************************************************
*                            P U B L I C   D A T A
********************************************************************************
*/

PFN_TX_DATA_DONE_CB g_pfTxDataDoneCb = nicTxMsduDoneCb;

static const TX_RESOURCE_CONTROL_T arTcResourceControl[TC_NUM] = {
	/* dest port index, dest queue index,   HIF TX queue index */
	/* First HW queue */
	{PORT_INDEX_LMAC, MAC_TXQ_AC0_INDEX, HIF_TX_AC0_INDEX},
	{PORT_INDEX_LMAC, MAC_TXQ_AC1_INDEX, HIF_TX_AC1_INDEX},
	{PORT_INDEX_LMAC, MAC_TXQ_AC2_INDEX, HIF_TX_AC2_INDEX},
	{PORT_INDEX_LMAC, MAC_TXQ_AC3_INDEX, HIF_TX_AC3_INDEX},
	{PORT_INDEX_MCU, MCU_Q1_INDEX, HIF_TX_CPU_INDEX},
	{PORT_INDEX_LMAC, MAC_TXQ_AC1_INDEX, HIF_TX_AC1_INDEX},

	/* Second HW queue */
#if NIC_TX_ENABLE_SECOND_HW_QUEUE
	{PORT_INDEX_LMAC, MAC_TXQ_AC10_INDEX, HIF_TX_AC10_INDEX},
	{PORT_INDEX_LMAC, MAC_TXQ_AC11_INDEX, HIF_TX_AC11_INDEX},
	{PORT_INDEX_LMAC, MAC_TXQ_AC12_INDEX, HIF_TX_AC12_INDEX},
	{PORT_INDEX_LMAC, MAC_TXQ_AC13_INDEX, HIF_TX_AC13_INDEX},
	{PORT_INDEX_LMAC, MAC_TXQ_AC11_INDEX, HIF_TX_AC11_INDEX},
#endif
};

/* Traffic settings per TC */
static const TX_TC_TRAFFIC_SETTING_T arTcTrafficSettings[NET_TC_NUM] = {
	/* Tx desc template format,                    Remaining Tx time,                               Retry count */
	/* For Data frame with StaRec, set Long Format to enable the following settings */
	{NIC_TX_DESC_LONG_FORMAT_LENGTH, NIC_TX_AC_BE_REMAINING_TX_TIME,
	 NIC_TX_DATA_DEFAULT_RETRY_COUNT_LIMIT},
	{NIC_TX_DESC_LONG_FORMAT_LENGTH, NIC_TX_AC_BK_REMAINING_TX_TIME,
	 NIC_TX_DATA_DEFAULT_RETRY_COUNT_LIMIT},
	{NIC_TX_DESC_LONG_FORMAT_LENGTH, NIC_TX_AC_VI_REMAINING_TX_TIME,
	 NIC_TX_DATA_DEFAULT_RETRY_COUNT_LIMIT},
	{NIC_TX_DESC_LONG_FORMAT_LENGTH, NIC_TX_AC_VO_REMAINING_TX_TIME,
	 NIC_TX_DATA_DEFAULT_RETRY_COUNT_LIMIT},

	/* MGMT frame */
	{NIC_TX_DESC_LONG_FORMAT_LENGTH, NIC_TX_MGMT_REMAINING_TX_TIME,
	 NIC_TX_MGMT_DEFAULT_RETRY_COUNT_LIMIT},

	/* non-StaRec frame (BMC, etc...) */
	{NIC_TX_DESC_LONG_FORMAT_LENGTH, TX_DESC_TX_TIME_NO_LIMIT,
	 NIC_TX_DATA_DEFAULT_RETRY_COUNT_LIMIT},
};

/*******************************************************************************
*                           P R I V A T E   D A T A
********************************************************************************
*/

/*******************************************************************************
*                                 M A C R O S
********************************************************************************
*/

/*******************************************************************************
*                  F U N C T I O N   D E C L A R A T I O N S
********************************************************************************
*/

/*******************************************************************************
*                              F U N C T I O N S
********************************************************************************
*/
/*----------------------------------------------------------------------------*/
/*!
* @brief This function will initial all variables in regard to SW TX Queues and
*        all free lists of MSDU_INFO_T and SW_TFCB_T.
*
* @param prAdapter  Pointer to the Adapter structure.
*
* @return (none)
*/
/*----------------------------------------------------------------------------*/
VOID nicTxInitialize(IN P_ADAPTER_T prAdapter)
{
	P_TX_CTRL_T prTxCtrl;
	PUINT_8 pucMemHandle;
	P_MSDU_INFO_T prMsduInfo;
	UINT_32 i;

	KAL_SPIN_LOCK_DECLARATION();

	DEBUGFUNC("nicTxInitialize");

	ASSERT(prAdapter);
	prTxCtrl = &prAdapter->rTxCtrl;

	/* 4 <1> Initialization of Traffic Class Queue Parameters */
	nicTxResetResource(prAdapter);

	prTxCtrl->pucTxCoalescingBufPtr = prAdapter->pucCoalescingBufCached;

	prTxCtrl->u4WrIdx = 0;

	/* allocate MSDU_INFO_T and link it into rFreeMsduInfoList */
	QUEUE_INITIALIZE(&prTxCtrl->rFreeMsduInfoList);

	pucMemHandle = prTxCtrl->pucTxCached;
	for (i = 0; i < CFG_TX_MAX_PKT_NUM; i++) {
		prMsduInfo = (P_MSDU_INFO_T) pucMemHandle;
		kalMemZero(prMsduInfo, sizeof(MSDU_INFO_T));

		KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
		QUEUE_INSERT_TAIL(&prTxCtrl->rFreeMsduInfoList, (P_QUE_ENTRY_T) prMsduInfo);
		KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);

		pucMemHandle += ALIGN_4(sizeof(MSDU_INFO_T));
	}

	ASSERT(prTxCtrl->rFreeMsduInfoList.u4NumElem == CFG_TX_MAX_PKT_NUM);
	/* Check if the memory allocation consist with this initialization function */
	ASSERT((UINT_32) (pucMemHandle - prTxCtrl->pucTxCached) == prTxCtrl->u4TxCachedSize);

	QUEUE_INITIALIZE(&prTxCtrl->rTxMgmtTxingQueue);
	prTxCtrl->i4TxMgmtPendingNum = 0;

#if CFG_HIF_STATISTICS
	prTxCtrl->u4TotalTxAccessNum = 0;
	prTxCtrl->u4TotalTxPacketNum = 0;
#endif

	prTxCtrl->i4PendingFwdFrameCount = 0;

	/* Assign init value */
	/* Tx sequence number */
	prAdapter->ucTxSeqNum = 0;
	/* PID pool */
	for (i = 0; i < WTBL_SIZE; i++)
		prAdapter->aucPidPool[i] = NIC_TX_DESC_DRIVER_PID_MIN;

	prTxCtrl->u4PageSize = NIC_TX_PAGE_SIZE;

	/* enable/disable TX resource control */
	prTxCtrl->fgIsTxResourceCtrl = NIC_TX_RESOURCE_CTRL;

	qmInit(prAdapter);

	TX_RESET_ALL_CNTS(prTxCtrl);

}				/* end of nicTxInitialize() */

BOOLEAN nicTxSanityCheckResource(IN P_ADAPTER_T prAdapter)
{
	P_TX_CTRL_T prTxCtrl;
	UINT_8 ucTC;
	UINT_32 ucTotalMaxResource = 0;
	UINT_32 ucTotalFreeResource = 0;
	BOOLEAN fgError = FALSE;

	if (prAdapter->rWifiVar.ucTxDbg & BIT(0)) {
		prTxCtrl = &prAdapter->rTxCtrl;

		for (ucTC = TC0_INDEX; ucTC < TC_NUM; ucTC++) {
			ucTotalMaxResource += prTxCtrl->rTc.au4MaxNumOfPage[ucTC];
			ucTotalFreeResource += prTxCtrl->rTc.au4FreePageCount[ucTC];

			if (prTxCtrl->rTc.au4FreePageCount[ucTC] > prTxCtrl->u4TotalPageNum) {
				DBGLOG(TX, ERROR, "%s:%u\n error\n", __func__, __LINE__);
				fgError = TRUE;
			}

			if (prTxCtrl->rTc.au4MaxNumOfPage[ucTC] > prTxCtrl->u4TotalPageNum) {
				DBGLOG(TX, ERROR, "%s:%u\n error\n", __func__, __LINE__);
				fgError = TRUE;
			}

			if (prTxCtrl->rTc.au4FreePageCount[ucTC] > prTxCtrl->rTc.au4MaxNumOfPage[ucTC]) {
				DBGLOG(TX, ERROR, "%s:%u\n error\n", __func__, __LINE__);
				fgError = TRUE;
			}
		}

		if (ucTotalMaxResource != prTxCtrl->u4TotalPageNum) {
			DBGLOG(TX, ERROR, "%s:%u\n error\n", __func__, __LINE__);
			fgError = TRUE;
		}

		if (ucTotalMaxResource < ucTotalFreeResource) {
			DBGLOG(TX, ERROR, "%s:%u\n error\n", __func__, __LINE__);
			fgError = TRUE;
		}

		if (ucTotalFreeResource > prTxCtrl->u4TotalPageNum) {
			DBGLOG(TX, ERROR, "%s:%u\n error\n", __func__, __LINE__);
			fgError = TRUE;
		}

		if (fgError) {
			DBGLOG(TX, ERROR, "Total resource[%u]\n", prTxCtrl->u4TotalPageNum);
			qmDumpQueueStatus(prAdapter, NULL, 0);
		}
	}

	return !fgError;
}

/*----------------------------------------------------------------------------*/
/*!
* \brief Driver maintain a variable that is synchronous with the usage of individual
*        TC Buffer Count. This function will check if has enough TC Buffer for incoming
*        packet and then update the value after promise to provide the resources.
*
* \param[in] prAdapter              Pointer to the Adapter structure.
* \param[in] ucTC                   Specify the resource of TC
*
* \retval WLAN_STATUS_SUCCESS   Resource is available and been assigned.
* \retval WLAN_STATUS_RESOURCES Resource is not available.
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS nicTxAcquireResource(IN P_ADAPTER_T prAdapter, IN UINT_8 ucTC, IN UINT_32 u4PageCount,
	IN BOOLEAN fgReqLock)
{
	P_TX_CTRL_T prTxCtrl;
	P_TX_TCQ_STATUS_T prTc;
	WLAN_STATUS u4Status = WLAN_STATUS_RESOURCES;

	KAL_SPIN_LOCK_DECLARATION();

	/* enable/disable TX resource control */
	if (!prAdapter->rTxCtrl.fgIsTxResourceCtrl)
		return WLAN_STATUS_SUCCESS;

	ASSERT(prAdapter);
	prTxCtrl = &prAdapter->rTxCtrl;
	prTc = &prTxCtrl->rTc;

	if (fgReqLock)
		KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE);
#if 1
	if (prTc->au4FreePageCount[ucTC] >= u4PageCount) {
		prTc->au4FreePageCount[ucTC] -= u4PageCount;
		prTc->au4FreeBufferCount[ucTC] = (prTc->au4FreePageCount[ucTC] / NIC_TX_MAX_PAGE_PER_FRAME);

		DBGLOG(TX, LOUD, "Acquire: TC%d AcquirePageCnt[%u] FreeBufferCnt[%u] FreePageCnt[%u]\n",
			ucTC, u4PageCount, prTc->au4FreeBufferCount[ucTC], prTc->au4FreePageCount[ucTC]);

		u4Status = WLAN_STATUS_SUCCESS;
	}
#else
	if (prTxCtrl->rTc.au4FreePageCount[ucTC] > 0) {

		prTxCtrl->rTc.au4FreePageCount[ucTC] -= 1;

		u4Status = WLAN_STATUS_SUCCESS;
	}
#endif
	if (fgReqLock)
		KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE);

	return u4Status;
}

/*----------------------------------------------------------------------------*/
/*!
* @brief Driver maintain a variable that is synchronous with the usage of individual
*        TC Buffer Count. This function will do polling if FW has return the resource.
*        Used when driver start up before enable interrupt.
*
* @param prAdapter      Pointer to the Adapter structure.
* @param ucTC           Specify the resource of TC
*
* @retval WLAN_STATUS_SUCCESS   Resource is available.
* @retval WLAN_STATUS_FAILURE   Resource is not available.
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS nicTxPollingResource(IN P_ADAPTER_T prAdapter, IN UINT_8 ucTC)
{
	P_TX_CTRL_T prTxCtrl;
	WLAN_STATUS u4Status = WLAN_STATUS_FAILURE;
	INT_32 i = NIC_TX_RESOURCE_POLLING_TIMEOUT;
	/*UINT_32 au4WTSR[8];*/

	ASSERT(prAdapter);
	prTxCtrl = &prAdapter->rTxCtrl;

	if (ucTC >= TC_NUM)
		return WLAN_STATUS_FAILURE;

	if (prTxCtrl->rTc.au4FreeBufferCount[ucTC] > 0)
		return WLAN_STATUS_SUCCESS;

	while (i-- > 0) {
#if 1
		u4Status = halTxPollingResource(prAdapter, ucTC);
		if (u4Status == WLAN_STATUS_RESOURCES)
			kalMsleep(NIC_TX_RESOURCE_POLLING_DELAY_MSEC);
		else
			break;
#else
		HAL_READ_TX_RELEASED_COUNT(prAdapter, au4WTSR);

		if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) {
			u4Status = WLAN_STATUS_FAILURE;
			break;
		} else if (halTxReleaseResource(prAdapter, (PUINT_16) au4WTSR)) {
			if (prTxCtrl->rTc.au4FreeBufferCount[ucTC] > 0) {
				u4Status = WLAN_STATUS_SUCCESS;
				break;
			}
				kalMsleep(NIC_TX_RESOURCE_POLLING_DELAY_MSEC);
		} else {
			kalMsleep(NIC_TX_RESOURCE_POLLING_DELAY_MSEC);
		}
#endif
	}

#if DBG
	{
		INT_32 i4Times = NIC_TX_RESOURCE_POLLING_TIMEOUT - (i + 1);

		if (i4Times) {
			DBGLOG(TX, TRACE, "Polling MCR_WTSR delay %ld times, %ld msec\n",
			       i4Times, (i4Times * NIC_TX_RESOURCE_POLLING_DELAY_MSEC));
		}
	}
#endif /* DBG */

	return u4Status;

}				/* end of nicTxPollingResource() */

/*----------------------------------------------------------------------------*/
/*!
* \brief Driver maintain a variable that is synchronous with the usage of individual
*        TC Buffer Count. This function will release TC Buffer count according to
*        the given TX_STATUS COUNTER after TX Done.
*
* @return (none)
*/
/*----------------------------------------------------------------------------*/
BOOLEAN nicTxReleaseResource(IN P_ADAPTER_T prAdapter, IN UINT_8 ucTc, IN UINT_32 u4PageCount,
	IN BOOLEAN fgReqLock)
{
	P_TX_TCQ_STATUS_T prTcqStatus;
	BOOLEAN bStatus = FALSE;

	KAL_SPIN_LOCK_DECLARATION();

	/* enable/disable TX resource control */
	if (!prAdapter->rTxCtrl.fgIsTxResourceCtrl)
		return TRUE;

	ASSERT(prAdapter);
	prTcqStatus = &prAdapter->rTxCtrl.rTc;

	/* Return free Tc page count */
	if (fgReqLock)
		KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE);

	prTcqStatus->au4FreePageCount[ucTc] += u4PageCount;
	prTcqStatus->au4FreeBufferCount[ucTc] = (prTcqStatus->au4FreePageCount[ucTc] / NIC_TX_MAX_PAGE_PER_FRAME);

	if (fgReqLock)
		KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE);

	bStatus = TRUE;

	return bStatus;
}				/* end of nicTxReleaseResource() */

/*----------------------------------------------------------------------------*/
/*!
* \brief Driver maintain a variable that is synchronous with the usage of individual
*        TC Buffer Count. This function will release TC Buffer count for resource
*        allocated but un-Tx MSDU_INFO
*
* @return (none)
*/
/*----------------------------------------------------------------------------*/
VOID nicTxReleaseMsduResource(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead)
{
	P_MSDU_INFO_T prMsduInfo = prMsduInfoListHead, prNextMsduInfo;

	KAL_SPIN_LOCK_DECLARATION();

	KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE);

	while (prMsduInfo) {
		prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo);

		nicTxReleaseResource(prAdapter, prMsduInfo->ucTC,
			nicTxGetPageCount(prMsduInfo->u2FrameLength, FALSE), FALSE);

		prMsduInfo = prNextMsduInfo;
	};

	KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE);
}

/*----------------------------------------------------------------------------*/
/*!
* \brief Reset TC Buffer Count to initialized value
*
* \param[in] prAdapter              Pointer to the Adapter structure.
*
* @return WLAN_STATUS_SUCCESS
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS nicTxResetResource(IN P_ADAPTER_T prAdapter)
{
	P_TX_CTRL_T prTxCtrl;
	UINT_8 ucIdx;

	KAL_SPIN_LOCK_DECLARATION();

	DEBUGFUNC("nicTxResetResource");

	ASSERT(prAdapter);
	prTxCtrl = &prAdapter->rTxCtrl;

	KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE);

	/* Delta page count */
	kalMemZero(prTxCtrl->rTc.au4TxDonePageCount, sizeof(prTxCtrl->rTc.au4TxDonePageCount));
	kalMemZero(prTxCtrl->rTc.au4PreUsedPageCount, sizeof(prTxCtrl->rTc.au4PreUsedPageCount));

	prTxCtrl->rTc.ucNextTcIdx = TC0_INDEX;
	prTxCtrl->rTc.u4AvaliablePageCount = 0;

	DBGLOG(TX, TRACE, "Default TCQ free resource [%u %u %u %u %u %u]\n",
	       prAdapter->rWifiVar.au4TcPageCount[TC0_INDEX],
	       prAdapter->rWifiVar.au4TcPageCount[TC1_INDEX],
	       prAdapter->rWifiVar.au4TcPageCount[TC2_INDEX],
	       prAdapter->rWifiVar.au4TcPageCount[TC3_INDEX],
	       prAdapter->rWifiVar.au4TcPageCount[TC4_INDEX], prAdapter->rWifiVar.au4TcPageCount[TC5_INDEX]);

	prAdapter->rTxCtrl.u4TotalPageNum = 0;
	prAdapter->rTxCtrl.u4TotalTxRsvPageNum = 0;

	for (ucIdx = TC0_INDEX; ucIdx < TC_NUM; ucIdx++) {
		/* Page Count */
		prTxCtrl->rTc.au4MaxNumOfPage[ucIdx] = prAdapter->rWifiVar.au4TcPageCount[ucIdx];
		prTxCtrl->rTc.au4FreePageCount[ucIdx] = prAdapter->rWifiVar.au4TcPageCount[ucIdx];

		DBGLOG(TX, TRACE, "Set TC%u Default[%u] Max[%u] Free[%u]\n",
		       ucIdx,
		       prAdapter->rWifiVar.au4TcPageCount[ucIdx],
		       prTxCtrl->rTc.au4MaxNumOfPage[ucIdx], prTxCtrl->rTc.au4FreePageCount[ucIdx]);

		/* Buffer count */
		prTxCtrl->rTc.au4MaxNumOfBuffer[ucIdx] =
		    (prTxCtrl->rTc.au4MaxNumOfPage[ucIdx] / NIC_TX_MAX_PAGE_PER_FRAME);
		prTxCtrl->rTc.au4FreeBufferCount[ucIdx] =
		    (prTxCtrl->rTc.au4FreePageCount[ucIdx] / NIC_TX_MAX_PAGE_PER_FRAME);

		DBGLOG(TX, TRACE, "Set TC%u Default[%u] Buffer Max[%u] Free[%u]\n",
		       ucIdx,
		       prAdapter->rWifiVar.au4TcPageCount[ucIdx],
		       prTxCtrl->rTc.au4MaxNumOfBuffer[ucIdx], prTxCtrl->rTc.au4FreeBufferCount[ucIdx]);

		prAdapter->rTxCtrl.u4TotalPageNum += prTxCtrl->rTc.au4MaxNumOfPage[ucIdx];
	}

	KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE);

	DBGLOG(TX, TRACE, "Reset TCQ free resource to Page:Buf [%u:%u %u:%u %u:%u %u:%u %u:%u %u:%u ]\n",
	       prTxCtrl->rTc.au4FreePageCount[TC0_INDEX],
	       prTxCtrl->rTc.au4FreeBufferCount[TC0_INDEX],
	       prTxCtrl->rTc.au4FreePageCount[TC1_INDEX],
	       prTxCtrl->rTc.au4FreeBufferCount[TC1_INDEX],
	       prTxCtrl->rTc.au4FreePageCount[TC2_INDEX],
	       prTxCtrl->rTc.au4FreeBufferCount[TC2_INDEX],
	       prTxCtrl->rTc.au4FreePageCount[TC3_INDEX],
	       prTxCtrl->rTc.au4FreeBufferCount[TC3_INDEX],
	       prTxCtrl->rTc.au4FreePageCount[TC4_INDEX],
	       prTxCtrl->rTc.au4FreeBufferCount[TC4_INDEX],
	       prTxCtrl->rTc.au4FreePageCount[TC5_INDEX], prTxCtrl->rTc.au4FreeBufferCount[TC5_INDEX]);

	DBGLOG(TX, TRACE, "Reset TCQ MAX resource to Page:Buf [%u:%u %u:%u %u:%u %u:%u %u:%u %u:%u]\n",
	       prTxCtrl->rTc.au4MaxNumOfPage[TC0_INDEX],
	       prTxCtrl->rTc.au4MaxNumOfBuffer[TC0_INDEX],
	       prTxCtrl->rTc.au4MaxNumOfPage[TC1_INDEX],
	       prTxCtrl->rTc.au4MaxNumOfBuffer[TC1_INDEX],
	       prTxCtrl->rTc.au4MaxNumOfPage[TC2_INDEX],
	       prTxCtrl->rTc.au4MaxNumOfBuffer[TC2_INDEX],
	       prTxCtrl->rTc.au4MaxNumOfPage[TC3_INDEX],
	       prTxCtrl->rTc.au4MaxNumOfBuffer[TC3_INDEX],
	       prTxCtrl->rTc.au4MaxNumOfPage[TC4_INDEX],
	       prTxCtrl->rTc.au4MaxNumOfBuffer[TC4_INDEX],
	       prTxCtrl->rTc.au4MaxNumOfPage[TC5_INDEX], prTxCtrl->rTc.au4MaxNumOfBuffer[TC5_INDEX]);

	return WLAN_STATUS_SUCCESS;
}

/*----------------------------------------------------------------------------*/
/*!
* @brief Driver maintain a variable that is synchronous with the usage of individual
*        TC Buffer Count. This function will return the value for other component
*        which needs this information for making decisions
*
* @param prAdapter      Pointer to the Adapter structure.
* @param ucTC           Specify the resource of TC
*
* @retval UINT_8        The number of corresponding TC number
*/
/*----------------------------------------------------------------------------*/
UINT_16 nicTxGetResource(IN P_ADAPTER_T prAdapter, IN UINT_8 ucTC)
{
	P_TX_CTRL_T prTxCtrl;

	ASSERT(prAdapter);
	prTxCtrl = &prAdapter->rTxCtrl;

	ASSERT(prTxCtrl);

	if (ucTC >= TC_NUM)
		return 0;
	else
		return prTxCtrl->rTc.au4FreePageCount[ucTC];
}

UINT_8 nicTxGetFrameResourceType(IN UINT_8 eFrameType, IN P_MSDU_INFO_T prMsduInfo)
{
	UINT_8 ucTC;

	switch (eFrameType) {
	case FRAME_TYPE_802_1X:
		ucTC = TC4_INDEX;
		break;

	case FRAME_TYPE_MMPDU:
		if (prMsduInfo)
			ucTC = prMsduInfo->ucTC;
		else
			ucTC = TC4_INDEX;
		break;

	default:
		DBGLOG(INIT, WARN, "Undefined Frame Type(%u)\n", eFrameType);
		ucTC = TC4_INDEX;
		break;
	}

	return ucTC;
}

UINT_8 nicTxGetCmdResourceType(IN P_CMD_INFO_T prCmdInfo)
{
	UINT_8 ucTC;

	switch (prCmdInfo->eCmdType) {
	case COMMAND_TYPE_NETWORK_IOCTL:
	case COMMAND_TYPE_GENERAL_IOCTL:
		ucTC = TC4_INDEX;
		break;

	case COMMAND_TYPE_SECURITY_FRAME:
		ucTC = nicTxGetFrameResourceType(FRAME_TYPE_802_1X, NULL);
		break;

	case COMMAND_TYPE_MANAGEMENT_FRAME:
		ucTC = nicTxGetFrameResourceType(FRAME_TYPE_MMPDU, prCmdInfo->prMsduInfo);
		break;

	default:
		DBGLOG(INIT, WARN, "Undefined CMD Type(%u)\n", prCmdInfo->eCmdType);
		ucTC = TC4_INDEX;
		break;
	}

	return ucTC;
}

UINT_8 nicTxGetTxQByTc(IN P_ADAPTER_T prAdapter, IN UINT_8 ucTc)
{
	return arTcResourceControl[ucTc].ucHifTxQIndex;
}

/*----------------------------------------------------------------------------*/
/*!
* @brief In this function, we'll aggregate frame(PACKET_INFO_T)
* corresponding to HIF TX port
*
* @param prAdapter              Pointer to the Adapter structure.
* @param prMsduInfoListHead     a link list of P_MSDU_INFO_T
*
* @retval WLAN_STATUS_SUCCESS   Bus access ok.
* @retval WLAN_STATUS_FAILURE   Bus access fail.
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS nicTxMsduInfoList(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead)
{
	P_MSDU_INFO_T prMsduInfo, prNextMsduInfo;
	QUE_T qDataPort0, qDataPort1;
	P_QUE_T prDataPort0, prDataPort1;
	WLAN_STATUS status;

	ASSERT(prAdapter);
	ASSERT(prMsduInfoListHead);

	prMsduInfo = prMsduInfoListHead;

	prDataPort0 = &qDataPort0;
	prDataPort1 = &qDataPort1;

	QUEUE_INITIALIZE(prDataPort0);
	QUEUE_INITIALIZE(prDataPort1);

	/* Separate MSDU_INFO_T lists into 2 categories: for Port#0 & Port#1 */
	while (prMsduInfo) {
		prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo);

		switch (prMsduInfo->ucTC) {
		case TC0_INDEX:
		case TC1_INDEX:
		case TC2_INDEX:
		case TC3_INDEX:
		case TC5_INDEX:	/* Broadcast/multicast data packets */
			QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo) = NULL;
			QUEUE_INSERT_TAIL(prDataPort0, (P_QUE_ENTRY_T) prMsduInfo);
			status = nicTxAcquireResource(prAdapter, prMsduInfo->ucTC,
				nicTxGetPageCount(prMsduInfo->u2FrameLength, FALSE), TRUE);
			ASSERT(status == WLAN_STATUS_SUCCESS);

			break;

		case TC4_INDEX:	/* Management packets */
			QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo) = NULL;
			QUEUE_INSERT_TAIL(prDataPort1, (P_QUE_ENTRY_T) prMsduInfo);

			status = nicTxAcquireResource(prAdapter, prMsduInfo->ucTC,
				nicTxGetPageCount(prMsduInfo->u2FrameLength, FALSE), TRUE);
			ASSERT(status == WLAN_STATUS_SUCCESS);

			break;

		default:
			ASSERT(0);
			break;
		}

		prMsduInfo = prNextMsduInfo;
	}

	if (prDataPort0->u4NumElem > 0)
		nicTxMsduQueue(prAdapter, 0, prDataPort0);

	if (prDataPort1->u4NumElem > 0)
		nicTxMsduQueue(prAdapter, 1, prDataPort1);

	return WLAN_STATUS_SUCCESS;
}

#if CFG_SUPPORT_MULTITHREAD
/*----------------------------------------------------------------------------*/
/*!
* @brief In this function, we'll aggregate frame(PACKET_INFO_T)
* corresponding to HIF TX port
*
* @param prAdapter              Pointer to the Adapter structure.
* @param prMsduInfoListHead     a link list of P_MSDU_INFO_T
*
* @retval WLAN_STATUS_SUCCESS   Bus access ok.
* @retval WLAN_STATUS_FAILURE   Bus access fail.
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS nicTxMsduInfoListMthread(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead)
{
#if CFG_FIX_2_TX_PORT
	P_MSDU_INFO_T prMsduInfo, prNextMsduInfo;
	QUE_T qDataPort0, qDataPort1;
	P_QUE_T prDataPort0, prDataPort1;

	KAL_SPIN_LOCK_DECLARATION();

	ASSERT(prAdapter);
	ASSERT(prMsduInfoListHead);

	prMsduInfo = prMsduInfoListHead;

	prDataPort0 = &qDataPort0;
	prDataPort1 = &qDataPort1;

	QUEUE_INITIALIZE(prDataPort0);
	QUEUE_INITIALIZE(prDataPort1);

	/* Separate MSDU_INFO_T lists into 2 categories: for Port#0 & Port#1 */
	while (prMsduInfo) {
		prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo);

		switch (prMsduInfo->ucTC) {
		case TC0_INDEX:
		case TC1_INDEX:
		case TC2_INDEX:
		case TC3_INDEX:
		case TC5_INDEX:	/* Broadcast/multicast data packets */
			QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo) = NULL;
			QUEUE_INSERT_TAIL(prDataPort0, (P_QUE_ENTRY_T) prMsduInfo);
			break;

		case TC4_INDEX:	/* Management packets */
			QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo) = NULL;
			QUEUE_INSERT_TAIL(prDataPort1, (P_QUE_ENTRY_T) prMsduInfo);
			break;

		default:
			ASSERT(0);
			break;
		}

		nicTxFillDataDesc(prAdapter, prMsduInfo);

		prMsduInfo = prNextMsduInfo;
	}

	if (prDataPort0->u4NumElem > 0 || prDataPort1->u4NumElem > 0) {

		KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_PORT_QUE);
		QUEUE_CONCATENATE_QUEUES((&(prAdapter->rTxP0Queue)), (prDataPort0));
		QUEUE_CONCATENATE_QUEUES((&(prAdapter->rTxP1Queue)), (prDataPort1));
		KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_PORT_QUE);

		kalSetTxEvent2Hif(prAdapter->prGlueInfo);
	}
#else

	P_MSDU_INFO_T prMsduInfo, prNextMsduInfo;
	QUE_T qDataPort[TX_PORT_NUM];
	P_QUE_T prDataPort[TX_PORT_NUM];
	INT_32 i;
	BOOLEAN fgSetTx2Hif = FALSE;

	KAL_SPIN_LOCK_DECLARATION();

	ASSERT(prAdapter);
	ASSERT(prMsduInfoListHead);

	prMsduInfo = prMsduInfoListHead;

	for (i = 0; i < TX_PORT_NUM; i++) {
		prDataPort[i] = &qDataPort[i];
		QUEUE_INITIALIZE(prDataPort[i]);
	}

	/* Separate MSDU_INFO_T lists into 2 categories: for Port#0 & Port#1 */
	while (prMsduInfo) {

		fgSetTx2Hif = TRUE;
		prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo);

		if (prMsduInfo->ucWmmQueSet == DBDC_2G_WMM_INDEX) {
			QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo) = NULL;
			QUEUE_INSERT_TAIL(prDataPort[TX_2G_WMM_PORT_NUM], (P_QUE_ENTRY_T) prMsduInfo);
		} else {
			if (prMsduInfo->ucTC >= 0 &&
				prMsduInfo->ucTC < TC_NUM) {
				QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo) = NULL;
				QUEUE_INSERT_TAIL(prDataPort[prMsduInfo->ucTC], (P_QUE_ENTRY_T) prMsduInfo);
			} else
				ASSERT(0);
		}
		nicTxFillDataDesc(prAdapter, prMsduInfo);

		prMsduInfo = prNextMsduInfo;
	}

	if (fgSetTx2Hif) {
		KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_PORT_QUE);
		for (i = 0; i < TX_PORT_NUM; i++)
			QUEUE_CONCATENATE_QUEUES((&(prAdapter->rTxPQueue[i])), (prDataPort[i]));
		KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_PORT_QUE);
		kalSetTxEvent2Hif(prAdapter->prGlueInfo);
	}

#endif
	return WLAN_STATUS_SUCCESS;
}

/*----------------------------------------------------------------------------*/
/*!
* @brief In this function, we'll write frame(PACKET_INFO_T) into HIF when apply multithread.
*
* @param prAdapter              Pointer to the Adapter structure.
*
* @retval WLAN_STATUS_SUCCESS   Bus access ok.
* @retval WLAN_STATUS_FAILURE   Bus access fail.
*/
/*----------------------------------------------------------------------------*/
UINT_32 nicTxMsduQueueMthread(IN P_ADAPTER_T prAdapter)
{
#if CFG_FIX_2_TX_PORT
	QUE_T qDataPort0, qDataPort1;
	P_QUE_T prDataPort0, prDataPort1;
	UINT_32 u4TxLoopCount;

	KAL_SPIN_LOCK_DECLARATION();

	prDataPort0 = &qDataPort0;
	prDataPort1 = &qDataPort1;

	QUEUE_INITIALIZE(prDataPort0);
	QUEUE_INITIALIZE(prDataPort1);

	u4TxLoopCount = prAdapter->rWifiVar.u4HifTxloopCount;

	while (u4TxLoopCount--) {
		while (QUEUE_IS_NOT_EMPTY(&(prAdapter->rTxP0Queue))) {
			KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_PORT_QUE);
			QUEUE_MOVE_ALL(prDataPort0, &(prAdapter->rTxP0Queue));
			KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_PORT_QUE);

			nicTxMsduQueue(prAdapter, 0, prDataPort0);

			if (QUEUE_IS_NOT_EMPTY(prDataPort0)) {
				KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_PORT_QUE);
				QUEUE_CONCATENATE_QUEUES_HEAD(&(prAdapter->rTxP0Queue), prDataPort0);
				KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_PORT_QUE);

				break;
			}
		}

		while (QUEUE_IS_NOT_EMPTY(&(prAdapter->rTxP1Queue))) {
			KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_PORT_QUE);
			QUEUE_MOVE_ALL(prDataPort1, &(prAdapter->rTxP1Queue));
			KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_PORT_QUE);

			nicTxMsduQueue(prAdapter, 1, prDataPort1);

			if (QUEUE_IS_NOT_EMPTY(prDataPort1)) {
				KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_PORT_QUE);
				QUEUE_CONCATENATE_QUEUES_HEAD(&(prAdapter->rTxP1Queue), prDataPort1);
				KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_PORT_QUE);

				break;
			}
		}
	}
#else

	UINT_32 u4TxLoopCount;
	QUE_T qDataPort[TX_PORT_NUM];
	P_QUE_T prDataPort[TX_PORT_NUM];
	INT_32 i;

	KAL_SPIN_LOCK_DECLARATION();

	for (i = 0; i < TX_PORT_NUM; i++) {
		prDataPort[i] = &qDataPort[i];
		QUEUE_INITIALIZE(prDataPort[i]);
	}

	u4TxLoopCount = prAdapter->rWifiVar.u4HifTxloopCount;

	while (u4TxLoopCount--) {
		for (i = TC_NUM; i >= 0; i--) {
			while (QUEUE_IS_NOT_EMPTY(&(prAdapter->rTxPQueue[i]))) {
				KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_PORT_QUE);
				QUEUE_MOVE_ALL(prDataPort[i], &(prAdapter->rTxPQueue[i]));
				KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_PORT_QUE);

				nicTxMsduQueue(prAdapter, 0, prDataPort[i]);

				if (QUEUE_IS_NOT_EMPTY(prDataPort[i])) {
					KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_PORT_QUE);
					QUEUE_CONCATENATE_QUEUES_HEAD(&(prAdapter->rTxPQueue[i]), prDataPort[i]);
					KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_PORT_QUE);

					break;
				}
			}
		}
	}
#endif
	return WLAN_STATUS_SUCCESS;
}

UINT_32 nicTxGetMsduPendingCnt(IN P_ADAPTER_T prAdapter)
{
#if CFG_FIX_2_TX_PORT
	return (prAdapter->rTxP0Queue.u4NumElem + prAdapter->rTxP1Queue.u4NumElem);
#else
	INT_32 i;
	UINT_32 retValue = 0;

	for (i = 0; i < TX_PORT_NUM; i++)
		retValue += prAdapter->rTxPQueue[i].u4NumElem;
	return retValue;
#endif
}

#endif

VOID nicTxComposeDescAppend(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo,
	OUT PUINT_8 prTxDescBuffer)
{
	P_HW_MAC_TX_DESC_APPEND_T prHwTxDescAppend;

	/* Fill TxD append */
	prHwTxDescAppend = (P_HW_MAC_TX_DESC_APPEND_T)prTxDescBuffer;
	kalMemZero(prHwTxDescAppend, HW_MAC_TX_DESC_APPEND_T_LENGTH);
	prHwTxDescAppend->u2PktFlags = HIT_PKT_FLAGS_CT_WITH_TXD;
	prHwTxDescAppend->ucBssIndex = prMsduInfo->ucBssIndex;
}

/*----------------------------------------------------------------------------*/
/*!
* @brief In this function, we'll compose the Tx descriptor of the MSDU.
*
* @param prAdapter              Pointer to the Adapter structure.
* @param prMsduInfo             Pointer to the Msdu info
* @param prTxDesc               Pointer to the Tx descriptor buffer
*
* @retval VOID
*/
/*----------------------------------------------------------------------------*/
VOID
nicTxComposeDesc(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo,
	IN UINT_32 u4TxDescLength, IN BOOLEAN fgIsTemplate, OUT PUINT_8 prTxDescBuffer)
{
	P_HW_MAC_TX_DESC_T prTxDesc;
	P_STA_RECORD_T prStaRec;
	P_BSS_INFO_T prBssInfo;
	UINT_8 ucEtherTypeOffsetInWord;
	UINT_32 u4TxDescAndPaddingLength;
	UINT_8 ucTarPort, ucTarQueue;

	prTxDesc = (P_HW_MAC_TX_DESC_T) prTxDescBuffer;
	prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prMsduInfo->ucBssIndex);
	prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);

	u4TxDescAndPaddingLength = u4TxDescLength + NIC_TX_DESC_PADDING_LENGTH;

	kalMemZero(prTxDesc, u4TxDescAndPaddingLength);

	/* Move to nicTxFillDesc */
	/* Tx byte count */
	/* HAL_MAC_TX_DESC_SET_TX_BYTE_COUNT(prTxDesc, ucTxDescAndPaddingLength + prMsduInfo->u2FrameLength); */

	/* Ether-type offset */
	if (prMsduInfo->fgIs802_11) {
		ucEtherTypeOffsetInWord =
		    (NIC_TX_PSE_HEADER_LENGTH + prMsduInfo->ucMacHeaderLength + prMsduInfo->ucLlcLength) >> 1;
	} else {
		ucEtherTypeOffsetInWord = ((ETHER_HEADER_LEN - ETHER_TYPE_LEN) + NIC_TX_PSE_HEADER_LENGTH) >> 1;
	}
	HAL_MAC_TX_DESC_SET_ETHER_TYPE_OFFSET(prTxDesc, ucEtherTypeOffsetInWord);

	/* Port index / queue index */
	ucTarPort = arTcResourceControl[prMsduInfo->ucTC].ucDestPortIndex;
	HAL_MAC_TX_DESC_SET_PORT_INDEX(prTxDesc, ucTarPort);

	ucTarQueue = arTcResourceControl[prMsduInfo->ucTC].ucDestQueueIndex;
	if (ucTarPort == PORT_INDEX_LMAC)
		ucTarQueue += (prBssInfo->ucWmmQueSet * WMM_AC_INDEX_NUM);

	HAL_MAC_TX_DESC_SET_QUEUE_INDEX(prTxDesc, ucTarQueue);

	/* BMC packet */
	if (prMsduInfo->ucStaRecIndex == STA_REC_INDEX_BMCAST) {
		HAL_MAC_TX_DESC_SET_BMC(prTxDesc);

		/* Must set No ACK to mask retry bit in FC */
		HAL_MAC_TX_DESC_SET_NO_ACK(prTxDesc);
	}
	/* WLAN index */
	prMsduInfo->ucWlanIndex = nicTxGetWlanIdx(prAdapter, prMsduInfo->ucBssIndex, prMsduInfo->ucStaRecIndex);

#if 0				/* DBG */
	DBGLOG(RSN, INFO,
	       "Tx WlanIndex = %d eAuthMode = %d\n", prMsduInfo->ucWlanIndex,
	       prAdapter->rWifiVar.rConnSettings.eAuthMode);
#endif
	HAL_MAC_TX_DESC_SET_WLAN_INDEX(prTxDesc, prMsduInfo->ucWlanIndex);

	/* Header format */
	if (prMsduInfo->fgIs802_11) {
		HAL_MAC_TX_DESC_SET_HEADER_FORMAT(prTxDesc, HEADER_FORMAT_802_11_NORMAL_MODE);
		HAL_MAC_TX_DESC_SET_802_11_HEADER_LENGTH(prTxDesc, (prMsduInfo->ucMacHeaderLength >> 1));
	} else {
		HAL_MAC_TX_DESC_SET_HEADER_FORMAT(prTxDesc, HEADER_FORMAT_NON_802_11);
		HAL_MAC_TX_DESC_SET_ETHERNET_II(prTxDesc);
	}

	/* Header Padding */
	HAL_MAC_TX_DESC_SET_HEADER_PADDING(prTxDesc, NIC_TX_DESC_HEADER_PADDING_LENGTH);

	/* TID */
	HAL_MAC_TX_DESC_SET_TID(prTxDesc, prMsduInfo->ucUserPriority);

	/* Protection */
	if (secIsProtectedFrame(prAdapter, prMsduInfo, prStaRec)) {
		/* Update Packet option, PF bit will be set in nicTxFillDescByPktOption() */
		if ((prStaRec && prStaRec->fgTransmitKeyExist) || fgIsTemplate) {
			nicTxConfigPktOption(prMsduInfo, MSDU_OPT_PROTECTED_FRAME, TRUE);

			if (prMsduInfo->fgIs802_1x_NonProtected) {
				nicTxConfigPktOption(prMsduInfo, MSDU_OPT_PROTECTED_FRAME, FALSE);
				DBGLOG(RSN, LOUD, "Pairwise EAPoL not protect!\n");
			}
		} else if (prMsduInfo->ucStaRecIndex == STA_REC_INDEX_BMCAST) {/* BMC packet */
			nicTxConfigPktOption(prMsduInfo, MSDU_OPT_PROTECTED_FRAME, TRUE);
			DBGLOG(RSN, LOUD, "Protect BMC frame!\n");
		}
	}
#if (UNIFIED_MAC_TX_FORMAT == 1)
	/* Packet Format */
	if (prMsduInfo->eSrc == TX_PACKET_MGMT)
		HAL_MAC_TX_DESC_SET_PKT_FORMAT(prTxDesc, TXD_PKT_FORMAT_COMMAND);

#endif

	/* Own MAC */
	HAL_MAC_TX_DESC_SET_OWN_MAC_INDEX(prTxDesc, prBssInfo->ucOwnMacIndex);

	if (u4TxDescLength == NIC_TX_DESC_SHORT_FORMAT_LENGTH) {
		HAL_MAC_TX_DESC_SET_SHORT_FORMAT(prTxDesc);

		/* Update Packet option */
		nicTxFillDescByPktOption(prMsduInfo, prTxDesc);

		/* Short format, Skip DW 2~6 */
		return;
	}
		HAL_MAC_TX_DESC_SET_LONG_FORMAT(prTxDesc);

		/* Update Packet option */
		nicTxFillDescByPktOption(prMsduInfo, prTxDesc);

		nicTxFillDescByPktControl(prMsduInfo, prTxDesc);

	/* Type */
	if (prMsduInfo->fgIs802_11) {
		P_WLAN_MAC_HEADER_T prWlanHeader =
		    (P_WLAN_MAC_HEADER_T) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD);

		HAL_MAC_TX_DESC_SET_TYPE(prTxDesc, (prWlanHeader->u2FrameCtrl & MASK_FC_TYPE) >> 2);
		HAL_MAC_TX_DESC_SET_SUB_TYPE(prTxDesc,
					     (prWlanHeader->u2FrameCtrl & MASK_FC_SUBTYPE) >> OFFSET_OF_FC_SUBTYPE);
	}
	/* PID */
	if (prMsduInfo->pfTxDoneHandler) {
		prMsduInfo->ucPID = nicTxAssignPID(prAdapter, prMsduInfo->ucWlanIndex);
		HAL_MAC_TX_DESC_SET_PID(prTxDesc, prMsduInfo->ucPID);
		HAL_MAC_TX_DESC_SET_TXS_TO_MCU(prTxDesc);
	} else if (prAdapter->rWifiVar.ucDataTxDone == 2) {
		/* Log mode: only TxS to FW, no event to driver */
		HAL_MAC_TX_DESC_SET_PID(prTxDesc, NIC_TX_DESC_PID_RESERVED);
		HAL_MAC_TX_DESC_SET_TXS_TO_MCU(prTxDesc);
	}

	/* Remaining TX time */
	if (!(prMsduInfo->u4Option & MSDU_OPT_MANUAL_LIFE_TIME))
		prMsduInfo->u4RemainingLifetime = arTcTrafficSettings[prMsduInfo->ucTC].u4RemainingTxTime;
	HAL_MAC_TX_DESC_SET_REMAINING_LIFE_TIME_IN_MS(prTxDesc, prMsduInfo->u4RemainingLifetime);

	/* Tx count limit */
	if (!(prMsduInfo->u4Option & MSDU_OPT_MANUAL_RETRY_LIMIT)) {
		/* Note: BMC packet retry limit is set to unlimited */
		prMsduInfo->ucRetryLimit = arTcTrafficSettings[prMsduInfo->ucTC].ucTxCountLimit;
	}
	HAL_MAC_TX_DESC_SET_REMAINING_TX_COUNT(prTxDesc, prMsduInfo->ucRetryLimit);

	/* Power Offset */
	HAL_MAC_TX_DESC_SET_POWER_OFFSET(prTxDesc, prMsduInfo->cPowerOffset);

	/* Fix rate */
	switch (prMsduInfo->ucRateMode) {
	case MSDU_RATE_MODE_MANUAL_DESC:
		HAL_MAC_TX_DESC_SET_DW(prTxDesc, 6, 1, &prMsduInfo->u4FixedRateOption);
#if CFG_SISO_SW_DEVELOP
		/* Update spatial extension index setting */
		HAL_MAC_TX_DESC_SET_SPE_IDX(prTxDesc, wlanGetSpeIdx(prAdapter, prBssInfo->ucBssIndex));
#endif
		HAL_MAC_TX_DESC_SET_FIXED_RATE_MODE_TO_DESC(prTxDesc);
		HAL_MAC_TX_DESC_SET_FIXED_RATE_ENABLE(prTxDesc);
		break;

	case MSDU_RATE_MODE_MANUAL_CR:
		HAL_MAC_TX_DESC_SET_FIXED_RATE_MODE_TO_CR(prTxDesc);
		HAL_MAC_TX_DESC_SET_FIXED_RATE_ENABLE(prTxDesc);
		break;

	case MSDU_RATE_MODE_AUTO:
	default:
		break;
	}

}

VOID
nicTxComposeSecurityFrameDesc(IN P_ADAPTER_T prAdapter,
			      IN P_CMD_INFO_T prCmdInfo, OUT PUINT_8 prTxDescBuffer, OUT PUINT_8 pucTxDescLength)
{
	P_HW_MAC_TX_DESC_T prTxDesc = (P_HW_MAC_TX_DESC_T) prTxDescBuffer;
	UINT_8 ucTxDescAndPaddingLength = NIC_TX_DESC_LONG_FORMAT_LENGTH + NIC_TX_DESC_PADDING_LENGTH;
	/* P_STA_RECORD_T prStaRec = cnmGetStaRecByIndex(prAdapter, prCmdInfo->ucStaRecIndex); */
	P_BSS_INFO_T prBssInfo;
	UINT_8 ucTid = 0;
	UINT_8 ucTempTC = TC4_INDEX;
	P_NATIVE_PACKET prNativePacket;
	UINT_8 ucEtherTypeOffsetInWord;
	P_MSDU_INFO_T prMsduInfo;

	prMsduInfo = prCmdInfo->prMsduInfo;
	prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prMsduInfo->ucBssIndex);
	prNativePacket = prMsduInfo->prPacket;

	ASSERT(prNativePacket);

	kalMemZero(prTxDesc, ucTxDescAndPaddingLength);

	/* WLAN index */
	prMsduInfo->ucWlanIndex = nicTxGetWlanIdx(prAdapter, prMsduInfo->ucBssIndex, prMsduInfo->ucStaRecIndex);

	/* UC to a connected peer */
	HAL_MAC_TX_DESC_SET_WLAN_INDEX(prTxDesc, prMsduInfo->ucWlanIndex);
	/* Redirect Security frame to TID0 */
	/* ucTempTC = arNetwork2TcResource[prStaRec->ucBssIndex][aucTid2ACI[ucTid]]; */

	/* Tx byte count */
	HAL_MAC_TX_DESC_SET_TX_BYTE_COUNT(prTxDesc, ucTxDescAndPaddingLength + prCmdInfo->u2InfoBufLen);

	/* Ether-type offset */
	ucEtherTypeOffsetInWord = ((ETHER_HEADER_LEN - ETHER_TYPE_LEN) + NIC_TX_PSE_HEADER_LENGTH) >> 1;
	HAL_MAC_TX_DESC_SET_ETHER_TYPE_OFFSET(prTxDesc, ucEtherTypeOffsetInWord);

	/* Port index / queue index */
	HAL_MAC_TX_DESC_SET_PORT_INDEX(prTxDesc, arTcResourceControl[ucTempTC].ucDestPortIndex);
	HAL_MAC_TX_DESC_SET_QUEUE_INDEX(prTxDesc, arTcResourceControl[ucTempTC].ucDestQueueIndex);

	/* Header format */
	HAL_MAC_TX_DESC_SET_HEADER_FORMAT(prTxDesc, HEADER_FORMAT_NON_802_11);

	/* Long Format */
	HAL_MAC_TX_DESC_SET_LONG_FORMAT(prTxDesc);

	/* Update Packet option */
	nicTxFillDescByPktOption(prMsduInfo, prTxDesc);

	if (!GLUE_TEST_PKT_FLAG(prNativePacket, ENUM_PKT_802_3)) {
		/* Set EthernetII */
		HAL_MAC_TX_DESC_SET_ETHERNET_II(prTxDesc);
	}
	/* Header Padding */
	HAL_MAC_TX_DESC_SET_HEADER_PADDING(prTxDesc, NIC_TX_DESC_HEADER_PADDING_LENGTH);

	/* TID */
	HAL_MAC_TX_DESC_SET_TID(prTxDesc, ucTid);

	/* Remaining TX time */
	HAL_MAC_TX_DESC_SET_REMAINING_LIFE_TIME_IN_MS(prTxDesc, arTcTrafficSettings[ucTempTC].u4RemainingTxTime);

	/* Tx count limit */
	HAL_MAC_TX_DESC_SET_REMAINING_TX_COUNT(prTxDesc, arTcTrafficSettings[ucTempTC].ucTxCountLimit);

	/* Set lowest BSS basic rate */
	HAL_MAC_TX_DESC_SET_FR_RATE(prTxDesc, prBssInfo->u2HwDefaultFixedRateCode);
	HAL_MAC_TX_DESC_SET_FIXED_RATE_MODE_TO_DESC(prTxDesc);
	HAL_MAC_TX_DESC_SET_FIXED_RATE_ENABLE(prTxDesc);

	/* Packet Format */
	HAL_MAC_TX_DESC_SET_PKT_FORMAT(prTxDesc, TXD_PKT_FORMAT_COMMAND);

	/* Own MAC */
	HAL_MAC_TX_DESC_SET_OWN_MAC_INDEX(prTxDesc, prBssInfo->ucOwnMacIndex);

	/* PID */
	if (prMsduInfo->pfTxDoneHandler) {
		prMsduInfo->ucPID = nicTxAssignPID(prAdapter, prMsduInfo->ucWlanIndex);
		HAL_MAC_TX_DESC_SET_PID(prTxDesc, prMsduInfo->ucPID);
		HAL_MAC_TX_DESC_SET_TXS_TO_MCU(prTxDesc);
	}

	if (pucTxDescLength)
		*pucTxDescLength = ucTxDescAndPaddingLength;
}

BOOLEAN nicTxIsTXDTemplateAllowed(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN P_STA_RECORD_T prStaRec)
{
	if (prMsduInfo->fgIsTXDTemplateValid) {
		if (prMsduInfo->fgIs802_1x)
			return FALSE;

		if (prMsduInfo->ucRateMode != MSDU_RATE_MODE_AUTO)
			return FALSE;

		if (!prStaRec)
			return FALSE;

		if (prMsduInfo->ucControlFlag)
			return FALSE;

		if (prMsduInfo->pfTxDoneHandler)
			return FALSE;

		if (prAdapter->rWifiVar.ucDataTxRateMode)
			return FALSE;

		return TRUE;
	}
	return FALSE;
}

/*----------------------------------------------------------------------------*/
/*!
* @brief In this function, we'll compose the Tx descriptor of the MSDU.
*
* @param prAdapter              Pointer to the Adapter structure.
* @param prMsduInfo             Pointer to the Msdu info
* @param prTxDesc               Pointer to the Tx descriptor buffer
*
* @retval VOID
*/
/*----------------------------------------------------------------------------*/
VOID
nicTxFillDesc(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo,
	OUT PUINT_8 prTxDescBuffer, OUT PUINT_32 pu4TxDescLength)
{
	P_HW_MAC_TX_DESC_T prTxDesc = (P_HW_MAC_TX_DESC_T) prTxDescBuffer;
	P_HW_MAC_TX_DESC_T prTxDescTemplate = NULL;
	P_STA_RECORD_T prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
	UINT_32 u4TxDescLength, u4TxDescAppendLength;
#if CFG_TCP_IP_CHKSUM_OFFLOAD
	UINT_8 ucChksumFlag = 0;
#endif

/*
*------------------------------------------------------------------------------
* Fill up common fileds
*------------------------------------------------------------------------------
*/
	/* Decide TxD append length */
	if (prMsduInfo->ucPacketType == TX_PACKET_TYPE_DATA)
		u4TxDescAppendLength = HW_MAC_TX_DESC_APPEND_T_LENGTH;
	else
		u4TxDescAppendLength = 0;

	/* Get TXD from pre-allocated template */
	if (nicTxIsTXDTemplateAllowed(prAdapter, prMsduInfo, prStaRec)) {
		prTxDescTemplate = prStaRec->aprTxDescTemplate[prMsduInfo->ucUserPriority];
#if 1
		u4TxDescLength = NIC_TX_DESC_LONG_FORMAT_LENGTH;
#else
		if (HAL_MAC_TX_DESC_IS_LONG_FORMAT(prTxDescTemplate))
			u4TxDescLength = NIC_TX_DESC_LONG_FORMAT_LENGTH;
		else
			u4TxDescLength = NIC_TX_DESC_SHORT_FORMAT_LENGTH;
#endif

		kalMemCopy(prTxDesc, prTxDescTemplate, u4TxDescLength + u4TxDescAppendLength);

		/* Overwrite fields for EOSP or More data */
		nicTxFillDescByPktOption(prMsduInfo, prTxDesc);
	}
	/* Compose TXD by Msdu info */
	else {
		u4TxDescLength = NIC_TX_DESC_LONG_FORMAT_LENGTH;
		nicTxComposeDesc(prAdapter, prMsduInfo, u4TxDescLength, FALSE, prTxDescBuffer);

		/* Compose TxD append */
		if (prMsduInfo->ucPacketType == TX_PACKET_TYPE_DATA)
			nicTxComposeDescAppend(prAdapter, prMsduInfo, prTxDescBuffer + u4TxDescLength);
	}

/*
*------------------------------------------------------------------------------
* Fill up remaining parts, per-packet variant fields
*------------------------------------------------------------------------------
*/
	/* Calculate Tx byte count */
	HAL_MAC_TX_DESC_SET_TX_BYTE_COUNT(prTxDesc, u4TxDescLength + u4TxDescAppendLength + prMsduInfo->u2FrameLength);

	/* Checksum offload */
#if CFG_TCP_IP_CHKSUM_OFFLOAD
	if (prMsduInfo->eSrc == TX_PACKET_OS) {
		if (prAdapter->u4CSUMFlags &
				(CSUM_OFFLOAD_EN_TX_TCP | CSUM_OFFLOAD_EN_TX_UDP | CSUM_OFFLOAD_EN_TX_IP)) {
			ASSERT(prMsduInfo->prPacket);
			kalQueryTxChksumOffloadParam(prMsduInfo->prPacket, &ucChksumFlag);
			if ((ucChksumFlag & TX_CS_IP_GEN))
				HAL_MAC_TX_DESC_SET_IP_CHKSUM(prTxDesc);
			if ((ucChksumFlag & TX_CS_TCP_UDP_GEN))
				HAL_MAC_TX_DESC_SET_TCP_UDP_CHKSUM(prTxDesc);
		}
	}
#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */

	/* Set EtherType & VLAN for non 802.11 frame */
	if (!prMsduInfo->fgIs802_11) {
		if (prMsduInfo->fgIs802_3)
			HAL_MAC_TX_DESC_UNSET_ETHERNET_II(prTxDesc);
		if (prMsduInfo->fgIsVlanExists)
			HAL_MAC_TX_DESC_SET_VLAN(prTxDesc);
	}

	if (pu4TxDescLength)
		*pu4TxDescLength = u4TxDescLength;
}

VOID
nicTxFillDataDesc(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo)
{
	PUINT_8 pucOutputBuf;

	pucOutputBuf = skb_push((struct sk_buff *)prMsduInfo->prPacket, NIC_TX_HEAD_ROOM);

	nicTxFillDesc(prAdapter, prMsduInfo, pucOutputBuf, NULL);
}

VOID
nicTxCopyDesc(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucTarTxDesc, IN PUINT_8 pucSrcTxDesc, OUT PUINT_8 pucTxDescLength)
{
	UINT_8 ucTxDescLength;

	if (HAL_MAC_TX_DESC_IS_LONG_FORMAT((P_HW_MAC_TX_DESC_T) pucSrcTxDesc))
		ucTxDescLength = NIC_TX_DESC_LONG_FORMAT_LENGTH;
	else
		ucTxDescLength = NIC_TX_DESC_SHORT_FORMAT_LENGTH;

	kalMemCopy(pucTarTxDesc, pucSrcTxDesc, ucTxDescLength);

	if (pucTxDescLength)
		*pucTxDescLength = ucTxDescLength;
}

/*----------------------------------------------------------------------------*/
/*!
* @brief In this function, we'll generate Tx descriptor template for each TID.
*
* @param prAdapter              Pointer to the Adapter structure.
* @param prStaRec              Pointer to the StaRec structure.
*
* @retval VOID
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS nicTxGenerateDescTemplate(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec)
{
	UINT_8 ucTid;
	UINT_8 ucTc;
	UINT_32 u4TxDescSize, u4TxDescAppendSize;
	P_HW_MAC_TX_DESC_T prTxDesc;
	P_MSDU_INFO_T prMsduInfo;
	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;

	ASSERT(prAdapter);

	/* Free previous template, first */
	/* nicTxFreeDescTemplate(prAdapter, prStaRec); */
	for (ucTid = 0; ucTid < TX_DESC_TID_NUM; ucTid++)
		prStaRec->aprTxDescTemplate[ucTid] = NULL;

	prMsduInfo = cnmPktAlloc(prAdapter, 0);

	if (!prMsduInfo)
		return WLAN_STATUS_RESOURCES;

	/* Fill up MsduInfo template */
	prMsduInfo->eSrc = TX_PACKET_OS;
	prMsduInfo->fgIs802_11 = FALSE;
	prMsduInfo->fgIs802_1x = FALSE;
	prMsduInfo->fgIs802_1x_NonProtected = FALSE;
	prMsduInfo->fgIs802_3 = FALSE;
	prMsduInfo->fgIsVlanExists = FALSE;
	prMsduInfo->pfTxDoneHandler = NULL;
	prMsduInfo->prPacket = NULL;
	prMsduInfo->u2FrameLength = 0;
	prMsduInfo->u4Option = 0;
	prMsduInfo->u4FixedRateOption = 0;
	prMsduInfo->ucRateMode = MSDU_RATE_MODE_AUTO;
	prMsduInfo->ucBssIndex = prStaRec->ucBssIndex;
	prMsduInfo->ucPacketType = TX_PACKET_TYPE_DATA;
	prMsduInfo->ucStaRecIndex = prStaRec->ucIndex;
	prMsduInfo->ucPID = NIC_TX_DESC_PID_RESERVED;

	u4TxDescSize = NIC_TX_DESC_LONG_FORMAT_LENGTH;
	u4TxDescAppendSize = HW_MAC_TX_DESC_APPEND_T_LENGTH;

	DBGLOG(QM, INFO, "Generate TXD template for STA[%u] QoS[%u]\n", prStaRec->ucIndex, prStaRec->fgIsQoS);

	/* Generate new template */
	if (prStaRec->fgIsQoS) {
		/* For QoS STA, generate 8 TXD template (TID0~TID7) */
		for (ucTid = 0; ucTid < TX_DESC_TID_NUM; ucTid++) {

			if (prAdapter->rWifiVar.ucTcRestrict < TC_NUM)
				ucTc = prAdapter->rWifiVar.ucTcRestrict;
			else
				ucTc = arNetwork2TcResource[prStaRec->ucBssIndex][aucTid2ACI[ucTid]];
			u4TxDescSize = arTcTrafficSettings[ucTc].u4TxDescLength;

			/* Include TxD append */
			prTxDesc = kalMemAlloc(u4TxDescSize + u4TxDescAppendSize, VIR_MEM_TYPE);
			DBGLOG(QM, TRACE, "STA[%u] TID[%u] TxDTemp[0x%p]\n", prStaRec->ucIndex, ucTid, prTxDesc);
			if (!prTxDesc) {
				rStatus = WLAN_STATUS_RESOURCES;
				break;
			}

			/* Update MsduInfo TID & TC */
			prMsduInfo->ucUserPriority = ucTid;
			prMsduInfo->ucTC = ucTc;

			/* Compose Tx desc template */
			nicTxComposeDesc(prAdapter, prMsduInfo, u4TxDescSize, TRUE, (PUINT_8) prTxDesc);

			/* Fill TxD append */
			nicTxComposeDescAppend(prAdapter, prMsduInfo, ((PUINT_8)prTxDesc + u4TxDescSize));

			prStaRec->aprTxDescTemplate[ucTid] = prTxDesc;
		}
	} else {
		/* For non-QoS STA, generate 1 TXD template (TID0) */
		do {
			if (prAdapter->rWifiVar.ucTcRestrict < TC_NUM)
				ucTc = prAdapter->rWifiVar.ucTcRestrict;
			else
				ucTc = arNetwork2TcResource[prStaRec->ucBssIndex][NET_TC_WMM_AC_BE_INDEX];

			/* ucTxDescSize = arTcTrafficSettings[ucTc].ucTxDescLength; */
			u4TxDescSize = NIC_TX_DESC_LONG_FORMAT_LENGTH;

			prTxDesc = kalMemAlloc(u4TxDescSize + u4TxDescAppendSize, VIR_MEM_TYPE);
			if (!prTxDesc) {
				rStatus = WLAN_STATUS_RESOURCES;
				break;
			}
			/* Update MsduInfo TID & TC */
			prMsduInfo->ucUserPriority = 0;
			prMsduInfo->ucTC = ucTc;

			/* Compose Tx desc template */
			nicTxComposeDesc(prAdapter, prMsduInfo, u4TxDescSize, TRUE, (PUINT_8) prTxDesc);

			/* Fill TxD append */
			nicTxComposeDescAppend(prAdapter, prMsduInfo, ((PUINT_8)prTxDesc + u4TxDescSize));

			for (ucTid = 0; ucTid < TX_DESC_TID_NUM; ucTid++) {
				prStaRec->aprTxDescTemplate[ucTid] = prTxDesc;
				DBGLOG(QM, TRACE, "TXD template: TID[%u] Ptr[0x%x]\n", ucTid, (ULONG) prTxDesc);
			}
		} while (FALSE);
	}

	nicTxReturnMsduInfo(prAdapter, prMsduInfo);

	return rStatus;
}

/*----------------------------------------------------------------------------*/
/*!
* @brief In this function, we'll free Tx descriptor template for each TID.
*
* @param prAdapter              Pointer to the Adapter structure.
* @param prStaRec              Pointer to the StaRec structure.
*
* @retval VOID
*/
/*----------------------------------------------------------------------------*/
VOID nicTxFreeDescTemplate(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec)
{
	UINT_8 ucTid;
	UINT_8 ucTxDescSize;
	P_HW_MAC_TX_DESC_T prTxDesc;

	DBGLOG(QM, INFO, "Free TXD template for STA[%u] QoS[%u]\n", prStaRec->ucIndex, prStaRec->fgIsQoS);

	if (prStaRec->fgIsQoS) {
		for (ucTid = 0; ucTid < TX_DESC_TID_NUM; ucTid++) {
			prTxDesc = (P_HW_MAC_TX_DESC_T) prStaRec->aprTxDescTemplate[ucTid];

			if (prTxDesc) {
				if (HAL_MAC_TX_DESC_IS_LONG_FORMAT(prTxDesc))
					ucTxDescSize = NIC_TX_DESC_LONG_FORMAT_LENGTH;
				else
					ucTxDescSize = NIC_TX_DESC_SHORT_FORMAT_LENGTH;

				kalMemFree(prTxDesc, VIR_MEM_TYPE, ucTxDescSize);

				prTxDesc = prStaRec->aprTxDescTemplate[ucTid] = NULL;
			}
		}
	} else {
		prTxDesc = (P_HW_MAC_TX_DESC_T) prStaRec->aprTxDescTemplate[0];
		if (prTxDesc) {
			if (HAL_MAC_TX_DESC_IS_LONG_FORMAT(prTxDesc))
				ucTxDescSize = NIC_TX_DESC_LONG_FORMAT_LENGTH;
			else
				ucTxDescSize = NIC_TX_DESC_SHORT_FORMAT_LENGTH;

			kalMemFree(prTxDesc, VIR_MEM_TYPE, ucTxDescSize);
			prTxDesc = NULL;
		}
		for (ucTid = 0; ucTid < TX_DESC_TID_NUM; ucTid++)
			prStaRec->aprTxDescTemplate[ucTid] = NULL;
	}
}

/*----------------------------------------------------------------------------*/
/*!
* \brief Write data to device done
*
* \param[in] prGlueInfo         Pointer to the GLUE_INFO_T structure.
* \param[in] prQue              msdu info que to be free
*
* \retval TRUE          operation success
* \retval FALSE         operation fail
*/
/*----------------------------------------------------------------------------*/
void nicTxMsduDoneCb(IN P_GLUE_INFO_T prGlueInfo, IN P_QUE_T prQue)
{
	P_MSDU_INFO_T prMsduInfo, prNextMsduInfo;
	QUE_T rFreeQueue;
	P_QUE_T prFreeQueue;
	/* P_NATIVE_PACKET prNativePacket; */
	P_TX_CTRL_T prTxCtrl;
	P_ADAPTER_T prAdapter = prGlueInfo->prAdapter;

	ASSERT(prAdapter);
	prTxCtrl = &prAdapter->rTxCtrl;
	ASSERT(prTxCtrl);

	prFreeQueue = &rFreeQueue;
	QUEUE_INITIALIZE(prFreeQueue);

	if (prQue && prQue->u4NumElem > 0) {
		prMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_HEAD(prQue);

		while (prMsduInfo) {
			prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY(&prMsduInfo->rQueEntry);

#if 1
			nicTxFreePacket(prAdapter, prMsduInfo, FALSE);
#else
			prNativePacket = prMsduInfo->prPacket;

			/* Free MSDU_INFO */
			if (prMsduInfo->eSrc == TX_PACKET_OS) {
				wlanTxProfilingTagMsdu(prAdapter, prMsduInfo, TX_PROF_TAG_DRV_TX_DONE);
				kalSendComplete(prAdapter->prGlueInfo, prNativePacket, WLAN_STATUS_SUCCESS);
				prMsduInfo->prPacket = NULL;
			} else if (prMsduInfo->eSrc == TX_PACKET_FORWARDING) {
				GLUE_DEC_REF_CNT(prTxCtrl->i4PendingFwdFrameCount);
			}
#endif

			if (!prMsduInfo->pfTxDoneHandler)
				QUEUE_INSERT_TAIL(prFreeQueue, (P_QUE_ENTRY_T) prMsduInfo);

			prMsduInfo = prNextMsduInfo;
		}
		nicTxReturnMsduInfo(prAdapter, (P_MSDU_INFO_T) QUEUE_GET_HEAD(&rFreeQueue));
	}
}

/*----------------------------------------------------------------------------*/
/*!
* @brief In this function, we'll write frame(PACKET_INFO_T) into HIF.
*
* @param prAdapter              Pointer to the Adapter structure.
* @param ucPortIdx              Port Number
* @param prQue                  a link list of P_MSDU_INFO_T
*
* @retval WLAN_STATUS_SUCCESS   Bus access ok.
* @retval WLAN_STATUS_FAILURE   Bus access fail.
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS nicTxMsduQueue(IN P_ADAPTER_T prAdapter, UINT_8 ucPortIdx, P_QUE_T prQue)
{
	P_MSDU_INFO_T prMsduInfo;
	P_TX_CTRL_T prTxCtrl;

	ASSERT(prAdapter);
	ASSERT(prQue);

	prTxCtrl = &prAdapter->rTxCtrl;

#if CFG_HIF_STATISTICS
	prTxCtrl->u4TotalTxAccessNum++;
	prTxCtrl->u4TotalTxPacketNum += prQue->u4NumElem;
#endif

	while (QUEUE_IS_NOT_EMPTY(prQue)) {
		QUEUE_REMOVE_HEAD(prQue, prMsduInfo, P_MSDU_INFO_T);

		if (!halTxIsDataBufEnough(prAdapter, prMsduInfo)) {
			QUEUE_INSERT_HEAD(prQue, (P_QUE_ENTRY_T) prMsduInfo);
			break;
		}

#if !CFG_SUPPORT_MULTITHREAD
		nicTxFillDataDesc(prAdapter, prMsduInfo);
#endif

		if (prMsduInfo->pfTxDoneHandler) {
			KAL_SPIN_LOCK_DECLARATION();

			/* Record native packet pointer for Tx done log */
			WLAN_GET_FIELD_32(&prMsduInfo->prPacket, &prMsduInfo->u4TxDoneTag);

			KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST);
			QUEUE_INSERT_TAIL(&(prTxCtrl->rTxMgmtTxingQueue), (P_QUE_ENTRY_T) prMsduInfo);
			KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST);
		}

		HAL_WRITE_TX_DATA(prAdapter, prMsduInfo);
	}

	HAL_KICK_TX_DATA(prAdapter);

	return WLAN_STATUS_SUCCESS;
}

/*----------------------------------------------------------------------------*/
/*!
* \brief In this function, we'll write Command(CMD_INFO_T) into HIF.
*
* @param prAdapter      Pointer to the Adapter structure.
* @param prPacketInfo   Pointer of CMD_INFO_T
* @param ucTC           Specify the resource of TC
*
* @retval WLAN_STATUS_SUCCESS   Bus access ok.
* @retval WLAN_STATUS_FAILURE   Bus access fail.
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS nicTxCmd(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN UINT_8 ucTC)
{
	P_WIFI_CMD_T prWifiCmd;
	P_MSDU_INFO_T prMsduInfo;
	P_TX_CTRL_T prTxCtrl;
	struct sk_buff *skb;

	KAL_SPIN_LOCK_DECLARATION();

	ASSERT(prAdapter);
	ASSERT(prCmdInfo);

	prTxCtrl = &prAdapter->rTxCtrl;

	if (prCmdInfo->eCmdType == COMMAND_TYPE_SECURITY_FRAME) {
		prMsduInfo = prCmdInfo->prMsduInfo;

		prCmdInfo->pucTxd = prMsduInfo->aucTxDescBuffer;
		if (HAL_MAC_TX_DESC_IS_LONG_FORMAT((P_HW_MAC_TX_DESC_T) prMsduInfo->aucTxDescBuffer))
			prCmdInfo->u4TxdLen = NIC_TX_DESC_LONG_FORMAT_LENGTH;
		else
			prCmdInfo->u4TxdLen = NIC_TX_DESC_SHORT_FORMAT_LENGTH;

		skb = (struct sk_buff *)prMsduInfo->prPacket;
		prCmdInfo->pucTxp = skb->data;
		prCmdInfo->u4TxpLen = skb->len;

		HAL_WRITE_TX_CMD(prAdapter, prCmdInfo, ucTC);

		prMsduInfo->prPacket = NULL;

		if (prMsduInfo->pfTxDoneHandler) {
			/* DBGLOG(INIT, TRACE,("Wait Cmd TxSeqNum:%d\n", prMsduInfo->ucTxSeqNum)); */
			KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST);
			QUEUE_INSERT_TAIL(&(prTxCtrl->rTxMgmtTxingQueue), (P_QUE_ENTRY_T) prMsduInfo);
			KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST);
		} else {
			/* Only return MSDU_INFO */
			/* NativePacket will be freed at SEC frame CMD callback */
			nicTxReturnMsduInfo(prAdapter, prMsduInfo);
		}

	} else if (prCmdInfo->eCmdType == COMMAND_TYPE_MANAGEMENT_FRAME) {
		prMsduInfo = prCmdInfo->prMsduInfo;

		ASSERT(prMsduInfo->fgIs802_11 == TRUE);
		ASSERT(prMsduInfo->eSrc == TX_PACKET_MGMT);

		prCmdInfo->pucTxd = prMsduInfo->aucTxDescBuffer;
		if (HAL_MAC_TX_DESC_IS_LONG_FORMAT((P_HW_MAC_TX_DESC_T) prMsduInfo->aucTxDescBuffer))
			prCmdInfo->u4TxdLen = NIC_TX_DESC_LONG_FORMAT_LENGTH;
		else
			prCmdInfo->u4TxdLen = NIC_TX_DESC_SHORT_FORMAT_LENGTH;

		prCmdInfo->pucTxp = prMsduInfo->prPacket;
		prCmdInfo->u4TxpLen = prMsduInfo->u2FrameLength;

		HAL_WRITE_TX_CMD(prAdapter, prCmdInfo, ucTC);
		/* <4> Management Frame Post-Processing */
		GLUE_DEC_REF_CNT(prTxCtrl->i4TxMgmtPendingNum);

		DBGLOG(INIT, INFO, "TX MGMT Frame: BSS[%u] WIDX:PID[%u:%u] SEQ[%u] STA[%u] RSP[%u]\n",
			prMsduInfo->ucBssIndex, prMsduInfo->ucWlanIndex, prMsduInfo->ucPID,
			prMsduInfo->ucTxSeqNum, prMsduInfo->ucStaRecIndex, prMsduInfo->pfTxDoneHandler ? TRUE : FALSE);

		if (prMsduInfo->pfTxDoneHandler) {
			/* DBGLOG(INIT, TRACE,("Wait Cmd TxSeqNum:%d\n", prMsduInfo->ucTxSeqNum)); */
			KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST);
			QUEUE_INSERT_TAIL(&(prTxCtrl->rTxMgmtTxingQueue), (P_QUE_ENTRY_T) prMsduInfo);
			KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST);
		} else {
			cnmMgtPktFree(prAdapter, prMsduInfo);
		}

	} else {
		P_PSE_CMD_HDR_T prPseCmdHdr;

		prWifiCmd = (P_WIFI_CMD_T) prCmdInfo->pucInfoBuffer;

		prPseCmdHdr = (P_PSE_CMD_HDR_T) (prCmdInfo->pucInfoBuffer);
		prPseCmdHdr->u2Qidx = TXD_Q_IDX_MCU_RQ0;
		prPseCmdHdr->u2Pidx = TXD_P_IDX_MCU;
		prPseCmdHdr->u2Hf = TXD_HF_CMD;
		prPseCmdHdr->u2Ft = TXD_FT_LONG_FORMAT;
		prPseCmdHdr->u2PktFt = TXD_PKT_FT_CMD;

		prWifiCmd->u2Length = prWifiCmd->u2TxByteCount - sizeof(PSE_CMD_HDR_T);

#if (CFG_UMAC_GENERATION >= 0x20)
		/* TODO ? */
		/* prWifiCmd->prPseCmd.u2TxByteCount = u2OverallBufferLength; */
		/* prWifiCmd->u2TxByteCount = u2OverallBufferLength - sizeof(PSE_CMD_HDR_T); */
#else
		prWifiCmd->u2TxByteCount =
		    TFCB_FRAME_PAD_TO_DW((prCmdInfo->u2InfoBufLen) & (UINT_16) HIF_TX_HDR_TX_BYTE_COUNT_MASK);
#endif
		prWifiCmd->u2PQ_ID = CMD_PQ_ID;
		prWifiCmd->ucPktTypeID = CMD_PACKET_TYPE_ID;
		prWifiCmd->ucS2DIndex = S2D_INDEX_CMD_H2N_H2C;
		prCmdInfo->pucTxd = prCmdInfo->pucInfoBuffer;
		prCmdInfo->u4TxdLen = prCmdInfo->u2InfoBufLen;
		prCmdInfo->pucTxp = NULL;
		prCmdInfo->u4TxpLen = 0;

		HAL_WRITE_TX_CMD(prAdapter, prCmdInfo, ucTC);

		DBGLOG(INIT, INFO, "TX CMD: ID[0x%02X] SEQ[%u] SET[%u] LEN[%u]\n",
			prWifiCmd->ucCID, prWifiCmd->ucSeqNum, prWifiCmd->ucSetQuery, prWifiCmd->u2Length);
	}

	return WLAN_STATUS_SUCCESS;
}				/* end of nicTxCmd() */

/*----------------------------------------------------------------------------*/
/*!
* @brief This function will clean up all the pending frames in internal SW Queues
*        by return the pending TX packet to the system.
*
* @param prAdapter  Pointer to the Adapter structure.
*
* @return (none)
*/
/*----------------------------------------------------------------------------*/
VOID nicTxRelease(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgProcTxDoneHandler)
{
	P_TX_CTRL_T prTxCtrl;
	P_MSDU_INFO_T prMsduInfo;

	KAL_SPIN_LOCK_DECLARATION();

	ASSERT(prAdapter);

	prTxCtrl = &prAdapter->rTxCtrl;

	nicTxFlush(prAdapter);

	/* free MSDU_INFO_T from rTxMgmtMsduInfoList */
	do {
		KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST);
		QUEUE_REMOVE_HEAD(&prTxCtrl->rTxMgmtTxingQueue, prMsduInfo, P_MSDU_INFO_T);
		KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST);

		if (prMsduInfo) {
			DBGLOG(TX, TRACE, "%s: Get Msdu WIDX:PID[%u:%u] SEQ[%u] from Pending Q\n",
			       __func__, prMsduInfo->ucWlanIndex, prMsduInfo->ucPID, prMsduInfo->ucTxSeqNum);

			/* invoke done handler */
			if (prMsduInfo->pfTxDoneHandler && fgProcTxDoneHandler)
				prMsduInfo->pfTxDoneHandler(prAdapter, prMsduInfo, TX_RESULT_DROPPED_IN_DRIVER);

			nicTxFreeMsduInfoPacket(prAdapter, prMsduInfo);
			nicTxReturnMsduInfo(prAdapter, prMsduInfo);
		} else {
			break;
		}
	} while (TRUE);

}				/* end of nicTxRelease() */

/*----------------------------------------------------------------------------*/
/*!
* @brief Process the TX Done interrupt and pull in more pending frames in SW
*        Queues for transmission.
*
* @param prAdapter  Pointer to the Adapter structure.
*
* @return (none)
*/
/*----------------------------------------------------------------------------*/
VOID nicProcessTxInterrupt(IN P_ADAPTER_T prAdapter)
{
	P_WIFI_VAR_T prWifiVar = &prAdapter->rWifiVar;

	halProcessTxInterrupt(prAdapter);

	/* Indicate Service Thread */
	if (kalGetTxPendingCmdCount(prAdapter->prGlueInfo) > 0 || wlanGetTxPendingFrameCount(prAdapter) > 0)
		kalSetEvent(prAdapter->prGlueInfo);

	/* SER break point */
	if (nicSerIsTxStop(prAdapter)) {
		/* Skip following Tx handling */
		return;
	}

	/* TX Commands */
	if (kalGetTxPendingCmdCount(prAdapter->prGlueInfo))
		wlanTxCmdMthread(prAdapter);

	/* Process TX data packet to HIF */
	if (nicTxGetMsduPendingCnt(prAdapter) >= prWifiVar->u4TxIntThCount)
		nicTxMsduQueueMthread(prAdapter);
} /* end of nicProcessTxInterrupt() */

VOID nicTxFreePacket(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN BOOLEAN fgDrop)
{
	P_NATIVE_PACKET prNativePacket;
	P_TX_CTRL_T prTxCtrl;
	WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;

	ASSERT(prAdapter);

	prTxCtrl = &prAdapter->rTxCtrl;

	prNativePacket = prMsduInfo->prPacket;

	if (fgDrop)
		rStatus = WLAN_STATUS_FAILURE;

	if (prMsduInfo->eSrc == TX_PACKET_OS) {
		if (prNativePacket)
			kalSendComplete(prAdapter->prGlueInfo, prNativePacket, rStatus);
		if (fgDrop)
			wlanUpdateTxStatistics(prAdapter, prMsduInfo, TRUE); /*get per-AC Tx drop packets */
	} else if (prMsduInfo->eSrc == TX_PACKET_MGMT) {
		if (prMsduInfo->pfTxDoneHandler)
			prMsduInfo->pfTxDoneHandler(prAdapter, prMsduInfo, TX_RESULT_DROPPED_IN_DRIVER);
		if (prNativePacket)
			cnmMemFree(prAdapter, prNativePacket);
	} else if (prMsduInfo->eSrc == TX_PACKET_FORWARDING) {
		GLUE_DEC_REF_CNT(prTxCtrl->i4PendingFwdFrameCount);
	}
}

/*----------------------------------------------------------------------------*/
/*!
* @brief this function frees packet of P_MSDU_INFO_T linked-list
*
* @param prAdapter              Pointer to the Adapter structure.
* @param prMsduInfoList         a link list of P_MSDU_INFO_T
*
* @return (none)
*/
/*----------------------------------------------------------------------------*/
VOID nicTxFreeMsduInfoPacket(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead)
{
	P_NATIVE_PACKET prNativePacket;
	P_MSDU_INFO_T prMsduInfo = prMsduInfoListHead;
	P_TX_CTRL_T prTxCtrl;

	ASSERT(prAdapter);
	ASSERT(prMsduInfoListHead);

	prTxCtrl = &prAdapter->rTxCtrl;

	while (prMsduInfo) {
		prNativePacket = prMsduInfo->prPacket;

#if 1
		nicTxFreePacket(prAdapter, prMsduInfo, TRUE);
#else
		if (prMsduInfo->eSrc == TX_PACKET_OS) {
			if (prNativePacket)
				kalSendComplete(prAdapter->prGlueInfo, prNativePacket, WLAN_STATUS_FAILURE);
			/*get per-AC Tx drop packets */
			wlanUpdateTxStatistics(prAdapter, prMsduInfo, TRUE);
		} else if (prMsduInfo->eSrc == TX_PACKET_MGMT) {
			if (prMsduInfo->pfTxDoneHandler)
				prMsduInfo->pfTxDoneHandler(prAdapter, prMsduInfo, TX_RESULT_DROPPED_IN_DRIVER);
			if (prNativePacket)
				cnmMemFree(prAdapter, prNativePacket);
		} else if (prMsduInfo->eSrc == TX_PACKET_FORWARDING) {
			GLUE_DEC_REF_CNT(prTxCtrl->i4PendingFwdFrameCount);
		}
#endif
		prMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo);
	}

}

/*----------------------------------------------------------------------------*/
/*!
* @brief this function returns P_MSDU_INFO_T of MsduInfoList to TxCtrl->rfreeMsduInfoList
*
* @param prAdapter              Pointer to the Adapter structure.
* @param prMsduInfoList         a link list of P_MSDU_INFO_T
*
* @return (none)
*/
/*----------------------------------------------------------------------------*/
VOID nicTxReturnMsduInfo(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead)
{
	P_TX_CTRL_T prTxCtrl;
	P_MSDU_INFO_T prMsduInfo = prMsduInfoListHead, prNextMsduInfo;

	KAL_SPIN_LOCK_DECLARATION();

	ASSERT(prAdapter);

	prTxCtrl = &prAdapter->rTxCtrl;
	ASSERT(prTxCtrl);

	while (prMsduInfo) {
		prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo);

		switch (prMsduInfo->eSrc) {
		case TX_PACKET_FORWARDING:
			wlanReturnPacket(prAdapter, prMsduInfo->prPacket);
			break;
		case TX_PACKET_OS:
		case TX_PACKET_OS_OID:
		case TX_PACKET_MGMT:
		default:
			break;
		}

		/* Reset MSDU_INFO fields */
		kalMemZero(prMsduInfo, sizeof(MSDU_INFO_T));

		KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
		QUEUE_INSERT_TAIL(&prTxCtrl->rFreeMsduInfoList, (P_QUE_ENTRY_T) prMsduInfo);
		KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
		prMsduInfo = prNextMsduInfo;
	};

}

/*----------------------------------------------------------------------------*/
/*!
* @brief this function fills packet information to P_MSDU_INFO_T
*
* @param prAdapter              Pointer to the Adapter structure.
* @param prMsduInfo             P_MSDU_INFO_T
* @param prPacket               P_NATIVE_PACKET
*
* @retval TRUE      Success to extract information
* @retval FALSE     Fail to extract correct information
*/
/*----------------------------------------------------------------------------*/
BOOLEAN nicTxFillMsduInfo(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN P_NATIVE_PACKET prPacket)
{
	P_GLUE_INFO_T prGlueInfo;

	ASSERT(prAdapter);

	kalMemZero(prMsduInfo, sizeof(MSDU_INFO_T));

	prGlueInfo = prAdapter->prGlueInfo;
	ASSERT(prGlueInfo);

	kalGetEthDestAddr(prAdapter->prGlueInfo, prPacket, prMsduInfo->aucEthDestAddr);

	prMsduInfo->prPacket = prPacket;
	prMsduInfo->ucBssIndex = GLUE_GET_PKT_BSS_IDX(prPacket);
	prMsduInfo->ucUserPriority = GLUE_GET_PKT_TID(prPacket);
	prMsduInfo->ucMacHeaderLength = GLUE_GET_PKT_HEADER_LEN(prPacket);
	prMsduInfo->u2FrameLength = (UINT_16) GLUE_GET_PKT_FRAME_LEN(prPacket);
	prMsduInfo->u4PageCount = nicTxGetPageCount(prMsduInfo->u2FrameLength, FALSE);

	if (GLUE_IS_PKT_FLAG_SET(prPacket)) {
		prMsduInfo->fgIs802_1x = GLUE_TEST_PKT_FLAG(prPacket, ENUM_PKT_1X) ? TRUE:FALSE;
		prMsduInfo->fgIs802_1x_NonProtected =
				GLUE_TEST_PKT_FLAG(prPacket, ENUM_PKT_NON_PROTECTED_1X) ? TRUE:FALSE;
		prMsduInfo->fgIs802_3 = GLUE_TEST_PKT_FLAG(prPacket, ENUM_PKT_802_3) ? TRUE:FALSE;
		prMsduInfo->fgIsVlanExists = GLUE_TEST_PKT_FLAG(prPacket, ENUM_PKT_VLAN_EXIST) ? TRUE:FALSE;

		if (GLUE_TEST_PKT_FLAG(prPacket, ENUM_PKT_DHCP) && prAdapter->rWifiVar.ucDhcpTxDone)
			prMsduInfo->pfTxDoneHandler = wlanDhcpTxDone;
		else if (GLUE_TEST_PKT_FLAG(prPacket, ENUM_PKT_ARP) && prAdapter->rWifiVar.ucArpTxDone)
			prMsduInfo->pfTxDoneHandler = wlanArpTxDone;
		else if (GLUE_TEST_PKT_FLAG(prPacket, ENUM_PKT_1X))
			prMsduInfo->pfTxDoneHandler = wlan1xTxDone;

		if (GLUE_TEST_PKT_FLAG(prPacket, ENUM_PKT_DHCP) ||
			GLUE_TEST_PKT_FLAG(prPacket, ENUM_PKT_ARP) ||
			GLUE_TEST_PKT_FLAG(prPacket, ENUM_PKT_1X)) {
			/* Set BSS/STA lowest basic rate */
			prMsduInfo->ucRateMode = MSDU_RATE_MODE_LOWEST_RATE;

			/* Set higher priority */
			prMsduInfo->ucUserPriority = NIC_TX_CRITICAL_DATA_TID;
		}
	}

	/* Add dummy Tx done */
	if ((prAdapter->rWifiVar.ucDataTxDone == 1) && (prMsduInfo->pfTxDoneHandler == NULL))
		prMsduInfo->pfTxDoneHandler = nicTxDummyTxDone;

	return TRUE;
}

/*----------------------------------------------------------------------------*/
/*!
* @brief this function update TCQ values by passing current status to txAdjustTcQuotas
*
* @param prAdapter              Pointer to the Adapter structure.
*
* @retval WLAN_STATUS_SUCCESS   Updated successfully
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS nicTxAdjustTcq(IN P_ADAPTER_T prAdapter)
{
#if CFG_SUPPORT_MULTITHREAD
	TX_TCQ_ADJUST_T rTcqAdjust;
	P_TX_CTRL_T prTxCtrl;

	ASSERT(prAdapter);

	prTxCtrl = &prAdapter->rTxCtrl;
	ASSERT(prTxCtrl);

	qmAdjustTcQuotasMthread(prAdapter, &rTcqAdjust, &prTxCtrl->rTc);

#else

	UINT_32 u4Num;
	TX_TCQ_ADJUST_T rTcqAdjust;
	P_TX_CTRL_T prTxCtrl;
	P_TX_TCQ_STATUS_T prTcqStatus;

	KAL_SPIN_LOCK_DECLARATION();

	ASSERT(prAdapter);

	prTxCtrl = &prAdapter->rTxCtrl;
	prTcqStatus = &prAdapter->rTxCtrl.rTc;
	ASSERT(prTxCtrl);

	if (qmAdjustTcQuotas(prAdapter, &rTcqAdjust, &prTxCtrl->rTc)) {

		KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE);

		for (u4Num = 0; u4Num < TC_NUM; u4Num++) {
			/* Page count */
			prTxCtrl->rTc.au4FreePageCount[u4Num] +=
			    (rTcqAdjust.ai4Variation[u4Num] * NIC_TX_MAX_PAGE_PER_FRAME);
			prTxCtrl->rTc.au4MaxNumOfPage[u4Num] +=
			    (rTcqAdjust.ai4Variation[u4Num] * NIC_TX_MAX_PAGE_PER_FRAME);

			/* Buffer count */
			prTxCtrl->rTc.au4FreeBufferCount[u4Num] += rTcqAdjust.ai4Variation[u4Num];
			prTxCtrl->rTc.au4MaxNumOfBuffer[u4Num] += rTcqAdjust.ai4Variation[u4Num];

			ASSERT(prTxCtrl->rTc.au4FreeBufferCount[u4Num] >= 0);
			ASSERT(prTxCtrl->rTc.au4MaxNumOfBuffer[u4Num] >= 0);
		}

		KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE);
#if 0
		DBGLOG(TX, LOUD,
		       "TCQ Status Free Page:Buf[%03u:%02u, %03u:%02u, %03u:%02u, %03u:%02u, %03u:%02u, %03u:%02u]\n",
		       prTcqStatus->au4FreePageCount[TC0_INDEX],
		       prTcqStatus->au4FreeBufferCount[TC0_INDEX],
		       prTcqStatus->au4FreePageCount[TC1_INDEX],
		       prTcqStatus->au4FreeBufferCount[TC1_INDEX],
		       prTcqStatus->au4FreePageCount[TC2_INDEX],
		       prTcqStatus->au4FreeBufferCount[TC2_INDEX],
		       prTcqStatus->au4FreePageCount[TC3_INDEX],
		       prTcqStatus->au4FreeBufferCount[TC3_INDEX],
		       prTcqStatus->au4FreePageCount[TC4_INDEX],
		       prTcqStatus->au4FreeBufferCount[TC4_INDEX],
		       prTcqStatus->au4FreePageCount[TC5_INDEX], prTcqStatus->au4FreeBufferCount[TC5_INDEX]);
#endif
		DBGLOG(TX, LOUD,
		       "TCQ Status Max Page:Buf[%03u:%02u, %03u:%02u, %03u:%02u, %03u:%02u, %03u:%02u, %03u:%02u]\n",
		       prTcqStatus->au4MaxNumOfPage[TC0_INDEX],
		       prTcqStatus->au4MaxNumOfBuffer[TC0_INDEX],
		       prTcqStatus->au4MaxNumOfPage[TC1_INDEX],
		       prTcqStatus->au4MaxNumOfBuffer[TC1_INDEX],
		       prTcqStatus->au4MaxNumOfPage[TC2_INDEX],
		       prTcqStatus->au4MaxNumOfBuffer[TC2_INDEX],
		       prTcqStatus->au4MaxNumOfPage[TC3_INDEX],
		       prTcqStatus->au4MaxNumOfBuffer[TC3_INDEX],
		       prTcqStatus->au4MaxNumOfPage[TC4_INDEX],
		       prTcqStatus->au4MaxNumOfBuffer[TC4_INDEX],
		       prTcqStatus->au4MaxNumOfPage[TC5_INDEX], prTcqStatus->au4MaxNumOfBuffer[TC5_INDEX]);

	}
#endif
	return WLAN_STATUS_SUCCESS;
}

/*----------------------------------------------------------------------------*/
/*!
* @brief this function flushes all packets queued in STA/AC queue
*
* @param prAdapter              Pointer to the Adapter structure.
*
* @retval WLAN_STATUS_SUCCESS   Flushed successfully
*/
/*----------------------------------------------------------------------------*/

WLAN_STATUS nicTxFlush(IN P_ADAPTER_T prAdapter)
{
	P_MSDU_INFO_T prMsduInfo;

	KAL_SPIN_LOCK_DECLARATION();

	ASSERT(prAdapter);

	/* ask Per STA/AC queue to be fllushed and return all queued packets */
	KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE);
	prMsduInfo = qmFlushTxQueues(prAdapter);
	KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE);

	if (prMsduInfo != NULL) {
		nicTxFreeMsduInfoPacket(prAdapter, prMsduInfo);
		nicTxReturnMsduInfo(prAdapter, prMsduInfo);
	}

	return WLAN_STATUS_SUCCESS;
}

#if CFG_ENABLE_FW_DOWNLOAD
/*----------------------------------------------------------------------------*/
/*!
* \brief In this function, we'll write Command(CMD_INFO_T) into HIF.
*        However this function is used for INIT_CMD.
*
*        In order to avoid further maintenance issues, these 2 functions are separated
*
* @param prAdapter      Pointer to the Adapter structure.
* @param prPacketInfo   Pointer of CMD_INFO_T
* @param ucTC           Specify the resource of TC
*
* @retval WLAN_STATUS_SUCCESS   Bus access ok.
* @retval WLAN_STATUS_FAILURE   Bus access fail.
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS nicTxInitCmd(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo)
{
	UINT_16 u2OverallBufferLength;
	PUINT_8 pucOutputBuf = (PUINT_8) NULL;	/* Pointer to Transmit Data Structure Frame */
	P_TX_CTRL_T prTxCtrl;

	ASSERT(prAdapter);
	ASSERT(prCmdInfo);

	prTxCtrl = &prAdapter->rTxCtrl;
	pucOutputBuf = prTxCtrl->pucTxCoalescingBufPtr;
	u2OverallBufferLength = TFCB_FRAME_PAD_TO_DW((prCmdInfo->u2InfoBufLen) & (UINT_16)
						     HIF_TX_HDR_TX_BYTE_COUNT_MASK);

	/* <1> Copy CMD Header to command buffer (by using pucCoalescingBufCached) */
	kalMemCopy((PVOID)&pucOutputBuf[0], (PVOID) prCmdInfo->pucInfoBuffer, prCmdInfo->u2InfoBufLen);

	ASSERT(u2OverallBufferLength <= prAdapter->u4CoalescingBufCachedSize);

	/* <2> Write frame to data port */
	HAL_WRITE_TX_PORT(prAdapter, NIC_TX_INIT_CMD_PORT,
			  (UINT_32) u2OverallBufferLength,
			  (PUINT_8) pucOutputBuf, (UINT_32) prAdapter->u4CoalescingBufCachedSize);

	return WLAN_STATUS_SUCCESS;
}

/*----------------------------------------------------------------------------*/
/*!
* \brief In this function, we'll reset TX resource counter to initial value used
*        in F/W download state
*
* @param prAdapter      Pointer to the Adapter structure.
*
* @retval WLAN_STATUS_SUCCESS   Reset is done successfully.
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS nicTxInitResetResource(IN P_ADAPTER_T prAdapter)
{
	P_TX_CTRL_T prTxCtrl;
	UINT_8 ucIdx;

	DEBUGFUNC("nicTxInitResetResource");

	ASSERT(prAdapter);
	prTxCtrl = &prAdapter->rTxCtrl;

	/* Delta page count */
	kalMemZero(prTxCtrl->rTc.au4TxDonePageCount, sizeof(prTxCtrl->rTc.au4TxDonePageCount));
	kalMemZero(prTxCtrl->rTc.au4PreUsedPageCount, sizeof(prTxCtrl->rTc.au4PreUsedPageCount));
	prTxCtrl->rTc.ucNextTcIdx = TC0_INDEX;
	prTxCtrl->rTc.u4AvaliablePageCount = 0;

	/* Page count */
	prTxCtrl->rTc.au4MaxNumOfPage[TC0_INDEX] = NIC_TX_INIT_PAGE_COUNT_TC0;
	prTxCtrl->rTc.au4FreePageCount[TC0_INDEX] = NIC_TX_INIT_PAGE_COUNT_TC0;

	prTxCtrl->rTc.au4MaxNumOfPage[TC1_INDEX] = NIC_TX_INIT_PAGE_COUNT_TC1;
	prTxCtrl->rTc.au4FreePageCount[TC1_INDEX] = NIC_TX_INIT_PAGE_COUNT_TC1;

	prTxCtrl->rTc.au4MaxNumOfPage[TC2_INDEX] = NIC_TX_INIT_PAGE_COUNT_TC2;
	prTxCtrl->rTc.au4FreePageCount[TC2_INDEX] = NIC_TX_INIT_PAGE_COUNT_TC2;

	prTxCtrl->rTc.au4MaxNumOfPage[TC3_INDEX] = NIC_TX_INIT_PAGE_COUNT_TC3;
	prTxCtrl->rTc.au4FreePageCount[TC3_INDEX] = NIC_TX_INIT_PAGE_COUNT_TC3;

	prTxCtrl->rTc.au4MaxNumOfPage[TC4_INDEX] = NIC_TX_INIT_PAGE_COUNT_TC4;
	prTxCtrl->rTc.au4FreePageCount[TC4_INDEX] = NIC_TX_INIT_PAGE_COUNT_TC4;

	prTxCtrl->rTc.au4MaxNumOfPage[TC5_INDEX] = NIC_TX_INIT_PAGE_COUNT_TC5;
	prTxCtrl->rTc.au4FreePageCount[TC5_INDEX] = NIC_TX_INIT_PAGE_COUNT_TC5;

	/* Buffer count */
	for (ucIdx = TC0_INDEX; ucIdx < TC_NUM; ucIdx++) {
		prTxCtrl->rTc.au4MaxNumOfBuffer[ucIdx] =
		    prTxCtrl->rTc.au4MaxNumOfPage[ucIdx] / NIC_TX_MAX_PAGE_PER_FRAME;
		prTxCtrl->rTc.au4FreeBufferCount[ucIdx] =
		    prTxCtrl->rTc.au4FreePageCount[ucIdx] / NIC_TX_MAX_PAGE_PER_FRAME;
	}

	return WLAN_STATUS_SUCCESS;

}

#endif

BOOLEAN nicTxProcessMngPacket(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo)
{
#if 0
	UINT_16 u2RateCode;
#endif
	P_BSS_INFO_T prBssInfo;
	P_STA_RECORD_T prStaRec;

	if (prMsduInfo->eSrc != TX_PACKET_MGMT)
		return FALSE;

	/* Sanity check */
	if (!prMsduInfo->prPacket)
		return FALSE;

	if (!prMsduInfo->u2FrameLength)
		return FALSE;

	if (!prMsduInfo->ucMacHeaderLength)
		return FALSE;

	prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prMsduInfo->ucBssIndex);
	prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);

	/* MMPDU: force stick to TC4 */
	prMsduInfo->ucTC = TC4_INDEX;

	/* No Tx descriptor template for MMPDU */
	prMsduInfo->fgIsTXDTemplateValid = FALSE;

	/* Fixed Rate */
	if (prMsduInfo->ucRateMode == MSDU_RATE_MODE_AUTO) {
#if 0
		prMsduInfo->ucRateMode = MSDU_RATE_MODE_MANUAL_DESC;

		if (prStaRec)
			u2RateCode = prStaRec->u2HwDefaultFixedRateCode;
		else
			u2RateCode = prBssInfo->u2HwDefaultFixedRateCode;

		nicTxSetPktFixedRateOption(prMsduInfo, u2RateCode, FIX_BW_NO_FIXED, FALSE, FALSE);
#else
		nicTxSetPktLowestFixedRate(prAdapter, prMsduInfo);
#endif
	}
#if CFG_SUPPORT_MULTITHREAD
	nicTxFillDesc(prAdapter, prMsduInfo, prMsduInfo->aucTxDescBuffer, NULL);
#endif

	return TRUE;
}

VOID nicTxProcessTxDoneEvent(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent)
{
	P_EVENT_TX_DONE_T prTxDone;
	P_MSDU_INFO_T prMsduInfo;
	PUINT_8 apucBandwidt[4] = {(PUINT_8)"20", (PUINT_8)"40", (PUINT_8)"80", (PUINT_8)"160/80+80"};

	prTxDone = (P_EVENT_TX_DONE_T) (prEvent->aucBuffer);

	if (prTxDone->ucFlag & BIT(TXS_WITH_ADVANCED_INFO)) {
		/* Tx Done with advanced info */
		DBGLOG(NIC, INFO, "EVENT_ID_TX_DONE WIDX:PID[%u:%u] Status[%u] TID[%u] SN[%u] CNT[%u] RATE[0x%04x]\n",
			prTxDone->ucWlanIndex, prTxDone->ucPacketSeq, prTxDone->ucStatus, prTxDone->ucTid,
			prTxDone->u2SequenceNumber, prTxDone->ucTxCount, prTxDone->u2TxRate);

		if (prTxDone->ucFlag & BIT(TXS_IS_EXIST)) {
			UINT_8 ucNss, ucStbc;
			INT_8 icTxPwr;

			ucNss = (prTxDone->u2TxRate & TX_DESC_NSTS_MASK) >> TX_DESC_NSTS_OFFSET;
			ucNss += 1;
			ucStbc = (prTxDone->u2TxRate & TX_DESC_STBC) ? TRUE:FALSE;

			if (ucStbc)
				ucNss /= 2;

			DBGLOG(NIC, INFO, "||BW[%s] NSS[%u] ArIdx[%u] RspRate[0x%02x]\n",
				apucBandwidt[prTxDone->ucBandwidth], ucNss, prTxDone->ucRateTableIdx,
				prTxDone->ucRspRate);

			icTxPwr = (INT_8)prTxDone->ucTxPower;
			if (icTxPwr & BIT(6))
				icTxPwr |= BIT(7);

			DBGLOG(NIC, INFO, "||AMPDU[%u] PS[%u] IBF[%u] EBF[%u] TxPwr[%d%sdBm] TSF[%u] TxDelay[%uus]\n",
				prTxDone->u4AppliedFlag & BIT(TX_FRAME_IN_AMPDU_FORMAT) ? TRUE:FALSE,
				prTxDone->u4AppliedFlag & BIT(TX_FRAME_PS_BIT) ? TRUE:FALSE,
				prTxDone->u4AppliedFlag & BIT(TX_FRAME_IMP_BF) ? TRUE:FALSE,
				prTxDone->u4AppliedFlag & BIT(TX_FRAME_EXP_BF) ? TRUE:FALSE,
				icTxPwr / 2, icTxPwr & BIT(0) ? ".5" : "",
				prTxDone->u4Timestamp, prTxDone->u4TxDelay);
		}
	} else {
		DBGLOG(NIC, INFO, "EVENT_ID_TX_DONE WIDX:PID[%u:%u] Status[%u] SN[%u]\n",
			prTxDone->ucWlanIndex, prTxDone->ucPacketSeq, prTxDone->ucStatus, prTxDone->u2SequenceNumber);
	}

	/* call related TX Done Handler */
	prMsduInfo = nicGetPendingTxMsduInfo(prAdapter, prTxDone->ucWlanIndex, prTxDone->ucPacketSeq);

#if CFG_SUPPORT_802_11V_TIMING_MEASUREMENT
	DBGLOG(NIC, TRACE, "EVENT_ID_TX_DONE u4TimeStamp = %x u2AirDelay = %x\n",
		prTxDone->au4Reserved1, prTxDone->au4Reserved2);

	wnmReportTimingMeas(prAdapter, prMsduInfo->ucStaRecIndex,
		prTxDone->au4Reserved1, prTxDone->au4Reserved1 + prTxDone->au4Reserved2);
#endif

	if (prMsduInfo) {
		prMsduInfo->pfTxDoneHandler(prAdapter, prMsduInfo, (ENUM_TX_RESULT_CODE_T) (prTxDone->ucStatus));

		if (prMsduInfo->eSrc == TX_PACKET_MGMT)
			cnmMgtPktFree(prAdapter, prMsduInfo);
#if defined(_HIF_PCIE)
		else if (prMsduInfo->prToken)
			prMsduInfo->pfTxDoneHandler = NULL;
#endif
		else {
			nicTxFreePacket(prAdapter, prMsduInfo, FALSE);
			nicTxReturnMsduInfo(prAdapter, prMsduInfo);
		}
	}
}

/*----------------------------------------------------------------------------*/
/*!
* \brief this function enqueues MSDU_INFO_T into queue management,
*        or command queue
*
* @param prAdapter      Pointer to the Adapter structure.
*        prMsduInfo     Pointer to MSDU
*
* @retval WLAN_STATUS_SUCCESS   Reset is done successfully.
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS nicTxEnqueueMsdu(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo)
{
	P_TX_CTRL_T prTxCtrl;
	P_MSDU_INFO_T prNextMsduInfo, prRetMsduInfo, prMsduInfoHead;
	QUE_T qDataPort0, qDataPort1;
	P_QUE_T prDataPort0, prDataPort1;
	P_CMD_INFO_T prCmdInfo;
	WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS;

	KAL_SPIN_LOCK_DECLARATION();

	ASSERT(prAdapter);
	ASSERT(prMsduInfo);

	prTxCtrl = &prAdapter->rTxCtrl;
	ASSERT(prTxCtrl);

	prDataPort0 = &qDataPort0;
	prDataPort1 = &qDataPort1;

	QUEUE_INITIALIZE(prDataPort0);
	QUEUE_INITIALIZE(prDataPort1);

	/* check how many management frame are being queued */
	while (prMsduInfo) {
		prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo);

		QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo) = NULL;

		if (prMsduInfo->eSrc == TX_PACKET_MGMT) {
			if (nicTxProcessMngPacket(prAdapter, prMsduInfo)) {
				/* Valid MGMT */
				QUEUE_INSERT_TAIL(prDataPort1, (P_QUE_ENTRY_T) prMsduInfo);
			} else {
				/* Invalid MGMT */
				DBGLOG(TX, WARN, "Invalid MGMT[0x%p] BSS[%u] STA[%u],free it\n",
				       prMsduInfo, prMsduInfo->ucBssIndex, prMsduInfo->ucStaRecIndex);

				cnmMgtPktFree(prAdapter, prMsduInfo);
			}
		} else {
			QUEUE_INSERT_TAIL(prDataPort0, (P_QUE_ENTRY_T) prMsduInfo);
		}

		prMsduInfo = prNextMsduInfo;
	}

	if (prDataPort0->u4NumElem) {
		/* send to QM */
		KAL_SPIN_LOCK_DECLARATION();
		KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE);
		prRetMsduInfo = qmEnqueueTxPackets(prAdapter, (P_MSDU_INFO_T) QUEUE_GET_HEAD(prDataPort0));
		KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE);

		/* post-process for dropped packets */
		if (prRetMsduInfo) {	/* unable to enqueue */
			nicTxFreeMsduInfoPacket(prAdapter, prRetMsduInfo);
			nicTxReturnMsduInfo(prAdapter, prRetMsduInfo);
		}
	}

	if (prDataPort1->u4NumElem) {
		prMsduInfoHead = (P_MSDU_INFO_T) QUEUE_GET_HEAD(prDataPort1);

		if (nicTxGetFreeCmdCount(prAdapter) < NIC_TX_CMD_INFO_RESERVED_COUNT) {
			/* not enough descriptors for sending */
			u4Status = WLAN_STATUS_FAILURE;

			/* free all MSDUs */
			while (prMsduInfoHead) {
				prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY(&prMsduInfoHead->rQueEntry);

				if (prMsduInfoHead->pfTxDoneHandler != NULL) {
					prMsduInfoHead->pfTxDoneHandler(prAdapter, prMsduInfoHead,
									TX_RESULT_DROPPED_IN_DRIVER);
				}

				cnmMgtPktFree(prAdapter, prMsduInfoHead);

				prMsduInfoHead = prNextMsduInfo;
			}
		} else {
			/* send to command queue */
			while (prMsduInfoHead) {
				prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY(&prMsduInfoHead->rQueEntry);

				KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE);
				QUEUE_REMOVE_HEAD(&prAdapter->rFreeCmdList, prCmdInfo, P_CMD_INFO_T);
				KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE);

				if (prCmdInfo) {
					GLUE_INC_REF_CNT(prTxCtrl->i4TxMgmtPendingNum);

					kalMemZero(prCmdInfo, sizeof(CMD_INFO_T));

#if CFG_ENABLE_PKT_LIFETIME_PROFILE
					/* Tag MGMT enqueue time */
					GET_CURRENT_SYSTIME(&prMsduInfoHead->rPktProfile.rEnqueueTimestamp);
#endif
					prCmdInfo->eCmdType = COMMAND_TYPE_MANAGEMENT_FRAME;
					prCmdInfo->u2InfoBufLen = prMsduInfoHead->u2FrameLength;
					prCmdInfo->pucInfoBuffer = NULL;
					prCmdInfo->prMsduInfo = prMsduInfoHead;
					prCmdInfo->pfCmdDoneHandler = NULL;
					prCmdInfo->pfCmdTimeoutHandler = NULL;
					prCmdInfo->fgIsOid = FALSE;
					prCmdInfo->fgSetQuery = TRUE;
					prCmdInfo->fgNeedResp = FALSE;
					prCmdInfo->ucCmdSeqNum = prMsduInfoHead->ucTxSeqNum;

					DBGLOG(TX, TRACE, "%s: EN-Q MSDU[0x%p] SEQ[%u] BSS[%u] STA[%u] to CMD Q\n",
					       __func__, prMsduInfoHead,
					       prMsduInfoHead->ucTxSeqNum, prMsduInfoHead->ucBssIndex,
					       prMsduInfoHead->ucStaRecIndex);

					kalEnqueueCommand(prAdapter->prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo);
				} else {
					/* Cmd free count is larger than expected, but allocation fail. */
					u4Status = WLAN_STATUS_FAILURE;

					if (prMsduInfoHead->pfTxDoneHandler != NULL) {
						prMsduInfoHead->pfTxDoneHandler(prAdapter,
										prMsduInfoHead,
										TX_RESULT_DROPPED_IN_DRIVER);
					}

					cnmMgtPktFree(prAdapter, prMsduInfoHead);
				}

				prMsduInfoHead = prNextMsduInfo;
			}
		}
	}

	/* indicate service thread for sending */
	if (prTxCtrl->i4TxMgmtPendingNum > 0 || kalGetTxPendingFrameCount(prAdapter->prGlueInfo) > 0)
		kalSetEvent(prAdapter->prGlueInfo);

	return u4Status;
}

/*----------------------------------------------------------------------------*/
/*!
* \brief this function returns WLAN index
*
* @param prAdapter      Pointer to the Adapter structure.
*
* @retval
*/
/*----------------------------------------------------------------------------*/
UINT_8 nicTxGetWlanIdx(P_ADAPTER_T prAdapter, UINT_8 ucBssIdx, UINT_8 ucStaRecIdx)
{
	P_STA_RECORD_T prStaRec;
	P_BSS_INFO_T prBssInfo;
	UINT_8 ucWlanIndex = NIC_TX_DEFAULT_WLAN_INDEX;

	prStaRec = cnmGetStaRecByIndex(prAdapter, ucStaRecIdx);
	prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIdx);

	if (prStaRec)
		ucWlanIndex = prStaRec->ucWlanIndex;
	else if ((ucStaRecIdx == STA_REC_INDEX_BMCAST) && prBssInfo->fgIsInUse) {
		if (prBssInfo->fgBcDefaultKeyExist) {
			if (prBssInfo->wepkeyWlanIdx < NIC_TX_DEFAULT_WLAN_INDEX)
				ucWlanIndex = prBssInfo->wepkeyWlanIdx;
			else if (prBssInfo->ucBMCWlanIndexSUsed[prBssInfo->ucBcDefaultKeyIdx])
				ucWlanIndex = prBssInfo->ucBMCWlanIndexS[prBssInfo->ucBcDefaultKeyIdx];
		} else
			ucWlanIndex = prBssInfo->ucBMCWlanIndex;
	}

	if (ucWlanIndex >= WTBL_SIZE) {
		DBGLOG(TX, WARN, "%s: Unexpected WIDX[%u] BSS[%u] STA[%u], set WIDX to default value[%u]\n",
		       ucWlanIndex, ucBssIdx, ucStaRecIdx, NIC_TX_DEFAULT_WLAN_INDEX);

		ucWlanIndex = NIC_TX_DEFAULT_WLAN_INDEX;
	}

	return ucWlanIndex;
}

/*----------------------------------------------------------------------------*/
/*!
* \brief
*
* @param prAdapter      Pointer to the Adapter structure.
*
* @retval
*/
/*----------------------------------------------------------------------------*/
BOOLEAN nicTxIsMgmtResourceEnough(IN P_ADAPTER_T prAdapter)
{
	if (nicTxGetFreeCmdCount(prAdapter) > (CFG_TX_MAX_CMD_PKT_NUM / 2))
		return TRUE;
	else
		return FALSE;
}

/*----------------------------------------------------------------------------*/
/*!
* \brief this function returns available count in command queue
*
* @param prAdapter      Pointer to the Adapter structure.
*
* @retval
*/
/*----------------------------------------------------------------------------*/
UINT_32 nicTxGetFreeCmdCount(IN P_ADAPTER_T prAdapter)
{
	ASSERT(prAdapter);

	return prAdapter->rFreeCmdList.u4NumElem;
}

/*----------------------------------------------------------------------------*/
/*!
* \brief this function returns page count of frame
*
* @param u4FrameLength      frame length
*
* @retval page count of this frame
*/
/*----------------------------------------------------------------------------*/
UINT_32 nicTxGetPageCount(IN UINT_32 u4FrameLength, IN BOOLEAN fgIncludeDesc)
{
	return halTxGetPageCount(u4FrameLength, fgIncludeDesc);
}

UINT_32 nicTxGetCmdPageCount(IN P_CMD_INFO_T prCmdInfo)
{
	UINT_32 u4PageCount;

	switch (prCmdInfo->eCmdType) {
	case COMMAND_TYPE_NETWORK_IOCTL:
	case COMMAND_TYPE_GENERAL_IOCTL:
		u4PageCount = nicTxGetPageCount(prCmdInfo->u2InfoBufLen, TRUE);
		break;

	case COMMAND_TYPE_SECURITY_FRAME:
	case COMMAND_TYPE_MANAGEMENT_FRAME:
		/* No TxD append field for management packet */
		u4PageCount = nicTxGetPageCount(prCmdInfo->u2InfoBufLen + NIC_TX_DESC_LONG_FORMAT_LENGTH, TRUE);
		break;

	default:
		DBGLOG(INIT, WARN, "Undefined CMD Type(%u)\n", prCmdInfo->eCmdType);
		u4PageCount = nicTxGetPageCount(prCmdInfo->u2InfoBufLen, FALSE);
		break;
	}

	return u4PageCount;
}

VOID nicTxSetMngPacket(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo,
		       UINT_8 ucBssIndex, UINT_8 ucStaRecIndex, UINT_8 ucMacHeaderLength,
		       UINT_16 u2FrameLength, PFN_TX_DONE_HANDLER pfTxDoneHandler, UINT_8 ucRateMode)
{
	ASSERT(prMsduInfo);

	prMsduInfo->ucBssIndex = ucBssIndex;
	prMsduInfo->ucStaRecIndex = ucStaRecIndex;
	prMsduInfo->ucMacHeaderLength = ucMacHeaderLength;
	prMsduInfo->u2FrameLength = u2FrameLength;
	prMsduInfo->pfTxDoneHandler = pfTxDoneHandler;
	prMsduInfo->ucRateMode = ucRateMode;

	/* Reset default value for MMPDU */
	prMsduInfo->fgIs802_11 = TRUE;
	prMsduInfo->fgIs802_1x = FALSE;
	prMsduInfo->fgIs802_1x_NonProtected = TRUE; /*For data frame only, no sense for management frame*/
	prMsduInfo->u4FixedRateOption = 0;
	prMsduInfo->cPowerOffset = 0;
	prMsduInfo->u4Option = 0;
	prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
	prMsduInfo->ucPID = NIC_TX_DESC_PID_RESERVED;
	prMsduInfo->ucPacketType = TX_PACKET_TYPE_MGMT;
	prMsduInfo->ucUserPriority = 0;
	prMsduInfo->eSrc = TX_PACKET_MGMT;
}

VOID nicTxSetDataPacket(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo,
			UINT_8 ucBssIndex, UINT_8 ucStaRecIndex, UINT_8 ucMacHeaderLength,
			UINT_16 u2FrameLength, PFN_TX_DONE_HANDLER pfTxDoneHandler,
			UINT_8 ucRateMode, ENUM_TX_PACKET_SRC_T eSrc, UINT_8 ucTID,
			BOOLEAN fgIs802_11Frame, BOOLEAN fgIs1xFrame)
{
	ASSERT(prMsduInfo);

	prMsduInfo->ucBssIndex = ucBssIndex;
	prMsduInfo->ucStaRecIndex = ucStaRecIndex;
	prMsduInfo->ucMacHeaderLength = ucMacHeaderLength;
	prMsduInfo->u2FrameLength = u2FrameLength;
	prMsduInfo->pfTxDoneHandler = pfTxDoneHandler;
	prMsduInfo->ucRateMode = ucRateMode;
	prMsduInfo->ucUserPriority = ucTID;
	prMsduInfo->fgIs802_11 = fgIs802_11Frame;
	prMsduInfo->eSrc = eSrc;
	prMsduInfo->fgIs802_1x = fgIs1xFrame;

	/* Reset default value for data packet */
	prMsduInfo->u4FixedRateOption = 0;
	prMsduInfo->cPowerOffset = 0;
	prMsduInfo->u4Option = 0;
	prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
	prMsduInfo->ucPID = NIC_TX_DESC_PID_RESERVED;
	prMsduInfo->ucPacketType = TX_PACKET_TYPE_DATA;
}

VOID nicTxFillDescByPktOption(P_MSDU_INFO_T prMsduInfo, P_HW_MAC_TX_DESC_T prTxDesc)
{
	UINT_32 u4PktOption = prMsduInfo->u4Option;
	BOOLEAN fgIsLongFormat;
	BOOLEAN fgProtected = FALSE;

	/* Skip this function if no options is set */
	if (!u4PktOption)
		return;

	fgIsLongFormat = HAL_MAC_TX_DESC_IS_LONG_FORMAT(prTxDesc);

	/* Fields in DW0 and DW1 (Short Format) */
	if (u4PktOption & MSDU_OPT_NO_ACK)
		HAL_MAC_TX_DESC_SET_NO_ACK(prTxDesc);

	if (u4PktOption & MSDU_OPT_PROTECTED_FRAME) {
		/* DBGLOG(RSN, INFO, "MSDU_OPT_PROTECTED_FRAME\n"); */
		HAL_MAC_TX_DESC_SET_PROTECTION(prTxDesc);
		fgProtected = TRUE;
	}

	switch (HAL_MAC_TX_DESC_GET_HEADER_FORMAT(prTxDesc)) {
	case HEADER_FORMAT_802_11_ENHANCE_MODE:
		if (u4PktOption & MSDU_OPT_EOSP)
			HAL_MAC_TX_DESC_SET_EOSP(prTxDesc);

		if (u4PktOption & MSDU_OPT_AMSDU)
			HAL_MAC_TX_DESC_SET_AMSDU(prTxDesc);
		break;

	case HEADER_FORMAT_NON_802_11:
		if (u4PktOption & MSDU_OPT_EOSP)
			HAL_MAC_TX_DESC_SET_EOSP(prTxDesc);

		if (u4PktOption & MSDU_OPT_MORE_DATA)
			HAL_MAC_TX_DESC_SET_MORE_DATA(prTxDesc);

		if (u4PktOption & MSDU_OPT_REMOVE_VLAN)
			HAL_MAC_TX_DESC_SET_REMOVE_VLAN(prTxDesc);
		break;

	case HEADER_FORMAT_802_11_NORMAL_MODE:
		if (fgProtected && prMsduInfo->prPacket) {
			P_WLAN_MAC_HEADER_T prWlanHeader =
			    (P_WLAN_MAC_HEADER_T) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD);

			prWlanHeader->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME;
		}
		break;

	default:
		break;
	}

	if (!fgIsLongFormat)
		return;

	/* Fields in DW2~6 (Long Format) */
	if (u4PktOption & MSDU_OPT_NO_AGGREGATE)
		HAL_MAC_TX_DESC_SET_BA_DISABLE(prTxDesc);

	if (u4PktOption & MSDU_OPT_TIMING_MEASURE)
		HAL_MAC_TX_DESC_SET_TIMING_MEASUREMENT(prTxDesc);

	if (u4PktOption & MSDU_OPT_NDP)
		HAL_MAC_TX_DESC_SET_NDP(prTxDesc);

	if (u4PktOption & MSDU_OPT_NDPA)
		HAL_MAC_TX_DESC_SET_NDPA(prTxDesc);

	if (u4PktOption & MSDU_OPT_SOUNDING)
		HAL_MAC_TX_DESC_SET_SOUNDING_FRAME(prTxDesc);

	if (u4PktOption & MSDU_OPT_FORCE_RTS)
		HAL_MAC_TX_DESC_SET_FORCE_RTS_CTS(prTxDesc);

	if (u4PktOption & MSDU_OPT_BIP)
		HAL_MAC_TX_DESC_SET_BIP(prTxDesc);

	/* SW field */
	if (u4PktOption & MSDU_OPT_SW_DURATION)
		HAL_MAC_TX_DESC_SET_DURATION_CONTROL_BY_SW(prTxDesc);

	if (u4PktOption & MSDU_OPT_SW_PS_BIT)
		HAL_MAC_TX_DESC_SET_SW_PM_CONTROL(prTxDesc);

	if (u4PktOption & MSDU_OPT_SW_HTC)
		HAL_MAC_TX_DESC_SET_HTC_EXIST(prTxDesc);
#if 0
	if (u4PktOption & MSDU_OPT_SW_BAR_SN)
		HAL_MAC_TX_DESC_SET_SW_BAR_SSN(prTxDesc);
#endif
	if (u4PktOption & MSDU_OPT_MANUAL_SN) {
		HAL_MAC_TX_DESC_SET_TXD_SN_VALID(prTxDesc);
		HAL_MAC_TX_DESC_SET_SEQUENCE_NUMBER(prTxDesc, prMsduInfo->u2SwSN);
	}

}

/*----------------------------------------------------------------------------*/
/*!
* @brief Extra configuration for Tx packet
*
* @retval
*/
/*----------------------------------------------------------------------------*/
VOID nicTxConfigPktOption(P_MSDU_INFO_T prMsduInfo, UINT_32 u4OptionMask, BOOLEAN fgSetOption)
{
	if (fgSetOption)
		prMsduInfo->u4Option |= u4OptionMask;
	else
		prMsduInfo->u4Option &= ~u4OptionMask;
}

VOID nicTxFillDescByPktControl(P_MSDU_INFO_T prMsduInfo, P_HW_MAC_TX_DESC_T prTxDesc)
{
	UINT_8 ucPktControl = prMsduInfo->ucControlFlag;
	UINT_8 ucSwReserved;

	/* Skip this function if no options is set */
	if (!ucPktControl)
		return;

	if (HAL_MAC_TX_DESC_IS_LONG_FORMAT(prTxDesc)) {
		ucSwReserved = HAL_MAC_TX_DESC_GET_SW_RESERVED(prTxDesc);

		if (ucPktControl & MSDU_CONTROL_FLAG_FORCE_TX)
			ucSwReserved |= MSDU_CONTROL_FLAG_FORCE_TX;

		HAL_MAC_TX_DESC_SET_SW_RESERVED(prTxDesc, ucSwReserved);
	}
}

VOID nicTxConfigPktControlFlag(P_MSDU_INFO_T prMsduInfo, UINT_8 ucControlFlagMask, BOOLEAN fgSetFlag)
{
	/* Set control flag */
	if (fgSetFlag)
		prMsduInfo->ucControlFlag |= ucControlFlagMask;
	else
		prMsduInfo->ucControlFlag &= ~ucControlFlagMask;	/* Clear control flag */
}

VOID nicTxSetPktLifeTime(P_MSDU_INFO_T prMsduInfo, UINT_32 u4TxLifeTimeInMs)
{
	prMsduInfo->u4RemainingLifetime = u4TxLifeTimeInMs;
	prMsduInfo->u4Option |= MSDU_OPT_MANUAL_LIFE_TIME;
}

VOID nicTxSetPktRetryLimit(P_MSDU_INFO_T prMsduInfo, UINT_8 ucRetryLimit)
{
	prMsduInfo->ucRetryLimit = ucRetryLimit;
	prMsduInfo->u4Option |= MSDU_OPT_MANUAL_RETRY_LIMIT;
}

VOID nicTxSetPktPowerOffset(P_MSDU_INFO_T prMsduInfo, INT_8 cPowerOffset)
{
	prMsduInfo->cPowerOffset = cPowerOffset;
	prMsduInfo->u4Option |= MSDU_OPT_MANUAL_POWER_OFFSET;
}

VOID nicTxSetPktSequenceNumber(P_MSDU_INFO_T prMsduInfo, UINT_16 u2SN)
{
	prMsduInfo->u2SwSN = u2SN;
	prMsduInfo->u4Option |= MSDU_OPT_MANUAL_SN;
}

VOID nicTxSetPktMacTxQue(P_MSDU_INFO_T prMsduInfo, UINT_8 ucMacTxQue)
{
	UINT_8 ucTcIdx;

	for (ucTcIdx = TC0_INDEX; ucTcIdx < TC_NUM; ucTcIdx++) {
		if (arTcResourceControl[ucTcIdx].ucDestQueueIndex == ucMacTxQue)
			break;
	}

	if (ucTcIdx < TC_NUM) {
		prMsduInfo->ucTC = ucTcIdx;
		prMsduInfo->u4Option |= MSDU_OPT_MANUAL_TX_QUE;
	}
}

VOID nicTxSetPktFixedRateOptionFull(P_MSDU_INFO_T prMsduInfo,
				    UINT_16 u2RateCode,
				    UINT_8 ucBandwidth,
				    BOOLEAN fgShortGI,
				    BOOLEAN fgLDPC,
				    BOOLEAN fgDynamicBwRts, BOOLEAN fgBeamforming, UINT_8 ucAntennaIndex)
{
	HW_MAC_TX_DESC_T rTxDesc;
	P_HW_MAC_TX_DESC_T prTxDesc = &rTxDesc;

	kalMemZero(prTxDesc, NIC_TX_DESC_LONG_FORMAT_LENGTH);

	/* Follow the format of Tx descriptor DW 6 */
	HAL_MAC_TX_DESC_SET_FR_RATE(prTxDesc, u2RateCode);

	if (ucBandwidth)
		HAL_MAC_TX_DESC_SET_FR_BW(prTxDesc, ucBandwidth);

	if (fgBeamforming)
		HAL_MAC_TX_DESC_SET_FR_BF(prTxDesc);

	if (fgShortGI)
		HAL_MAC_TX_DESC_SET_FR_SHORT_GI(prTxDesc);

	if (fgLDPC)
		HAL_MAC_TX_DESC_SET_FR_LDPC(prTxDesc);

	if (fgDynamicBwRts)
		HAL_MAC_TX_DESC_SET_FR_DYNAMIC_BW_RTS(prTxDesc);

	HAL_MAC_TX_DESC_SET_FR_ANTENNA_ID(prTxDesc, ucAntennaIndex);

	/* Write back to RateOption of MSDU_INFO */
	HAL_MAC_TX_DESC_GET_DW(prTxDesc, 6, 1, &prMsduInfo->u4FixedRateOption);

	prMsduInfo->ucRateMode = MSDU_RATE_MODE_MANUAL_DESC;

}

VOID nicTxSetPktFixedRateOption(P_MSDU_INFO_T prMsduInfo,
				UINT_16 u2RateCode, UINT_8 ucBandwidth, BOOLEAN fgShortGI, BOOLEAN fgDynamicBwRts)
{
	HW_MAC_TX_DESC_T rTxDesc;
	P_HW_MAC_TX_DESC_T prTxDesc = &rTxDesc;

	kalMemZero(prTxDesc, NIC_TX_DESC_LONG_FORMAT_LENGTH);

	/* Follow the format of Tx descriptor DW 6 */
	HAL_MAC_TX_DESC_SET_FR_RATE(prTxDesc, u2RateCode);

	if (ucBandwidth)
		HAL_MAC_TX_DESC_SET_FR_BW(prTxDesc, ucBandwidth);

	if (fgShortGI)
		HAL_MAC_TX_DESC_SET_FR_SHORT_GI(prTxDesc);

	if (fgDynamicBwRts)
		HAL_MAC_TX_DESC_SET_FR_DYNAMIC_BW_RTS(prTxDesc);

	/* Write back to RateOption of MSDU_INFO */
	HAL_MAC_TX_DESC_GET_DW(prTxDesc, 6, 1, &prMsduInfo->u4FixedRateOption);

	prMsduInfo->ucRateMode = MSDU_RATE_MODE_MANUAL_DESC;

}

VOID nicTxSetPktLowestFixedRate(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo)
{
	P_BSS_INFO_T prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prMsduInfo->ucBssIndex);
	P_STA_RECORD_T prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
	UINT_8 ucRateSwIndex, ucRateIndex, ucRatePreamble;
	UINT_16 u2RateCode, u2RateCodeLimit, u2OperationalRateSet;
	UINT_32 u4CurrentPhyRate, u4Status;

	/* Not to use TxD template for fixed rate */
	prMsduInfo->fgIsTXDTemplateValid = FALSE;

	/* Fixed Rate */
	prMsduInfo->ucRateMode = MSDU_RATE_MODE_MANUAL_DESC;

	if (prStaRec) {
		u2RateCode = prStaRec->u2HwDefaultFixedRateCode;
		u2OperationalRateSet = prStaRec->u2OperationalRateSet;
	} else {
		u2RateCode = prBssInfo->u2HwDefaultFixedRateCode;
		u2OperationalRateSet = prBssInfo->u2OperationalRateSet;
	}

	/* CoexPhyRateLimit is 0 means phy rate is unlimited */
	if (prBssInfo->u4CoexPhyRateLimit != 0) {

		u4CurrentPhyRate = nicRateCode2PhyRate(u2RateCode, FIX_BW_NO_FIXED, MAC_GI_NORMAL, AR_SS_NULL);

		if (prBssInfo->u4CoexPhyRateLimit > u4CurrentPhyRate) {
			nicGetRateIndexFromRateSetWithLimit(
				u2OperationalRateSet,
				prBssInfo->u4CoexPhyRateLimit, TRUE, &ucRateSwIndex);

			/* Convert SW rate index to rate code */
			nicSwIndex2RateIndex(ucRateSwIndex, &ucRateIndex, &ucRatePreamble);
			u4Status = nicRateIndex2RateCode(ucRatePreamble, ucRateIndex, &u2RateCodeLimit);
			if (u4Status == WLAN_STATUS_SUCCESS) {
				/* Replace by limitation rate */
				u2RateCode = u2RateCodeLimit;
				DBGLOG(NIC, INFO, "Coex RatePreamble=%d, R_SW_IDX:%d, R_CODE:0x%x\n",
						ucRatePreamble, ucRateIndex, u2RateCode);
			}
		}
	}
	nicTxSetPktFixedRateOption(prMsduInfo, u2RateCode, FIX_BW_NO_FIXED, FALSE, FALSE);
}

VOID nicTxSetPktMoreData(P_MSDU_INFO_T prCurrentMsduInfo, BOOLEAN fgSetMoreDataBit)
{
	P_WLAN_MAC_HEADER_T prWlanMacHeader = NULL;

	if (prCurrentMsduInfo->fgIs802_11) {
		prWlanMacHeader =
		    (P_WLAN_MAC_HEADER_T) (((PUINT_8) (prCurrentMsduInfo->prPacket)) + MAC_TX_RESERVED_FIELD);
	}

	if (fgSetMoreDataBit) {
		if (!prCurrentMsduInfo->fgIs802_11)
			prCurrentMsduInfo->u4Option |= MSDU_OPT_MORE_DATA;
		else
			prWlanMacHeader->u2FrameCtrl |= MASK_FC_MORE_DATA;
	} else {
		if (!prCurrentMsduInfo->fgIs802_11)
			prCurrentMsduInfo->u4Option &= ~MSDU_OPT_MORE_DATA;
		else
			prWlanMacHeader->u2FrameCtrl &= ~MASK_FC_MORE_DATA;
	}
}

UINT_8 nicTxAssignPID(IN P_ADAPTER_T prAdapter, IN UINT_8 ucWlanIndex)
{
	UINT_8 ucRetval;
	PUINT_8 pucPidPool;

	ASSERT(prAdapter);

	pucPidPool = &prAdapter->aucPidPool[ucWlanIndex];

	ucRetval = *pucPidPool;

	/* Driver side Tx Sequence number: 1~127 */
	(*pucPidPool)++;

	if (*pucPidPool > NIC_TX_DESC_DRIVER_PID_MAX)
		*pucPidPool = NIC_TX_DESC_DRIVER_PID_MIN;

	return ucRetval;
}

VOID nicTxSetPktEOSP(P_MSDU_INFO_T prCurrentMsduInfo, BOOLEAN fgSetEOSPBit)
{
	P_WLAN_MAC_HEADER_QOS_T prWlanMacHeader = NULL;
	BOOLEAN fgWriteToDesc = TRUE;

	if (prCurrentMsduInfo->fgIs802_11) {
		prWlanMacHeader =
		    (P_WLAN_MAC_HEADER_QOS_T) (((PUINT_8) (prCurrentMsduInfo->prPacket)) + MAC_TX_RESERVED_FIELD);
		fgWriteToDesc = FALSE;
	}

	if (fgSetEOSPBit) {
		if (fgWriteToDesc)
			prCurrentMsduInfo->u4Option |= MSDU_OPT_EOSP;
		else
			prWlanMacHeader->u2QosCtrl |= MASK_QC_EOSP;
	} else {
		if (fgWriteToDesc)
			prCurrentMsduInfo->u4Option &= ~MSDU_OPT_EOSP;
		else
			prWlanMacHeader->u2QosCtrl &= ~MASK_QC_EOSP;
	}
}

WLAN_STATUS
nicTxDummyTxDone(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus)
{
	DBGLOG(TX, TRACE, "Msdu WIDX:PID[%u:%u] SEQ[%u] Tx Status[%u]\n",
	       prMsduInfo->ucWlanIndex, prMsduInfo->ucPID, prMsduInfo->ucTxSeqNum, rTxDoneStatus);

	return WLAN_STATUS_SUCCESS;
}

/*----------------------------------------------------------------------------*/
/*!
* @brief Update BSS Tx Params
*
* @param prStaRec The peer
*
* @return (none)
*/
/*----------------------------------------------------------------------------*/
VOID nicTxUpdateBssDefaultRate(P_BSS_INFO_T prBssInfo)
{
	UINT_8 ucLowestBasicRateIndex;

	prBssInfo->u2HwDefaultFixedRateCode = RATE_OFDM_6M;

	/* 4 <1> Find Lowest Basic Rate Index for default TX Rate of MMPDU */
	if (rateGetLowestRateIndexFromRateSet(prBssInfo->u2BSSBasicRateSet, &ucLowestBasicRateIndex)) {
		nicRateIndex2RateCode(PREAMBLE_DEFAULT_LONG_NONE, ucLowestBasicRateIndex,
				      &prBssInfo->u2HwDefaultFixedRateCode);
	} else {
		switch (prBssInfo->ucNonHTBasicPhyType) {
		case PHY_TYPE_ERP_INDEX:
		case PHY_TYPE_OFDM_INDEX:
			prBssInfo->u2HwDefaultFixedRateCode = RATE_OFDM_6M;
			break;

		default:
			prBssInfo->u2HwDefaultFixedRateCode = RATE_CCK_1M_LONG;
			break;
		}
	}
}

/*----------------------------------------------------------------------------*/
/*!
* @brief Update StaRec Tx parameters
*
* @param prStaRec The peer
*
* @return (none)
*/
/*----------------------------------------------------------------------------*/
VOID nicTxUpdateStaRecDefaultRate(P_STA_RECORD_T prStaRec)
{
	UINT_8 ucLowestBasicRateIndex;

	prStaRec->u2HwDefaultFixedRateCode = RATE_OFDM_6M;

	/* 4 <1> Find Lowest Basic Rate Index for default TX Rate of MMPDU */
	if (rateGetLowestRateIndexFromRateSet(prStaRec->u2BSSBasicRateSet, &ucLowestBasicRateIndex)) {
		nicRateIndex2RateCode(PREAMBLE_DEFAULT_LONG_NONE,
				      ucLowestBasicRateIndex, &prStaRec->u2HwDefaultFixedRateCode);
	} else {
		if (prStaRec->ucDesiredPhyTypeSet & PHY_TYPE_SET_802_11B)
			prStaRec->u2HwDefaultFixedRateCode = RATE_CCK_1M_LONG;
		else if (prStaRec->ucDesiredPhyTypeSet & PHY_TYPE_SET_802_11G)
			prStaRec->u2HwDefaultFixedRateCode = RATE_OFDM_6M;
		else if (prStaRec->ucDesiredPhyTypeSet & PHY_TYPE_SET_802_11A)
			prStaRec->u2HwDefaultFixedRateCode = RATE_OFDM_6M;
		else if (prStaRec->ucDesiredPhyTypeSet & PHY_TYPE_SET_802_11N)
			prStaRec->u2HwDefaultFixedRateCode = RATE_MM_MCS_0;
	}
}

VOID nicTxCancelSendingCmd(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo)
{
	halTxCancelSendingCmd(prAdapter, prCmdInfo);
}

