aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/rt2860/sta/rtmp_data.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/rt2860/sta/rtmp_data.c')
-rw-r--r--drivers/staging/rt2860/sta/rtmp_data.c2552
1 files changed, 0 insertions, 2552 deletions
diff --git a/drivers/staging/rt2860/sta/rtmp_data.c b/drivers/staging/rt2860/sta/rtmp_data.c
deleted file mode 100644
index e82c6b669eb2..000000000000
--- a/drivers/staging/rt2860/sta/rtmp_data.c
+++ /dev/null
@@ -1,2552 +0,0 @@
-/*
- *************************************************************************
- * 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
- Justin P. Mattock 11/07/2010 Fix typos
- -------- ---------- ----------------------------------------------
-*/
-#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 {
- /* Determine 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 does 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));
- /* Resource 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));
- /* Resource 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 is larger 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 relative ring descriptor to find
- out available 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 alignment. */
- 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 alignment */
- 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. Because the length is not adjusted */
- /* to correct length, 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;
- }
- /* */
- /* calculate 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);
- }
-}