/*
 *************************************************************************
 * Ralink Tech Inc.
 * 5F., No.36, Taiyuan St., Jhubei City,
 * Hsinchu County 302,
 * Taiwan, R.O.C.
 *
 * (c) Copyright 2002-2007, Ralink Technology, Inc.
 *
 * This program is free software; you can redistribute it and/or modify  *
 * it under the terms of the GNU General Public License as published by  *
 * the Free Software Foundation; either version 2 of the License, or     *
 * (at your option) any later version.                                   *
 *                                                                       *
 * 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 the         *
 * GNU General Public License for more details.                          *
 *                                                                       *
 * You should have received a copy of the GNU General Public License     *
 * along with this program; if not, write to the                         *
 * Free Software Foundation, Inc.,                                       *
 * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 *                                                                       *
 *************************************************************************

	Module Name:
	rtmp_data.c

	Abstract:
	Data path subroutines

	Revision History:
	Who 		When			What
	--------	----------		----------------------------------------------
*/
#include "../rt_config.h"
#include <linux/kernel.h>

void STARxEAPOLFrameIndicate(struct rt_rtmp_adapter *pAd,
			     struct rt_mac_table_entry *pEntry,
			     struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID)
{
	PRT28XX_RXD_STRUC pRxD = &(pRxBlk->RxD);
	struct rt_rxwi * pRxWI = pRxBlk->pRxWI;
	u8 *pTmpBuf;

	if (pAd->StaCfg.WpaSupplicantUP) {
		/* All EAPoL frames have to pass to upper layer (ex. WPA_SUPPLICANT daemon) */
		/* TBD : process fragmented EAPol frames */
		{
			/* In 802.1x mode, if the received frame is EAP-SUCCESS packet, turn on the PortSecured variable */
			if (pAd->StaCfg.IEEE8021X == TRUE &&
			    (EAP_CODE_SUCCESS ==
			     WpaCheckEapCode(pAd, pRxBlk->pData,
					     pRxBlk->DataSize,
					     LENGTH_802_1_H))) {
				u8 *Key;
				u8 CipherAlg;
				int idx = 0;

				DBGPRINT_RAW(RT_DEBUG_TRACE,
					     ("Receive EAP-SUCCESS Packet\n"));
				/*pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; */
				STA_PORT_SECURED(pAd);

				if (pAd->StaCfg.IEEE8021x_required_keys ==
				    FALSE) {
					idx = pAd->StaCfg.DesireSharedKeyId;
					CipherAlg =
					    pAd->StaCfg.DesireSharedKey[idx].
					    CipherAlg;
					Key =
					    pAd->StaCfg.DesireSharedKey[idx].
					    Key;

					if (pAd->StaCfg.DesireSharedKey[idx].
					    KeyLen > 0) {
#ifdef RTMP_MAC_PCI
						struct rt_mac_table_entry *pEntry =
						    &pAd->MacTab.
						    Content[BSSID_WCID];

						/* Set key material and cipherAlg to Asic */
						AsicAddSharedKeyEntry(pAd, BSS0,
								      idx,
								      CipherAlg,
								      Key, NULL,
								      NULL);

						/* Assign group key info */
						RTMPAddWcidAttributeEntry(pAd,
									  BSS0,
									  idx,
									  CipherAlg,
									  NULL);

						/* Assign pairwise key info */
						RTMPAddWcidAttributeEntry(pAd,
									  BSS0,
									  idx,
									  CipherAlg,
									  pEntry);

						pAd->IndicateMediaState =
						    NdisMediaStateConnected;
						pAd->ExtraInfo =
						    GENERAL_LINK_UP;
#endif /* RTMP_MAC_PCI // */
#ifdef RTMP_MAC_USB
						union {
							char buf[sizeof
								 (struct rt_ndis_802_11_wep)
								 +
								 MAX_LEN_OF_KEY
								 - 1];
							struct rt_ndis_802_11_wep keyinfo;
						}
						WepKey;
						int len;

						NdisZeroMemory(&WepKey,
							       sizeof(WepKey));
						len =
						    pAd->StaCfg.
						    DesireSharedKey[idx].KeyLen;

						NdisMoveMemory(WepKey.keyinfo.
							       KeyMaterial,
							       pAd->StaCfg.
							       DesireSharedKey
							       [idx].Key,
							       pAd->StaCfg.
							       DesireSharedKey
							       [idx].KeyLen);

						WepKey.keyinfo.KeyIndex =
						    0x80000000 + idx;
						WepKey.keyinfo.KeyLength = len;
						pAd->SharedKey[BSS0][idx].
						    KeyLen =
						    (u8)(len <= 5 ? 5 : 13);

						pAd->IndicateMediaState =
						    NdisMediaStateConnected;
						pAd->ExtraInfo =
						    GENERAL_LINK_UP;
						/* need to enqueue cmd to thread */
						RTUSBEnqueueCmdFromNdis(pAd,
									OID_802_11_ADD_WEP,
									TRUE,
									&WepKey,
									sizeof
									(WepKey.
									 keyinfo)
									+ len -
									1);
#endif /* RTMP_MAC_USB // */
						/* For Preventing ShardKey Table is cleared by remove key procedure. */
						pAd->SharedKey[BSS0][idx].
						    CipherAlg = CipherAlg;
						pAd->SharedKey[BSS0][idx].
						    KeyLen =
						    pAd->StaCfg.
						    DesireSharedKey[idx].KeyLen;
						NdisMoveMemory(pAd->
							       SharedKey[BSS0]
							       [idx].Key,
							       pAd->StaCfg.
							       DesireSharedKey
							       [idx].Key,
							       pAd->StaCfg.
							       DesireSharedKey
							       [idx].KeyLen);
					}
				}
			}

			Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);
			return;
		}
	} else {
		/* Special DATA frame that has to pass to MLME */
		/*       1. Cisco Aironet frames for CCX2. We need pass it to MLME for special process */
		/*       2. EAPOL handshaking frames when driver supplicant enabled, pass to MLME for special process */
		{
			pTmpBuf = pRxBlk->pData - LENGTH_802_11;
			NdisMoveMemory(pTmpBuf, pRxBlk->pHeader, LENGTH_802_11);
			REPORT_MGMT_FRAME_TO_MLME(pAd, pRxWI->WirelessCliID,
						  pTmpBuf,
						  pRxBlk->DataSize +
						  LENGTH_802_11, pRxWI->RSSI0,
						  pRxWI->RSSI1, pRxWI->RSSI2,
						  pRxD->PlcpSignal);
			DBGPRINT_RAW(RT_DEBUG_TRACE,
				     ("report EAPOL/AIRONET DATA to MLME (len=%d) !\n",
				      pRxBlk->DataSize));
		}
	}

	RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
	return;

}

void STARxDataFrameAnnounce(struct rt_rtmp_adapter *pAd,
			    struct rt_mac_table_entry *pEntry,
			    struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID)
{

	/* non-EAP frame */
	if (!RTMPCheckWPAframe
	    (pAd, pEntry, pRxBlk->pData, pRxBlk->DataSize, FromWhichBSSID)) {

		{
			/* drop all non-EAP DATA frame before */
			/* this client's Port-Access-Control is secured */
			if (pRxBlk->pHeader->FC.Wep) {
				/* unsupported cipher suite */
				if (pAd->StaCfg.WepStatus ==
				    Ndis802_11EncryptionDisabled) {
					/* release packet */
					RELEASE_NDIS_PACKET(pAd,
							    pRxBlk->pRxPacket,
							    NDIS_STATUS_FAILURE);
					return;
				}
			} else {
				/* encryption in-use but receive a non-EAPOL clear text frame, drop it */
				if ((pAd->StaCfg.WepStatus !=
				     Ndis802_11EncryptionDisabled)
				    && (pAd->StaCfg.PortSecured ==
					WPA_802_1X_PORT_NOT_SECURED)) {
					/* release packet */
					RELEASE_NDIS_PACKET(pAd,
							    pRxBlk->pRxPacket,
							    NDIS_STATUS_FAILURE);
					return;
				}
			}
		}
		RX_BLK_CLEAR_FLAG(pRxBlk, fRX_EAP);
		if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_ARALINK)) {
			/* Normal legacy, AMPDU or AMSDU */
			CmmRxnonRalinkFrameIndicate(pAd, pRxBlk,
						    FromWhichBSSID);

		} else {
			/* ARALINK */
			CmmRxRalinkFrameIndicate(pAd, pEntry, pRxBlk,
						 FromWhichBSSID);
		}
	} else {
		RX_BLK_SET_FLAG(pRxBlk, fRX_EAP);

		if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMPDU)
		    && (pAd->CommonCfg.bDisableReordering == 0)) {
			Indicate_AMPDU_Packet(pAd, pRxBlk, FromWhichBSSID);
		} else {
			/* Determin the destination of the EAP frame */
			/*  to WPA state machine or upper layer */
			STARxEAPOLFrameIndicate(pAd, pEntry, pRxBlk,
						FromWhichBSSID);
		}
	}
}

/* For TKIP frame, calculate the MIC value */
BOOLEAN STACheckTkipMICValue(struct rt_rtmp_adapter *pAd,
			     struct rt_mac_table_entry *pEntry, struct rt_rx_blk *pRxBlk)
{
	struct rt_header_802_11 * pHeader = pRxBlk->pHeader;
	u8 *pData = pRxBlk->pData;
	u16 DataSize = pRxBlk->DataSize;
	u8 UserPriority = pRxBlk->UserPriority;
	struct rt_cipher_key *pWpaKey;
	u8 *pDA, *pSA;

	pWpaKey = &pAd->SharedKey[BSS0][pRxBlk->pRxWI->KeyIndex];

	pDA = pHeader->Addr1;
	if (RX_BLK_TEST_FLAG(pRxBlk, fRX_INFRA)) {
		pSA = pHeader->Addr3;
	} else {
		pSA = pHeader->Addr2;
	}

	if (RTMPTkipCompareMICValue(pAd,
				    pData,
				    pDA,
				    pSA,
				    pWpaKey->RxMic,
				    UserPriority, DataSize) == FALSE) {
		DBGPRINT_RAW(RT_DEBUG_ERROR, ("Rx MIC Value error 2\n"));

		if (pAd->StaCfg.WpaSupplicantUP) {
			WpaSendMicFailureToWpaSupplicant(pAd,
							 (pWpaKey->Type ==
							  PAIRWISEKEY) ? TRUE :
							 FALSE);
		} else {
			RTMPReportMicError(pAd, pWpaKey);
		}

		/* release packet */
		RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket,
				    NDIS_STATUS_FAILURE);
		return FALSE;
	}

	return TRUE;
}

/* */
/* All Rx routines use struct rt_rx_blk structure to hande rx events */
/* It is very important to build pRxBlk attributes */
/*  1. pHeader pointer to 802.11 Header */
/*  2. pData pointer to payload including LLC (just skip Header) */
/*  3. set payload size including LLC to DataSize */
/*  4. set some flags with RX_BLK_SET_FLAG() */
/* */
void STAHandleRxDataFrame(struct rt_rtmp_adapter *pAd, struct rt_rx_blk *pRxBlk)
{
	PRT28XX_RXD_STRUC pRxD = &(pRxBlk->RxD);
	struct rt_rxwi * pRxWI = pRxBlk->pRxWI;
	struct rt_header_802_11 * pHeader = pRxBlk->pHeader;
	void *pRxPacket = pRxBlk->pRxPacket;
	BOOLEAN bFragment = FALSE;
	struct rt_mac_table_entry *pEntry = NULL;
	u8 FromWhichBSSID = BSS0;
	u8 UserPriority = 0;

	{
		/* before LINK UP, all DATA frames are rejected */
		if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) {
			/* release packet */
			RELEASE_NDIS_PACKET(pAd, pRxPacket,
					    NDIS_STATUS_FAILURE);
			return;
		}
		/* Drop not my BSS frames */
		if (pRxD->MyBss == 0) {
			{
				/* release packet */
				RELEASE_NDIS_PACKET(pAd, pRxPacket,
						    NDIS_STATUS_FAILURE);
				return;
			}
		}

		pAd->RalinkCounters.RxCountSinceLastNULL++;
		if (pAd->CommonCfg.bAPSDCapable
		    && pAd->CommonCfg.APEdcaParm.bAPSDCapable
		    && (pHeader->FC.SubType & 0x08)) {
			u8 *pData;
			DBGPRINT(RT_DEBUG_INFO, ("bAPSDCapable\n"));

			/* Qos bit 4 */
			pData = (u8 *)pHeader + LENGTH_802_11;
			if ((*pData >> 4) & 0x01) {
				DBGPRINT(RT_DEBUG_INFO,
					 ("RxDone- Rcv EOSP frame, driver may fall into sleep\n"));
				pAd->CommonCfg.bInServicePeriod = FALSE;

				/* Force driver to fall into sleep mode when rcv EOSP frame */
				if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) {
					u16 TbttNumToNextWakeUp;
					u16 NextDtim =
					    pAd->StaCfg.DtimPeriod;
					unsigned long Now;

					NdisGetSystemUpTime(&Now);
					NextDtim -=
					    (u16)(Now -
						      pAd->StaCfg.
						      LastBeaconRxTime) /
					    pAd->CommonCfg.BeaconPeriod;

					TbttNumToNextWakeUp =
					    pAd->StaCfg.DefaultListenCount;
					if (OPSTATUS_TEST_FLAG
					    (pAd, fOP_STATUS_RECEIVE_DTIM)
					    && (TbttNumToNextWakeUp > NextDtim))
						TbttNumToNextWakeUp = NextDtim;

					RTMP_SET_PSM_BIT(pAd, PWR_SAVE);
					/* if WMM-APSD is failed, try to disable following line */
					AsicSleepThenAutoWakeup(pAd,
								TbttNumToNextWakeUp);
				}
			}

			if ((pHeader->FC.MoreData)
			    && (pAd->CommonCfg.bInServicePeriod)) {
				DBGPRINT(RT_DEBUG_TRACE,
					 ("Sending another trigger frame when More Data bit is set to 1\n"));
			}
		}
		/* Drop NULL, CF-ACK(no data), CF-POLL(no data), and CF-ACK+CF-POLL(no data) data frame */
		if ((pHeader->FC.SubType & 0x04))	/* bit 2 : no DATA */
		{
			/* release packet */
			RELEASE_NDIS_PACKET(pAd, pRxPacket,
					    NDIS_STATUS_FAILURE);
			return;
		}
		/* Drop not my BSS frame (we can not only check the MyBss bit in RxD) */

		if (INFRA_ON(pAd)) {
			/* Infrastructure mode, check address 2 for BSSID */
			if (!RTMPEqualMemory
			    (&pHeader->Addr2, &pAd->CommonCfg.Bssid, 6)) {
				/* Receive frame not my BSSID */
				/* release packet */
				RELEASE_NDIS_PACKET(pAd, pRxPacket,
						    NDIS_STATUS_FAILURE);
				return;
			}
		} else		/* Ad-Hoc mode or Not associated */
		{
			/* Ad-Hoc mode, check address 3 for BSSID */
			if (!RTMPEqualMemory
			    (&pHeader->Addr3, &pAd->CommonCfg.Bssid, 6)) {
				/* Receive frame not my BSSID */
				/* release packet */
				RELEASE_NDIS_PACKET(pAd, pRxPacket,
						    NDIS_STATUS_FAILURE);
				return;
			}
		}

		/* */
		/* find pEntry */
		/* */
		if (pRxWI->WirelessCliID < MAX_LEN_OF_MAC_TABLE) {
			pEntry = &pAd->MacTab.Content[pRxWI->WirelessCliID];
		} else {
			/* 1. release packet if infra mode */
			/* 2. new a pEntry if ad-hoc mode */
			RELEASE_NDIS_PACKET(pAd, pRxPacket,
					    NDIS_STATUS_FAILURE);
			return;
		}

		/* infra or ad-hoc */
		if (INFRA_ON(pAd)) {
			RX_BLK_SET_FLAG(pRxBlk, fRX_INFRA);
			ASSERT(pRxWI->WirelessCliID == BSSID_WCID);
		}
		/* check Atheros Client */
		if ((pEntry->bIAmBadAtheros == FALSE) && (pRxD->AMPDU == 1)
		    && (pHeader->FC.Retry)) {
			pEntry->bIAmBadAtheros = TRUE;
			pAd->CommonCfg.IOTestParm.bCurrentAtheros = TRUE;
			pAd->CommonCfg.IOTestParm.bLastAtheros = TRUE;
			if (!STA_AES_ON(pAd)) {
				AsicUpdateProtect(pAd, 8, ALLN_SETPROTECT, TRUE,
						  FALSE);
			}
		}
	}

	pRxBlk->pData = (u8 *) pHeader;

	/* */
	/* update RxBlk->pData, DataSize */
	/* 802.11 Header, QOS, HTC, Hw Padding */
	/* */

	/* 1. skip 802.11 HEADER */
	{
		pRxBlk->pData += LENGTH_802_11;
		pRxBlk->DataSize -= LENGTH_802_11;
	}

	/* 2. QOS */
	if (pHeader->FC.SubType & 0x08) {
		RX_BLK_SET_FLAG(pRxBlk, fRX_QOS);
		UserPriority = *(pRxBlk->pData) & 0x0f;
		/* bit 7 in QoS Control field signals the HT A-MSDU format */
		if ((*pRxBlk->pData) & 0x80) {
			RX_BLK_SET_FLAG(pRxBlk, fRX_AMSDU);
		}
		/* skip QOS contorl field */
		pRxBlk->pData += 2;
		pRxBlk->DataSize -= 2;
	}
	pRxBlk->UserPriority = UserPriority;

	/* check if need to resend PS Poll when received packet with MoreData = 1 */
	if ((pAd->StaCfg.Psm == PWR_SAVE) && (pHeader->FC.MoreData == 1)) {
		if ((((UserPriority == 0) || (UserPriority == 3)) &&
		     pAd->CommonCfg.bAPSDAC_BE == 0) ||
		    (((UserPriority == 1) || (UserPriority == 2)) &&
		     pAd->CommonCfg.bAPSDAC_BK == 0) ||
		    (((UserPriority == 4) || (UserPriority == 5)) &&
		     pAd->CommonCfg.bAPSDAC_VI == 0) ||
		    (((UserPriority == 6) || (UserPriority == 7)) &&
		     pAd->CommonCfg.bAPSDAC_VO == 0)) {
			/* non-UAPSD delivery-enabled AC */
			RTMP_PS_POLL_ENQUEUE(pAd);
		}
	}
	/* 3. Order bit: A-Ralink or HTC+ */
	if (pHeader->FC.Order) {
#ifdef AGGREGATION_SUPPORT
		if ((pRxWI->PHYMODE <= MODE_OFDM)
		    && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED)))
		{
			RX_BLK_SET_FLAG(pRxBlk, fRX_ARALINK);
		} else
#endif /* AGGREGATION_SUPPORT // */
		{
			RX_BLK_SET_FLAG(pRxBlk, fRX_HTC);
			/* skip HTC contorl field */
			pRxBlk->pData += 4;
			pRxBlk->DataSize -= 4;
		}
	}
	/* 4. skip HW padding */
	if (pRxD->L2PAD) {
		/* just move pData pointer */
		/* because DataSize excluding HW padding */
		RX_BLK_SET_FLAG(pRxBlk, fRX_PAD);
		pRxBlk->pData += 2;
	}

	if (pRxD->BA) {
		RX_BLK_SET_FLAG(pRxBlk, fRX_AMPDU);
	}
	/* */
	/* Case I  Process Broadcast & Multicast data frame */
	/* */
	if (pRxD->Bcast || pRxD->Mcast) {
		INC_COUNTER64(pAd->WlanCounters.MulticastReceivedFrameCount);

		/* Drop Mcast/Bcast frame with fragment bit on */
		if (pHeader->FC.MoreFrag) {
			/* release packet */
			RELEASE_NDIS_PACKET(pAd, pRxPacket,
					    NDIS_STATUS_FAILURE);
			return;
		}
		/* Filter out Bcast frame which AP relayed for us */
		if (pHeader->FC.FrDs
		    && MAC_ADDR_EQUAL(pHeader->Addr3, pAd->CurrentAddress)) {
			/* release packet */
			RELEASE_NDIS_PACKET(pAd, pRxPacket,
					    NDIS_STATUS_FAILURE);
			return;
		}

		Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);
		return;
	} else if (pRxD->U2M) {
		pAd->LastRxRate =
		    (u16)((pRxWI->MCS) + (pRxWI->BW << 7) +
			      (pRxWI->ShortGI << 8) + (pRxWI->PHYMODE << 14));

		if (ADHOC_ON(pAd)) {
			pEntry = MacTableLookup(pAd, pHeader->Addr2);
			if (pEntry)
				Update_Rssi_Sample(pAd, &pEntry->RssiSample,
						   pRxWI);
		}

		Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, pRxWI);

		pAd->StaCfg.LastSNR0 = (u8)(pRxWI->SNR0);
		pAd->StaCfg.LastSNR1 = (u8)(pRxWI->SNR1);

		pAd->RalinkCounters.OneSecRxOkDataCnt++;

		if (!((pHeader->Frag == 0) && (pHeader->FC.MoreFrag == 0))) {
			/* re-assemble the fragmented packets */
			/* return complete frame (pRxPacket) or NULL */
			bFragment = TRUE;
			pRxPacket = RTMPDeFragmentDataFrame(pAd, pRxBlk);
		}

		if (pRxPacket) {
			pEntry = &pAd->MacTab.Content[pRxWI->WirelessCliID];

			/* process complete frame */
			if (bFragment && (pRxD->Decrypted)
			    && (pEntry->WepStatus ==
				Ndis802_11Encryption2Enabled)) {
				/* Minus MIC length */
				pRxBlk->DataSize -= 8;

				/* For TKIP frame, calculate the MIC value */
				if (STACheckTkipMICValue(pAd, pEntry, pRxBlk) ==
				    FALSE) {
					return;
				}
			}

			STARxDataFrameAnnounce(pAd, pEntry, pRxBlk,
					       FromWhichBSSID);
			return;
		} else {
			/* just return */
			/* because RTMPDeFragmentDataFrame() will release rx packet, */
			/* if packet is fragmented */
			return;
		}
	}

	ASSERT(0);
	/* release packet */
	RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
}

void STAHandleRxMgmtFrame(struct rt_rtmp_adapter *pAd, struct rt_rx_blk *pRxBlk)
{
	PRT28XX_RXD_STRUC pRxD = &(pRxBlk->RxD);
	struct rt_rxwi * pRxWI = pRxBlk->pRxWI;
	struct rt_header_802_11 * pHeader = pRxBlk->pHeader;
	void *pRxPacket = pRxBlk->pRxPacket;

	do {

		/* check if need to resend PS Poll when received packet with MoreData = 1 */
		if ((pAd->StaCfg.Psm == PWR_SAVE)
		    && (pHeader->FC.MoreData == 1)) {
			/* for UAPSD, all management frames will be VO priority */
			if (pAd->CommonCfg.bAPSDAC_VO == 0) {
				/* non-UAPSD delivery-enabled AC */
				RTMP_PS_POLL_ENQUEUE(pAd);
			}
		}

		/* TODO: if MoreData == 0, station can go to sleep */

		/* We should collect RSSI not only U2M data but also my beacon */
		if ((pHeader->FC.SubType == SUBTYPE_BEACON)
		    && (MAC_ADDR_EQUAL(&pAd->CommonCfg.Bssid, &pHeader->Addr2))
		    && (pAd->RxAnt.EvaluatePeriod == 0)) {
			Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, pRxWI);

			pAd->StaCfg.LastSNR0 = (u8)(pRxWI->SNR0);
			pAd->StaCfg.LastSNR1 = (u8)(pRxWI->SNR1);
		}

		/* First check the size, it MUST not exceed the mlme queue size */
		if (pRxWI->MPDUtotalByteCount > MGMT_DMA_BUFFER_SIZE) {
			DBGPRINT_ERR(("STAHandleRxMgmtFrame: frame too large, size = %d \n", pRxWI->MPDUtotalByteCount));
			break;
		}

		REPORT_MGMT_FRAME_TO_MLME(pAd, pRxWI->WirelessCliID, pHeader,
					  pRxWI->MPDUtotalByteCount,
					  pRxWI->RSSI0, pRxWI->RSSI1,
					  pRxWI->RSSI2, pRxD->PlcpSignal);
	} while (FALSE);

	RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_SUCCESS);
}

void STAHandleRxControlFrame(struct rt_rtmp_adapter *pAd, struct rt_rx_blk *pRxBlk)
{
	struct rt_rxwi * pRxWI = pRxBlk->pRxWI;
	struct rt_header_802_11 * pHeader = pRxBlk->pHeader;
	void *pRxPacket = pRxBlk->pRxPacket;

	switch (pHeader->FC.SubType) {
	case SUBTYPE_BLOCK_ACK_REQ:
		{
			CntlEnqueueForRecv(pAd, pRxWI->WirelessCliID,
					   (pRxWI->MPDUtotalByteCount),
					   (struct rt_frame_ba_req *) pHeader);
		}
		break;
	case SUBTYPE_BLOCK_ACK:
	case SUBTYPE_ACK:
	default:
		break;
	}

	RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
}

/*
	========================================================================

	Routine Description:
		Process RxDone interrupt, running in DPC level

	Arguments:
		pAd Pointer to our adapter

	Return Value:
		None

	IRQL = DISPATCH_LEVEL

	Note:
		This routine has to maintain Rx ring read pointer.
		Need to consider QOS DATA format when converting to 802.3
	========================================================================
*/
BOOLEAN STARxDoneInterruptHandle(struct rt_rtmp_adapter *pAd, IN BOOLEAN argc)
{
	int Status;
	u32 RxProcessed, RxPending;
	BOOLEAN bReschedule = FALSE;
	PRT28XX_RXD_STRUC pRxD;
	u8 *pData;
	struct rt_rxwi * pRxWI;
	void *pRxPacket;
	struct rt_header_802_11 * pHeader;
	struct rt_rx_blk RxCell;

	RxProcessed = RxPending = 0;

	/* process whole rx ring */
	while (1) {

		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF |
				   fRTMP_ADAPTER_RESET_IN_PROGRESS |
				   fRTMP_ADAPTER_HALT_IN_PROGRESS |
				   fRTMP_ADAPTER_NIC_NOT_EXIST) ||
		    !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP)) {
			break;
		}
#ifdef RTMP_MAC_PCI
		if (RxProcessed++ > MAX_RX_PROCESS_CNT) {
			/* need to reschedule rx handle */
			bReschedule = TRUE;
			break;
		}
#endif /* RTMP_MAC_PCI // */

		RxProcessed++;	/* test */

		/* 1. allocate a new data packet into rx ring to replace received packet */
		/*    then processing the received packet */
		/* 2. the callee must take charge of release of packet */
		/* 3. As far as driver is concerned , */
		/*    the rx packet must */
		/*      a. be indicated to upper layer or */
		/*      b. be released if it is discarded */
		pRxPacket =
		    GetPacketFromRxRing(pAd, &(RxCell.RxD), &bReschedule,
					&RxPending);
		if (pRxPacket == NULL) {
			/* no more packet to process */
			break;
		}
		/* get rx ring descriptor */
		pRxD = &(RxCell.RxD);
		/* get rx data buffer */
		pData = GET_OS_PKT_DATAPTR(pRxPacket);
		pRxWI = (struct rt_rxwi *) pData;
		pHeader = (struct rt_header_802_11 *) (pData + RXWI_SIZE);

		/* build RxCell */
		RxCell.pRxWI = pRxWI;
		RxCell.pHeader = pHeader;
		RxCell.pRxPacket = pRxPacket;
		RxCell.pData = (u8 *) pHeader;
		RxCell.DataSize = pRxWI->MPDUtotalByteCount;
		RxCell.Flags = 0;

		/* Increase Total receive byte counter after real data received no mater any error or not */
		pAd->RalinkCounters.ReceivedByteCount +=
		    pRxWI->MPDUtotalByteCount;
		pAd->RalinkCounters.OneSecReceivedByteCount +=
		    pRxWI->MPDUtotalByteCount;
		pAd->RalinkCounters.RxCount++;

		INC_COUNTER64(pAd->WlanCounters.ReceivedFragmentCount);

		if (pRxWI->MPDUtotalByteCount < 14)
			Status = NDIS_STATUS_FAILURE;

		if (MONITOR_ON(pAd)) {
			send_monitor_packets(pAd, &RxCell);
			break;
		}

		/* STARxDoneInterruptHandle() is called in rtusb_bulk.c */

		/* Check for all RxD errors */
		Status = RTMPCheckRxError(pAd, pHeader, pRxWI, pRxD);

		/* Handle the received frame */
		if (Status == NDIS_STATUS_SUCCESS) {
			switch (pHeader->FC.Type) {
				/* CASE I, receive a DATA frame */
			case BTYPE_DATA:
				{
					/* process DATA frame */
					STAHandleRxDataFrame(pAd, &RxCell);
				}
				break;
				/* CASE II, receive a MGMT frame */
			case BTYPE_MGMT:
				{
					STAHandleRxMgmtFrame(pAd, &RxCell);
				}
				break;
				/* CASE III. receive a CNTL frame */
			case BTYPE_CNTL:
				{
					STAHandleRxControlFrame(pAd, &RxCell);
				}
				break;
				/* discard other type */
			default:
				RELEASE_NDIS_PACKET(pAd, pRxPacket,
						    NDIS_STATUS_FAILURE);
				break;
			}
		} else {
			pAd->Counters8023.RxErrors++;
			/* discard this frame */
			RELEASE_NDIS_PACKET(pAd, pRxPacket,
					    NDIS_STATUS_FAILURE);
		}
	}

	return bReschedule;
}

/*
	========================================================================

	Routine Description:
	Arguments:
		pAd 	Pointer to our adapter

	IRQL = DISPATCH_LEVEL

	========================================================================
*/
void RTMPHandleTwakeupInterrupt(struct rt_rtmp_adapter *pAd)
{
	AsicForceWakeup(pAd, FALSE);
}

/*
========================================================================
Routine Description:
    Early checking and OS-depened parsing for Tx packet send to our STA driver.

Arguments:
    void *	MiniportAdapterContext	Pointer refer to the device handle, i.e., the pAd.
	void **	ppPacketArray			The packet array need to do transmission.
	u32			NumberOfPackets			Number of packet in packet array.

Return Value:
	NONE

Note:
	This function do early checking and classification for send-out packet.
	You only can put OS-depened & STA related code in here.
========================================================================
*/
void STASendPackets(void *MiniportAdapterContext,
		    void **ppPacketArray, u32 NumberOfPackets)
{
	u32 Index;
	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)MiniportAdapterContext;
	void *pPacket;
	BOOLEAN allowToSend = FALSE;

	for (Index = 0; Index < NumberOfPackets; Index++) {
		pPacket = ppPacketArray[Index];

		do {
			if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)
			    || RTMP_TEST_FLAG(pAd,
					      fRTMP_ADAPTER_HALT_IN_PROGRESS)
			    || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) {
				/* Drop send request since hardware is in reset state */
				break;
			} else if (!INFRA_ON(pAd) && !ADHOC_ON(pAd)) {
				/* Drop send request since there are no physical connection yet */
				break;
			} else {
				/* Record that orignal packet source is from NDIS layer,so that */
				/* later on driver knows how to release this NDIS PACKET */
				RTMP_SET_PACKET_WCID(pPacket, 0);	/* this field is useless when in STA mode */
				RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
				NDIS_SET_PACKET_STATUS(pPacket,
						       NDIS_STATUS_PENDING);
				pAd->RalinkCounters.PendingNdisPacketCount++;

				allowToSend = TRUE;
			}
		} while (FALSE);

		if (allowToSend == TRUE)
			STASendPacket(pAd, pPacket);
		else
			RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
	}

	/* Dequeue outgoing frames from TxSwQueue[] and process it */
	RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);

}

/*
========================================================================
Routine Description:
	This routine is used to do packet parsing and classification for Tx packet
	to STA device, and it will en-queue packets to our TxSwQueue depends on AC
	class.

Arguments:
	pAd    		Pointer to our adapter
	pPacket 	Pointer to send packet

Return Value:
	NDIS_STATUS_SUCCESS			If success to queue the packet into TxSwQueue.
	NDIS_STATUS_FAILURE			If failed to do en-queue.

Note:
	You only can put OS-indepened & STA related code in here.
========================================================================
*/
int STASendPacket(struct rt_rtmp_adapter *pAd, void *pPacket)
{
	struct rt_packet_info PacketInfo;
	u8 *pSrcBufVA;
	u32 SrcBufLen;
	u32 AllowFragSize;
	u8 NumberOfFrag;
	u8 RTSRequired;
	u8 QueIdx, UserPriority;
	struct rt_mac_table_entry *pEntry = NULL;
	unsigned int IrqFlags;
	u8 FlgIsIP = 0;
	u8 Rate;

	/* Prepare packet information structure for buffer descriptor */
	/* chained within a single NDIS packet. */
	RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);

	if (pSrcBufVA == NULL) {
		DBGPRINT(RT_DEBUG_ERROR,
			 ("STASendPacket --> pSrcBufVA == NULL !SrcBufLen=%x\n",
			  SrcBufLen));
		/* Resourece is low, system did not allocate virtual address */
		/* return NDIS_STATUS_FAILURE directly to upper layer */
		RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
		return NDIS_STATUS_FAILURE;
	}

	if (SrcBufLen < 14) {
		DBGPRINT(RT_DEBUG_ERROR,
			 ("STASendPacket --> Ndis Packet buffer error!\n"));
		RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
		return (NDIS_STATUS_FAILURE);
	}
	/* In HT rate adhoc mode, A-MPDU is often used. So need to lookup BA Table and MAC Entry. */
	/* Note multicast packets in adhoc also use BSSID_WCID index. */
	{
		if (INFRA_ON(pAd)) {
			{
				pEntry = &pAd->MacTab.Content[BSSID_WCID];
				RTMP_SET_PACKET_WCID(pPacket, BSSID_WCID);
				Rate = pAd->CommonCfg.TxRate;
			}
		} else if (ADHOC_ON(pAd)) {
			if (*pSrcBufVA & 0x01) {
				RTMP_SET_PACKET_WCID(pPacket, MCAST_WCID);
				pEntry = &pAd->MacTab.Content[MCAST_WCID];
			} else {
				pEntry = MacTableLookup(pAd, pSrcBufVA);
			}
			Rate = pAd->CommonCfg.TxRate;
		}
	}

	if (!pEntry) {
		DBGPRINT(RT_DEBUG_ERROR,
			("STASendPacket->Cannot find pEntry(%pM) in MacTab!\n",
				pSrcBufVA));
		/* Resourece is low, system did not allocate virtual address */
		/* return NDIS_STATUS_FAILURE directly to upper layer */
		RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
		return NDIS_STATUS_FAILURE;
	}

	if (ADHOC_ON(pAd)
	    ) {
		RTMP_SET_PACKET_WCID(pPacket, (u8)pEntry->Aid);
	}
	/* */
	/* Check the Ethernet Frame type of this packet, and set the RTMP_SET_PACKET_SPECIFIC flags. */
	/*              Here we set the PACKET_SPECIFIC flags(LLC, VLAN, DHCP/ARP, EAPOL). */
	RTMPCheckEtherType(pAd, pPacket);

	/* */
	/* WPA 802.1x secured port control - drop all non-802.1x frame before port secured */
	/* */
	if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
	     (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
	     (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
	     (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
	     || (pAd->StaCfg.IEEE8021X == TRUE)
	    )
	    && ((pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED)
		|| (pAd->StaCfg.MicErrCnt >= 2))
	    && (RTMP_GET_PACKET_EAPOL(pPacket) == FALSE)
	    ) {
		DBGPRINT(RT_DEBUG_TRACE,
			 ("STASendPacket --> Drop packet before port secured!\n"));
		RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);

		return (NDIS_STATUS_FAILURE);
	}

	/* STEP 1. Decide number of fragments required to deliver this MSDU. */
	/*         The estimation here is not very accurate because difficult to */
	/*         take encryption overhead into consideration here. The result */
	/*         "NumberOfFrag" is then just used to pre-check if enough free */
	/*         TXD are available to hold this MSDU. */

	if (*pSrcBufVA & 0x01)	/* fragmentation not allowed on multicast & broadcast */
		NumberOfFrag = 1;
	else if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED))
		NumberOfFrag = 1;	/* Aggregation overwhelms fragmentation */
	else if (CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_AMSDU_INUSED))
		NumberOfFrag = 1;	/* Aggregation overwhelms fragmentation */
	else if ((pAd->StaCfg.HTPhyMode.field.MODE == MODE_HTMIX)
		 || (pAd->StaCfg.HTPhyMode.field.MODE == MODE_HTGREENFIELD))
		NumberOfFrag = 1;	/* MIMO RATE overwhelms fragmentation */
	else {
		/* The calculated "NumberOfFrag" is a rough estimation because of various */
		/* encryption/encapsulation overhead not taken into consideration. This number is just */
		/* used to make sure enough free TXD are available before fragmentation takes place. */
		/* In case the actual required number of fragments of an NDIS packet */
		/* excceeds "NumberOfFrag"caculated here and not enough free TXD available, the */
		/* last fragment (i.e. last MPDU) will be dropped in RTMPHardTransmit() due to out of */
		/* resource, and the NDIS packet will be indicated NDIS_STATUS_FAILURE. This should */
		/* rarely happen and the penalty is just like a TX RETRY fail. Affordable. */

		AllowFragSize =
		    (pAd->CommonCfg.FragmentThreshold) - LENGTH_802_11 -
		    LENGTH_CRC;
		NumberOfFrag =
		    ((PacketInfo.TotalPacketLength - LENGTH_802_3 +
		      LENGTH_802_1_H) / AllowFragSize) + 1;
		/* To get accurate number of fragmentation, Minus 1 if the size just match to allowable fragment size */
		if (((PacketInfo.TotalPacketLength - LENGTH_802_3 +
		      LENGTH_802_1_H) % AllowFragSize) == 0) {
			NumberOfFrag--;
		}
	}

	/* Save fragment number to Ndis packet reserved field */
	RTMP_SET_PACKET_FRAGMENTS(pPacket, NumberOfFrag);

	/* STEP 2. Check the requirement of RTS: */
	/*         If multiple fragment required, RTS is required only for the first fragment */
	/*         if the fragment size large than RTS threshold */
	/*     For RT28xx, Let ASIC send RTS/CTS */
/*      RTMP_SET_PACKET_RTS(pPacket, 0); */
	if (NumberOfFrag > 1)
		RTSRequired =
		    (pAd->CommonCfg.FragmentThreshold >
		     pAd->CommonCfg.RtsThreshold) ? 1 : 0;
	else
		RTSRequired =
		    (PacketInfo.TotalPacketLength >
		     pAd->CommonCfg.RtsThreshold) ? 1 : 0;

	/* Save RTS requirement to Ndis packet reserved field */
	RTMP_SET_PACKET_RTS(pPacket, RTSRequired);
	RTMP_SET_PACKET_TXRATE(pPacket, pAd->CommonCfg.TxRate);

	/* */
	/* STEP 3. Traffic classification. outcome = <UserPriority, QueIdx> */
	/* */
	UserPriority = 0;
	QueIdx = QID_AC_BE;
	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) &&
	    CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE)) {
		u16 Protocol;
		u8 LlcSnapLen = 0, Byte0, Byte1;
		do {
			/* get Ethernet protocol field */
			Protocol =
			    (u16)((pSrcBufVA[12] << 8) + pSrcBufVA[13]);
			if (Protocol <= 1500) {
				/* get Ethernet protocol field from LLC/SNAP */
				if (Sniff2BytesFromNdisBuffer
				    (PacketInfo.pFirstBuffer, LENGTH_802_3 + 6,
				     &Byte0, &Byte1) != NDIS_STATUS_SUCCESS)
					break;

				Protocol = (u16)((Byte0 << 8) + Byte1);
				LlcSnapLen = 8;
			}
			/* always AC_BE for non-IP packet */
			if (Protocol != 0x0800)
				break;

			/* get IP header */
			if (Sniff2BytesFromNdisBuffer
			    (PacketInfo.pFirstBuffer, LENGTH_802_3 + LlcSnapLen,
			     &Byte0, &Byte1) != NDIS_STATUS_SUCCESS)
				break;

			/* return AC_BE if packet is not IPv4 */
			if ((Byte0 & 0xf0) != 0x40)
				break;

			FlgIsIP = 1;
			UserPriority = (Byte1 & 0xe0) >> 5;
			QueIdx = MapUserPriorityToAccessCategory[UserPriority];

			/* TODO: have to check ACM bit. apply TSPEC if ACM is ON */
			/* TODO: downgrade UP & QueIdx before passing ACM */
			/*
			   Under WMM ACM control, we dont need to check the bit;
			   Or when a TSPEC is built for VO but we will change to issue
			   BA session for BE here, so we will not use BA to send VO packets.
			 */
			if (pAd->CommonCfg.APEdcaParm.bACM[QueIdx]) {
				UserPriority = 0;
				QueIdx = QID_AC_BE;
			}
		} while (FALSE);
	}

	RTMP_SET_PACKET_UP(pPacket, UserPriority);

	/* Make sure SendTxWait queue resource won't be used by other threads */
	RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
	if (pAd->TxSwQueue[QueIdx].Number >= MAX_PACKETS_IN_QUEUE) {
		RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
		RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);

		return NDIS_STATUS_FAILURE;
	} else {
		InsertTailQueueAc(pAd, pEntry, &pAd->TxSwQueue[QueIdx],
				  PACKET_TO_QUEUE_ENTRY(pPacket));
	}
	RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);

	if ((pAd->CommonCfg.BACapability.field.AutoBA == TRUE) &&
	    IS_HT_STA(pEntry)) {
		/*struct rt_mac_table_entry *pMacEntry = &pAd->MacTab.Content[BSSID_WCID]; */
		if (((pEntry->TXBAbitmap & (1 << UserPriority)) == 0) &&
		    ((pEntry->BADeclineBitmap & (1 << UserPriority)) == 0) &&
		    (pEntry->PortSecured == WPA_802_1X_PORT_SECURED)
		    /* For IOT compatibility, if */
		    /* 1. It is Ralink chip or */
		    /* 2. It is OPEN or AES mode, */
		    /* then BA session can be bulit. */
		    && ((pEntry->ValidAsCLI && pAd->MlmeAux.APRalinkIe != 0x0)
			|| (pEntry->WepStatus != Ndis802_11WEPEnabled
			    && pEntry->WepStatus !=
			    Ndis802_11Encryption2Enabled))
		    ) {
			BAOriSessionSetUp(pAd, pEntry, UserPriority, 0, 10,
					  FALSE);
		}
	}

	pAd->RalinkCounters.OneSecOsTxCount[QueIdx]++;	/* TODO: for debug only. to be removed */
	return NDIS_STATUS_SUCCESS;
}

/*
	========================================================================

	Routine Description:
		This subroutine will scan through releative ring descriptor to find
		out avaliable free ring descriptor and compare with request size.

	Arguments:
		pAd Pointer to our adapter
		QueIdx		Selected TX Ring

	Return Value:
		NDIS_STATUS_FAILURE 	Not enough free descriptor
		NDIS_STATUS_SUCCESS 	Enough free descriptor

	IRQL = PASSIVE_LEVEL
	IRQL = DISPATCH_LEVEL

	Note:

	========================================================================
*/
#ifdef RTMP_MAC_PCI
int RTMPFreeTXDRequest(struct rt_rtmp_adapter *pAd,
			       u8 QueIdx,
			       u8 NumberRequired, u8 *FreeNumberIs)
{
	unsigned long FreeNumber = 0;
	int Status = NDIS_STATUS_FAILURE;

	switch (QueIdx) {
	case QID_AC_BK:
	case QID_AC_BE:
	case QID_AC_VI:
	case QID_AC_VO:
		if (pAd->TxRing[QueIdx].TxSwFreeIdx >
		    pAd->TxRing[QueIdx].TxCpuIdx)
			FreeNumber =
			    pAd->TxRing[QueIdx].TxSwFreeIdx -
			    pAd->TxRing[QueIdx].TxCpuIdx - 1;
		else
			FreeNumber =
			    pAd->TxRing[QueIdx].TxSwFreeIdx + TX_RING_SIZE -
			    pAd->TxRing[QueIdx].TxCpuIdx - 1;

		if (FreeNumber >= NumberRequired)
			Status = NDIS_STATUS_SUCCESS;
		break;

	case QID_MGMT:
		if (pAd->MgmtRing.TxSwFreeIdx > pAd->MgmtRing.TxCpuIdx)
			FreeNumber =
			    pAd->MgmtRing.TxSwFreeIdx - pAd->MgmtRing.TxCpuIdx -
			    1;
		else
			FreeNumber =
			    pAd->MgmtRing.TxSwFreeIdx + MGMT_RING_SIZE -
			    pAd->MgmtRing.TxCpuIdx - 1;

		if (FreeNumber >= NumberRequired)
			Status = NDIS_STATUS_SUCCESS;
		break;

	default:
		DBGPRINT(RT_DEBUG_ERROR,
			 ("RTMPFreeTXDRequest::Invalid QueIdx(=%d)\n", QueIdx));
		break;
	}
	*FreeNumberIs = (u8)FreeNumber;

	return (Status);
}
#endif /* RTMP_MAC_PCI // */
#ifdef RTMP_MAC_USB
/*
	Actually, this function used to check if the TxHardware Queue still has frame need to send.
	If no frame need to send, go to sleep, else, still wake up.
*/
int RTMPFreeTXDRequest(struct rt_rtmp_adapter *pAd,
			       u8 QueIdx,
			       u8 NumberRequired, u8 *FreeNumberIs)
{
	/*unsigned long         FreeNumber = 0; */
	int Status = NDIS_STATUS_FAILURE;
	unsigned long IrqFlags;
	struct rt_ht_tx_context *pHTTXContext;

	switch (QueIdx) {
	case QID_AC_BK:
	case QID_AC_BE:
	case QID_AC_VI:
	case QID_AC_VO:
		{
			pHTTXContext = &pAd->TxContext[QueIdx];
			RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx],
				      IrqFlags);
			if ((pHTTXContext->CurWritePosition !=
			     pHTTXContext->ENextBulkOutPosition)
			    || (pHTTXContext->IRPPending == TRUE)) {
				Status = NDIS_STATUS_FAILURE;
			} else {
				Status = NDIS_STATUS_SUCCESS;
			}
			RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx],
					IrqFlags);
		}
		break;
	case QID_MGMT:
		if (pAd->MgmtRing.TxSwFreeIdx != MGMT_RING_SIZE)
			Status = NDIS_STATUS_FAILURE;
		else
			Status = NDIS_STATUS_SUCCESS;
		break;
	default:
		DBGPRINT(RT_DEBUG_ERROR,
			 ("RTMPFreeTXDRequest::Invalid QueIdx(=%d)\n", QueIdx));
		break;
	}

	return (Status);
}
#endif /* RTMP_MAC_USB // */

void RTMPSendDisassociationFrame(struct rt_rtmp_adapter *pAd)
{
}

void RTMPSendNullFrame(struct rt_rtmp_adapter *pAd,
		       u8 TxRate, IN BOOLEAN bQosNull)
{
	u8 NullFrame[48];
	unsigned long Length;
	struct rt_header_802_11 * pHeader_802_11;

	/* WPA 802.1x secured port control */
	if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
	     (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
	     (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
	     (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
	     || (pAd->StaCfg.IEEE8021X == TRUE)
	    ) && (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED)) {
		return;
	}

	NdisZeroMemory(NullFrame, 48);
	Length = sizeof(struct rt_header_802_11);

	pHeader_802_11 = (struct rt_header_802_11 *) NullFrame;

	pHeader_802_11->FC.Type = BTYPE_DATA;
	pHeader_802_11->FC.SubType = SUBTYPE_NULL_FUNC;
	pHeader_802_11->FC.ToDs = 1;
	COPY_MAC_ADDR(pHeader_802_11->Addr1, pAd->CommonCfg.Bssid);
	COPY_MAC_ADDR(pHeader_802_11->Addr2, pAd->CurrentAddress);
	COPY_MAC_ADDR(pHeader_802_11->Addr3, pAd->CommonCfg.Bssid);

	if (pAd->CommonCfg.bAPSDForcePowerSave) {
		pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
	} else {
		pHeader_802_11->FC.PwrMgmt =
		    (pAd->StaCfg.Psm == PWR_SAVE) ? 1 : 0;
	}
	pHeader_802_11->Duration =
	    pAd->CommonCfg.Dsifs + RTMPCalcDuration(pAd, TxRate, 14);

	pAd->Sequence++;
	pHeader_802_11->Sequence = pAd->Sequence;

	/* Prepare QosNull function frame */
	if (bQosNull) {
		pHeader_802_11->FC.SubType = SUBTYPE_QOS_NULL;

		/* copy QOS control bytes */
		NullFrame[Length] = 0;
		NullFrame[Length + 1] = 0;
		Length += 2;	/* if pad with 2 bytes for alignment, APSD will fail */
	}

	HAL_KickOutNullFrameTx(pAd, 0, NullFrame, Length);

}

/* IRQL = DISPATCH_LEVEL */
void RTMPSendRTSFrame(struct rt_rtmp_adapter *pAd,
		      u8 *pDA,
		      IN unsigned int NextMpduSize,
		      u8 TxRate,
		      u8 RTSRate,
		      u16 AckDuration, u8 QueIdx, u8 FrameGap)
{
}

/* -------------------------------------------------------- */
/*  FIND ENCRYPT KEY AND DECIDE CIPHER ALGORITHM */
/*              Find the WPA key, either Group or Pairwise Key */
/*              LEAP + TKIP also use WPA key. */
/* -------------------------------------------------------- */
/* Decide WEP bit and cipher suite to be used. Same cipher suite should be used for whole fragment burst */
/* In Cisco CCX 2.0 Leap Authentication */
/*                 WepStatus is Ndis802_11Encryption1Enabled but the key will use PairwiseKey */
/*                 Instead of the SharedKey, SharedKey Length may be Zero. */
void STAFindCipherAlgorithm(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk)
{
	NDIS_802_11_ENCRYPTION_STATUS Cipher;	/* To indicate cipher used for this packet */
	u8 CipherAlg = CIPHER_NONE;	/* cipher alogrithm */
	u8 KeyIdx = 0xff;
	u8 *pSrcBufVA;
	struct rt_cipher_key *pKey = NULL;

	pSrcBufVA = GET_OS_PKT_DATAPTR(pTxBlk->pPacket);

	{
		/* Select Cipher */
		if ((*pSrcBufVA & 0x01) && (ADHOC_ON(pAd)))
			Cipher = pAd->StaCfg.GroupCipher;	/* Cipher for Multicast or Broadcast */
		else
			Cipher = pAd->StaCfg.PairCipher;	/* Cipher for Unicast */

		if (RTMP_GET_PACKET_EAPOL(pTxBlk->pPacket)) {
			ASSERT(pAd->SharedKey[BSS0][0].CipherAlg <=
			       CIPHER_CKIP128);

			/* 4-way handshaking frame must be clear */
			if (!(TX_BLK_TEST_FLAG(pTxBlk, fTX_bClearEAPFrame))
			    && (pAd->SharedKey[BSS0][0].CipherAlg)
			    && (pAd->SharedKey[BSS0][0].KeyLen)) {
				CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;
				KeyIdx = 0;
			}
		} else if (Cipher == Ndis802_11Encryption1Enabled) {
			KeyIdx = pAd->StaCfg.DefaultKeyId;
		} else if ((Cipher == Ndis802_11Encryption2Enabled) ||
			   (Cipher == Ndis802_11Encryption3Enabled)) {
			if ((*pSrcBufVA & 0x01) && (ADHOC_ON(pAd)))	/* multicast */
				KeyIdx = pAd->StaCfg.DefaultKeyId;
			else if (pAd->SharedKey[BSS0][0].KeyLen)
				KeyIdx = 0;
			else
				KeyIdx = pAd->StaCfg.DefaultKeyId;
		}

		if (KeyIdx == 0xff)
			CipherAlg = CIPHER_NONE;
		else if ((Cipher == Ndis802_11EncryptionDisabled)
			 || (pAd->SharedKey[BSS0][KeyIdx].KeyLen == 0))
			CipherAlg = CIPHER_NONE;
		else if (pAd->StaCfg.WpaSupplicantUP &&
			 (Cipher == Ndis802_11Encryption1Enabled) &&
			 (pAd->StaCfg.IEEE8021X == TRUE) &&
			 (pAd->StaCfg.PortSecured ==
			  WPA_802_1X_PORT_NOT_SECURED))
			CipherAlg = CIPHER_NONE;
		else {
			/*Header_802_11.FC.Wep = 1; */
			CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
			pKey = &pAd->SharedKey[BSS0][KeyIdx];
		}
	}

	pTxBlk->CipherAlg = CipherAlg;
	pTxBlk->pKey = pKey;
}

void STABuildCommon802_11Header(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk)
{
	struct rt_header_802_11 *pHeader_802_11;

	/* */
	/* MAKE A COMMON 802.11 HEADER */
	/* */

	/* normal wlan header size : 24 octets */
	pTxBlk->MpduHeaderLen = sizeof(struct rt_header_802_11);

	pHeader_802_11 =
	    (struct rt_header_802_11 *) & pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];

	NdisZeroMemory(pHeader_802_11, sizeof(struct rt_header_802_11));

	pHeader_802_11->FC.FrDs = 0;
	pHeader_802_11->FC.Type = BTYPE_DATA;
	pHeader_802_11->FC.SubType =
	    ((TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM)) ? SUBTYPE_QDATA :
	     SUBTYPE_DATA);

	if (pTxBlk->pMacEntry) {
		if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bForceNonQoS)) {
			pHeader_802_11->Sequence =
			    pTxBlk->pMacEntry->NonQosDataSeq;
			pTxBlk->pMacEntry->NonQosDataSeq =
			    (pTxBlk->pMacEntry->NonQosDataSeq + 1) & MAXSEQ;
		} else {
			{
				pHeader_802_11->Sequence =
				    pTxBlk->pMacEntry->TxSeq[pTxBlk->
							     UserPriority];
				pTxBlk->pMacEntry->TxSeq[pTxBlk->UserPriority] =
				    (pTxBlk->pMacEntry->
				     TxSeq[pTxBlk->UserPriority] + 1) & MAXSEQ;
			}
		}
	} else {
		pHeader_802_11->Sequence = pAd->Sequence;
		pAd->Sequence = (pAd->Sequence + 1) & MAXSEQ;	/* next sequence */
	}

	pHeader_802_11->Frag = 0;

	pHeader_802_11->FC.MoreData = TX_BLK_TEST_FLAG(pTxBlk, fTX_bMoreData);

	{
		if (INFRA_ON(pAd)) {
			{
				COPY_MAC_ADDR(pHeader_802_11->Addr1,
					      pAd->CommonCfg.Bssid);
				COPY_MAC_ADDR(pHeader_802_11->Addr2,
					      pAd->CurrentAddress);
				COPY_MAC_ADDR(pHeader_802_11->Addr3,
					      pTxBlk->pSrcBufHeader);
				pHeader_802_11->FC.ToDs = 1;
			}
		} else if (ADHOC_ON(pAd)) {
			COPY_MAC_ADDR(pHeader_802_11->Addr1,
				      pTxBlk->pSrcBufHeader);
			COPY_MAC_ADDR(pHeader_802_11->Addr2,
				      pAd->CurrentAddress);
			COPY_MAC_ADDR(pHeader_802_11->Addr3,
				      pAd->CommonCfg.Bssid);
			pHeader_802_11->FC.ToDs = 0;
		}
	}

	if (pTxBlk->CipherAlg != CIPHER_NONE)
		pHeader_802_11->FC.Wep = 1;

	/* ----------------------------------------------------------------- */
	/* STEP 2. MAKE A COMMON 802.11 HEADER SHARED BY ENTIRE FRAGMENT BURST. Fill sequence later. */
	/* ----------------------------------------------------------------- */
	if (pAd->CommonCfg.bAPSDForcePowerSave)
		pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
	else
		pHeader_802_11->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE);
}

void STABuildCache802_11Header(struct rt_rtmp_adapter *pAd,
			       struct rt_tx_blk *pTxBlk, u8 * pHeader)
{
	struct rt_mac_table_entry *pMacEntry;
	struct rt_header_802_11 * pHeader80211;

	pHeader80211 = (struct rt_header_802_11 *) pHeader;
	pMacEntry = pTxBlk->pMacEntry;

	/* */
	/* Update the cached 802.11 HEADER */
	/* */

	/* normal wlan header size : 24 octets */
	pTxBlk->MpduHeaderLen = sizeof(struct rt_header_802_11);

	/* More Bit */
	pHeader80211->FC.MoreData = TX_BLK_TEST_FLAG(pTxBlk, fTX_bMoreData);

	/* Sequence */
	pHeader80211->Sequence = pMacEntry->TxSeq[pTxBlk->UserPriority];
	pMacEntry->TxSeq[pTxBlk->UserPriority] =
	    (pMacEntry->TxSeq[pTxBlk->UserPriority] + 1) & MAXSEQ;

	{
		/* Check if the frame can be sent through DLS direct link interface */
		/* If packet can be sent through DLS, then force aggregation disable. (Hard to determine peer STA's capability) */

		/* The addr3 of normal packet send from DS is Dest Mac address. */
		if (ADHOC_ON(pAd))
			COPY_MAC_ADDR(pHeader80211->Addr3,
				      pAd->CommonCfg.Bssid);
		else
			COPY_MAC_ADDR(pHeader80211->Addr3,
				      pTxBlk->pSrcBufHeader);
	}

	/* ----------------------------------------------------------------- */
	/* STEP 2. MAKE A COMMON 802.11 HEADER SHARED BY ENTIRE FRAGMENT BURST. Fill sequence later. */
	/* ----------------------------------------------------------------- */
	if (pAd->CommonCfg.bAPSDForcePowerSave)
		pHeader80211->FC.PwrMgmt = PWR_SAVE;
	else
		pHeader80211->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE);
}

static inline u8 *STA_Build_ARalink_Frame_Header(struct rt_rtmp_adapter *pAd,
						    struct rt_tx_blk *pTxBlk)
{
	u8 *pHeaderBufPtr;
	struct rt_header_802_11 *pHeader_802_11;
	void *pNextPacket;
	u32 nextBufLen;
	struct rt_queue_entry *pQEntry;

	STAFindCipherAlgorithm(pAd, pTxBlk);
	STABuildCommon802_11Header(pAd, pTxBlk);

	pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
	pHeader_802_11 = (struct rt_header_802_11 *) pHeaderBufPtr;

	/* steal "order" bit to mark "aggregation" */
	pHeader_802_11->FC.Order = 1;

	/* skip common header */
	pHeaderBufPtr += pTxBlk->MpduHeaderLen;

	if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM)) {
		/* */
		/* build QOS Control bytes */
		/* */
		*pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);

		*(pHeaderBufPtr + 1) = 0;
		pHeaderBufPtr += 2;
		pTxBlk->MpduHeaderLen += 2;
	}
	/* padding at front of LLC header. LLC header should at 4-bytes aligment. */
	pTxBlk->HdrPadLen = (unsigned long)pHeaderBufPtr;
	pHeaderBufPtr = (u8 *)ROUND_UP(pHeaderBufPtr, 4);
	pTxBlk->HdrPadLen = (unsigned long)(pHeaderBufPtr - pTxBlk->HdrPadLen);

	/* For RA Aggregation, */
	/* put the 2nd MSDU length(extra 2-byte field) after struct rt_qos_control in little endian format */
	pQEntry = pTxBlk->TxPacketList.Head;
	pNextPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
	nextBufLen = GET_OS_PKT_LEN(pNextPacket);
	if (RTMP_GET_PACKET_VLAN(pNextPacket))
		nextBufLen -= LENGTH_802_1Q;

	*pHeaderBufPtr = (u8)nextBufLen & 0xff;
	*(pHeaderBufPtr + 1) = (u8)(nextBufLen >> 8);

	pHeaderBufPtr += 2;
	pTxBlk->MpduHeaderLen += 2;

	return pHeaderBufPtr;

}

static inline u8 *STA_Build_AMSDU_Frame_Header(struct rt_rtmp_adapter *pAd,
						  struct rt_tx_blk *pTxBlk)
{
	u8 *pHeaderBufPtr;	/*, pSaveBufPtr; */
	struct rt_header_802_11 *pHeader_802_11;

	STAFindCipherAlgorithm(pAd, pTxBlk);
	STABuildCommon802_11Header(pAd, pTxBlk);

	pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
	pHeader_802_11 = (struct rt_header_802_11 *) pHeaderBufPtr;

	/* skip common header */
	pHeaderBufPtr += pTxBlk->MpduHeaderLen;

	/* */
	/* build QOS Control bytes */
	/* */
	*pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);

	/* */
	/* A-MSDU packet */
	/* */
	*pHeaderBufPtr |= 0x80;

	*(pHeaderBufPtr + 1) = 0;
	pHeaderBufPtr += 2;
	pTxBlk->MpduHeaderLen += 2;

	/*pSaveBufPtr = pHeaderBufPtr; */

	/* */
	/* padding at front of LLC header */
	/* LLC header should locate at 4-octets aligment */
	/* */
	/* @@@ MpduHeaderLen excluding padding @@@ */
	/* */
	pTxBlk->HdrPadLen = (unsigned long)pHeaderBufPtr;
	pHeaderBufPtr = (u8 *)ROUND_UP(pHeaderBufPtr, 4);
	pTxBlk->HdrPadLen = (unsigned long)(pHeaderBufPtr - pTxBlk->HdrPadLen);

	return pHeaderBufPtr;

}

void STA_AMPDU_Frame_Tx(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk)
{
	struct rt_header_802_11 *pHeader_802_11;
	u8 *pHeaderBufPtr;
	u16 FreeNumber;
	struct rt_mac_table_entry *pMacEntry;
	BOOLEAN bVLANPkt;
	struct rt_queue_entry *pQEntry;

	ASSERT(pTxBlk);

	while (pTxBlk->TxPacketList.Head) {
		pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
		pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
		if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE) {
			RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket,
					    NDIS_STATUS_FAILURE);
			continue;
		}

		bVLANPkt =
		    (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);

		pMacEntry = pTxBlk->pMacEntry;
		if (pMacEntry->isCached) {
			/* NOTE: Please make sure the size of pMacEntry->CachedBuf[] is smaller than pTxBlk->HeaderBuf[]! */
			NdisMoveMemory((u8 *)& pTxBlk->
				       HeaderBuf[TXINFO_SIZE],
				       (u8 *)& pMacEntry->CachedBuf[0],
				       TXWI_SIZE + sizeof(struct rt_header_802_11));
			pHeaderBufPtr =
			    (u8 *)(&pTxBlk->
				      HeaderBuf[TXINFO_SIZE + TXWI_SIZE]);
			STABuildCache802_11Header(pAd, pTxBlk, pHeaderBufPtr);
		} else {
			STAFindCipherAlgorithm(pAd, pTxBlk);
			STABuildCommon802_11Header(pAd, pTxBlk);

			pHeaderBufPtr =
			    &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
		}

		pHeader_802_11 = (struct rt_header_802_11 *) pHeaderBufPtr;

		/* skip common header */
		pHeaderBufPtr += pTxBlk->MpduHeaderLen;

		/* */
		/* build QOS Control bytes */
		/* */
		*pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
		*(pHeaderBufPtr + 1) = 0;
		pHeaderBufPtr += 2;
		pTxBlk->MpduHeaderLen += 2;

		/* */
		/* build HTC+ */
		/* HTC control filed following QoS field */
		/* */
		if ((pAd->CommonCfg.bRdg == TRUE)
		    && CLIENT_STATUS_TEST_FLAG(pTxBlk->pMacEntry,
					       fCLIENT_STATUS_RDG_CAPABLE)) {
			if (pMacEntry->isCached == FALSE) {
				/* mark HTC bit */
				pHeader_802_11->FC.Order = 1;

				NdisZeroMemory(pHeaderBufPtr, 4);
				*(pHeaderBufPtr + 3) |= 0x80;
			}
			pHeaderBufPtr += 4;
			pTxBlk->MpduHeaderLen += 4;
		}
		/*pTxBlk->MpduHeaderLen = pHeaderBufPtr - pTxBlk->HeaderBuf - TXWI_SIZE - TXINFO_SIZE; */
		ASSERT(pTxBlk->MpduHeaderLen >= 24);

		/* skip 802.3 header */
		pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
		pTxBlk->SrcBufLen -= LENGTH_802_3;

		/* skip vlan tag */
		if (bVLANPkt) {
			pTxBlk->pSrcBufData += LENGTH_802_1Q;
			pTxBlk->SrcBufLen -= LENGTH_802_1Q;
		}
		/* */
		/* padding at front of LLC header */
		/* LLC header should locate at 4-octets aligment */
		/* */
		/* @@@ MpduHeaderLen excluding padding @@@ */
		/* */
		pTxBlk->HdrPadLen = (unsigned long)pHeaderBufPtr;
		pHeaderBufPtr = (u8 *)ROUND_UP(pHeaderBufPtr, 4);
		pTxBlk->HdrPadLen = (unsigned long)(pHeaderBufPtr - pTxBlk->HdrPadLen);

		{

			/* */
			/* Insert LLC-SNAP encapsulation - 8 octets */
			/* */
			EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk->
							    pSrcBufData - 2,
							    pTxBlk->
							    pExtraLlcSnapEncap);
			if (pTxBlk->pExtraLlcSnapEncap) {
				NdisMoveMemory(pHeaderBufPtr,
					       pTxBlk->pExtraLlcSnapEncap, 6);
				pHeaderBufPtr += 6;
				/* get 2 octets (TypeofLen) */
				NdisMoveMemory(pHeaderBufPtr,
					       pTxBlk->pSrcBufData - 2, 2);
				pHeaderBufPtr += 2;
				pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
			}

		}

		if (pMacEntry->isCached) {
			RTMPWriteTxWI_Cache(pAd,
					    (struct rt_txwi *) (&pTxBlk->
							   HeaderBuf
							   [TXINFO_SIZE]),
					    pTxBlk);
		} else {
			RTMPWriteTxWI_Data(pAd,
					   (struct rt_txwi *) (&pTxBlk->
							  HeaderBuf
							  [TXINFO_SIZE]),
					   pTxBlk);

			NdisZeroMemory((u8 *)(&pMacEntry->CachedBuf[0]),
				       sizeof(pMacEntry->CachedBuf));
			NdisMoveMemory((u8 *)(&pMacEntry->CachedBuf[0]),
				       (u8 *)(&pTxBlk->
						 HeaderBuf[TXINFO_SIZE]),
				       (pHeaderBufPtr -
					(u8 *)(&pTxBlk->
						  HeaderBuf[TXINFO_SIZE])));
			pMacEntry->isCached = TRUE;
		}

		/* calculate Transmitted AMPDU count and ByteCount */
		{
			pAd->RalinkCounters.TransmittedMPDUsInAMPDUCount.u.
			    LowPart++;
			pAd->RalinkCounters.TransmittedOctetsInAMPDUCount.
			    QuadPart += pTxBlk->SrcBufLen;
		}

		/*FreeNumber = GET_TXRING_FREENO(pAd, QueIdx); */

		HAL_WriteTxResource(pAd, pTxBlk, TRUE, &FreeNumber);

		/* */
		/* Kick out Tx */
		/* */
		if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
			HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);

		pAd->RalinkCounters.KickTxCount++;
		pAd->RalinkCounters.OneSecTxDoneCount++;
	}

}

void STA_AMSDU_Frame_Tx(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk)
{
	u8 *pHeaderBufPtr;
	u16 FreeNumber;
	u16 subFramePayloadLen = 0;	/* AMSDU Subframe length without AMSDU-Header / Padding. */
	u16 totalMPDUSize = 0;
	u8 *subFrameHeader;
	u8 padding = 0;
	u16 FirstTx = 0, LastTxIdx = 0;
	BOOLEAN bVLANPkt;
	int frameNum = 0;
	struct rt_queue_entry *pQEntry;

	ASSERT(pTxBlk);

	ASSERT((pTxBlk->TxPacketList.Number > 1));

	while (pTxBlk->TxPacketList.Head) {
		pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
		pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
		if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE) {
			RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket,
					    NDIS_STATUS_FAILURE);
			continue;
		}

		bVLANPkt =
		    (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);

		/* skip 802.3 header */
		pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
		pTxBlk->SrcBufLen -= LENGTH_802_3;

		/* skip vlan tag */
		if (bVLANPkt) {
			pTxBlk->pSrcBufData += LENGTH_802_1Q;
			pTxBlk->SrcBufLen -= LENGTH_802_1Q;
		}

		if (frameNum == 0) {
			pHeaderBufPtr =
			    STA_Build_AMSDU_Frame_Header(pAd, pTxBlk);

			/* NOTE: TxWI->MPDUtotalByteCount will be updated after final frame was handled. */
			RTMPWriteTxWI_Data(pAd,
					   (struct rt_txwi *) (&pTxBlk->
							  HeaderBuf
							  [TXINFO_SIZE]),
					   pTxBlk);
		} else {
			pHeaderBufPtr = &pTxBlk->HeaderBuf[0];
			padding =
			    ROUND_UP(LENGTH_AMSDU_SUBFRAMEHEAD +
				     subFramePayloadLen,
				     4) - (LENGTH_AMSDU_SUBFRAMEHEAD +
					   subFramePayloadLen);
			NdisZeroMemory(pHeaderBufPtr,
				       padding + LENGTH_AMSDU_SUBFRAMEHEAD);
			pHeaderBufPtr += padding;
			pTxBlk->MpduHeaderLen = padding;
		}

		/* */
		/* A-MSDU subframe */
		/*   DA(6)+SA(6)+Length(2) + LLC/SNAP Encap */
		/* */
		subFrameHeader = pHeaderBufPtr;
		subFramePayloadLen = pTxBlk->SrcBufLen;

		NdisMoveMemory(subFrameHeader, pTxBlk->pSrcBufHeader, 12);

		pHeaderBufPtr += LENGTH_AMSDU_SUBFRAMEHEAD;
		pTxBlk->MpduHeaderLen += LENGTH_AMSDU_SUBFRAMEHEAD;

		/* */
		/* Insert LLC-SNAP encapsulation - 8 octets */
		/* */
		EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk->pSrcBufData - 2,
						    pTxBlk->pExtraLlcSnapEncap);

		subFramePayloadLen = pTxBlk->SrcBufLen;

		if (pTxBlk->pExtraLlcSnapEncap) {
			NdisMoveMemory(pHeaderBufPtr,
				       pTxBlk->pExtraLlcSnapEncap, 6);
			pHeaderBufPtr += 6;
			/* get 2 octets (TypeofLen) */
			NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData - 2,
				       2);
			pHeaderBufPtr += 2;
			pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
			subFramePayloadLen += LENGTH_802_1_H;
		}
		/* update subFrame Length field */
		subFrameHeader[12] = (subFramePayloadLen & 0xFF00) >> 8;
		subFrameHeader[13] = subFramePayloadLen & 0xFF;

		totalMPDUSize += pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;

		if (frameNum == 0)
			FirstTx =
			    HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum,
						     &FreeNumber);
		else
			LastTxIdx =
			    HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum,
						     &FreeNumber);

		frameNum++;

		pAd->RalinkCounters.KickTxCount++;
		pAd->RalinkCounters.OneSecTxDoneCount++;

		/* calculate Transmitted AMSDU Count and ByteCount */
		{
			pAd->RalinkCounters.TransmittedAMSDUCount.u.LowPart++;
			pAd->RalinkCounters.TransmittedOctetsInAMSDU.QuadPart +=
			    totalMPDUSize;
		}

	}

	HAL_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, FirstTx);
	HAL_LastTxIdx(pAd, pTxBlk->QueIdx, LastTxIdx);

	/* */
	/* Kick out Tx */
	/* */
	if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
		HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
}

void STA_Legacy_Frame_Tx(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk)
{
	struct rt_header_802_11 *pHeader_802_11;
	u8 *pHeaderBufPtr;
	u16 FreeNumber;
	BOOLEAN bVLANPkt;
	struct rt_queue_entry *pQEntry;

	ASSERT(pTxBlk);

	pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
	pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
	if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE) {
		RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
		return;
	}

	if (pTxBlk->TxFrameType == TX_MCAST_FRAME) {
		INC_COUNTER64(pAd->WlanCounters.MulticastTransmittedFrameCount);
	}

	if (RTMP_GET_PACKET_RTS(pTxBlk->pPacket))
		TX_BLK_SET_FLAG(pTxBlk, fTX_bRtsRequired);
	else
		TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bRtsRequired);

	bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);

	if (pTxBlk->TxRate < pAd->CommonCfg.MinTxRate)
		pTxBlk->TxRate = pAd->CommonCfg.MinTxRate;

	STAFindCipherAlgorithm(pAd, pTxBlk);
	STABuildCommon802_11Header(pAd, pTxBlk);

	/* skip 802.3 header */
	pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
	pTxBlk->SrcBufLen -= LENGTH_802_3;

	/* skip vlan tag */
	if (bVLANPkt) {
		pTxBlk->pSrcBufData += LENGTH_802_1Q;
		pTxBlk->SrcBufLen -= LENGTH_802_1Q;
	}

	pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
	pHeader_802_11 = (struct rt_header_802_11 *) pHeaderBufPtr;

	/* skip common header */
	pHeaderBufPtr += pTxBlk->MpduHeaderLen;

	if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM)) {
		/* */
		/* build QOS Control bytes */
		/* */
		*(pHeaderBufPtr) =
		    ((pTxBlk->UserPriority & 0x0F) | (pAd->CommonCfg.
						      AckPolicy[pTxBlk->
								QueIdx] << 5));
		*(pHeaderBufPtr + 1) = 0;
		pHeaderBufPtr += 2;
		pTxBlk->MpduHeaderLen += 2;
	}
	/* The remaining content of MPDU header should locate at 4-octets aligment */
	pTxBlk->HdrPadLen = (unsigned long)pHeaderBufPtr;
	pHeaderBufPtr = (u8 *)ROUND_UP(pHeaderBufPtr, 4);
	pTxBlk->HdrPadLen = (unsigned long)(pHeaderBufPtr - pTxBlk->HdrPadLen);

	{

		/* */
		/* Insert LLC-SNAP encapsulation - 8 octets */
		/* */
		/* */
		/* if original Ethernet frame contains no LLC/SNAP, */
		/* then an extra LLC/SNAP encap is required */
		/* */
		EXTRA_LLCSNAP_ENCAP_FROM_PKT_START(pTxBlk->pSrcBufHeader,
						   pTxBlk->pExtraLlcSnapEncap);
		if (pTxBlk->pExtraLlcSnapEncap) {
			u8 vlan_size;

			NdisMoveMemory(pHeaderBufPtr,
				       pTxBlk->pExtraLlcSnapEncap, 6);
			pHeaderBufPtr += 6;
			/* skip vlan tag */
			vlan_size = (bVLANPkt) ? LENGTH_802_1Q : 0;
			/* get 2 octets (TypeofLen) */
			NdisMoveMemory(pHeaderBufPtr,
				       pTxBlk->pSrcBufHeader + 12 + vlan_size,
				       2);
			pHeaderBufPtr += 2;
			pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
		}

	}

	/* */
	/* prepare for TXWI */
	/* use Wcid as Key Index */
	/* */

	RTMPWriteTxWI_Data(pAd, (struct rt_txwi *) (&pTxBlk->HeaderBuf[TXINFO_SIZE]),
			   pTxBlk);

	/*FreeNumber = GET_TXRING_FREENO(pAd, QueIdx); */

	HAL_WriteTxResource(pAd, pTxBlk, TRUE, &FreeNumber);

	pAd->RalinkCounters.KickTxCount++;
	pAd->RalinkCounters.OneSecTxDoneCount++;

	/* */
	/* Kick out Tx */
	/* */
	if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
		HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
}

void STA_ARalink_Frame_Tx(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk)
{
	u8 *pHeaderBufPtr;
	u16 FreeNumber;
	u16 totalMPDUSize = 0;
	u16 FirstTx, LastTxIdx;
	int frameNum = 0;
	BOOLEAN bVLANPkt;
	struct rt_queue_entry *pQEntry;

	ASSERT(pTxBlk);

	ASSERT((pTxBlk->TxPacketList.Number == 2));

	FirstTx = LastTxIdx = 0;	/* Is it ok init they as 0? */
	while (pTxBlk->TxPacketList.Head) {
		pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
		pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);

		if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE) {
			RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket,
					    NDIS_STATUS_FAILURE);
			continue;
		}

		bVLANPkt =
		    (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);

		/* skip 802.3 header */
		pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
		pTxBlk->SrcBufLen -= LENGTH_802_3;

		/* skip vlan tag */
		if (bVLANPkt) {
			pTxBlk->pSrcBufData += LENGTH_802_1Q;
			pTxBlk->SrcBufLen -= LENGTH_802_1Q;
		}

		if (frameNum == 0) {	/* For first frame, we need to create the 802.11 header + padding(optional) + RA-AGG-LEN + SNAP Header */

			pHeaderBufPtr =
			    STA_Build_ARalink_Frame_Header(pAd, pTxBlk);

			/* It's ok write the TxWI here, because the TxWI->MPDUtotalByteCount */
			/*      will be updated after final frame was handled. */
			RTMPWriteTxWI_Data(pAd,
					   (struct rt_txwi *) (&pTxBlk->
							  HeaderBuf
							  [TXINFO_SIZE]),
					   pTxBlk);

			/* */
			/* Insert LLC-SNAP encapsulation - 8 octets */
			/* */
			EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk->
							    pSrcBufData - 2,
							    pTxBlk->
							    pExtraLlcSnapEncap);

			if (pTxBlk->pExtraLlcSnapEncap) {
				NdisMoveMemory(pHeaderBufPtr,
					       pTxBlk->pExtraLlcSnapEncap, 6);
				pHeaderBufPtr += 6;
				/* get 2 octets (TypeofLen) */
				NdisMoveMemory(pHeaderBufPtr,
					       pTxBlk->pSrcBufData - 2, 2);
				pHeaderBufPtr += 2;
				pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
			}
		} else {	/* For second aggregated frame, we need create the 802.3 header to headerBuf, because PCI will copy it to SDPtr0. */

			pHeaderBufPtr = &pTxBlk->HeaderBuf[0];
			pTxBlk->MpduHeaderLen = 0;

			/* A-Ralink sub-sequent frame header is the same as 802.3 header. */
			/*   DA(6)+SA(6)+FrameType(2) */
			NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufHeader,
				       12);
			pHeaderBufPtr += 12;
			/* get 2 octets (TypeofLen) */
			NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData - 2,
				       2);
			pHeaderBufPtr += 2;
			pTxBlk->MpduHeaderLen = LENGTH_ARALINK_SUBFRAMEHEAD;
		}

		totalMPDUSize += pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;

		/*FreeNumber = GET_TXRING_FREENO(pAd, QueIdx); */
		if (frameNum == 0)
			FirstTx =
			    HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum,
						     &FreeNumber);
		else
			LastTxIdx =
			    HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum,
						     &FreeNumber);

		frameNum++;

		pAd->RalinkCounters.OneSecTxAggregationCount++;
		pAd->RalinkCounters.KickTxCount++;
		pAd->RalinkCounters.OneSecTxDoneCount++;

	}

	HAL_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, FirstTx);
	HAL_LastTxIdx(pAd, pTxBlk->QueIdx, LastTxIdx);

	/* */
	/* Kick out Tx */
	/* */
	if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
		HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);

}

void STA_Fragment_Frame_Tx(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk)
{
	struct rt_header_802_11 *pHeader_802_11;
	u8 *pHeaderBufPtr;
	u16 FreeNumber;
	u8 fragNum = 0;
	struct rt_packet_info PacketInfo;
	u16 EncryptionOverhead = 0;
	u32 FreeMpduSize, SrcRemainingBytes;
	u16 AckDuration;
	u32 NextMpduSize;
	BOOLEAN bVLANPkt;
	struct rt_queue_entry *pQEntry;
	HTTRANSMIT_SETTING *pTransmit;

	ASSERT(pTxBlk);

	pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
	pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
	if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE) {
		RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
		return;
	}

	ASSERT(TX_BLK_TEST_FLAG(pTxBlk, fTX_bAllowFrag));
	bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);

	STAFindCipherAlgorithm(pAd, pTxBlk);
	STABuildCommon802_11Header(pAd, pTxBlk);

	if (pTxBlk->CipherAlg == CIPHER_TKIP) {
		pTxBlk->pPacket =
		    duplicate_pkt_with_TKIP_MIC(pAd, pTxBlk->pPacket);
		if (pTxBlk->pPacket == NULL)
			return;
		RTMP_QueryPacketInfo(pTxBlk->pPacket, &PacketInfo,
				     &pTxBlk->pSrcBufHeader,
				     &pTxBlk->SrcBufLen);
	}
	/* skip 802.3 header */
	pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
	pTxBlk->SrcBufLen -= LENGTH_802_3;

	/* skip vlan tag */
	if (bVLANPkt) {
		pTxBlk->pSrcBufData += LENGTH_802_1Q;
		pTxBlk->SrcBufLen -= LENGTH_802_1Q;
	}

	pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
	pHeader_802_11 = (struct rt_header_802_11 *) pHeaderBufPtr;

	/* skip common header */
	pHeaderBufPtr += pTxBlk->MpduHeaderLen;

	if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM)) {
		/* */
		/* build QOS Control bytes */
		/* */
		*pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);

		*(pHeaderBufPtr + 1) = 0;
		pHeaderBufPtr += 2;
		pTxBlk->MpduHeaderLen += 2;
	}
	/* */
	/* padding at front of LLC header */
	/* LLC header should locate at 4-octets aligment */
	/* */
	pTxBlk->HdrPadLen = (unsigned long)pHeaderBufPtr;
	pHeaderBufPtr = (u8 *)ROUND_UP(pHeaderBufPtr, 4);
	pTxBlk->HdrPadLen = (unsigned long)(pHeaderBufPtr - pTxBlk->HdrPadLen);

	/* */
	/* Insert LLC-SNAP encapsulation - 8 octets */
	/* */
	/* */
	/* if original Ethernet frame contains no LLC/SNAP, */
	/* then an extra LLC/SNAP encap is required */
	/* */
	EXTRA_LLCSNAP_ENCAP_FROM_PKT_START(pTxBlk->pSrcBufHeader,
					   pTxBlk->pExtraLlcSnapEncap);
	if (pTxBlk->pExtraLlcSnapEncap) {
		u8 vlan_size;

		NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6);
		pHeaderBufPtr += 6;
		/* skip vlan tag */
		vlan_size = (bVLANPkt) ? LENGTH_802_1Q : 0;
		/* get 2 octets (TypeofLen) */
		NdisMoveMemory(pHeaderBufPtr,
			       pTxBlk->pSrcBufHeader + 12 + vlan_size, 2);
		pHeaderBufPtr += 2;
		pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
	}

	/* If TKIP is used and fragmentation is required. Driver has to */
	/*      append TKIP MIC at tail of the scatter buffer */
	/*      MAC ASIC will only perform IV/EIV/ICV insertion but no TKIP MIC */
	if (pTxBlk->CipherAlg == CIPHER_TKIP) {
		RTMPCalculateMICValue(pAd, pTxBlk->pPacket,
				      pTxBlk->pExtraLlcSnapEncap, pTxBlk->pKey,
				      0);

		/* NOTE: DON'T refer the skb->len directly after following copy. Becasue the length is not adjust */
		/*                      to correct lenght, refer to pTxBlk->SrcBufLen for the packet length in following progress. */
		NdisMoveMemory(pTxBlk->pSrcBufData + pTxBlk->SrcBufLen,
			       &pAd->PrivateInfo.Tx.MIC[0], 8);
		/*skb_put((RTPKT_TO_OSPKT(pTxBlk->pPacket))->tail, 8); */
		pTxBlk->SrcBufLen += 8;
		pTxBlk->TotalFrameLen += 8;
		pTxBlk->CipherAlg = CIPHER_TKIP_NO_MIC;
	}
	/* */
	/* calcuate the overhead bytes that encryption algorithm may add. This */
	/* affects the calculate of "duration" field */
	/* */
	if ((pTxBlk->CipherAlg == CIPHER_WEP64)
	    || (pTxBlk->CipherAlg == CIPHER_WEP128))
		EncryptionOverhead = 8;	/*WEP: IV[4] + ICV[4]; */
	else if (pTxBlk->CipherAlg == CIPHER_TKIP_NO_MIC)
		EncryptionOverhead = 12;	/*TKIP: IV[4] + EIV[4] + ICV[4], MIC will be added to TotalPacketLength */
	else if (pTxBlk->CipherAlg == CIPHER_TKIP)
		EncryptionOverhead = 20;	/*TKIP: IV[4] + EIV[4] + ICV[4] + MIC[8] */
	else if (pTxBlk->CipherAlg == CIPHER_AES)
		EncryptionOverhead = 16;	/* AES: IV[4] + EIV[4] + MIC[8] */
	else
		EncryptionOverhead = 0;

	pTransmit = pTxBlk->pTransmit;
	/* Decide the TX rate */
	if (pTransmit->field.MODE == MODE_CCK)
		pTxBlk->TxRate = pTransmit->field.MCS;
	else if (pTransmit->field.MODE == MODE_OFDM)
		pTxBlk->TxRate = pTransmit->field.MCS + RATE_FIRST_OFDM_RATE;
	else
		pTxBlk->TxRate = RATE_6_5;

	/* decide how much time an ACK/CTS frame will consume in the air */
	if (pTxBlk->TxRate <= RATE_LAST_OFDM_RATE)
		AckDuration =
		    RTMPCalcDuration(pAd,
				     pAd->CommonCfg.ExpectedACKRate[pTxBlk->
								    TxRate],
				     14);
	else
		AckDuration = RTMPCalcDuration(pAd, RATE_6_5, 14);

	/* Init the total payload length of this frame. */
	SrcRemainingBytes = pTxBlk->SrcBufLen;

	pTxBlk->TotalFragNum = 0xff;

	do {

		FreeMpduSize = pAd->CommonCfg.FragmentThreshold - LENGTH_CRC;

		FreeMpduSize -= pTxBlk->MpduHeaderLen;

		if (SrcRemainingBytes <= FreeMpduSize) {	/* this is the last or only fragment */

			pTxBlk->SrcBufLen = SrcRemainingBytes;

			pHeader_802_11->FC.MoreFrag = 0;
			pHeader_802_11->Duration =
			    pAd->CommonCfg.Dsifs + AckDuration;

			/* Indicate the lower layer that this's the last fragment. */
			pTxBlk->TotalFragNum = fragNum;
		} else {	/* more fragment is required */

			pTxBlk->SrcBufLen = FreeMpduSize;

			NextMpduSize =
			    min(((u32)SrcRemainingBytes - pTxBlk->SrcBufLen),
				((u32)pAd->CommonCfg.FragmentThreshold));
			pHeader_802_11->FC.MoreFrag = 1;
			pHeader_802_11->Duration =
			    (3 * pAd->CommonCfg.Dsifs) + (2 * AckDuration) +
			    RTMPCalcDuration(pAd, pTxBlk->TxRate,
					     NextMpduSize + EncryptionOverhead);
		}

		if (fragNum == 0)
			pTxBlk->FrameGap = IFS_HTTXOP;
		else
			pTxBlk->FrameGap = IFS_SIFS;

		RTMPWriteTxWI_Data(pAd,
				   (struct rt_txwi *) (&pTxBlk->
						  HeaderBuf[TXINFO_SIZE]),
				   pTxBlk);

		HAL_WriteFragTxResource(pAd, pTxBlk, fragNum, &FreeNumber);

		pAd->RalinkCounters.KickTxCount++;
		pAd->RalinkCounters.OneSecTxDoneCount++;

		/* Update the frame number, remaining size of the NDIS packet payload. */

		/* space for 802.11 header. */
		if (fragNum == 0 && pTxBlk->pExtraLlcSnapEncap)
			pTxBlk->MpduHeaderLen -= LENGTH_802_1_H;

		fragNum++;
		SrcRemainingBytes -= pTxBlk->SrcBufLen;
		pTxBlk->pSrcBufData += pTxBlk->SrcBufLen;

		pHeader_802_11->Frag++;	/* increase Frag # */

	} while (SrcRemainingBytes > 0);

	/* */
	/* Kick out Tx */
	/* */
	if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
		HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
}

#define RELEASE_FRAMES_OF_TXBLK(_pAd, _pTxBlk, _pQEntry, _Status) 										\
		while(_pTxBlk->TxPacketList.Head)														\
		{																						\
			_pQEntry = RemoveHeadQueue(&_pTxBlk->TxPacketList);									\
			RELEASE_NDIS_PACKET(_pAd, QUEUE_ENTRY_TO_PACKET(_pQEntry), _Status);	\
		}

/*
	========================================================================

	Routine Description:
		Copy frame from waiting queue into relative ring buffer and set
	appropriate ASIC register to kick hardware encryption before really
	sent out to air.

	Arguments:
		pAd 	Pointer to our adapter
		void *	Pointer to outgoing Ndis frame
		NumberOfFrag	Number of fragment required

	Return Value:
		None

	IRQL = DISPATCH_LEVEL

	Note:

	========================================================================
*/
int STAHardTransmit(struct rt_rtmp_adapter *pAd,
			    struct rt_tx_blk *pTxBlk, u8 QueIdx)
{
	char *pPacket;
	struct rt_queue_entry *pQEntry;

	/* --------------------------------------------- */
	/* STEP 0. DO SANITY CHECK AND SOME EARLY PREPARATION. */
	/* --------------------------------------------- */
	/* */
	ASSERT(pTxBlk->TxPacketList.Number);
	if (pTxBlk->TxPacketList.Head == NULL) {
		DBGPRINT(RT_DEBUG_ERROR,
			 ("pTxBlk->TotalFrameNum == %ld!\n",
			  pTxBlk->TxPacketList.Number));
		return NDIS_STATUS_FAILURE;
	}

	pPacket = QUEUE_ENTRY_TO_PACKET(pTxBlk->TxPacketList.Head);

	/* ------------------------------------------------------------------ */
	/* STEP 1. WAKE UP PHY */
	/*              outgoing frame always wakeup PHY to prevent frame lost and */
	/*              turn off PSM bit to improve performance */
	/* ------------------------------------------------------------------ */
	/* not to change PSM bit, just send this frame out? */
	if ((pAd->StaCfg.Psm == PWR_SAVE)
	    && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) {
		DBGPRINT_RAW(RT_DEBUG_INFO, ("AsicForceWakeup At HardTx\n"));
#ifdef RTMP_MAC_PCI
		AsicForceWakeup(pAd, TRUE);
#endif /* RTMP_MAC_PCI // */
#ifdef RTMP_MAC_USB
		RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_FORCE_WAKE_UP, NULL, 0);
#endif /* RTMP_MAC_USB // */
	}
	/* It should not change PSM bit, when APSD turn on. */
	if ((!
	     (pAd->CommonCfg.bAPSDCapable
	      && pAd->CommonCfg.APEdcaParm.bAPSDCapable)
	     && (pAd->CommonCfg.bAPSDForcePowerSave == FALSE))
	    || (RTMP_GET_PACKET_EAPOL(pTxBlk->pPacket))
	    || (RTMP_GET_PACKET_WAI(pTxBlk->pPacket))) {
		if ((pAd->StaCfg.Psm == PWR_SAVE) &&
		    (pAd->StaCfg.WindowsPowerMode ==
		     Ndis802_11PowerModeFast_PSP))
			RTMP_SET_PSM_BIT(pAd, PWR_ACTIVE);
	}

	switch (pTxBlk->TxFrameType) {
	case TX_AMPDU_FRAME:
		STA_AMPDU_Frame_Tx(pAd, pTxBlk);
		break;
	case TX_AMSDU_FRAME:
		STA_AMSDU_Frame_Tx(pAd, pTxBlk);
		break;
	case TX_LEGACY_FRAME:
		STA_Legacy_Frame_Tx(pAd, pTxBlk);
		break;
	case TX_MCAST_FRAME:
		STA_Legacy_Frame_Tx(pAd, pTxBlk);
		break;
	case TX_RALINK_FRAME:
		STA_ARalink_Frame_Tx(pAd, pTxBlk);
		break;
	case TX_FRAG_FRAME:
		STA_Fragment_Frame_Tx(pAd, pTxBlk);
		break;
	default:
		{
			/* It should not happened! */
			DBGPRINT(RT_DEBUG_ERROR,
				 ("Send a packet was not classified! It should not happen!\n"));
			while (pTxBlk->TxPacketList.Number) {
				pQEntry =
				    RemoveHeadQueue(&pTxBlk->TxPacketList);
				pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
				if (pPacket)
					RELEASE_NDIS_PACKET(pAd, pPacket,
							    NDIS_STATUS_FAILURE);
			}
		}
		break;
	}

	return (NDIS_STATUS_SUCCESS);

}

unsigned long HashBytesPolynomial(u8 * value, unsigned int len)
{
	unsigned char *word = value;
	unsigned int ret = 0;
	unsigned int i;

	for (i = 0; i < len; i++) {
		int mod = i % 32;
		ret ^= (unsigned int)(word[i]) << mod;
		ret ^= (unsigned int)(word[i]) >> (32 - mod);
	}
	return ret;
}

void Sta_Announce_or_Forward_802_3_Packet(struct rt_rtmp_adapter *pAd,
					  void *pPacket,
					  u8 FromWhichBSSID)
{
	if (TRUE) {
		announce_802_3_packet(pAd, pPacket);
	} else {
		/* release packet */
		RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
	}
}
