diff options
Diffstat (limited to 'drivers/staging/rt2860/sta/rtmp_data.c')
-rw-r--r-- | drivers/staging/rt2860/sta/rtmp_data.c | 2552 |
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); - } -} |