📄 cmm_data.c
字号:
/* ************************************************************************* * 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"UCHAR SNAP_802_1H[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};UCHAR SNAP_BRIDGE_TUNNEL[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8};// Add Cisco Aironet SNAP heade for CCX2 supportUCHAR SNAP_AIRONET[] = {0xaa, 0xaa, 0x03, 0x00, 0x40, 0x96, 0x00, 0x00};UCHAR CKIP_LLC_SNAP[] = {0xaa, 0xaa, 0x03, 0x00, 0x40, 0x96, 0x00, 0x02};UCHAR EAPOL_LLC_SNAP[]= {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8e};UCHAR EAPOL[] = {0x88, 0x8e};UCHAR TPID[] = {0x81, 0x00}; /* VLAN related */UCHAR IPX[] = {0x81, 0x37};UCHAR APPLE_TALK[] = {0x80, 0xf3};UCHAR 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.14UCHAR 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};UCHAR 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};UCHAR 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"};UCHAR default_cwmin[]={CW_MIN_IN_BITS, CW_MIN_IN_BITS, CW_MIN_IN_BITS-1, CW_MIN_IN_BITS-2};//UCHAR default_cwmax[]={CW_MAX_IN_BITS, CW_MAX_IN_BITS, CW_MIN_IN_BITS, CW_MIN_IN_BITS-1};UCHAR default_sta_aifsn[]={3,7,2,2};UCHAR 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: ========================================================================*/NDIS_STATUS MiniportMMRequest( IN PRTMP_ADAPTER pAd, IN UCHAR QueIdx, IN PUCHAR pData, IN UINT Length){ PNDIS_PACKET pPacket; NDIS_STATUS Status = NDIS_STATUS_SUCCESS; ULONG FreeNum; UCHAR rtmpHwHdr[TXINFO_SIZE + TXWI_SIZE]; //RTMP_HW_HDR_LEN]; 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); } 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. { 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, (PUCHAR)&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; Status = MlmeHardTransmit(pAd, QueIdx, pPacket); if (Status == NDIS_STATUS_SUCCESS) retryCnt = 0; else RTMPFreeNdisPacket(pAd, pPacket); } else { pAd->RalinkCounters.MgmtRingFullCount++; DBGPRINT(RT_DEBUG_ERROR, ("Qidx(%d), not enough space in MgmtRing, MgmtRingFullCount=%ld!\n", QueIdx, pAd->RalinkCounters.MgmtRingFullCount)); } } while (retryCnt > 0); 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: ========================================================================*/NDIS_STATUS MlmeHardTransmit( IN PRTMP_ADAPTER pAd, IN UCHAR QueIdx, IN PNDIS_PACKET pPacket){ PACKET_INFO PacketInfo; PUCHAR pSrcBufVA; UINT SrcBufLen; PHEADER_802_11 pHeader_802_11; if ((pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)#ifdef CARRIER_DETECTION_SUPPORT#endif // CARRIER_DETECTION_SUPPORT // ) { return NDIS_STATUS_FAILURE; } RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen); if (pSrcBufVA == NULL) return NDIS_STATUS_FAILURE; pHeader_802_11 = (PHEADER_802_11) (pSrcBufVA + TXINFO_SIZE + TXWI_SIZE); return MlmeHardTransmitMgmtRing(pAd,QueIdx,pPacket);}NDIS_STATUS MlmeHardTransmitMgmtRing( IN PRTMP_ADAPTER pAd, IN UCHAR QueIdx, IN PNDIS_PACKET pPacket){ PACKET_INFO PacketInfo; PUCHAR pSrcBufVA; UINT SrcBufLen; PHEADER_802_11 pHeader_802_11; BOOLEAN bAckRequired, bInsertTimestamp; UCHAR MlmeRate; PTXWI_STRUC pFirstTxWI; MAC_TABLE_ENTRY *pMacEntry = NULL; UCHAR 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; }#ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { // outgoing frame always wakeup PHY to prevent frame lost if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) AsicForceWakeup(pAd, TRUE); }#endif // CONFIG_STA_SUPPORT // pFirstTxWI = (PTXWI_STRUC)(pSrcBufVA + TXINFO_SIZE); pHeader_802_11 = (PHEADER_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); }#ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { // Fixed W52 with Activity scan issue in ABG_MIXED and ABGN_MIXED mode. if (pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED#ifdef DOT11_N_SUPPORT || pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED#endif // DOT11_N_SUPPORT // ) { if (pAd->LatchRfRegs.Channel > 14) pAd->CommonCfg.MlmeTransmit.field.MODE = 1; else pAd->CommonCfg.MlmeTransmit.field.MODE = 0; } }#endif // CONFIG_STA_SUPPORT // // // 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);#ifdef CONFIG_STA_SUPPORT // // In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame // Data-Null packets alse 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; } }#endif // CONFIG_STA_SUPPORT // bInsertTimestamp = FALSE; if (pHeader_802_11->FC.Type == BTYPE_CNTL) // must be PS-POLL {#ifdef CONFIG_STA_SUPPORT //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; }#endif // CONFIG_STA_SUPPORT // 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); }#ifdef RT_BIG_ENDIAN RTMPFrameEndianChange(pAd, (PUCHAR)pHeader_802_11, DIR_WRITE, FALSE);#endif // // 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, (UCHAR)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, (UCHAR)pMacEntry->MaxHTPhyMode.field.MCS, IFS_BACKOFF, FALSE, &pMacEntry->MaxHTPhyMode); }#ifdef RT_BIG_ENDIAN RTMPWIEndianChange((PUCHAR)pFirstTxWI, TYPE_TXWI);#endif // 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -