📄 cmm_data.c.bak
字号:
/* ************************************************************************* * Ralink Tech Inc. * 4F, No. 2 Technology 5th Rd. * Science-based Industrial Park * Hsin-chu, 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"#define MAX_TX_IN_TBTT (16)#define GET_TXRING_FREENO(_pAd, _QueIdx) \ (_pAd->TxRing[_QueIdx].TxSwFreeIdx > _pAd->TxRing[QueIdx].TxCpuIdx) ? \ (_pAd->TxRing[_QueIdx].TxSwFreeIdx - _pAd->TxRing[_QueIdx].TxCpuIdx - 1) \ : \ (_pAd->TxRing[_QueIdx].TxSwFreeIdx + TX_RING_SIZE - _pAd->TxRing[_QueIdx].TxCpuIdx - 1);#define GET_MGMTRING_FREENO(_pAd) \ (_pAd->MgmtRing.TxSwFreeIdx > _pAd->MgmtRing.TxCpuIdx) ? \ (_pAd->MgmtRing.TxSwFreeIdx - _pAd->MgmtRing.TxCpuIdx - 1) \ : \ (_pAd->MgmtRing.TxSwFreeIdx + MGMT_RING_SIZE - _pAd->MgmtRing.TxCpuIdx - 1);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; TXWI_STRUC TXWI; ULONG SW_TX_IDX; //TEMP, SW_TX_IDX; PTXD_STRUC pTxD; unsigned long IrqFlags = 0; UCHAR IrqState; QueIdx=3; ASSERT(Length <= MGMT_DMA_BUFFER_SIZE); // 2860C use Tx Ring IrqState = pAd->irq_disabled; if ((pAd->MACVersion == 0x28600100) && (!IrqState)) RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags); 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)|| !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. // 2860C use Tx Ring if (pAd->MACVersion == 0x28600100) { FreeNum = GET_TXRING_FREENO(pAd, QueIdx); SW_TX_IDX = pAd->TxRing[QueIdx].TxCpuIdx; pTxD = (PTXD_STRUC) pAd->TxRing[QueIdx].Cell[SW_TX_IDX].AllocVa; } else { FreeNum = GET_MGMTRING_FREENO(pAd); SW_TX_IDX = pAd->MgmtRing.TxCpuIdx; pTxD = (PTXD_STRUC) pAd->MgmtRing.Cell[SW_TX_IDX].AllocVa; } if ((FreeNum > 0)) { NdisZeroMemory(&TXWI, TXWI_SIZE); Status = RTMPAllocateNdisPacket(pAd, &pPacket, (PUCHAR)&TXWI, 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) RTMPFreeNdisPacket(pAd, pPacket); } else { pAd->RalinkCounters.MgmtRingFullCount++; DBGPRINT(RT_DEBUG_ERROR, ("Qidx(%d), not enough space in MgmtRing\n", QueIdx)); } } while (FALSE); // 2860C use Tx Ring if ((pAd->MACVersion == 0x28600100) && (!IrqState)) RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags); return Status;}NDIS_STATUS MiniportMMRequestUnlock( IN PRTMP_ADAPTER pAd, IN UCHAR QueIdx, IN PUCHAR pData, IN UINT Length){ PNDIS_PACKET pPacket; NDIS_STATUS Status = NDIS_STATUS_SUCCESS; ULONG FreeNum; TXWI_STRUC TXWI; ULONG SW_TX_IDX; //TEMP, SW_TX_IDX; PTXD_STRUC pTxD; //ULONG IrqFlags = 0; QueIdx = 3; ASSERT(Length <= MGMT_DMA_BUFFER_SIZE); 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)|| !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. // 2860C use Tx Ring if (pAd->MACVersion == 0x28600100) { FreeNum = GET_TXRING_FREENO(pAd, QueIdx); SW_TX_IDX = pAd->TxRing[QueIdx].TxCpuIdx; pTxD = (PTXD_STRUC) pAd->TxRing[QueIdx].Cell[SW_TX_IDX].AllocVa; } else { FreeNum = GET_MGMTRING_FREENO(pAd); SW_TX_IDX = pAd->MgmtRing.TxCpuIdx; pTxD = (PTXD_STRUC) pAd->MgmtRing.Cell[SW_TX_IDX].AllocVa; } if ((FreeNum > 0)) { NdisZeroMemory(&TXWI, TXWI_SIZE); Status = RTMPAllocateNdisPacket(pAd, &pPacket, (PUCHAR)&TXWI, 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) RTMPFreeNdisPacket(pAd, pPacket); } else { pAd->RalinkCounters.MgmtRingFullCount++; DBGPRINT(RT_DEBUG_ERROR, ("Qidx(%d), not enough space in MgmtRing\n", QueIdx)); } } while (FALSE); 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){ if ((pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)#ifdef CARRIER_DETECTION_SUPPORT ||(isCarrierDetectExist(pAd) == TRUE)#endif // CARRIER_DETECTION_SUPPORT // ) { return NDIS_STATUS_FAILURE; } if ( pAd->MACVersion == 0x28600100 ) return MlmeHardTransmitTxRing(pAd,QueIdx,pPacket); else return MlmeHardTransmitMgmtRing(pAd,QueIdx,pPacket);}NDIS_STATUS MlmeHardTransmitTxRing( IN PRTMP_ADAPTER pAd, IN UCHAR QueIdx, IN PNDIS_PACKET pPacket){ PACKET_INFO PacketInfo; PUCHAR pSrcBufVA; UINT SrcBufLen; PTXD_STRUC pTxD;#ifdef BIG_ENDIAN PTXD_STRUC pDestTxD; TXD_STRUC TxD;#endif PHEADER_802_11 pHeader_802_11; BOOLEAN bAckRequired, bInsertTimestamp; ULONG SrcBufPA; //UCHAR TxBufIdx; UCHAR MlmeRate; ULONG SwIdx = pAd->TxRing[QueIdx].TxCpuIdx; PTXWI_STRUC pFirstTxWI; //ULONG i; //HTTRANSMIT_SETTING MlmeTransmit; //Rate for this MGMT frame. ULONG FreeNum; RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen); if (pSrcBufVA == NULL) { // The buffer shouldn't be NULL return NDIS_STATUS_FAILURE; } // Make sure MGMT ring resource won't be used by other threads //NdisAcquireSpinLock(&pAd->TxRingLock); FreeNum = GET_TXRING_FREENO(pAd, QueIdx); if (FreeNum == 0) { //NdisReleaseSpinLock(&pAd->TxRingLock); return NDIS_STATUS_FAILURE; } SwIdx = pAd->TxRing[QueIdx].TxCpuIdx;#ifndef BIG_ENDIAN pTxD = (PTXD_STRUC) pAd->TxRing[QueIdx].Cell[SwIdx].AllocVa;#else pDestTxD = (PTXD_STRUC)pAd->TxRing[QueIdx].Cell[SwIdx].AllocVa; TxD = *pDestTxD; pTxD = &TxD; RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);#endif if (pAd->TxRing[QueIdx].Cell[SwIdx].pNdisPacket) { printk("MlmeHardTransmit Error\n"); //NdisReleaseSpinLock(&pAd->TxRingLock); return NDIS_STATUS_FAILURE; } // outgoing frame always wakeup PHY to prevent frame lost // if (pAd->StaCfg.Psm == PWR_SAVE) if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) AsicForceWakeup(pAd); pFirstTxWI =(PTXWI_STRUC)pSrcBufVA; pHeader_802_11 = (PHEADER_802_11) (pSrcBufVA + 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; // // 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 = 0; // (pAd->StaCfg.Psm == PWR_SAVE); // // In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame#ifdef CONFIG_STA_SUPPORT // 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) {#endif // CONFIG_STA_SUPPORT // if ((pHeader_802_11->FC.SubType == SUBTYPE_PROBE_REQ) || !(pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable)) { pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE; } else { pHeader_802_11->FC.PwrMgmt = pAd->CommonCfg.bAPSDForcePowerSave; }#ifdef CONFIG_STA_SUPPORT }#endif // CONFIG_STA_SUPPORT // bInsertTimestamp = FALSE; if (pHeader_802_11->FC.Type == BTYPE_CNTL) // must be PS-POLL { bAckRequired = FALSE; } else // BTYPE_MGMT or BTYPE_DATA(must be NULL frame) { 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) { bInsertTimestamp = TRUE; } } } 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")); //NdisReleaseSpinLock(&pAd->TxRingLock); return (NDIS_STATUS_FAILURE); }#ifdef 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 ohysical buffer, and the whole frame size equals
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -