diff options
Diffstat (limited to 'drivers/staging/rt2860/common/cmm_data.c')
-rw-r--r-- | drivers/staging/rt2860/common/cmm_data.c | 2361 |
1 files changed, 0 insertions, 2361 deletions
diff --git a/drivers/staging/rt2860/common/cmm_data.c b/drivers/staging/rt2860/common/cmm_data.c deleted file mode 100644 index 33799e1449ae..000000000000 --- a/drivers/staging/rt2860/common/cmm_data.c +++ /dev/null @@ -1,2361 +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. * - * * - ************************************************************************* -*/ - -#include "../rt_config.h" - -u8 SNAP_802_1H[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 }; -u8 SNAP_BRIDGE_TUNNEL[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 }; - -/* Add Cisco Aironet SNAP heade for CCX2 support */ -u8 SNAP_AIRONET[] = { 0xaa, 0xaa, 0x03, 0x00, 0x40, 0x96, 0x00, 0x00 }; -u8 CKIP_LLC_SNAP[] = { 0xaa, 0xaa, 0x03, 0x00, 0x40, 0x96, 0x00, 0x02 }; -u8 EAPOL_LLC_SNAP[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8e }; -u8 EAPOL[] = { 0x88, 0x8e }; -u8 TPID[] = { 0x81, 0x00 }; /* VLAN related */ - -u8 IPX[] = { 0x81, 0x37 }; -u8 APPLE_TALK[] = { 0x80, 0xf3 }; - -u8 RateIdToPlcpSignal[12] = { - 0, /* RATE_1 */ 1, /* RATE_2 */ 2, /* RATE_5_5 */ 3, /* RATE_11 *//* see BBP spec */ - 11, /* RATE_6 */ 15, /* RATE_9 */ 10, /* RATE_12 */ 14, /* RATE_18 *//* see IEEE802.11a-1999 p.14 */ - 9, /* RATE_24 */ 13, /* RATE_36 */ 8, /* RATE_48 */ 12 /* RATE_54 */ -}; /* see IEEE802.11a-1999 p.14 */ - -u8 OfdmSignalToRateId[16] = { - RATE_54, RATE_54, RATE_54, RATE_54, /* OFDM PLCP Signal = 0, 1, 2, 3 respectively */ - RATE_54, RATE_54, RATE_54, RATE_54, /* OFDM PLCP Signal = 4, 5, 6, 7 respectively */ - RATE_48, RATE_24, RATE_12, RATE_6, /* OFDM PLCP Signal = 8, 9, 10, 11 respectively */ - RATE_54, RATE_36, RATE_18, RATE_9, /* OFDM PLCP Signal = 12, 13, 14, 15 respectively */ -}; - -u8 OfdmRateToRxwiMCS[12] = { - 0, 0, 0, 0, - 0, 1, 2, 3, /* OFDM rate 6,9,12,18 = rxwi mcs 0,1,2,3 */ - 4, 5, 6, 7, /* OFDM rate 24,36,48,54 = rxwi mcs 4,5,6,7 */ -}; - -u8 RxwiMCSToOfdmRate[12] = { - RATE_6, RATE_9, RATE_12, RATE_18, - RATE_24, RATE_36, RATE_48, RATE_54, /* OFDM rate 6,9,12,18 = rxwi mcs 0,1,2,3 */ - 4, 5, 6, 7, /* OFDM rate 24,36,48,54 = rxwi mcs 4,5,6,7 */ -}; - -char *MCSToMbps[] = - { "1Mbps", "2Mbps", "5.5Mbps", "11Mbps", "06Mbps", "09Mbps", "12Mbps", -"18Mbps", "24Mbps", "36Mbps", "48Mbps", "54Mbps", "MM-0", "MM-1", "MM-2", "MM-3", -"MM-4", "MM-5", "MM-6", "MM-7", "MM-8", "MM-9", "MM-10", "MM-11", "MM-12", "MM-13", -"MM-14", "MM-15", "MM-32", "ee1", "ee2", "ee3" }; - -u8 default_cwmin[] = - { CW_MIN_IN_BITS, CW_MIN_IN_BITS, CW_MIN_IN_BITS - 1, CW_MIN_IN_BITS - 2 }; -/*u8 default_cwmax[]={CW_MAX_IN_BITS, CW_MAX_IN_BITS, CW_MIN_IN_BITS, CW_MIN_IN_BITS-1}; */ -u8 default_sta_aifsn[] = { 3, 7, 2, 2 }; - -u8 MapUserPriorityToAccessCategory[8] = - { QID_AC_BE, QID_AC_BK, QID_AC_BK, QID_AC_BE, QID_AC_VI, QID_AC_VI, -QID_AC_VO, QID_AC_VO }; - -/* - ======================================================================== - - Routine Description: - API for MLME to transmit management frame to AP (BSS Mode) - or station (IBSS Mode) - - Arguments: - pAd Pointer to our adapter - pData Pointer to the outgoing 802.11 frame - Length Size of outgoing management frame - - Return Value: - NDIS_STATUS_FAILURE - NDIS_STATUS_PENDING - NDIS_STATUS_SUCCESS - - IRQL = PASSIVE_LEVEL - IRQL = DISPATCH_LEVEL - - Note: - - ======================================================================== -*/ -int MiniportMMRequest(struct rt_rtmp_adapter *pAd, - u8 QueIdx, u8 *pData, u32 Length) -{ - void *pPacket; - int Status = NDIS_STATUS_SUCCESS; - unsigned long FreeNum; - u8 rtmpHwHdr[TXINFO_SIZE + TXWI_SIZE]; /*RTMP_HW_HDR_LEN]; */ -#ifdef RTMP_MAC_PCI - unsigned long IrqFlags = 0; - u8 IrqState; -#endif /* RTMP_MAC_PCI // */ - BOOLEAN bUseDataQ = FALSE; - int retryCnt = 0; - - ASSERT(Length <= MGMT_DMA_BUFFER_SIZE); - - if ((QueIdx & MGMT_USE_QUEUE_FLAG) == MGMT_USE_QUEUE_FLAG) { - bUseDataQ = TRUE; - QueIdx &= (~MGMT_USE_QUEUE_FLAG); - } -#ifdef RTMP_MAC_PCI - /* 2860C use Tx Ring */ - IrqState = pAd->irq_disabled; - if (pAd->MACVersion == 0x28600100) { - QueIdx = (bUseDataQ == TRUE ? QueIdx : 3); - bUseDataQ = TRUE; - } - if (bUseDataQ && (!IrqState)) - RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags); -#endif /* RTMP_MAC_PCI // */ - - do { - /* Reset is in progress, stop immediately */ - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) || - RTMP_TEST_FLAG(pAd, - fRTMP_ADAPTER_HALT_IN_PROGRESS | - fRTMP_ADAPTER_NIC_NOT_EXIST) - || !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP)) { - Status = NDIS_STATUS_FAILURE; - break; - } - /* Check Free priority queue */ - /* Since we use PBF Queue2 for management frame. Its corresponding DMA ring should be using TxRing. */ -#ifdef RTMP_MAC_PCI - if (bUseDataQ) { - retryCnt = MAX_DATAMM_RETRY; - /* free Tx(QueIdx) resources */ - RTMPFreeTXDUponTxDmaDone(pAd, QueIdx); - FreeNum = GET_TXRING_FREENO(pAd, QueIdx); - } else -#endif /* RTMP_MAC_PCI // */ - { - FreeNum = GET_MGMTRING_FREENO(pAd); - } - - if ((FreeNum > 0)) { - /* We need to reserve space for rtmp hardware header. i.e., TxWI for RT2860 and TxInfo+TxWI for RT2870 */ - NdisZeroMemory(&rtmpHwHdr, (TXINFO_SIZE + TXWI_SIZE)); - Status = - RTMPAllocateNdisPacket(pAd, &pPacket, - (u8 *)& rtmpHwHdr, - (TXINFO_SIZE + TXWI_SIZE), - pData, Length); - if (Status != NDIS_STATUS_SUCCESS) { - DBGPRINT(RT_DEBUG_WARN, - ("MiniportMMRequest (error:: can't allocate NDIS PACKET)\n")); - break; - } - /*pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK; */ - /*pAd->CommonCfg.MlmeRate = RATE_2; */ - -#ifdef RTMP_MAC_PCI - if (bUseDataQ) { - Status = - MlmeDataHardTransmit(pAd, QueIdx, pPacket); - retryCnt--; - } else -#endif /* RTMP_MAC_PCI // */ - Status = MlmeHardTransmit(pAd, QueIdx, pPacket); - if (Status == NDIS_STATUS_SUCCESS) - retryCnt = 0; - else - RTMPFreeNdisPacket(pAd, pPacket); - } else { - pAd->RalinkCounters.MgmtRingFullCount++; -#ifdef RTMP_MAC_PCI - if (bUseDataQ) { - retryCnt--; - DBGPRINT(RT_DEBUG_TRACE, - ("retryCnt %d\n", retryCnt)); - if (retryCnt == 0) { - DBGPRINT(RT_DEBUG_ERROR, - ("Qidx(%d), not enough space in DataRing, MgmtRingFullCount=%ld!\n", - QueIdx, - pAd->RalinkCounters. - MgmtRingFullCount)); - } - } -#endif /* RTMP_MAC_PCI // */ - DBGPRINT(RT_DEBUG_ERROR, - ("Qidx(%d), not enough space in MgmtRing, MgmtRingFullCount=%ld!\n", - QueIdx, - pAd->RalinkCounters.MgmtRingFullCount)); - } - } while (retryCnt > 0); - -#ifdef RTMP_MAC_PCI - if (bUseDataQ && (!IrqState)) - RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags); -#endif /* RTMP_MAC_PCI // */ - - return Status; -} - -/* - ======================================================================== - - Routine Description: - Copy frame from waiting queue into relative ring buffer and set - appropriate ASIC register to kick hardware transmit function - - Arguments: - pAd Pointer to our adapter - pBuffer Pointer to memory of outgoing frame - Length Size of outgoing management frame - - Return Value: - NDIS_STATUS_FAILURE - NDIS_STATUS_PENDING - NDIS_STATUS_SUCCESS - - IRQL = PASSIVE_LEVEL - IRQL = DISPATCH_LEVEL - - Note: - - ======================================================================== -*/ -int MlmeHardTransmit(struct rt_rtmp_adapter *pAd, - u8 QueIdx, void *pPacket) -{ - struct rt_packet_info PacketInfo; - u8 *pSrcBufVA; - u32 SrcBufLen; - struct rt_header_802_11 * pHeader_802_11; - - if ((pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE) - ) { - return NDIS_STATUS_FAILURE; - } - - RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen); - if (pSrcBufVA == NULL) - return NDIS_STATUS_FAILURE; - - pHeader_802_11 = (struct rt_header_802_11 *) (pSrcBufVA + TXINFO_SIZE + TXWI_SIZE); - -#ifdef RTMP_MAC_PCI - if (pAd->MACVersion == 0x28600100) - return MlmeHardTransmitTxRing(pAd, QueIdx, pPacket); - else -#endif /* RTMP_MAC_PCI // */ - return MlmeHardTransmitMgmtRing(pAd, QueIdx, pPacket); - -} - -int MlmeHardTransmitMgmtRing(struct rt_rtmp_adapter *pAd, - u8 QueIdx, void *pPacket) -{ - struct rt_packet_info PacketInfo; - u8 *pSrcBufVA; - u32 SrcBufLen; - struct rt_header_802_11 * pHeader_802_11; - BOOLEAN bAckRequired, bInsertTimestamp; - u8 MlmeRate; - struct rt_txwi * pFirstTxWI; - struct rt_mac_table_entry *pMacEntry = NULL; - u8 PID; - - RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen); - - /* Make sure MGMT ring resource won't be used by other threads */ - RTMP_SEM_LOCK(&pAd->MgmtRingLock); - if (pSrcBufVA == NULL) { - /* The buffer shouldn't be NULL */ - RTMP_SEM_UNLOCK(&pAd->MgmtRingLock); - return NDIS_STATUS_FAILURE; - } - - { - /* outgoing frame always wakeup PHY to prevent frame lost */ - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) - AsicForceWakeup(pAd, TRUE); - } - - pFirstTxWI = (struct rt_txwi *) (pSrcBufVA + TXINFO_SIZE); - pHeader_802_11 = (struct rt_header_802_11 *) (pSrcBufVA + TXINFO_SIZE + TXWI_SIZE); /*TXWI_SIZE); */ - - if (pHeader_802_11->Addr1[0] & 0x01) { - MlmeRate = pAd->CommonCfg.BasicMlmeRate; - } else { - MlmeRate = pAd->CommonCfg.MlmeRate; - } - - /* Verify Mlme rate for a / g bands. */ - if ((pAd->LatchRfRegs.Channel > 14) && (MlmeRate < RATE_6)) /* 11A band */ - MlmeRate = RATE_6; - - if ((pHeader_802_11->FC.Type == BTYPE_DATA) && - (pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL)) { - pMacEntry = MacTableLookup(pAd, pHeader_802_11->Addr1); - } - - { - /* Fixed W52 with Activity scan issue in ABG_MIXED and ABGN_MIXED mode. */ - if (pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED - || pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED) { - if (pAd->LatchRfRegs.Channel > 14) - pAd->CommonCfg.MlmeTransmit.field.MODE = 1; - else - pAd->CommonCfg.MlmeTransmit.field.MODE = 0; - } - } - - /* */ - /* Should not be hard code to set PwrMgmt to 0 (PWR_ACTIVE) */ - /* Snice it's been set to 0 while on MgtMacHeaderInit */ - /* By the way this will cause frame to be send on PWR_SAVE failed. */ - /* */ - pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE; /* (pAd->StaCfg.Psm == PWR_SAVE); */ - - /* */ - /* In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame */ - /* Data-Null packets also pass through MMRequest in RT2860, however, we hope control the psm bit to pass APSD */ -/* if ((pHeader_802_11->FC.Type != BTYPE_DATA) && (pHeader_802_11->FC.Type != BTYPE_CNTL)) */ - { - if ((pHeader_802_11->FC.SubType == SUBTYPE_ACTION) || - ((pHeader_802_11->FC.Type == BTYPE_DATA) && - ((pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL) || - (pHeader_802_11->FC.SubType == SUBTYPE_NULL_FUNC)))) { - if (pAd->StaCfg.Psm == PWR_SAVE) - pHeader_802_11->FC.PwrMgmt = PWR_SAVE; - else - pHeader_802_11->FC.PwrMgmt = - pAd->CommonCfg.bAPSDForcePowerSave; - } - } - - bInsertTimestamp = FALSE; - if (pHeader_802_11->FC.Type == BTYPE_CNTL) /* must be PS-POLL */ - { - /*Set PM bit in ps-poll, to fix WLK 1.2 PowerSaveMode_ext failure issue. */ - if ((pAd->OpMode == OPMODE_STA) - && (pHeader_802_11->FC.SubType == SUBTYPE_PS_POLL)) { - pHeader_802_11->FC.PwrMgmt = PWR_SAVE; - } - bAckRequired = FALSE; - } else /* BTYPE_MGMT or BTYPE_DATA(must be NULL frame) */ - { - /*pAd->Sequence++; */ - /*pHeader_802_11->Sequence = pAd->Sequence; */ - - if (pHeader_802_11->Addr1[0] & 0x01) /* MULTICAST, BROADCAST */ - { - bAckRequired = FALSE; - pHeader_802_11->Duration = 0; - } else { - bAckRequired = TRUE; - pHeader_802_11->Duration = - RTMPCalcDuration(pAd, MlmeRate, 14); - if ((pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP) - && (pHeader_802_11->FC.Type == BTYPE_MGMT)) { - bInsertTimestamp = TRUE; - bAckRequired = FALSE; /* Disable ACK to prevent retry 0x1f for Probe Response */ - } else - if ((pHeader_802_11->FC.SubType == - SUBTYPE_PROBE_REQ) - && (pHeader_802_11->FC.Type == BTYPE_MGMT)) { - bAckRequired = FALSE; /* Disable ACK to prevent retry 0x1f for Probe Request */ - } - } - } - - pHeader_802_11->Sequence = pAd->Sequence++; - if (pAd->Sequence > 0xfff) - pAd->Sequence = 0; - - /* Before radar detection done, mgmt frame can not be sent but probe req */ - /* Because we need to use probe req to trigger driver to send probe req in passive scan */ - if ((pHeader_802_11->FC.SubType != SUBTYPE_PROBE_REQ) - && (pAd->CommonCfg.bIEEE80211H == 1) - && (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)) { - DBGPRINT(RT_DEBUG_ERROR, - ("MlmeHardTransmit --> radar detect not in normal mode!\n")); -/* if (!IrqState) */ - RTMP_SEM_UNLOCK(&pAd->MgmtRingLock); - return (NDIS_STATUS_FAILURE); - } - - /* */ - /* fill scatter-and-gather buffer list into TXD. Internally created NDIS PACKET */ - /* should always has only one physical buffer, and the whole frame size equals */ - /* to the first scatter buffer size */ - /* */ - - /* Initialize TX Descriptor */ - /* For inter-frame gap, the number is for this frame and next frame */ - /* For MLME rate, we will fix as 2Mb to match other vendor's implement */ -/* pAd->CommonCfg.MlmeTransmit.field.MODE = 1; */ - -/* management frame doesn't need encryption. so use RESERVED_WCID no matter u are sending to specific wcid or not. */ - PID = PID_MGMT; - - if (pMacEntry == NULL) { - RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp, - FALSE, bAckRequired, FALSE, 0, RESERVED_WCID, - (SrcBufLen - TXINFO_SIZE - TXWI_SIZE), PID, 0, - (u8)pAd->CommonCfg.MlmeTransmit.field.MCS, - IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit); - } else { - /* dont use low rate to send QoS Null data frame */ - RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, - bInsertTimestamp, FALSE, bAckRequired, FALSE, - 0, pMacEntry->Aid, - (SrcBufLen - TXINFO_SIZE - TXWI_SIZE), - pMacEntry->MaxHTPhyMode.field.MCS, 0, - (u8)pMacEntry->MaxHTPhyMode.field.MCS, - IFS_BACKOFF, FALSE, &pMacEntry->MaxHTPhyMode); - } - - /* Now do hardware-depened kick out. */ - HAL_KickOutMgmtTx(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen); - - /* Make sure to release MGMT ring resource */ -/* if (!IrqState) */ - RTMP_SEM_UNLOCK(&pAd->MgmtRingLock); - return NDIS_STATUS_SUCCESS; -} - -/******************************************************************************** - - New DeQueue Procedures. - - ********************************************************************************/ - -#define DEQUEUE_LOCK(lock, bIntContext, IrqFlags) \ - do{ \ - if (bIntContext == FALSE) \ - RTMP_IRQ_LOCK((lock), IrqFlags); \ - }while(0) - -#define DEQUEUE_UNLOCK(lock, bIntContext, IrqFlags) \ - do{ \ - if (bIntContext == FALSE) \ - RTMP_IRQ_UNLOCK((lock), IrqFlags); \ - }while(0) - -/* - ======================================================================== - Tx Path design algorithm: - Basically, we divide the packets into four types, Broadcast/Multicast, 11N Rate(AMPDU, AMSDU, Normal), B/G Rate(ARALINK, Normal), - Specific Packet Type. Following show the classification rule and policy for each kinds of packets. - Classification Rule=> - Multicast: (*addr1 & 0x01) == 0x01 - Specific : bDHCPFrame, bARPFrame, bEAPOLFrame, etc. - 11N Rate : If peer support HT - (1).AMPDU -- If TXBA is negotiated. - (2).AMSDU -- If AMSDU is capable for both peer and ourself. - *). AMSDU can embedded in a AMPDU, but now we didn't support it. - (3).Normal -- Other packets which send as 11n rate. - - B/G Rate : If peer is b/g only. - (1).ARALINK-- If both of peer/us supprot Ralink proprietary Aggregation and the TxRate is large than RATE_6 - (2).Normal -- Other packets which send as b/g rate. - Fragment: - The packet must be unicast, NOT A-RALINK, NOT A-MSDU, NOT 11n, then can consider about fragment. - - Classified Packet Handle Rule=> - Multicast: - No ACK, //pTxBlk->bAckRequired = FALSE; - No WMM, //pTxBlk->bWMM = FALSE; - No piggyback, //pTxBlk->bPiggyBack = FALSE; - Force LowRate, //pTxBlk->bForceLowRate = TRUE; - Specific : Basically, for specific packet, we should handle it specifically, but now all specific packets are use - the same policy to handle it. - Force LowRate, //pTxBlk->bForceLowRate = TRUE; - - 11N Rate : - No piggyback, //pTxBlk->bPiggyBack = FALSE; - - (1).AMSDU - pTxBlk->bWMM = TRUE; - (2).AMPDU - pTxBlk->bWMM = TRUE; - (3).Normal - - B/G Rate : - (1).ARALINK - - (2).Normal - ======================================================================== -*/ -static u8 TxPktClassification(struct rt_rtmp_adapter *pAd, void *pPacket) -{ - u8 TxFrameType = TX_UNKOWN_FRAME; - u8 Wcid; - struct rt_mac_table_entry *pMacEntry = NULL; - BOOLEAN bHTRate = FALSE; - - Wcid = RTMP_GET_PACKET_WCID(pPacket); - if (Wcid == MCAST_WCID) { /* Handle for RA is Broadcast/Multicast Address. */ - return TX_MCAST_FRAME; - } - /* Handle for unicast packets */ - pMacEntry = &pAd->MacTab.Content[Wcid]; - if (RTMP_GET_PACKET_LOWRATE(pPacket)) { /* It's a specific packet need to force low rate, i.e., bDHCPFrame, bEAPOLFrame, bWAIFrame */ - TxFrameType = TX_LEGACY_FRAME; - } else if (IS_HT_RATE(pMacEntry)) { /* it's a 11n capable packet */ - - /* Depends on HTPhyMode to check if the peer support the HTRate transmission. */ - /* Currently didn't support A-MSDU embedded in A-MPDU */ - bHTRate = TRUE; - if (RTMP_GET_PACKET_MOREDATA(pPacket) - || (pMacEntry->PsMode == PWR_SAVE)) - TxFrameType = TX_LEGACY_FRAME; - else if ((pMacEntry-> - TXBAbitmap & (1 << (RTMP_GET_PACKET_UP(pPacket)))) != - 0) - return TX_AMPDU_FRAME; - else if (CLIENT_STATUS_TEST_FLAG - (pMacEntry, fCLIENT_STATUS_AMSDU_INUSED)) - return TX_AMSDU_FRAME; - else - TxFrameType = TX_LEGACY_FRAME; - } else { /* it's a legacy b/g packet. */ - if ((CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE) && pAd->CommonCfg.bAggregationCapable) && (RTMP_GET_PACKET_TXRATE(pPacket) >= RATE_6) && (!(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE)))) { /* if peer support Ralink Aggregation, we use it. */ - TxFrameType = TX_RALINK_FRAME; - } else { - TxFrameType = TX_LEGACY_FRAME; - } - } - - /* Currently, our fragment only support when a unicast packet send as NOT-ARALINK, NOT-AMSDU and NOT-AMPDU. */ - if ((RTMP_GET_PACKET_FRAGMENTS(pPacket) > 1) - && (TxFrameType == TX_LEGACY_FRAME)) - TxFrameType = TX_FRAG_FRAME; - - return TxFrameType; -} - -BOOLEAN RTMP_FillTxBlkInfo(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk) -{ - struct rt_packet_info PacketInfo; - void *pPacket; - struct rt_mac_table_entry *pMacEntry = NULL; - - pPacket = pTxBlk->pPacket; - RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pTxBlk->pSrcBufHeader, - &pTxBlk->SrcBufLen); - - pTxBlk->Wcid = RTMP_GET_PACKET_WCID(pPacket); - pTxBlk->apidx = RTMP_GET_PACKET_IF(pPacket); - pTxBlk->UserPriority = RTMP_GET_PACKET_UP(pPacket); - pTxBlk->FrameGap = IFS_HTTXOP; /* ASIC determine Frame Gap */ - - if (RTMP_GET_PACKET_CLEAR_EAP_FRAME(pTxBlk->pPacket)) - TX_BLK_SET_FLAG(pTxBlk, fTX_bClearEAPFrame); - else - TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bClearEAPFrame); - - /* Default to clear this flag */ - TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bForceNonQoS); - - if (pTxBlk->Wcid == MCAST_WCID) { - pTxBlk->pMacEntry = NULL; - { - pTxBlk->pTransmit = - &pAd->MacTab.Content[MCAST_WCID].HTPhyMode; - } - - TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired); /* AckRequired = FALSE, when broadcast packet in Adhoc mode. */ - /*TX_BLK_SET_FLAG(pTxBlk, fTX_bForceLowRate); */ - TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAllowFrag); - TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bWMM); - if (RTMP_GET_PACKET_MOREDATA(pPacket)) { - TX_BLK_SET_FLAG(pTxBlk, fTX_bMoreData); - } - - } else { - pTxBlk->pMacEntry = &pAd->MacTab.Content[pTxBlk->Wcid]; - pTxBlk->pTransmit = &pTxBlk->pMacEntry->HTPhyMode; - - pMacEntry = pTxBlk->pMacEntry; - - /* For all unicast packets, need Ack unless the Ack Policy is not set as NORMAL_ACK. */ - if (pAd->CommonCfg.AckPolicy[pTxBlk->QueIdx] != NORMAL_ACK) - TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired); - else - TX_BLK_SET_FLAG(pTxBlk, fTX_bAckRequired); - - if ((pAd->OpMode == OPMODE_STA) && - (ADHOC_ON(pAd)) && - (RX_FILTER_TEST_FLAG(pAd, fRX_FILTER_ACCEPT_PROMISCUOUS))) { - if (pAd->CommonCfg.PSPXlink) - TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired); - } - - { - { - - /* If support WMM, enable it. */ - if (OPSTATUS_TEST_FLAG - (pAd, fOP_STATUS_WMM_INUSED) - && CLIENT_STATUS_TEST_FLAG(pMacEntry, - fCLIENT_STATUS_WMM_CAPABLE)) - TX_BLK_SET_FLAG(pTxBlk, fTX_bWMM); - -/* if (pAd->StaCfg.bAutoTxRateSwitch) */ -/* TX_BLK_SET_FLAG(pTxBlk, fTX_AutoRateSwitch); */ - } - } - - if (pTxBlk->TxFrameType == TX_LEGACY_FRAME) { - if ((RTMP_GET_PACKET_LOWRATE(pPacket)) || ((pAd->OpMode == OPMODE_AP) && (pMacEntry->MaxHTPhyMode.field.MODE == MODE_CCK) && (pMacEntry->MaxHTPhyMode.field.MCS == RATE_1))) { /* Specific packet, i.e., bDHCPFrame, bEAPOLFrame, bWAIFrame, need force low rate. */ - pTxBlk->pTransmit = - &pAd->MacTab.Content[MCAST_WCID].HTPhyMode; - - /* Modify the WMM bit for ICV issue. If we have a packet with EOSP field need to set as 1, how to handle it??? */ - if (IS_HT_STA(pTxBlk->pMacEntry) && - (CLIENT_STATUS_TEST_FLAG - (pMacEntry, fCLIENT_STATUS_RALINK_CHIPSET)) - && ((pAd->CommonCfg.bRdg == TRUE) - && CLIENT_STATUS_TEST_FLAG(pMacEntry, - fCLIENT_STATUS_RDG_CAPABLE))) - { - TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bWMM); - TX_BLK_SET_FLAG(pTxBlk, - fTX_bForceNonQoS); - } - } - - if ((IS_HT_RATE(pMacEntry) == FALSE) && (CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE))) { /* Currently piggy-back only support when peer is operate in b/g mode. */ - TX_BLK_SET_FLAG(pTxBlk, fTX_bPiggyBack); - } - - if (RTMP_GET_PACKET_MOREDATA(pPacket)) { - TX_BLK_SET_FLAG(pTxBlk, fTX_bMoreData); - } - } else if (pTxBlk->TxFrameType == TX_FRAG_FRAME) { - TX_BLK_SET_FLAG(pTxBlk, fTX_bAllowFrag); - } - - pMacEntry->DebugTxCount++; - } - - return TRUE; -} - -BOOLEAN CanDoAggregateTransmit(struct rt_rtmp_adapter *pAd, - char * pPacket, struct rt_tx_blk *pTxBlk) -{ - - /*DBGPRINT(RT_DEBUG_TRACE, ("Check if can do aggregation! TxFrameType=%d!\n", pTxBlk->TxFrameType)); */ - - if (RTMP_GET_PACKET_WCID(pPacket) == MCAST_WCID) - return FALSE; - - if (RTMP_GET_PACKET_DHCP(pPacket) || - RTMP_GET_PACKET_EAPOL(pPacket) || RTMP_GET_PACKET_WAI(pPacket)) - return FALSE; - - if ((pTxBlk->TxFrameType == TX_AMSDU_FRAME) && ((pTxBlk->TotalFrameLen + GET_OS_PKT_LEN(pPacket)) > (RX_BUFFER_AGGRESIZE - 100))) { /* For AMSDU, allow the packets with total length < max-amsdu size */ - return FALSE; - } - - if ((pTxBlk->TxFrameType == TX_RALINK_FRAME) && (pTxBlk->TxPacketList.Number == 2)) { /* For RALINK-Aggregation, allow two frames in one batch. */ - return FALSE; - } - - if ((INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA)) /* must be unicast to AP */ - return TRUE; - else - return FALSE; - -} - -/* - ======================================================================== - - Routine Description: - To do the enqueue operation and extract the first item of waiting - list. If a number of available shared memory segments could meet - the request of extracted item, the extracted item will be fragmented - into shared memory segments. - - Arguments: - pAd Pointer to our adapter - pQueue Pointer to Waiting Queue - - Return Value: - None - - IRQL = DISPATCH_LEVEL - - Note: - - ======================================================================== -*/ -void RTMPDeQueuePacket(struct rt_rtmp_adapter *pAd, IN BOOLEAN bIntContext, u8 QIdx, /* BulkOutPipeId */ - u8 Max_Tx_Packets) -{ - struct rt_queue_entry *pEntry = NULL; - void *pPacket; - int Status = NDIS_STATUS_SUCCESS; - u8 Count = 0; - struct rt_queue_header *pQueue; - unsigned long FreeNumber[NUM_OF_TX_RING]; - u8 QueIdx, sQIdx, eQIdx; - unsigned long IrqFlags = 0; - BOOLEAN hasTxDesc = FALSE; - struct rt_tx_blk TxBlk; - struct rt_tx_blk *pTxBlk; - - if (QIdx == NUM_OF_TX_RING) { - sQIdx = 0; - eQIdx = 3; /* 4 ACs, start from 0. */ - } else { - sQIdx = eQIdx = QIdx; - } - - for (QueIdx = sQIdx; QueIdx <= eQIdx; QueIdx++) { - Count = 0; - - RTMP_START_DEQUEUE(pAd, QueIdx, IrqFlags); - - while (1) { - if ((RTMP_TEST_FLAG - (pAd, - (fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS | - fRTMP_ADAPTER_RADIO_OFF | - fRTMP_ADAPTER_RESET_IN_PROGRESS | - fRTMP_ADAPTER_HALT_IN_PROGRESS | - fRTMP_ADAPTER_NIC_NOT_EXIST)))) { - RTMP_STOP_DEQUEUE(pAd, QueIdx, IrqFlags); - return; - } - - if (Count >= Max_Tx_Packets) - break; - - DEQUEUE_LOCK(&pAd->irq_lock, bIntContext, IrqFlags); - if (&pAd->TxSwQueue[QueIdx] == NULL) { - DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, - IrqFlags); - break; - } -#ifdef RTMP_MAC_PCI - FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx); - - if (FreeNumber[QueIdx] <= 5) { - /* free Tx(QueIdx) resources */ - RTMPFreeTXDUponTxDmaDone(pAd, QueIdx); - FreeNumber[QueIdx] = - GET_TXRING_FREENO(pAd, QueIdx); - } -#endif /* RTMP_MAC_PCI // */ - - /* probe the Queue Head */ - pQueue = &pAd->TxSwQueue[QueIdx]; - pEntry = pQueue->Head; - if (pEntry == NULL) { - DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, - IrqFlags); - break; - } - - pTxBlk = &TxBlk; - NdisZeroMemory((u8 *)pTxBlk, sizeof(struct rt_tx_blk)); - /*InitializeQueueHeader(&pTxBlk->TxPacketList); // Didn't need it because we already memzero it. */ - pTxBlk->QueIdx = QueIdx; - - pPacket = QUEUE_ENTRY_TO_PACKET(pEntry); - - /* Early check to make sure we have enoguh Tx Resource. */ - hasTxDesc = - RTMP_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, - FreeNumber[QueIdx], - pPacket); - if (!hasTxDesc) { - pAd->PrivateInfo.TxRingFullCnt++; - - DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, - IrqFlags); - - break; - } - - pTxBlk->TxFrameType = TxPktClassification(pAd, pPacket); - pEntry = RemoveHeadQueue(pQueue); - pTxBlk->TotalFrameNum++; - pTxBlk->TotalFragNum += RTMP_GET_PACKET_FRAGMENTS(pPacket); /* The real fragment number maybe vary */ - pTxBlk->TotalFrameLen += GET_OS_PKT_LEN(pPacket); - pTxBlk->pPacket = pPacket; - InsertTailQueue(&pTxBlk->TxPacketList, - PACKET_TO_QUEUE_ENTRY(pPacket)); - - if (pTxBlk->TxFrameType == TX_RALINK_FRAME - || pTxBlk->TxFrameType == TX_AMSDU_FRAME) { - /* Enhance SW Aggregation Mechanism */ - if (NEED_QUEUE_BACK_FOR_AGG - (pAd, QueIdx, FreeNumber[QueIdx], - pTxBlk->TxFrameType)) { - InsertHeadQueue(pQueue, - PACKET_TO_QUEUE_ENTRY - (pPacket)); - DEQUEUE_UNLOCK(&pAd->irq_lock, - bIntContext, IrqFlags); - break; - } - - do { - pEntry = pQueue->Head; - if (pEntry == NULL) - break; - - /* For TX_AMSDU_FRAME/TX_RALINK_FRAME, Need to check if next pakcet can do aggregation. */ - pPacket = QUEUE_ENTRY_TO_PACKET(pEntry); - FreeNumber[QueIdx] = - GET_TXRING_FREENO(pAd, QueIdx); - hasTxDesc = - RTMP_HAS_ENOUGH_FREE_DESC(pAd, - pTxBlk, - FreeNumber - [QueIdx], - pPacket); - if ((hasTxDesc == FALSE) - || - (CanDoAggregateTransmit - (pAd, pPacket, pTxBlk) == FALSE)) - break; - - /*Remove the packet from the TxSwQueue and insert into pTxBlk */ - pEntry = RemoveHeadQueue(pQueue); - ASSERT(pEntry); - pPacket = QUEUE_ENTRY_TO_PACKET(pEntry); - pTxBlk->TotalFrameNum++; - pTxBlk->TotalFragNum += RTMP_GET_PACKET_FRAGMENTS(pPacket); /* The real fragment number maybe vary */ - pTxBlk->TotalFrameLen += - GET_OS_PKT_LEN(pPacket); - InsertTailQueue(&pTxBlk->TxPacketList, - PACKET_TO_QUEUE_ENTRY - (pPacket)); - } while (1); - - if (pTxBlk->TxPacketList.Number == 1) - pTxBlk->TxFrameType = TX_LEGACY_FRAME; - } -#ifdef RTMP_MAC_USB - DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags); -#endif /* RTMP_MAC_USB // */ - Count += pTxBlk->TxPacketList.Number; - - /* Do HardTransmit now. */ - Status = STAHardTransmit(pAd, pTxBlk, QueIdx); - -#ifdef RTMP_MAC_PCI - DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags); - /* static rate also need NICUpdateFifoStaCounters() function. */ - /*if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)) */ - NICUpdateFifoStaCounters(pAd); -#endif /* RTMP_MAC_PCI // */ - - } - - RTMP_STOP_DEQUEUE(pAd, QueIdx, IrqFlags); - -#ifdef RTMP_MAC_USB - if (!hasTxDesc) - RTUSBKickBulkOut(pAd); -#endif /* RTMP_MAC_USB // */ - } - -} - -/* - ======================================================================== - - Routine Description: - Calculates the duration which is required to transmit out frames - with given size and specified rate. - - Arguments: - pAd Pointer to our adapter - Rate Transmit rate - Size Frame size in units of byte - - Return Value: - Duration number in units of usec - - IRQL = PASSIVE_LEVEL - IRQL = DISPATCH_LEVEL - - Note: - - ======================================================================== -*/ -u16 RTMPCalcDuration(struct rt_rtmp_adapter *pAd, u8 Rate, unsigned long Size) -{ - unsigned long Duration = 0; - - if (Rate < RATE_FIRST_OFDM_RATE) /* CCK */ - { - if ((Rate > RATE_1) - && OPSTATUS_TEST_FLAG(pAd, - fOP_STATUS_SHORT_PREAMBLE_INUSED)) - Duration = 96; /* 72+24 preamble+plcp */ - else - Duration = 192; /* 144+48 preamble+plcp */ - - Duration += (u16)((Size << 4) / RateIdTo500Kbps[Rate]); - if ((Size << 4) % RateIdTo500Kbps[Rate]) - Duration++; - } else if (Rate <= RATE_LAST_OFDM_RATE) /* OFDM rates */ - { - Duration = 20 + 6; /* 16+4 preamble+plcp + Signal Extension */ - Duration += - 4 * (u16)((11 + Size * 4) / RateIdTo500Kbps[Rate]); - if ((11 + Size * 4) % RateIdTo500Kbps[Rate]) - Duration += 4; - } else /*mimo rate */ - { - Duration = 20 + 6; /* 16+4 preamble+plcp + Signal Extension */ - } - - return (u16)Duration; -} - -/* - ======================================================================== - - Routine Description: - Calculates the duration which is required to transmit out frames - with given size and specified rate. - - Arguments: - pTxWI Pointer to head of each MPDU to HW. - Ack Setting for Ack requirement bit - Fragment Setting for Fragment bit - RetryMode Setting for retry mode - Ifs Setting for IFS gap - Rate Setting for transmit rate - Service Setting for service - Length Frame length - TxPreamble Short or Long preamble when using CCK rates - QueIdx - 0-3, according to 802.11e/d4.4 June/2003 - - Return Value: - None - - IRQL = PASSIVE_LEVEL - IRQL = DISPATCH_LEVEL - - See also : BASmartHardTransmit() ! - - ======================================================================== -*/ -void RTMPWriteTxWI(struct rt_rtmp_adapter *pAd, struct rt_txwi * pOutTxWI, IN BOOLEAN FRAG, IN BOOLEAN CFACK, IN BOOLEAN InsTimestamp, IN BOOLEAN AMPDU, IN BOOLEAN Ack, IN BOOLEAN NSeq, /* HW new a sequence. */ - u8 BASize, - u8 WCID, - unsigned long Length, - u8 PID, - u8 TID, - u8 TxRate, - u8 Txopmode, - IN BOOLEAN CfAck, IN HTTRANSMIT_SETTING * pTransmit) -{ - struct rt_mac_table_entry *pMac = NULL; - struct rt_txwi TxWI; - struct rt_txwi * pTxWI; - - if (WCID < MAX_LEN_OF_MAC_TABLE) - pMac = &pAd->MacTab.Content[WCID]; - - /* */ - /* Always use Long preamble before verifiation short preamble functionality works well. */ - /* Todo: remove the following line if short preamble functionality works */ - /* */ - OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED); - NdisZeroMemory(&TxWI, TXWI_SIZE); - pTxWI = &TxWI; - - pTxWI->FRAG = FRAG; - - pTxWI->CFACK = CFACK; - pTxWI->TS = InsTimestamp; - pTxWI->AMPDU = AMPDU; - pTxWI->ACK = Ack; - pTxWI->txop = Txopmode; - - pTxWI->NSEQ = NSeq; - /* John tune the performace with Intel Client in 20 MHz performance */ - BASize = pAd->CommonCfg.TxBASize; - if (pAd->MACVersion == 0x28720200) { - if (BASize > 13) - BASize = 13; - } else { - if (BASize > 7) - BASize = 7; - } - pTxWI->BAWinSize = BASize; - pTxWI->ShortGI = pTransmit->field.ShortGI; - pTxWI->STBC = pTransmit->field.STBC; - - pTxWI->WirelessCliID = WCID; - pTxWI->MPDUtotalByteCount = Length; - pTxWI->PacketId = PID; - - /* If CCK or OFDM, BW must be 20 */ - pTxWI->BW = - (pTransmit->field.MODE <= - MODE_OFDM) ? (BW_20) : (pTransmit->field.BW); - - pTxWI->MCS = pTransmit->field.MCS; - pTxWI->PHYMODE = pTransmit->field.MODE; - pTxWI->CFACK = CfAck; - - if (pMac) { - if (pAd->CommonCfg.bMIMOPSEnable) { - if ((pMac->MmpsMode == MMPS_DYNAMIC) - && (pTransmit->field.MCS > 7)) { - /* Dynamic MIMO Power Save Mode */ - pTxWI->MIMOps = 1; - } else if (pMac->MmpsMode == MMPS_STATIC) { - /* Static MIMO Power Save Mode */ - if (pTransmit->field.MODE >= MODE_HTMIX - && pTransmit->field.MCS > 7) { - pTxWI->MCS = 7; - pTxWI->MIMOps = 0; - } - } - } - /*pTxWI->MIMOps = (pMac->PsMode == PWR_MMPS)? 1:0; */ - if (pMac->bIAmBadAtheros - && (pMac->WepStatus != Ndis802_11WEPDisabled)) { - pTxWI->MpduDensity = 7; - } else { - pTxWI->MpduDensity = pMac->MpduDensity; - } - } - - pTxWI->PacketId = pTxWI->MCS; - NdisMoveMemory(pOutTxWI, &TxWI, sizeof(struct rt_txwi)); -} - -void RTMPWriteTxWI_Data(struct rt_rtmp_adapter *pAd, - struct rt_txwi * pTxWI, struct rt_tx_blk *pTxBlk) -{ - HTTRANSMIT_SETTING *pTransmit; - struct rt_mac_table_entry *pMacEntry; - u8 BASize; - - ASSERT(pTxWI); - - pTransmit = pTxBlk->pTransmit; - pMacEntry = pTxBlk->pMacEntry; - - /* */ - /* Always use Long preamble before verifiation short preamble functionality works well. */ - /* Todo: remove the following line if short preamble functionality works */ - /* */ - OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED); - NdisZeroMemory(pTxWI, TXWI_SIZE); - - pTxWI->FRAG = TX_BLK_TEST_FLAG(pTxBlk, fTX_bAllowFrag); - pTxWI->ACK = TX_BLK_TEST_FLAG(pTxBlk, fTX_bAckRequired); - pTxWI->txop = pTxBlk->FrameGap; - - pTxWI->WirelessCliID = pTxBlk->Wcid; - - pTxWI->MPDUtotalByteCount = pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen; - pTxWI->CFACK = TX_BLK_TEST_FLAG(pTxBlk, fTX_bPiggyBack); - - /* If CCK or OFDM, BW must be 20 */ - pTxWI->BW = - (pTransmit->field.MODE <= - MODE_OFDM) ? (BW_20) : (pTransmit->field.BW); - pTxWI->AMPDU = ((pTxBlk->TxFrameType == TX_AMPDU_FRAME) ? TRUE : FALSE); - - /* John tune the performace with Intel Client in 20 MHz performance */ - BASize = pAd->CommonCfg.TxBASize; - if ((pTxBlk->TxFrameType == TX_AMPDU_FRAME) && (pMacEntry)) { - u8 RABAOriIdx = 0; /*The RA's BA Originator table index. */ - - RABAOriIdx = - pTxBlk->pMacEntry->BAOriWcidArray[pTxBlk->UserPriority]; - BASize = pAd->BATable.BAOriEntry[RABAOriIdx].BAWinSize; - } - - pTxWI->TxBF = pTransmit->field.TxBF; - pTxWI->BAWinSize = BASize; - pTxWI->ShortGI = pTransmit->field.ShortGI; - pTxWI->STBC = pTransmit->field.STBC; - - pTxWI->MCS = pTransmit->field.MCS; - pTxWI->PHYMODE = pTransmit->field.MODE; - - if (pMacEntry) { - if ((pMacEntry->MmpsMode == MMPS_DYNAMIC) - && (pTransmit->field.MCS > 7)) { - /* Dynamic MIMO Power Save Mode */ - pTxWI->MIMOps = 1; - } else if (pMacEntry->MmpsMode == MMPS_STATIC) { - /* Static MIMO Power Save Mode */ - if (pTransmit->field.MODE >= MODE_HTMIX - && pTransmit->field.MCS > 7) { - pTxWI->MCS = 7; - pTxWI->MIMOps = 0; - } - } - - if (pMacEntry->bIAmBadAtheros - && (pMacEntry->WepStatus != Ndis802_11WEPDisabled)) { - pTxWI->MpduDensity = 7; - } else { - pTxWI->MpduDensity = pMacEntry->MpduDensity; - } - } - - /* for rate adapation */ - pTxWI->PacketId = pTxWI->MCS; -} - -void RTMPWriteTxWI_Cache(struct rt_rtmp_adapter *pAd, - struct rt_txwi * pTxWI, struct rt_tx_blk *pTxBlk) -{ - PHTTRANSMIT_SETTING /*pTxHTPhyMode, */ pTransmit; - struct rt_mac_table_entry *pMacEntry; - - /* */ - /* update TXWI */ - /* */ - pMacEntry = pTxBlk->pMacEntry; - pTransmit = pTxBlk->pTransmit; - - /*if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)) */ - /*if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pMacEntry)) */ - /*if (TX_BLK_TEST_FLAG(pTxBlk, fTX_AutoRateSwitch)) */ - if (pMacEntry->bAutoTxRateSwitch) { - pTxWI->txop = IFS_HTTXOP; - - /* If CCK or OFDM, BW must be 20 */ - pTxWI->BW = - (pTransmit->field.MODE <= - MODE_OFDM) ? (BW_20) : (pTransmit->field.BW); - pTxWI->ShortGI = pTransmit->field.ShortGI; - pTxWI->STBC = pTransmit->field.STBC; - - pTxWI->MCS = pTransmit->field.MCS; - pTxWI->PHYMODE = pTransmit->field.MODE; - - /* set PID for TxRateSwitching */ - pTxWI->PacketId = pTransmit->field.MCS; - } - - pTxWI->AMPDU = ((pMacEntry->NoBADataCountDown == 0) ? TRUE : FALSE); - pTxWI->MIMOps = 0; - - if (pAd->CommonCfg.bMIMOPSEnable) { - /* MIMO Power Save Mode */ - if ((pMacEntry->MmpsMode == MMPS_DYNAMIC) - && (pTransmit->field.MCS > 7)) { - /* Dynamic MIMO Power Save Mode */ - pTxWI->MIMOps = 1; - } else if (pMacEntry->MmpsMode == MMPS_STATIC) { - /* Static MIMO Power Save Mode */ - if ((pTransmit->field.MODE >= MODE_HTMIX) - && (pTransmit->field.MCS > 7)) { - pTxWI->MCS = 7; - pTxWI->MIMOps = 0; - } - } - } - - pTxWI->MPDUtotalByteCount = pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen; - -} - -/* should be called only when - */ -/* 1. MEADIA_CONNECTED */ -/* 2. AGGREGATION_IN_USED */ -/* 3. Fragmentation not in used */ -/* 4. either no previous frame (pPrevAddr1=NULL) .OR. previoud frame is aggregatible */ -BOOLEAN TxFrameIsAggregatible(struct rt_rtmp_adapter *pAd, - u8 *pPrevAddr1, u8 *p8023hdr) -{ - - /* can't aggregate EAPOL (802.1x) frame */ - if ((p8023hdr[12] == 0x88) && (p8023hdr[13] == 0x8e)) - return FALSE; - - /* can't aggregate multicast/broadcast frame */ - if (p8023hdr[0] & 0x01) - return FALSE; - - if (INFRA_ON(pAd)) /* must be unicast to AP */ - return TRUE; - else if ((pPrevAddr1 == NULL) || MAC_ADDR_EQUAL(pPrevAddr1, p8023hdr)) /* unicast to same STA */ - return TRUE; - else - return FALSE; -} - -/* - ======================================================================== - - Routine Description: - Check the MSDU Aggregation policy - 1.HT aggregation is A-MSDU - 2.legaacy rate aggregation is software aggregation by Ralink. - - Arguments: - - Return Value: - - Note: - - ======================================================================== -*/ -BOOLEAN PeerIsAggreOn(struct rt_rtmp_adapter *pAd, - unsigned long TxRate, struct rt_mac_table_entry *pMacEntry) -{ - unsigned long AFlags = - (fCLIENT_STATUS_AMSDU_INUSED | fCLIENT_STATUS_AGGREGATION_CAPABLE); - - if (pMacEntry != NULL && CLIENT_STATUS_TEST_FLAG(pMacEntry, AFlags)) { - if (pMacEntry->HTPhyMode.field.MODE >= MODE_HTMIX) { - return TRUE; - } -#ifdef AGGREGATION_SUPPORT - if (TxRate >= RATE_6 && pAd->CommonCfg.bAggregationCapable && (!(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE)))) { /* legacy Ralink Aggregation support */ - return TRUE; - } -#endif /* AGGREGATION_SUPPORT // */ - } - - return FALSE; - -} - -/* - ======================================================================== - - Routine Description: - Check and fine the packet waiting in SW queue with highest priority - - Arguments: - pAd Pointer to our adapter - - Return Value: - pQueue Pointer to Waiting Queue - - IRQL = DISPATCH_LEVEL - - Note: - - ======================================================================== -*/ -struct rt_queue_header *RTMPCheckTxSwQueue(struct rt_rtmp_adapter *pAd, u8 *pQueIdx) -{ - - unsigned long Number; - /* 2004-11-15 to be removed. test aggregation only */ -/* if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED)) && (*pNumber < 2)) */ -/* return NULL; */ - - Number = pAd->TxSwQueue[QID_AC_BK].Number - + pAd->TxSwQueue[QID_AC_BE].Number - + pAd->TxSwQueue[QID_AC_VI].Number - + pAd->TxSwQueue[QID_AC_VO].Number; - - if (pAd->TxSwQueue[QID_AC_VO].Head != NULL) { - *pQueIdx = QID_AC_VO; - return (&pAd->TxSwQueue[QID_AC_VO]); - } else if (pAd->TxSwQueue[QID_AC_VI].Head != NULL) { - *pQueIdx = QID_AC_VI; - return (&pAd->TxSwQueue[QID_AC_VI]); - } else if (pAd->TxSwQueue[QID_AC_BE].Head != NULL) { - *pQueIdx = QID_AC_BE; - return (&pAd->TxSwQueue[QID_AC_BE]); - } else if (pAd->TxSwQueue[QID_AC_BK].Head != NULL) { - *pQueIdx = QID_AC_BK; - return (&pAd->TxSwQueue[QID_AC_BK]); - } - /* No packet pending in Tx Sw queue */ - *pQueIdx = QID_AC_BK; - - return (NULL); -} - -/* - ======================================================================== - - Routine Description: - Suspend MSDU transmission - - Arguments: - pAd Pointer to our adapter - - Return Value: - None - - Note: - - ======================================================================== -*/ -void RTMPSuspendMsduTransmission(struct rt_rtmp_adapter *pAd) -{ - DBGPRINT(RT_DEBUG_TRACE, ("SCANNING, suspend MSDU transmission ...\n")); - - /* */ - /* Before BSS_SCAN_IN_PROGRESS, we need to keep Current R66 value and */ - /* use Lowbound as R66 value on ScanNextChannel(...) */ - /* */ - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, - &pAd->BbpTuning.R66CurrentValue); - - /* set BBP_R66 to 0x30/0x40 when scanning (AsicSwitchChannel will set R66 according to channel when scanning) */ - /*RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x26 + GET_LNA_GAIN(pAd))); */ - RTMPSetAGCInitValue(pAd, BW_20); - - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS); - /*RTMP_IO_WRITE32(pAd, TX_CNTL_CSR, 0x000f0000); // abort all TX rings */ -} - -/* - ======================================================================== - - Routine Description: - Resume MSDU transmission - - Arguments: - pAd Pointer to our adapter - - Return Value: - None - - IRQL = DISPATCH_LEVEL - - Note: - - ======================================================================== -*/ -void RTMPResumeMsduTransmission(struct rt_rtmp_adapter *pAd) -{ -/* u8 IrqState; */ - - DBGPRINT(RT_DEBUG_TRACE, ("SCAN done, resume MSDU transmission ...\n")); - - /* After finish BSS_SCAN_IN_PROGRESS, we need to restore Current R66 value */ - /* R66 should not be 0 */ - if (pAd->BbpTuning.R66CurrentValue == 0) { - pAd->BbpTuning.R66CurrentValue = 0x38; - DBGPRINT_ERR("RTMPResumeMsduTransmission, R66CurrentValue=0...\n"); - } - - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, - pAd->BbpTuning.R66CurrentValue); - - RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS); -/* sample, for IRQ LOCK to SEM LOCK */ -/* IrqState = pAd->irq_disabled; */ -/* if (IrqState) */ -/* RTMPDeQueuePacket(pAd, TRUE, NUM_OF_TX_RING, MAX_TX_PROCESS); */ -/* else */ - RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS); -} - -u32 deaggregate_AMSDU_announce(struct rt_rtmp_adapter *pAd, - void *pPacket, - u8 *pData, unsigned long DataSize) -{ - u16 PayloadSize; - u16 SubFrameSize; - struct rt_header_802_3 * pAMSDUsubheader; - u32 nMSDU; - u8 Header802_3[14]; - - u8 *pPayload, *pDA, *pSA, *pRemovedLLCSNAP; - void *pClonePacket; - - nMSDU = 0; - - while (DataSize > LENGTH_802_3) { - - nMSDU++; - - /*hex_dump("subheader", pData, 64); */ - pAMSDUsubheader = (struct rt_header_802_3 *) pData; - /*pData += LENGTH_802_3; */ - PayloadSize = - pAMSDUsubheader->Octet[1] + - (pAMSDUsubheader->Octet[0] << 8); - SubFrameSize = PayloadSize + LENGTH_802_3; - - if ((DataSize < SubFrameSize) || (PayloadSize > 1518)) { - break; - } - /*DBGPRINT(RT_DEBUG_TRACE,("%d subframe: Size = %d\n", nMSDU, PayloadSize)); */ - - pPayload = pData + LENGTH_802_3; - pDA = pData; - pSA = pData + MAC_ADDR_LEN; - - /* convert to 802.3 header */ - CONVERT_TO_802_3(Header802_3, pDA, pSA, pPayload, PayloadSize, - pRemovedLLCSNAP); - - if ((Header802_3[12] == 0x88) && (Header802_3[13] == 0x8E)) { - /* avoid local heap overflow, use dyanamic allocation */ - struct rt_mlme_queue_elem *Elem = - kmalloc(sizeof(struct rt_mlme_queue_elem), - MEM_ALLOC_FLAG); - if (Elem != NULL) { - memmove(Elem->Msg + - (LENGTH_802_11 + LENGTH_802_1_H), - pPayload, PayloadSize); - Elem->MsgLen = - LENGTH_802_11 + LENGTH_802_1_H + - PayloadSize; - /*WpaEAPOLKeyAction(pAd, Elem); */ - REPORT_MGMT_FRAME_TO_MLME(pAd, BSSID_WCID, - Elem->Msg, - Elem->MsgLen, 0, 0, 0, - 0); - kfree(Elem); - } - } - - { - if (pRemovedLLCSNAP) { - pPayload -= LENGTH_802_3; - PayloadSize += LENGTH_802_3; - NdisMoveMemory(pPayload, &Header802_3[0], - LENGTH_802_3); - } - } - - pClonePacket = ClonePacket(pAd, pPacket, pPayload, PayloadSize); - if (pClonePacket) { - ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pClonePacket, - RTMP_GET_PACKET_IF - (pPacket)); - } - - /* A-MSDU has padding to multiple of 4 including subframe header. */ - /* align SubFrameSize up to multiple of 4 */ - SubFrameSize = (SubFrameSize + 3) & (~0x3); - - if (SubFrameSize > 1528 || SubFrameSize < 32) { - break; - } - - if (DataSize > SubFrameSize) { - pData += SubFrameSize; - DataSize -= SubFrameSize; - } else { - /* end of A-MSDU */ - DataSize = 0; - } - } - - /* finally release original rx packet */ - RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS); - - return nMSDU; -} - -u32 BA_Reorder_AMSDU_Announce(struct rt_rtmp_adapter *pAd, void *pPacket) -{ - u8 *pData; - u16 DataSize; - u32 nMSDU = 0; - - pData = (u8 *)GET_OS_PKT_DATAPTR(pPacket); - DataSize = (u16)GET_OS_PKT_LEN(pPacket); - - nMSDU = deaggregate_AMSDU_announce(pAd, pPacket, pData, DataSize); - - return nMSDU; -} - -/* - ========================================================================== - Description: - Look up the MAC address in the MAC table. Return NULL if not found. - Return: - pEntry - pointer to the MAC entry; NULL is not found - ========================================================================== -*/ -struct rt_mac_table_entry *MacTableLookup(struct rt_rtmp_adapter *pAd, u8 *pAddr) -{ - unsigned long HashIdx; - struct rt_mac_table_entry *pEntry = NULL; - - HashIdx = MAC_ADDR_HASH_INDEX(pAddr); - pEntry = pAd->MacTab.Hash[HashIdx]; - - while (pEntry - && (pEntry->ValidAsCLI || pEntry->ValidAsWDS - || pEntry->ValidAsApCli || pEntry->ValidAsMesh)) { - if (MAC_ADDR_EQUAL(pEntry->Addr, pAddr)) { - break; - } else - pEntry = pEntry->pNext; - } - - return pEntry; -} - -struct rt_mac_table_entry *MacTableInsertEntry(struct rt_rtmp_adapter *pAd, - u8 *pAddr, - u8 apidx, IN BOOLEAN CleanAll) -{ - u8 HashIdx; - int i, FirstWcid; - struct rt_mac_table_entry *pEntry = NULL, *pCurrEntry; -/* u16 offset; */ -/* unsigned long addr; */ - - /* if FULL, return */ - if (pAd->MacTab.Size >= MAX_LEN_OF_MAC_TABLE) - return NULL; - - FirstWcid = 1; - - if (pAd->StaCfg.BssType == BSS_INFRA) - FirstWcid = 2; - - /* allocate one MAC entry */ - NdisAcquireSpinLock(&pAd->MacTabLock); - for (i = FirstWcid; i < MAX_LEN_OF_MAC_TABLE; i++) /* skip entry#0 so that "entry index == AID" for fast lookup */ - { - /* pick up the first available vacancy */ - if ((pAd->MacTab.Content[i].ValidAsCLI == FALSE) && - (pAd->MacTab.Content[i].ValidAsWDS == FALSE) && - (pAd->MacTab.Content[i].ValidAsApCli == FALSE) && - (pAd->MacTab.Content[i].ValidAsMesh == FALSE) - ) { - pEntry = &pAd->MacTab.Content[i]; - if (CleanAll == TRUE) { - pEntry->MaxSupportedRate = RATE_11; - pEntry->CurrTxRate = RATE_11; - NdisZeroMemory(pEntry, sizeof(struct rt_mac_table_entry)); - pEntry->PairwiseKey.KeyLen = 0; - pEntry->PairwiseKey.CipherAlg = CIPHER_NONE; - } - { - { - pEntry->ValidAsCLI = TRUE; - pEntry->ValidAsWDS = FALSE; - pEntry->ValidAsApCli = FALSE; - pEntry->ValidAsMesh = FALSE; - pEntry->ValidAsDls = FALSE; - } - } - - pEntry->bIAmBadAtheros = FALSE; - pEntry->pAd = pAd; - pEntry->CMTimerRunning = FALSE; - pEntry->EnqueueEapolStartTimerRunning = - EAPOL_START_DISABLE; - pEntry->RSNIE_Len = 0; - NdisZeroMemory(pEntry->R_Counter, - sizeof(pEntry->R_Counter)); - pEntry->ReTryCounter = PEER_MSG1_RETRY_TIMER_CTR; - - if (pEntry->ValidAsMesh) - pEntry->apidx = - (apidx - MIN_NET_DEVICE_FOR_MESH); - else if (pEntry->ValidAsApCli) - pEntry->apidx = - (apidx - MIN_NET_DEVICE_FOR_APCLI); - else if (pEntry->ValidAsWDS) - pEntry->apidx = - (apidx - MIN_NET_DEVICE_FOR_WDS); - else - pEntry->apidx = apidx; - - { - { - pEntry->AuthMode = pAd->StaCfg.AuthMode; - pEntry->WepStatus = - pAd->StaCfg.WepStatus; - pEntry->PrivacyFilter = - Ndis802_11PrivFilterAcceptAll; -#ifdef RTMP_MAC_PCI - AsicRemovePairwiseKeyEntry(pAd, - pEntry-> - apidx, - (u8)i); -#endif /* RTMP_MAC_PCI // */ - } - } - - pEntry->GTKState = REKEY_NEGOTIATING; - pEntry->PairwiseKey.KeyLen = 0; - pEntry->PairwiseKey.CipherAlg = CIPHER_NONE; - pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED; - - pEntry->PMKID_CacheIdx = ENTRY_NOT_FOUND; - COPY_MAC_ADDR(pEntry->Addr, pAddr); - pEntry->Sst = SST_NOT_AUTH; - pEntry->AuthState = AS_NOT_AUTH; - pEntry->Aid = (u16)i; /*0; */ - pEntry->CapabilityInfo = 0; - pEntry->PsMode = PWR_ACTIVE; - pEntry->PsQIdleCount = 0; - pEntry->NoDataIdleCount = 0; - pEntry->AssocDeadLine = MAC_TABLE_ASSOC_TIMEOUT; - pEntry->ContinueTxFailCnt = 0; - InitializeQueueHeader(&pEntry->PsQueue); - - pAd->MacTab.Size++; - /* Add this entry into ASIC RX WCID search table */ - RTMP_STA_ENTRY_ADD(pAd, pEntry); - - DBGPRINT(RT_DEBUG_TRACE, - ("MacTableInsertEntry - allocate entry #%d, Total= %d\n", - i, pAd->MacTab.Size)); - break; - } - } - - /* add this MAC entry into HASH table */ - if (pEntry) { - HashIdx = MAC_ADDR_HASH_INDEX(pAddr); - if (pAd->MacTab.Hash[HashIdx] == NULL) { - pAd->MacTab.Hash[HashIdx] = pEntry; - } else { - pCurrEntry = pAd->MacTab.Hash[HashIdx]; - while (pCurrEntry->pNext != NULL) - pCurrEntry = pCurrEntry->pNext; - pCurrEntry->pNext = pEntry; - } - } - - NdisReleaseSpinLock(&pAd->MacTabLock); - return pEntry; -} - -/* - ========================================================================== - Description: - Delete a specified client from MAC table - ========================================================================== - */ -BOOLEAN MacTableDeleteEntry(struct rt_rtmp_adapter *pAd, - u16 wcid, u8 *pAddr) -{ - u16 HashIdx; - struct rt_mac_table_entry *pEntry, *pPrevEntry, *pProbeEntry; - BOOLEAN Cancelled; - /*u16 offset; // unused variable */ - /*u8 j; // unused variable */ - - if (wcid >= MAX_LEN_OF_MAC_TABLE) - return FALSE; - - NdisAcquireSpinLock(&pAd->MacTabLock); - - HashIdx = MAC_ADDR_HASH_INDEX(pAddr); - /*pEntry = pAd->MacTab.Hash[HashIdx]; */ - pEntry = &pAd->MacTab.Content[wcid]; - - if (pEntry - && (pEntry->ValidAsCLI || pEntry->ValidAsApCli || pEntry->ValidAsWDS - || pEntry->ValidAsMesh)) { - if (MAC_ADDR_EQUAL(pEntry->Addr, pAddr)) { - - /* Delete this entry from ASIC on-chip WCID Table */ - RTMP_STA_ENTRY_MAC_RESET(pAd, wcid); - - /* free resources of BA */ - BASessionTearDownALL(pAd, pEntry->Aid); - - pPrevEntry = NULL; - pProbeEntry = pAd->MacTab.Hash[HashIdx]; - ASSERT(pProbeEntry); - - /* update Hash list */ - do { - if (pProbeEntry == pEntry) { - if (pPrevEntry == NULL) { - pAd->MacTab.Hash[HashIdx] = - pEntry->pNext; - } else { - pPrevEntry->pNext = - pEntry->pNext; - } - break; - } - - pPrevEntry = pProbeEntry; - pProbeEntry = pProbeEntry->pNext; - } while (pProbeEntry); - - /* not found ! */ - ASSERT(pProbeEntry != NULL); - - RTMP_STA_ENTRY_KEY_DEL(pAd, BSS0, wcid); - - if (pEntry->EnqueueEapolStartTimerRunning != - EAPOL_START_DISABLE) { - RTMPCancelTimer(&pEntry-> - EnqueueStartForPSKTimer, - &Cancelled); - pEntry->EnqueueEapolStartTimerRunning = - EAPOL_START_DISABLE; - } - - NdisZeroMemory(pEntry, sizeof(struct rt_mac_table_entry)); - pAd->MacTab.Size--; - DBGPRINT(RT_DEBUG_TRACE, - ("MacTableDeleteEntry1 - Total= %d\n", - pAd->MacTab.Size)); - } else { - DBGPRINT(RT_DEBUG_OFF, - ("\n%s: Impossible Wcid = %d !\n", - __func__, wcid)); - } - } - - NdisReleaseSpinLock(&pAd->MacTabLock); - - /*Reset operating mode when no Sta. */ - if (pAd->MacTab.Size == 0) { - pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode = 0; - RTMP_UPDATE_PROTECT(pAd); /* edit by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet */ - } - - return TRUE; -} - -/* - ========================================================================== - Description: - This routine reset the entire MAC table. All packets pending in - the power-saving queues are freed here. - ========================================================================== - */ -void MacTableReset(struct rt_rtmp_adapter *pAd) -{ - int i; - - DBGPRINT(RT_DEBUG_TRACE, ("MacTableReset\n")); - /*NdisAcquireSpinLock(&pAd->MacTabLock); */ - - for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++) { -#ifdef RTMP_MAC_PCI - RTMP_STA_ENTRY_MAC_RESET(pAd, i); -#endif /* RTMP_MAC_PCI // */ - if (pAd->MacTab.Content[i].ValidAsCLI == TRUE) { - - /* free resources of BA */ - BASessionTearDownALL(pAd, i); - - pAd->MacTab.Content[i].ValidAsCLI = FALSE; - -#ifdef RTMP_MAC_USB - NdisZeroMemory(pAd->MacTab.Content[i].Addr, 6); - RTMP_STA_ENTRY_MAC_RESET(pAd, i); -#endif /* RTMP_MAC_USB // */ - - /*AsicDelWcidTab(pAd, i); */ - } - } - - return; -} - -/* - ========================================================================== - Description: - - IRQL = DISPATCH_LEVEL - - ========================================================================== -*/ -void AssocParmFill(struct rt_rtmp_adapter *pAd, - struct rt_mlme_assoc_req *AssocReq, - u8 *pAddr, - u16 CapabilityInfo, - unsigned long Timeout, u16 ListenIntv) -{ - COPY_MAC_ADDR(AssocReq->Addr, pAddr); - /* Add mask to support 802.11b mode only */ - AssocReq->CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO; /* not cf-pollable, not cf-poll-request */ - AssocReq->Timeout = Timeout; - AssocReq->ListenIntv = ListenIntv; -} - -/* - ========================================================================== - Description: - - IRQL = DISPATCH_LEVEL - - ========================================================================== -*/ -void DisassocParmFill(struct rt_rtmp_adapter *pAd, - struct rt_mlme_disassoc_req *DisassocReq, - u8 *pAddr, u16 Reason) -{ - COPY_MAC_ADDR(DisassocReq->Addr, pAddr); - DisassocReq->Reason = Reason; -} - -/* - ======================================================================== - - Routine Description: - Check the out going frame, if this is an DHCP or ARP datagram - will be duplicate another frame at low data rate transmit. - - Arguments: - pAd Pointer to our adapter - pPacket Pointer to outgoing Ndis frame - - Return Value: - TRUE To be duplicate at Low data rate transmit. (1mb) - FALSE Do nothing. - - IRQL = DISPATCH_LEVEL - - Note: - - MAC header + IP Header + UDP Header - 14 Bytes 20 Bytes - - UDP Header - 00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15| - Source Port - 16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31| - Destination Port - - port 0x43 means Bootstrap Protocol, server. - Port 0x44 means Bootstrap Protocol, client. - - ======================================================================== -*/ - -BOOLEAN RTMPCheckDHCPFrame(struct rt_rtmp_adapter *pAd, void *pPacket) -{ - struct rt_packet_info PacketInfo; - unsigned long NumberOfBytesRead = 0; - unsigned long CurrentOffset = 0; - void *pVirtualAddress = NULL; - u32 NdisBufferLength; - u8 *pSrc; - u16 Protocol; - u8 ByteOffset36 = 0; - u8 ByteOffset38 = 0; - BOOLEAN ReadFirstParm = TRUE; - - RTMP_QueryPacketInfo(pPacket, &PacketInfo, (u8 **) & pVirtualAddress, - &NdisBufferLength); - - NumberOfBytesRead += NdisBufferLength; - pSrc = (u8 *)pVirtualAddress; - Protocol = *(pSrc + 12) * 256 + *(pSrc + 13); - - /* */ - /* Check DHCP & BOOTP protocol */ - /* */ - while (NumberOfBytesRead <= PacketInfo.TotalPacketLength) { - if ((NumberOfBytesRead >= 35) && (ReadFirstParm == TRUE)) { - CurrentOffset = - 35 - (NumberOfBytesRead - NdisBufferLength); - ByteOffset36 = *(pSrc + CurrentOffset); - ReadFirstParm = FALSE; - } - - if (NumberOfBytesRead >= 37) { - CurrentOffset = - 37 - (NumberOfBytesRead - NdisBufferLength); - ByteOffset38 = *(pSrc + CurrentOffset); - /*End of Read */ - break; - } - return FALSE; - } - - /* Check for DHCP & BOOTP protocol */ - if ((ByteOffset36 != 0x44) || (ByteOffset38 != 0x43)) { - /* */ - /* 2054 (hex 0806) for ARP datagrams */ - /* if this packet is not ARP datagrams, then do nothing */ - /* ARP datagrams will also be duplicate at 1mb broadcast frames */ - /* */ - if (Protocol != 0x0806) - return FALSE; - } - - return TRUE; -} - -BOOLEAN RTMPCheckEtherType(struct rt_rtmp_adapter *pAd, void *pPacket) -{ - u16 TypeLen; - u8 Byte0, Byte1; - u8 *pSrcBuf; - u32 pktLen; - u16 srcPort, dstPort; - BOOLEAN status = TRUE; - - pSrcBuf = GET_OS_PKT_DATAPTR(pPacket); - pktLen = GET_OS_PKT_LEN(pPacket); - - ASSERT(pSrcBuf); - - RTMP_SET_PACKET_SPECIFIC(pPacket, 0); - - /* get Ethernet protocol field */ - TypeLen = (pSrcBuf[12] << 8) | pSrcBuf[13]; - - pSrcBuf += LENGTH_802_3; /* Skip the Ethernet Header. */ - - if (TypeLen <= 1500) { /* 802.3, 802.3 LLC */ - /* - DestMAC(6) + SrcMAC(6) + Length(2) + - DSAP(1) + SSAP(1) + Control(1) + - if the DSAP = 0xAA, SSAP=0xAA, Contorl = 0x03, it has a 5-bytes SNAP header. - => + SNAP (5, OriginationID(3) + etherType(2)) - */ - if (pSrcBuf[0] == 0xAA && pSrcBuf[1] == 0xAA - && pSrcBuf[2] == 0x03) { - Sniff2BytesFromNdisBuffer((char *)pSrcBuf, 6, - &Byte0, &Byte1); - RTMP_SET_PACKET_LLCSNAP(pPacket, 1); - TypeLen = (u16)((Byte0 << 8) + Byte1); - pSrcBuf += 8; /* Skip this LLC/SNAP header */ - } else { - /*It just has 3-byte LLC header, maybe a legacy ether type frame. we didn't handle it. */ - } - } - /* If it's a VLAN packet, get the real Type/Length field. */ - if (TypeLen == 0x8100) { - /* 0x8100 means VLAN packets */ - - /* Dest. MAC Address (6-bytes) + - Source MAC Address (6-bytes) + - Length/Type = 802.1Q Tag Type (2-byte) + - Tag Control Information (2-bytes) + - Length / Type (2-bytes) + - data payload (0-n bytes) + - Pad (0-p bytes) + - Frame Check Sequence (4-bytes) */ - - RTMP_SET_PACKET_VLAN(pPacket, 1); - Sniff2BytesFromNdisBuffer((char *)pSrcBuf, 2, &Byte0, - &Byte1); - TypeLen = (u16)((Byte0 << 8) + Byte1); - - pSrcBuf += 4; /* Skip the VLAN Header. */ - } - - switch (TypeLen) { - case 0x0800: - { - ASSERT((pktLen > 34)); - if (*(pSrcBuf + 9) == 0x11) { /* udp packet */ - ASSERT((pktLen > 34)); /* 14 for ethernet header, 20 for IP header */ - - pSrcBuf += 20; /* Skip the IP header */ - srcPort = - OS_NTOHS(get_unaligned - ((u16 *)(pSrcBuf))); - dstPort = - OS_NTOHS(get_unaligned - ((u16 *)(pSrcBuf + 2))); - - if ((srcPort == 0x44 && dstPort == 0x43) || (srcPort == 0x43 && dstPort == 0x44)) { /*It's a BOOTP/DHCP packet */ - RTMP_SET_PACKET_DHCP(pPacket, 1); - } - } - } - break; - case 0x0806: - { - /*ARP Packet. */ - RTMP_SET_PACKET_DHCP(pPacket, 1); - } - break; - case 0x888e: - { - /* EAPOL Packet. */ - RTMP_SET_PACKET_EAPOL(pPacket, 1); - } - break; - default: - status = FALSE; - break; - } - - return status; - -} - -void Update_Rssi_Sample(struct rt_rtmp_adapter *pAd, - struct rt_rssi_sample *pRssi, struct rt_rxwi * pRxWI) -{ - char rssi0 = pRxWI->RSSI0; - char rssi1 = pRxWI->RSSI1; - char rssi2 = pRxWI->RSSI2; - - if (rssi0 != 0) { - pRssi->LastRssi0 = ConvertToRssi(pAd, (char)rssi0, RSSI_0); - pRssi->AvgRssi0X8 = - (pRssi->AvgRssi0X8 - pRssi->AvgRssi0) + pRssi->LastRssi0; - pRssi->AvgRssi0 = pRssi->AvgRssi0X8 >> 3; - } - - if (rssi1 != 0) { - pRssi->LastRssi1 = ConvertToRssi(pAd, (char)rssi1, RSSI_1); - pRssi->AvgRssi1X8 = - (pRssi->AvgRssi1X8 - pRssi->AvgRssi1) + pRssi->LastRssi1; - pRssi->AvgRssi1 = pRssi->AvgRssi1X8 >> 3; - } - - if (rssi2 != 0) { - pRssi->LastRssi2 = ConvertToRssi(pAd, (char)rssi2, RSSI_2); - pRssi->AvgRssi2X8 = - (pRssi->AvgRssi2X8 - pRssi->AvgRssi2) + pRssi->LastRssi2; - pRssi->AvgRssi2 = pRssi->AvgRssi2X8 >> 3; - } -} - -/* Normal legacy Rx packet indication */ -void Indicate_Legacy_Packet(struct rt_rtmp_adapter *pAd, - struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID) -{ - void *pRxPacket = pRxBlk->pRxPacket; - u8 Header802_3[LENGTH_802_3]; - - /* 1. get 802.3 Header */ - /* 2. remove LLC */ - /* a. pointer pRxBlk->pData to payload */ - /* b. modify pRxBlk->DataSize */ - RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3); - - if (pRxBlk->DataSize > MAX_RX_PKT_LEN) { - - /* release packet */ - RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE); - return; - } - - STATS_INC_RX_PACKETS(pAd, FromWhichBSSID); - -#ifdef RTMP_MAC_USB - if (pAd->CommonCfg.bDisableReordering == 0) { - struct rt_ba_rec_entry *pBAEntry; - unsigned long Now32; - u8 Wcid = pRxBlk->pRxWI->WirelessCliID; - u8 TID = pRxBlk->pRxWI->TID; - u16 Idx; - -#define REORDERING_PACKET_TIMEOUT ((100 * OS_HZ)/1000) /* system ticks -- 100 ms */ - - if (Wcid < MAX_LEN_OF_MAC_TABLE) { - Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID]; - if (Idx != 0) { - pBAEntry = &pAd->BATable.BARecEntry[Idx]; - /* update last rx time */ - NdisGetSystemUpTime(&Now32); - if ((pBAEntry->list.qlen > 0) && - RTMP_TIME_AFTER((unsigned long)Now32, - (unsigned long)(pBAEntry-> - LastIndSeqAtTimer - + - (REORDERING_PACKET_TIMEOUT))) - ) { - DBGPRINT(RT_DEBUG_OFF, - ("Indicate_Legacy_Packet():flush reordering_timeout_mpdus! RxWI->Flags=%d, pRxWI.TID=%d, RxD->AMPDU=%d!\n", - pRxBlk->Flags, - pRxBlk->pRxWI->TID, - pRxBlk->RxD.AMPDU)); - hex_dump("Dump the legacy Packet:", - GET_OS_PKT_DATAPTR(pRxBlk-> - pRxPacket), - 64); - ba_flush_reordering_timeout_mpdus(pAd, - pBAEntry, - Now32); - } - } - } - } -#endif /* RTMP_MAC_USB // */ - - wlan_802_11_to_802_3_packet(pAd, pRxBlk, Header802_3, FromWhichBSSID); - - /* */ - /* pass this 802.3 packet to upper layer or forward this packet to WM directly */ - /* */ - ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pRxPacket, FromWhichBSSID); -} - -/* Normal, AMPDU or AMSDU */ -void CmmRxnonRalinkFrameIndicate(struct rt_rtmp_adapter *pAd, - struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID) -{ - if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMPDU) - && (pAd->CommonCfg.bDisableReordering == 0)) { - Indicate_AMPDU_Packet(pAd, pRxBlk, FromWhichBSSID); - } else { - if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU)) { - /* handle A-MSDU */ - Indicate_AMSDU_Packet(pAd, pRxBlk, FromWhichBSSID); - } else { - Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID); - } - } -} - -void CmmRxRalinkFrameIndicate(struct rt_rtmp_adapter *pAd, - struct rt_mac_table_entry *pEntry, - struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID) -{ - u8 Header802_3[LENGTH_802_3]; - u16 Msdu2Size; - u16 Payload1Size, Payload2Size; - u8 *pData2; - void *pPacket2 = NULL; - - Msdu2Size = *(pRxBlk->pData) + (*(pRxBlk->pData + 1) << 8); - - if ((Msdu2Size <= 1536) && (Msdu2Size < pRxBlk->DataSize)) { - /* skip two byte MSDU2 len */ - pRxBlk->pData += 2; - pRxBlk->DataSize -= 2; - } else { - /* release packet */ - RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, - NDIS_STATUS_FAILURE); - return; - } - - /* get 802.3 Header and remove LLC */ - RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3); - - ASSERT(pRxBlk->pRxPacket); - - /* Ralink Aggregation frame */ - pAd->RalinkCounters.OneSecRxAggregationCount++; - Payload1Size = pRxBlk->DataSize - Msdu2Size; - Payload2Size = Msdu2Size - LENGTH_802_3; - - pData2 = pRxBlk->pData + Payload1Size + LENGTH_802_3; - - pPacket2 = - duplicate_pkt(pAd, (pData2 - LENGTH_802_3), LENGTH_802_3, pData2, - Payload2Size, FromWhichBSSID); - - if (!pPacket2) { - /* release packet */ - RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, - NDIS_STATUS_FAILURE); - return; - } - /* update payload size of 1st packet */ - pRxBlk->DataSize = Payload1Size; - wlan_802_11_to_802_3_packet(pAd, pRxBlk, Header802_3, FromWhichBSSID); - - ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pRxBlk->pRxPacket, - FromWhichBSSID); - - if (pPacket2) { - ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pPacket2, FromWhichBSSID); - } -} - -#define RESET_FRAGFRAME(_fragFrame) \ - { \ - _fragFrame.RxSize = 0; \ - _fragFrame.Sequence = 0; \ - _fragFrame.LastFrag = 0; \ - _fragFrame.Flags = 0; \ - } - -void *RTMPDeFragmentDataFrame(struct rt_rtmp_adapter *pAd, struct rt_rx_blk *pRxBlk) -{ - struct rt_header_802_11 * pHeader = pRxBlk->pHeader; - void *pRxPacket = pRxBlk->pRxPacket; - u8 *pData = pRxBlk->pData; - u16 DataSize = pRxBlk->DataSize; - void *pRetPacket = NULL; - u8 *pFragBuffer = NULL; - BOOLEAN bReassDone = FALSE; - u8 HeaderRoom = 0; - - ASSERT(pHeader); - - HeaderRoom = pData - (u8 *) pHeader; - - /* Re-assemble the fragmented packets */ - if (pHeader->Frag == 0) /* Frag. Number is 0 : First frag or only one pkt */ - { - /* the first pkt of fragment, record it. */ - if (pHeader->FC.MoreFrag) { - ASSERT(pAd->FragFrame.pFragPacket); - pFragBuffer = - GET_OS_PKT_DATAPTR(pAd->FragFrame.pFragPacket); - pAd->FragFrame.RxSize = DataSize + HeaderRoom; - NdisMoveMemory(pFragBuffer, pHeader, - pAd->FragFrame.RxSize); - pAd->FragFrame.Sequence = pHeader->Sequence; - pAd->FragFrame.LastFrag = pHeader->Frag; /* Should be 0 */ - ASSERT(pAd->FragFrame.LastFrag == 0); - goto done; /* end of processing this frame */ - } - } else /*Middle & End of fragment */ - { - if ((pHeader->Sequence != pAd->FragFrame.Sequence) || - (pHeader->Frag != (pAd->FragFrame.LastFrag + 1))) { - /* Fragment is not the same sequence or out of fragment number order */ - /* Reset Fragment control blk */ - RESET_FRAGFRAME(pAd->FragFrame); - DBGPRINT(RT_DEBUG_ERROR, - ("Fragment is not the same sequence or out of fragment number order.\n")); - goto done; /* give up this frame */ - } else if ((pAd->FragFrame.RxSize + DataSize) > MAX_FRAME_SIZE) { - /* Fragment frame is too large, it exeeds the maximum frame size. */ - /* Reset Fragment control blk */ - RESET_FRAGFRAME(pAd->FragFrame); - DBGPRINT(RT_DEBUG_ERROR, - ("Fragment frame is too large, it exeeds the maximum frame size.\n")); - goto done; /* give up this frame */ - } - /* */ - /* Broadcom AP(BCM94704AGR) will send out LLC in fragment's packet, LLC only can accpet at first fragment. */ - /* In this case, we will dropt it. */ - /* */ - if (NdisEqualMemory(pData, SNAP_802_1H, sizeof(SNAP_802_1H))) { - DBGPRINT(RT_DEBUG_ERROR, - ("Find another LLC at Middle or End fragment(SN=%d, Frag=%d)\n", - pHeader->Sequence, pHeader->Frag)); - goto done; /* give up this frame */ - } - - pFragBuffer = GET_OS_PKT_DATAPTR(pAd->FragFrame.pFragPacket); - - /* concatenate this fragment into the re-assembly buffer */ - NdisMoveMemory((pFragBuffer + pAd->FragFrame.RxSize), pData, - DataSize); - pAd->FragFrame.RxSize += DataSize; - pAd->FragFrame.LastFrag = pHeader->Frag; /* Update fragment number */ - - /* Last fragment */ - if (pHeader->FC.MoreFrag == FALSE) { - bReassDone = TRUE; - } - } - -done: - /* always release rx fragmented packet */ - RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE); - - /* return defragmented packet if packet is reassembled completely */ - /* otherwise return NULL */ - if (bReassDone) { - void *pNewFragPacket; - - /* allocate a new packet buffer for fragment */ - pNewFragPacket = - RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE); - if (pNewFragPacket) { - /* update RxBlk */ - pRetPacket = pAd->FragFrame.pFragPacket; - pAd->FragFrame.pFragPacket = pNewFragPacket; - pRxBlk->pHeader = - (struct rt_header_802_11 *) GET_OS_PKT_DATAPTR(pRetPacket); - pRxBlk->pData = (u8 *) pRxBlk->pHeader + HeaderRoom; - pRxBlk->DataSize = pAd->FragFrame.RxSize - HeaderRoom; - pRxBlk->pRxPacket = pRetPacket; - } else { - RESET_FRAGFRAME(pAd->FragFrame); - } - } - - return pRetPacket; -} - -void Indicate_AMSDU_Packet(struct rt_rtmp_adapter *pAd, - struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID) -{ - u32 nMSDU; - - update_os_packet_info(pAd, pRxBlk, FromWhichBSSID); - RTMP_SET_PACKET_IF(pRxBlk->pRxPacket, FromWhichBSSID); - nMSDU = - deaggregate_AMSDU_announce(pAd, pRxBlk->pRxPacket, pRxBlk->pData, - pRxBlk->DataSize); -} - -void Indicate_EAPOL_Packet(struct rt_rtmp_adapter *pAd, - struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID) -{ - struct rt_mac_table_entry *pEntry = NULL; - - { - pEntry = &pAd->MacTab.Content[BSSID_WCID]; - STARxEAPOLFrameIndicate(pAd, pEntry, pRxBlk, FromWhichBSSID); - return; - } - - if (pEntry == NULL) { - DBGPRINT(RT_DEBUG_WARN, - ("Indicate_EAPOL_Packet: drop and release the invalid packet.\n")); - /* release packet */ - RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, - NDIS_STATUS_FAILURE); - return; - } -} - -#define BCN_TBTT_OFFSET 64 /*defer 64 us */ -void ReSyncBeaconTime(struct rt_rtmp_adapter *pAd) -{ - - u32 Offset; - - Offset = (pAd->TbttTickCount) % (BCN_TBTT_OFFSET); - - pAd->TbttTickCount++; - - /* */ - /* The updated BeaconInterval Value will affect Beacon Interval after two TBTT */ - /* beacasue the original BeaconInterval had been loaded into next TBTT_TIMER */ - /* */ - if (Offset == (BCN_TBTT_OFFSET - 2)) { - BCN_TIME_CFG_STRUC csr; - RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word); - csr.field.BeaconInterval = (pAd->CommonCfg.BeaconPeriod << 4) - 1; /* ASIC register in units of 1/16 TU = 64us */ - RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word); - } else { - if (Offset == (BCN_TBTT_OFFSET - 1)) { - BCN_TIME_CFG_STRUC csr; - - RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word); - csr.field.BeaconInterval = (pAd->CommonCfg.BeaconPeriod) << 4; /* ASIC register in units of 1/16 TU */ - RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word); - } - } -} |