cmm_data.c

来自「ralink最新rt3070 usb wifi 无线网卡驱动程序」· C语言 代码 · 共 2,434 行 · 第 1/5 页

C
2,434
字号
/* ************************************************************************* * 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"#define MAX_TX_IN_TBTT		(16)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			IrqState;	UCHAR			rtmpHwHdr[TXINFO_SIZE + TXWI_SIZE]; //RTMP_HW_HDR_LEN];		ASSERT(Length <= MGMT_DMA_BUFFER_SIZE);		QueIdx=3;		// 2860C use Tx Ring		IrqState = pAd->irq_disabled;	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.			// 2860C use Tx Ring		if (pAd->MACVersion == 0x28600100)		{			FreeNum = GET_TXRING_FREENO(pAd, QueIdx);		}		else		{			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)				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 (FALSE);		return Status;}NDIS_STATUS MlmeDataHardTransmit(	IN	PRTMP_ADAPTER	pAd,	IN	UCHAR	QueIdx,	IN	PNDIS_PACKET	pPacket);#define MAX_DATAMM_RETRY	3/*	========================================================================	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 MiniportDataMMRequest(							 IN  PRTMP_ADAPTER   pAd,							 IN  UCHAR           QueIdx,							 IN  PUCHAR          pData,							 IN  UINT            Length){	PNDIS_PACKET    pPacket;	NDIS_STATUS  Status = NDIS_STATUS_SUCCESS;	ULONG    FreeNum;	int 	retry = 0;	UCHAR           IrqState;	UCHAR			rtmpHwHdr[TXINFO_SIZE + TXWI_SIZE]; //RTMP_HW_HDR_LEN];	ASSERT(Length <= MGMT_DMA_BUFFER_SIZE);	// 2860C use Tx Ring	IrqState = pAd->irq_disabled;	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.		// 2860C use Tx Ring		// free Tx(QueIdx) resources		FreeNum = GET_TXRING_FREENO(pAd, QueIdx);				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 = MlmeDataHardTransmit(pAd, QueIdx, pPacket);			if (Status != NDIS_STATUS_SUCCESS)				RTMPFreeNdisPacket(pAd, pPacket);			retry = MAX_DATAMM_RETRY;		}		else		{			retry ++;			printk("retry %d\n", retry);			pAd->RalinkCounters.MgmtRingFullCount++;			if (retry >= MAX_DATAMM_RETRY)			{								DBGPRINT(RT_DEBUG_ERROR, ("Qidx(%d), not enough space in DataRing, MgmtRingFullCount=%ld!\n",											QueIdx, pAd->RalinkCounters.MgmtRingFullCount));			}		}	} while (retry < MAX_DATAMM_RETRY);	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#endif // CARRIER_DETECTION_SUPPORT //		)	{		return NDIS_STATUS_FAILURE;	}		return MlmeHardTransmitMgmtRing(pAd,QueIdx,pPacket);}NDIS_STATUS MlmeDataHardTransmit(	IN	PRTMP_ADAPTER	pAd,	IN	UCHAR	QueIdx,	IN	PNDIS_PACKET	pPacket){	if ((pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)#ifdef CARRIER_DETECTION_SUPPORT#endif // CARRIER_DETECTION_SUPPORT //		)	{		return NDIS_STATUS_FAILURE;	}#ifdef RT2870	return MlmeHardTransmitMgmtRing(pAd,QueIdx,pPacket);#endif // RT2870 //}					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;	RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);		// Make sure MGMT ring resource won't be used by other threads// sample, for IRQ LOCK -> SEM LOCK//	IrqState = pAd->irq_disabled;//	if (!IrqState)		RTMP_SEM_LOCK(&pAd->MgmtRingLock);	if (pSrcBufVA == NULL)	{		// The buffer shouldn't be NULL//		if (!IrqState)			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 = 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) && (pHeader_802_11->FC.Type != BTYPE_CNTL))	{		if ((pAd->StaCfg.Psm == PWR_SAVE) &&			(pHeader_802_11->FC.SubType == SUBTYPE_ACTION))				pHeader_802_11->FC.PwrMgmt = PWR_SAVE;		else			pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE;	}#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)			{				bInsertTimestamp = TRUE;			}		}	}	pHeader_802_11->Sequence = pAd->Sequence++;	if (pAd->Sequence >0xfff)

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?