cmm_data.c

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

C
2,434
字号
		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 ohysical 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.	if (pMacEntry == NULL)	{		RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp, FALSE, bAckRequired, FALSE, 		0, RESERVED_WCID, (SrcBufLen - TXINFO_SIZE - TXWI_SIZE), PID_MGMT, 0,  (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);	}	else	{		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 									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 UCHAR TxPktClassification(	IN RTMP_ADAPTER *pAd, 	IN PNDIS_PACKET  pPacket){	UCHAR			TxFrameType = TX_UNKOWN_FRAME;	UCHAR			Wcid;	MAC_TABLE_ENTRY	*pMacEntry = NULL;#ifdef DOT11_N_SUPPORT	BOOLEAN			bHTRate = FALSE;#endif // DOT11_N_SUPPORT //	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;	}#ifdef DOT11_N_SUPPORT	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;#ifdef UAPSD_AP_SUPPORT		else if (RTMP_GET_PACKET_EOSP(pPacket))			TxFrameType = TX_LEGACY_FRAME;#endif // UAPSD_AP_SUPPORT //		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;	}#endif // DOT11_N_SUPPORT //	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(	IN RTMP_ADAPTER *pAd, 	IN TX_BLK *pTxBlk){	PACKET_INFO			PacketInfo;	PNDIS_PACKET		pPacket;	PMAC_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;		{#ifdef MCAST_RATE_SPECIFIC			PUCHAR pDA = GET_OS_PKT_DATAPTR(pPacket);			if (((*pDA & 0x01) == 0x01) && (*pDA != 0xff))				pTxBlk->pTransmit = &pAd->CommonCfg.MCastPhyMode;			else#endif // MCAST_RATE_SPECIFIC //				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);		{#ifdef CONFIG_STA_SUPPORT			IF_DEV_CONFIG_OPMODE_ON_STA(pAd)			{				// 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);			}#endif // CONFIG_STA_SUPPORT //		}		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;#ifdef DOT11_N_SUPPORT				// 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);				}#endif // DOT11_N_SUPPORT //			}			#ifdef DOT11_N_SUPPORT				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);			}#endif // DOT11_N_SUPPORT //			if (RTMP_GET_PACKET_MOREDATA(pPacket))			{				TX_BLK_SET_FLAG(pTxBlk, fTX_bMoreData);			}#ifdef UAPSD_AP_SUPPORT			if (RTMP_GET_PACKET_EOSP(pPacket))			{				TX_BLK_SET_FLAG(pTxBlk, fTX_bWMM_UAPSD_EOSP);			}#endif // UAPSD_AP_SUPPORT //		}		else if (pTxBlk->TxFrameType == TX_FRAG_FRAME)		{			TX_BLK_SET_FLAG(pTxBlk, fTX_bAllowFrag);		}				pMacEntry->DebugTxCount++;	}		return TRUE;FillTxBlkErr:	return FALSE;}BOOLEAN CanDoAggregateTransmit(	IN RTMP_ADAPTER *pAd,	IN NDIS_PACKET *pPacket,	IN TX_BLK		*pTxBlk){	//printk("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;	}#ifdef CONFIG_STA_SUPPORT	if ((INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA)) // must be unicast to AP		return TRUE;	else #endif // CONFIG_STA_SUPPORT //		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(	IN  PRTMP_ADAPTER   pAd,	IN  BOOLEAN         bIntContext,	IN  UCHAR			QIdx, /* BulkOutPipeId */	IN  UCHAR           Max_Tx_Packets){	PQUEUE_ENTRY    pEntry = NULL;	PNDIS_PACKET 	pPacket;	NDIS_STATUS     Status = NDIS_STATUS_SUCCESS;	UCHAR           Count=0;	PQUEUE_HEADER   pQueue;	ULONG           FreeNumber[NUM_OF_TX_RING];	UCHAR			QueIdx, sQIdx, eQIdx;	unsigned long	IrqFlags = 0;	BOOLEAN			hasTxDesc = FALSE;	TX_BLK			TxBlk;	TX_BLK			*pTxBlk;#ifdef DBG_DIAGNOSE	BOOLEAN			firstRound;	RtmpDiagStruct	*pDiagStruct = &pAd->DiagStruct;#endif	if (QIdx == NUM_OF_TX_RING)	{		sQIdx = 0; //PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)#ifdef CONFIG_STA_SUPPORT		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)		eQIdx = 3;	// 4 ACs, start from 0.#endif // CONFIG_STA_SUPPORT //	}	else	{		sQIdx = eQIdx = QIdx;	}		for (QueIdx=sQIdx; QueIdx <= eQIdx; QueIdx++)	{		Count=0;		RT28XX_START_DEQUEUE(pAd, QueIdx, IrqFlags);#ifdef DBG_DIAGNOSE		firstRound = ((QueIdx == 0) ? TRUE : FALSE);#endif // DBG_DIAGNOSE //		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))))			{				RT28XX_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);				return;			}						if (Count >= Max_Tx_Packets)				break;						DEQUEUE_LOCK(&pAd->irq_lock, bIntContext, IrqFlags);			if (&pAd->TxSwQueue[QueIdx] == NULL)			{#ifdef DBG_DIAGNOSE				if (firstRound == TRUE)					pDiagStruct->TxSWQueCnt[pDiagStruct->ArrayCurIdx][0]++;#endif // DBG_DIAGNOSE //				DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);				break;			}			// probe the Queue Head									pQueue = &pAd->TxSwQueue[QueIdx];			if ((pEntry = pQueue->Head) == NULL)			{				DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);				break;			}			pTxBlk = &TxBlk;			NdisZeroMemory((PUCHAR)pTxBlk, sizeof(TX_BLK));			//InitializeQueueHeader(&pTxBlk->TxPacketList);		// Didn't need it because we already memzero it.			pTxBlk->QueIdx = QueIdx;				pPacket = QUEUE_ENTRY_TO_PKT(pEntry);						// Early check to make sure we have enoguh Tx Resource.			hasTxDesc = RT28XX_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;

⌨️ 快捷键说明

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