aboutsummaryrefslogtreecommitdiff
path: root/drivers/staging/rt2870/sta/rtmp_data.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/rt2870/sta/rtmp_data.c')
-rw-r--r--drivers/staging/rt2870/sta/rtmp_data.c2620
1 files changed, 1 insertions, 2619 deletions
diff --git a/drivers/staging/rt2870/sta/rtmp_data.c b/drivers/staging/rt2870/sta/rtmp_data.c
index 9942ecaf5e2e..b67e06952bcf 100644
--- a/drivers/staging/rt2870/sta/rtmp_data.c
+++ b/drivers/staging/rt2870/sta/rtmp_data.c
@@ -1,2619 +1 @@
-/*
- *************************************************************************
- * 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
- -------- ---------- ----------------------------------------------
- John Aug/17/04 major modification for RT2561/2661
- Jan Lee Mar/17/06 major modification for RT2860 New Ring Design
-*/
-#include "../rt_config.h"
-
-
-VOID STARxEAPOLFrameIndicate(
- IN PRTMP_ADAPTER pAd,
- IN MAC_TABLE_ENTRY *pEntry,
- IN RX_BLK *pRxBlk,
- IN UCHAR FromWhichBSSID)
-{
- PRT28XX_RXD_STRUC pRxD = &(pRxBlk->RxD);
- PRXWI_STRUC pRxWI = pRxBlk->pRxWI;
- UCHAR *pTmpBuf;
-
-#ifdef WPA_SUPPLICANT_SUPPORT
- 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)))
- {
- PUCHAR Key;
- UCHAR 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 RT2870
- union
- {
- char buf[sizeof(NDIS_802_11_WEP)+MAX_LEN_OF_KEY- 1];
- 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 =(UCHAR) (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 // RT2870 //
- // 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
-#endif // WPA_SUPPLICANT_SUPPORT //
- {
- // 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(
- IN PRTMP_ADAPTER pAd,
- IN MAC_TABLE_ENTRY *pEntry,
- IN RX_BLK *pRxBlk,
- IN UCHAR 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);
- }
-#ifdef QOS_DLS_SUPPORT
- RX_BLK_CLEAR_FLAG(pRxBlk, fRX_DLS);
-#endif // QOS_DLS_SUPPORT //
- }
- else
- {
- RX_BLK_SET_FLAG(pRxBlk, fRX_EAP);
-#ifdef DOT11_N_SUPPORT
- if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMPDU) && (pAd->CommonCfg.bDisableReordering == 0))
- {
- Indicate_AMPDU_Packet(pAd, pRxBlk, FromWhichBSSID);
- }
- else
-#endif // DOT11_N_SUPPORT //
- {
- // 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(
- IN PRTMP_ADAPTER pAd,
- IN MAC_TABLE_ENTRY *pEntry,
- IN RX_BLK *pRxBlk)
-{
- PHEADER_802_11 pHeader = pRxBlk->pHeader;
- UCHAR *pData = pRxBlk->pData;
- USHORT DataSize = pRxBlk->DataSize;
- UCHAR UserPriority = pRxBlk->UserPriority;
- PCIPHER_KEY pWpaKey;
- UCHAR *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"));
-
-#ifdef WPA_SUPPLICANT_SUPPORT
- if (pAd->StaCfg.WpaSupplicantUP)
- {
- WpaSendMicFailureToWpaSupplicant(pAd, (pWpaKey->Type == PAIRWISEKEY) ? TRUE : FALSE);
- }
- else
-#endif // WPA_SUPPLICANT_SUPPORT //
- {
- RTMPReportMicError(pAd, pWpaKey);
- }
-
- // release packet
- RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
- return FALSE;
- }
-
- return TRUE;
-}
-
-
-//
-// All Rx routines use 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(
- IN PRTMP_ADAPTER pAd,
- IN RX_BLK *pRxBlk)
-{
- PRT28XX_RXD_STRUC pRxD = &(pRxBlk->RxD);
- PRXWI_STRUC pRxWI = pRxBlk->pRxWI;
- PHEADER_802_11 pHeader = pRxBlk->pHeader;
- PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket;
- BOOLEAN bFragment = FALSE;
- MAC_TABLE_ENTRY *pEntry = NULL;
- UCHAR FromWhichBSSID = BSS0;
- UCHAR 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;
- }
-
-#ifdef QOS_DLS_SUPPORT
- //if ((pHeader->FC.FrDs == 0) && (pHeader->FC.ToDs == 0))
- if (RTMPRcvFrameDLSCheck(pAd, pHeader, pRxWI->MPDUtotalByteCount, pRxD))
- {
- return;
- }
-#endif // QOS_DLS_SUPPORT //
-
- // 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))
- {
- UCHAR *pData;
- DBGPRINT(RT_DEBUG_TRACE,("bAPSDCapable\n"));
-
- // Qos bit 4
- pData = (PUCHAR)pHeader + LENGTH_802_11;
- if ((*pData >> 4) & 0x01)
- {
- DBGPRINT(RT_DEBUG_TRACE,("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))
- {
- USHORT TbttNumToNextWakeUp;
- USHORT NextDtim = pAd->StaCfg.DtimPeriod;
- ULONG Now;
-
- NdisGetSystemUpTime(&Now);
- NextDtim -= (USHORT)(Now - pAd->StaCfg.LastBeaconRxTime)/pAd->CommonCfg.BeaconPeriod;
-
- TbttNumToNextWakeUp = pAd->StaCfg.DefaultListenCount;
- if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM) && (TbttNumToNextWakeUp > NextDtim))
- TbttNumToNextWakeUp = NextDtim;
-
- MlmeSetPsmBit(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)
-#ifdef QOS_DLS_SUPPORT
- if (!pAd->CommonCfg.bDLSCapable)
- {
-#endif // QOS_DLS_SUPPORT //
- 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;
- }
- }
-#ifdef QOS_DLS_SUPPORT
- }
-#endif // QOS_DLS_SUPPORT //
-
- //
- // 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);
-#ifdef QOS_DLS_SUPPORT
- if ((pHeader->FC.FrDs == 0) && (pHeader->FC.ToDs == 0))
- RX_BLK_SET_FLAG(pRxBlk, fRX_DLS);
- else
-#endif // QOS_DLS_SUPPORT //
- 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 = (UCHAR *)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;
-
- // 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
- {
-#ifdef DOT11_N_SUPPORT
- RX_BLK_SET_FLAG(pRxBlk, fRX_HTC);
- // skip HTC contorl field
- pRxBlk->pData += 4;
- pRxBlk->DataSize -= 4;
-#endif // DOT11_N_SUPPORT //
- }
- }
-
- // 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;
- }
-
-#ifdef DOT11_N_SUPPORT
- if (pRxD->BA)
- {
- RX_BLK_SET_FLAG(pRxBlk, fRX_AMPDU);
- }
-#endif // DOT11_N_SUPPORT //
-
-
- //
- // 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 = (USHORT)((pRxWI->MCS) + (pRxWI->BW <<7) + (pRxWI->ShortGI <<8)+ (pRxWI->PHYMODE <<14)) ;
-
-
-#ifdef QOS_DLS_SUPPORT
- if (RX_BLK_TEST_FLAG(pRxBlk, fRX_DLS))
- {
- MAC_TABLE_ENTRY *pDlsEntry = NULL;
-
- pDlsEntry = DlsEntryTableLookupByWcid(pAd, pRxWI->WirelessCliID, pHeader->Addr2, TRUE);
- if(pDlsEntry)
- Update_Rssi_Sample(pAd, &pDlsEntry->RssiSample, pRxWI);
- }
- else
-#endif // QOS_DLS_SUPPORT //
- 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 = (UCHAR)(pRxWI->SNR0);
- pAd->StaCfg.LastSNR1 = (UCHAR)(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(
- IN PRTMP_ADAPTER pAd,
- IN RX_BLK *pRxBlk)
-{
- PRT28XX_RXD_STRUC pRxD = &(pRxBlk->RxD);
- PRXWI_STRUC pRxWI = pRxBlk->pRxWI;
- PHEADER_802_11 pHeader = pRxBlk->pHeader;
- PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket;
-
- do
- {
-
- // 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)))
- {
- Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, pRxWI);
-
- pAd->StaCfg.LastSNR0 = (UCHAR)(pRxWI->SNR0);
- pAd->StaCfg.LastSNR1 = (UCHAR)(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(
- IN PRTMP_ADAPTER pAd,
- IN RX_BLK *pRxBlk)
-{
-#ifdef DOT11_N_SUPPORT
- PRXWI_STRUC pRxWI = pRxBlk->pRxWI;
-#endif // DOT11_N_SUPPORT //
- PHEADER_802_11 pHeader = pRxBlk->pHeader;
- PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket;
-
- switch (pHeader->FC.SubType)
- {
- case SUBTYPE_BLOCK_ACK_REQ:
-#ifdef DOT11_N_SUPPORT
- {
- CntlEnqueueForRecv(pAd, pRxWI->WirelessCliID, (pRxWI->MPDUtotalByteCount), (PFRAME_BA_REQ)pHeader);
- }
- break;
-#endif // DOT11_N_SUPPORT //
- 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(
- IN PRTMP_ADAPTER pAd,
- IN BOOLEAN argc)
-{
- NDIS_STATUS Status;
- UINT32 RxProcessed, RxPending;
- BOOLEAN bReschedule = FALSE;
- RT28XX_RXD_STRUC *pRxD;
- UCHAR *pData;
- PRXWI_STRUC pRxWI;
- PNDIS_PACKET pRxPacket;
- PHEADER_802_11 pHeader;
- 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;
- }
-
-
- 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 = (PRXWI_STRUC) pData;
- pHeader = (PHEADER_802_11) (pData+RXWI_SIZE) ;
-
-#ifdef RT_BIG_ENDIAN
- RTMPFrameEndianChange(pAd, (PUCHAR)pHeader, DIR_READ, TRUE);
- RTMPWIEndianChange((PUCHAR)pRxWI, TYPE_RXWI);
-#endif
-
- // build RxCell
- RxCell.pRxWI = pRxWI;
- RxCell.pHeader = pHeader;
- RxCell.pRxPacket = pRxPacket;
- RxCell.pData = (UCHAR *) 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.RxCount ++;
-
- INC_COUNTER64(pAd->WlanCounters.ReceivedFragmentCount);
-
- if (pRxWI->MPDUtotalByteCount < 14)
- Status = NDIS_STATUS_FAILURE;
-
- if (MONITOR_ON(pAd))
- {
- send_monitor_packets(pAd, &RxCell);
- break;
- }
- /* RT2870 invokes STARxDoneInterruptHandle() in rtusb_bulk.c */
-#ifdef RALINK_ATE
- if (ATE_ON(pAd))
- {
- pAd->ate.RxCntPerSec++;
- ATESampleRssi(pAd, pRxWI);
-#ifdef RALINK_28xx_QA
- if (pAd->ate.bQARxStart == TRUE)
- {
- /* (*pRxD) has been swapped in GetPacketFromRxRing() */
- ATE_QA_Statistics(pAd, pRxWI, pRxD, pHeader);
- }
-#endif // RALINK_28xx_QA //
- RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_SUCCESS);
- continue;
- }
-#endif // RALINK_ATE //
-
- // 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(
- IN PRTMP_ADAPTER pAd)
-{
- AsicForceWakeup(pAd, FALSE);
-}
-
-/*
-========================================================================
-Routine Description:
- Early checking and OS-depened parsing for Tx packet send to our STA driver.
-
-Arguments:
- NDIS_HANDLE MiniportAdapterContext Pointer refer to the device handle, i.e., the pAd.
- PPNDIS_PACKET ppPacketArray The packet array need to do transmission.
- UINT 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(
- IN NDIS_HANDLE MiniportAdapterContext,
- IN PPNDIS_PACKET ppPacketArray,
- IN UINT NumberOfPackets)
-{
- UINT Index;
- PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) MiniportAdapterContext;
- PNDIS_PACKET 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
-#ifdef QOS_DLS_SUPPORT
- MAC_TABLE_ENTRY *pEntry;
- PUCHAR pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
-
- pEntry = MacTableLookup(pAd, pSrcBufVA);
- if (pEntry && (pEntry->ValidAsDls == TRUE))
- {
- RTMP_SET_PACKET_WCID(pPacket, pEntry->Aid);
- }
- else
-#endif // QOS_DLS_SUPPORT //
- 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 succes 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.
-========================================================================
-*/
-NDIS_STATUS STASendPacket(
- IN PRTMP_ADAPTER pAd,
- IN PNDIS_PACKET pPacket)
-{
- PACKET_INFO PacketInfo;
- PUCHAR pSrcBufVA;
- UINT SrcBufLen;
- UINT AllowFragSize;
- UCHAR NumberOfFrag;
-// UCHAR RTSRequired;
- UCHAR QueIdx, UserPriority;
- MAC_TABLE_ENTRY *pEntry = NULL;
- unsigned int IrqFlags;
- UCHAR FlgIsIP = 0;
- UCHAR 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))
- {
-#ifdef QOS_DLS_SUPPORT
- USHORT tmpWcid;
-
- tmpWcid = RTMP_GET_PACKET_WCID(pPacket);
- if (VALID_WCID(tmpWcid) &&
- (pAd->MacTab.Content[tmpWcid].ValidAsDls== TRUE))
- {
- pEntry = &pAd->MacTab.Content[tmpWcid];
- Rate = pAd->MacTab.Content[tmpWcid].CurrTxRate;
- }
- else
-#endif // QOS_DLS_SUPPORT //
- {
- 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(%2x:%2x:%2x:%2x:%2x:%2x) in MacTab!\n", PRINT_MAC(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, (UCHAR)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)
-#ifdef WPA_SUPPLICANT_SUPPORT
- || (pAd->StaCfg.IEEE8021X == TRUE)
-#endif // WPA_SUPPLICANT_SUPPORT //
-#ifdef LEAP_SUPPORT
- || (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
-#endif // LEAP_SUPPORT //
- )
- && ((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
-#ifdef DOT11_N_SUPPORT
- else if ((pAd->StaCfg.HTPhyMode.field.MODE == MODE_HTMIX) || (pAd->StaCfg.HTPhyMode.field.MODE == MODE_HTGREENFIELD))
- NumberOfFrag = 1; // MIMO RATE overwhelms fragmentation
-#endif // DOT11_N_SUPPORT //
- 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);
- 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))
- {
- USHORT Protocol;
- UCHAR LlcSnapLen = 0, Byte0, Byte1;
- do
- {
- // get Ethernet protocol field
- Protocol = (USHORT)((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 = (USHORT)((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
- 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);
-#ifdef BLOCK_NET_IF
- StopNetIfQueue(pAd, QueIdx, pPacket);
-#endif // BLOCK_NET_IF //
- RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
-
- return NDIS_STATUS_FAILURE;
- }
- else
- {
- InsertTailQueue(&pAd->TxSwQueue[QueIdx], PACKET_TO_QUEUE_ENTRY(pPacket));
- }
- RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
-
-#ifdef DOT11_N_SUPPORT
- if ((pAd->CommonCfg.BACapability.field.AutoBA == TRUE)&&
- IS_HT_STA(pEntry))
- {
- //PMAC_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_11WEPDisabled || pEntry->WepStatus == Ndis802_11Encryption3Enabled))
- )
- {
- BAOriSessionSetUp(pAd, pEntry, 0, 0, 10, FALSE);
- }
- }
-#endif // DOT11_N_SUPPORT //
-
- 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 RT2870
-/*
- 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.
-*/
-NDIS_STATUS RTMPFreeTXDRequest(
- IN PRTMP_ADAPTER pAd,
- IN UCHAR QueIdx,
- IN UCHAR NumberRequired,
- IN PUCHAR FreeNumberIs)
-{
- //ULONG FreeNumber = 0;
- NDIS_STATUS Status = NDIS_STATUS_FAILURE;
- unsigned long IrqFlags;
- HT_TX_CONTEXT *pHTTXContext;
-
- switch (QueIdx)
- {
- case QID_AC_BK:
- case QID_AC_BE:
- case QID_AC_VI:
- case QID_AC_VO:
- case QID_HCCA:
- {
- 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 // RT2870 //
-
-
-VOID RTMPSendDisassociationFrame(
- IN PRTMP_ADAPTER pAd)
-{
-}
-
-VOID RTMPSendNullFrame(
- IN PRTMP_ADAPTER pAd,
- IN UCHAR TxRate,
- IN BOOLEAN bQosNull)
-{
- UCHAR NullFrame[48];
- ULONG Length;
- PHEADER_802_11 pHeader_802_11;
-
-
-#ifdef RALINK_ATE
- if(ATE_ON(pAd))
- {
- return;
- }
-#endif // RALINK_ATE //
-
- // 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)
-#ifdef WPA_SUPPLICANT_SUPPORT
- || (pAd->StaCfg.IEEE8021X == TRUE)
-#endif
- ) &&
- (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
- {
- return;
- }
-
- NdisZeroMemory(NullFrame, 48);
- Length = sizeof(HEADER_802_11);
-
- pHeader_802_11 = (PHEADER_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(
- IN PRTMP_ADAPTER pAd,
- IN PUCHAR pDA,
- IN unsigned int NextMpduSize,
- IN UCHAR TxRate,
- IN UCHAR RTSRate,
- IN USHORT AckDuration,
- IN UCHAR QueIdx,
- IN UCHAR 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(
- IN PRTMP_ADAPTER pAd,
- IN TX_BLK *pTxBlk)
-{
- NDIS_802_11_ENCRYPTION_STATUS Cipher; // To indicate cipher used for this packet
- UCHAR CipherAlg = CIPHER_NONE; // cipher alogrithm
- UCHAR KeyIdx = 0xff;
- PUCHAR pSrcBufVA;
- PCIPHER_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)
- {
-#ifdef LEAP_SUPPORT
- if (pAd->StaCfg.CkipFlag & 0x10) // Cisco CKIP KP is on
- {
- if (LEAP_CCKM_ON(pAd))
- {
- if (((*pSrcBufVA & 0x01) && (ADHOC_ON(pAd))))
- KeyIdx = 1;
- else
- KeyIdx = 0;
- }
- else
- KeyIdx = pAd->StaCfg.DefaultKeyId;
- }
- else if (pAd->StaCfg.CkipFlag & 0x08) // only CKIP CMIC
- KeyIdx = pAd->StaCfg.DefaultKeyId;
- else if (LEAP_CCKM_ON(pAd))
- {
- if ((*pSrcBufVA & 0x01) && (ADHOC_ON(pAd)))
- KeyIdx = 1;
- else
- KeyIdx = 0;
- }
- else // standard WEP64 or WEP128
-#endif // LEAP_SUPPORT //
- 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;
-#ifdef WPA_SUPPLICANT_SUPPORT
- else if ( pAd->StaCfg.WpaSupplicantUP &&
- (Cipher == Ndis802_11Encryption1Enabled) &&
- (pAd->StaCfg.IEEE8021X == TRUE) &&
- (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
- CipherAlg = CIPHER_NONE;
-#endif // WPA_SUPPLICANT_SUPPORT //
- 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(
- IN PRTMP_ADAPTER pAd,
- IN TX_BLK *pTxBlk)
-{
-
- HEADER_802_11 *pHeader_802_11;
-#ifdef QOS_DLS_SUPPORT
- BOOLEAN bDLSFrame = FALSE;
- INT DlsEntryIndex = 0;
-#endif // QOS_DLS_SUPPORT //
-
- //
- // MAKE A COMMON 802.11 HEADER
- //
-
- // normal wlan header size : 24 octets
- pTxBlk->MpduHeaderLen = sizeof(HEADER_802_11);
-
- pHeader_802_11 = (HEADER_802_11 *) &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
-
- NdisZeroMemory(pHeader_802_11, sizeof(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);
-
-#ifdef QOS_DLS_SUPPORT
- if (INFRA_ON(pAd))
- {
- // 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)
- DlsEntryIndex = RTMPCheckDLSFrame(pAd, pTxBlk->pSrcBufHeader);
- if (DlsEntryIndex >= 0)
- bDLSFrame = TRUE;
- else
- bDLSFrame = FALSE;
- }
-#endif // QOS_DLS_SUPPORT //
-
- 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))
- {
-#ifdef QOS_DLS_SUPPORT
- if (bDLSFrame)
- {
- 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;
- }
- else
-#endif // QOS_DLS_SUPPORT //
- {
- 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);
-}
-
-#ifdef DOT11_N_SUPPORT
-VOID STABuildCache802_11Header(
- IN RTMP_ADAPTER *pAd,
- IN TX_BLK *pTxBlk,
- IN UCHAR *pHeader)
-{
- MAC_TABLE_ENTRY *pMacEntry;
- PHEADER_802_11 pHeader80211;
-
- pHeader80211 = (PHEADER_802_11)pHeader;
- pMacEntry = pTxBlk->pMacEntry;
-
- //
- // Update the cached 802.11 HEADER
- //
-
- // normal wlan header size : 24 octets
- pTxBlk->MpduHeaderLen = sizeof(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)
-#ifdef QOS_DLS_SUPPORT
- BOOLEAN bDLSFrame = FALSE;
- INT DlsEntryIndex = 0;
-
- DlsEntryIndex = RTMPCheckDLSFrame(pAd, pTxBlk->pSrcBufHeader);
- if (DlsEntryIndex >= 0)
- bDLSFrame = TRUE;
- else
- bDLSFrame = FALSE;
-#endif // QOS_DLS_SUPPORT //
-
- // The addr3 of normal packet send from DS is Dest Mac address.
-#ifdef QOS_DLS_SUPPORT
- if (bDLSFrame)
- {
- COPY_MAC_ADDR(pHeader80211->Addr1, pTxBlk->pSrcBufHeader);
- COPY_MAC_ADDR(pHeader80211->Addr3, pAd->CommonCfg.Bssid);
- pHeader80211->FC.ToDs = 0;
- }
- else
-#endif // QOS_DLS_SUPPORT //
- 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);
-}
-#endif // DOT11_N_SUPPORT //
-
-static inline PUCHAR STA_Build_ARalink_Frame_Header(
- IN RTMP_ADAPTER *pAd,
- IN TX_BLK *pTxBlk)
-{
- PUCHAR pHeaderBufPtr;
- HEADER_802_11 *pHeader_802_11;
- PNDIS_PACKET pNextPacket;
- UINT32 nextBufLen;
- PQUEUE_ENTRY pQEntry;
-
- STAFindCipherAlgorithm(pAd, pTxBlk);
- STABuildCommon802_11Header(pAd, pTxBlk);
-
-
- pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
- pHeader_802_11 = (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 = (ULONG)pHeaderBufPtr;
- pHeaderBufPtr = (PCHAR)ROUND_UP(pHeaderBufPtr, 4);
- pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
-
- // For RA Aggregation,
- // put the 2nd MSDU length(extra 2-byte field) after QOS_CONTROL in little endian format
- pQEntry = pTxBlk->TxPacketList.Head;
- pNextPacket = QUEUE_ENTRY_TO_PKT(pQEntry);
- nextBufLen = GET_OS_PKT_LEN(pNextPacket);
- if (RTMP_GET_PACKET_VLAN(pNextPacket))
- nextBufLen -= LENGTH_802_1Q;
-
- *pHeaderBufPtr = (UCHAR)nextBufLen & 0xff;
- *(pHeaderBufPtr+1) = (UCHAR)(nextBufLen >> 8);
-
- pHeaderBufPtr += 2;
- pTxBlk->MpduHeaderLen += 2;
-
- return pHeaderBufPtr;
-
-}
-
-#ifdef DOT11_N_SUPPORT
-static inline PUCHAR STA_Build_AMSDU_Frame_Header(
- IN RTMP_ADAPTER *pAd,
- IN TX_BLK *pTxBlk)
-{
- PUCHAR pHeaderBufPtr;//, pSaveBufPtr;
- HEADER_802_11 *pHeader_802_11;
-
-
- STAFindCipherAlgorithm(pAd, pTxBlk);
- STABuildCommon802_11Header(pAd, pTxBlk);
-
- pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
- pHeader_802_11 = (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 = (ULONG)pHeaderBufPtr;
- pHeaderBufPtr = (PCHAR) ROUND_UP(pHeaderBufPtr, 4);
- pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
-
- return pHeaderBufPtr;
-
-}
-
-
-VOID STA_AMPDU_Frame_Tx(
- IN PRTMP_ADAPTER pAd,
- IN TX_BLK *pTxBlk)
-{
- HEADER_802_11 *pHeader_802_11;
- PUCHAR pHeaderBufPtr;
- USHORT FreeNumber;
- MAC_TABLE_ENTRY *pMacEntry;
- BOOLEAN bVLANPkt;
- PQUEUE_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((PUCHAR)&pTxBlk->HeaderBuf[TXINFO_SIZE], (PUCHAR)&pMacEntry->CachedBuf[0], TXWI_SIZE + sizeof(HEADER_802_11));
- pHeaderBufPtr = (PUCHAR)(&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 = (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 = (ULONG)pHeaderBufPtr;
- pHeaderBufPtr = (PCHAR) ROUND_UP(pHeaderBufPtr, 4);
- pTxBlk->HdrPadLen = (ULONG)(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, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
- }
- else
- {
- RTMPWriteTxWI_Data(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
-
- NdisZeroMemory((PUCHAR)(&pMacEntry->CachedBuf[0]), sizeof(pMacEntry->CachedBuf));
- NdisMoveMemory((PUCHAR)(&pMacEntry->CachedBuf[0]), (PUCHAR)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), (pHeaderBufPtr - (PUCHAR)(&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
- //
- HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
-
- pAd->RalinkCounters.KickTxCount++;
- pAd->RalinkCounters.OneSecTxDoneCount++;
- }
-
-}
-
-
-VOID STA_AMSDU_Frame_Tx(
- IN PRTMP_ADAPTER pAd,
- IN TX_BLK *pTxBlk)
-{
- PUCHAR pHeaderBufPtr;
- USHORT FreeNumber;
- USHORT subFramePayloadLen = 0; // AMSDU Subframe length without AMSDU-Header / Padding.
- USHORT totalMPDUSize=0;
- UCHAR *subFrameHeader;
- UCHAR padding = 0;
- USHORT FirstTx = 0, LastTxIdx = 0;
- BOOLEAN bVLANPkt;
- int frameNum = 0;
- PQUEUE_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, (PTXWI_STRUC)(&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
- //
- HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
-}
-#endif // DOT11_N_SUPPORT //
-
-VOID STA_Legacy_Frame_Tx(
- IN PRTMP_ADAPTER pAd,
- IN TX_BLK *pTxBlk)
-{
- HEADER_802_11 *pHeader_802_11;
- PUCHAR pHeaderBufPtr;
- USHORT FreeNumber;
- BOOLEAN bVLANPkt;
- PQUEUE_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 = (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;
- }
-
- // The remaining content of MPDU header should locate at 4-octets aligment
- pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
- pHeaderBufPtr = (PCHAR) ROUND_UP(pHeaderBufPtr, 4);
- pTxBlk->HdrPadLen = (ULONG)(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)
- {
- UCHAR 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, (PTXWI_STRUC)(&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
- //
- HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
-}
-
-
-VOID STA_ARalink_Frame_Tx(
- IN PRTMP_ADAPTER pAd,
- IN TX_BLK *pTxBlk)
-{
- PUCHAR pHeaderBufPtr;
- USHORT FreeNumber;
- USHORT totalMPDUSize=0;
- USHORT FirstTx, LastTxIdx;
- int frameNum = 0;
- BOOLEAN bVLANPkt;
- PQUEUE_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, (PTXWI_STRUC)(&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
- //
- HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
-
-}
-
-
-VOID STA_Fragment_Frame_Tx(
- IN RTMP_ADAPTER *pAd,
- IN TX_BLK *pTxBlk)
-{
- HEADER_802_11 *pHeader_802_11;
- PUCHAR pHeaderBufPtr;
- USHORT FreeNumber;
- UCHAR fragNum = 0;
- PACKET_INFO PacketInfo;
- USHORT EncryptionOverhead = 0;
- UINT32 FreeMpduSize, SrcRemainingBytes;
- USHORT AckDuration;
- UINT NextMpduSize;
- BOOLEAN bVLANPkt;
- PQUEUE_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;
- }
-
- 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 = (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 = (ULONG)pHeaderBufPtr;
- pHeaderBufPtr = (PCHAR) ROUND_UP(pHeaderBufPtr, 4);
- pTxBlk->HdrPadLen = (ULONG)(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)
- {
- UCHAR 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)
- {
-
- // 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;
-
- // decide how much time an ACK/CTS frame will consume in the air
- AckDuration = RTMPCalcDuration(pAd, pAd->CommonCfg.ExpectedACKRate[pTxBlk->TxRate], 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(((UINT)SrcRemainingBytes - pTxBlk->SrcBufLen), ((UINT)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, (PTXWI_STRUC)(&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
- //
- 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
- PNDIS_PACKET Pointer to outgoing Ndis frame
- NumberOfFrag Number of fragment required
-
- Return Value:
- None
-
- IRQL = DISPATCH_LEVEL
-
- Note:
-
- ========================================================================
-*/
-NDIS_STATUS STAHardTransmit(
- IN PRTMP_ADAPTER pAd,
- IN TX_BLK *pTxBlk,
- IN UCHAR QueIdx)
-{
- NDIS_PACKET *pPacket;
- PQUEUE_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);
-
-#if 0 //def CARRIER_DETECTION_SUPPORT // Roger sync Carrier
- if ((pAd->CommonCfg.CarrierDetect.Enable == TRUE) && (isCarrierDetectExist(pAd) == TRUE))
- {
- DBGPRINT(RT_DEBUG_INFO,("STAHardTransmit --> radar detect not in normal mode !!!\n"));
- RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
- return (NDIS_STATUS_FAILURE);
- }
-#endif // CARRIER_DETECTION_SUPPORT //
-
- // ------------------------------------------------------------------
- // 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_TRACE, ("AsicForceWakeup At HardTx\n"));
- AsicForceWakeup(pAd, TRUE);
- }
-
- // 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))
- MlmeSetPsmBit(pAd, PWR_ACTIVE);
- }
-
- switch (pTxBlk->TxFrameType)
- {
-#ifdef DOT11_N_SUPPORT
- case TX_AMPDU_FRAME:
- STA_AMPDU_Frame_Tx(pAd, pTxBlk);
- break;
- case TX_AMSDU_FRAME:
- STA_AMSDU_Frame_Tx(pAd, pTxBlk);
- break;
-#endif // DOT11_N_SUPPORT //
- 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 pacekt 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);
-
-}
-
-ULONG HashBytesPolynomial(UCHAR *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(
- IN PRTMP_ADAPTER pAd,
- IN PNDIS_PACKET pPacket,
- IN UCHAR FromWhichBSSID)
-{
- if (TRUE
- )
- {
- announce_802_3_packet(pAd, pPacket);
- }
- else
- {
- // release packet
- RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
- }
-}
-
+#include "../../rt2860/sta/rtmp_data.c"