⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mdata.c

📁 atheros ar5001 5002 driver
💻 C
📖 第 1 页 / 共 5 页
字号:
/* mData.c - contians frame transmit functions */
/* Copyright (c) 2001 Atheros Communications, Inc., All Rights Reserved */

#ident	"ACI $Id: //depot/sw/branches/ART_V45/sw/src/dk/mdk/devlib/mData.c#5 $, $Header: //depot/sw/branches/ART_V45/sw/src/dk/mdk/devlib/mData.c#5 $"

/* 
Revsision history
--------------------
1.0 	  Created.
*/

#ifdef VXWORKS
#include "timers.h"
#include "vxdrv.h"
#endif

#ifdef __ATH_DJGPPDOS__
#include <unistd.h>
#ifndef EILSEQ  
    #define EILSEQ EIO
#endif	// EILSEQ

#define __int64	long long
typedef unsigned long DWORD;
#define HANDLE long
#define Sleep	delay
#endif	// #ifdef __ATH_DJGPPDOS__

#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "wlantype.h"
#include "athreg.h"
#include "manlib.h"
#include "mdata.h"
#include "mEeprom.h"
#include "mConfig.h"
#ifndef VXWORKS
#include <malloc.h>
#ifdef LINUX
#include "linuxdrv.h"
#else
#include "ntdrv.h"
#endif
#endif // VXWorks
#include "mData210.h"
#include "mData211.h"
#include "mData212.h"
#include "mDevtbl.h"

#ifdef LINUX
#undef BIG_ENDIAN
#endif

#ifdef BIG_ENDIAN 
#include "endian_func.h"
#endif

static void mdkExtractAddrAndSequence(A_UINT32 devNum, RX_STATS_TEMP_INFO *pStatsInfo);
static void mdkCountDuplicatePackets(A_UINT32	devNum, 
				RX_STATS_TEMP_INFO	*pStatsInfo, A_BOOL *pIsDuplicate);
static void mdkGetSignalStrengthStats(SIG_STRENGTH_STATS *pStats, A_INT8	signalStrength);
static void txAccumulateStats(A_UINT32 devNum, A_UINT32 txTime, A_UINT16 queueIndex);
static void mdkExtractTxStats(A_UINT32	devNum, TX_STATS_TEMP_INFO	*pStatsInfo, A_UINT16 queueIndex);
static void mdkExtractRxStats(A_UINT32 devNum, RX_STATS_TEMP_INFO	*pStatsInfo);
static void sendStatsPkt(A_UINT32 devNum, A_UINT32 rate, A_UINT16 StatsType, A_UCHAR *dest);
static A_BOOL mdkExtractRemoteStats(A_UINT32 devNum, RX_STATS_TEMP_INFO *pStatsInfo);
static void comparePktData(A_UINT32 devNum, RX_STATS_TEMP_INFO	*pStatsInfo);
static void extractPPM(A_UINT32 devNum, RX_STATS_TEMP_INFO *pStatsInfo);
static A_UINT32 countBits(A_UINT32 mismatchBits);
static void fillCompareBuffer(A_UCHAR *pBuffer, A_UINT32 compareBufferSize, 
				A_UCHAR *pDataPattern, A_UINT32 dataPatternLength);

#if defined(__ATH_DJGPPDOS__)
static A_UINT32 milliTime(void);
#endif

////////////////////// __TODO__   ////////////////////////////////////////////////////////////////////////////////
MANLIB_API void txDataStart(A_UINT32 devNum);
MANLIB_API void txDataComplete(A_UINT32 devNum, A_UINT32 timeout, A_UINT32 remoteStats);

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////

static char bitCount[256] = {
//	0  1  2  3	4  5  6  7	8  9  a  b	c  d  e  f
	0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 	// 0X
	1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 	// 1X
	1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 	// 2X
	2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 	// 3X
	1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 	// 4X
	2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 	// 5X
	2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 	// 6X
	3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 	// 7X
	1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 	// 8X
	2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 	// 9X
	2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 	// aX
	3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 	// bX
	2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 	// cX
	3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 	// dX
	3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 	// eX
	4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8		// fX
};

// A quick lookup translating from rate 6, 9, 12... to the stats_struct array index
//static const A_UCHAR StatsRateArray[19] = 
//	{0, 0, 1, 2, 3, 0, 4, 0, 5, 0,	0,	0,	6,	0,	0,	0,	7,	0,	8};
//#define rate2bin(x) (StatsRateArray[((x)/3)])

// A quick lookup translating from IEEE rate field to the stats bin
//static const A_UCHAR IEEErateArray[8] = {7, 5, 3, 1, 8, 6, 4, 2};
//#define descRate2bin(x) (IEEErateArray[(x)-8])


A_UINT32 rate2bin(A_UINT32 rateCode) {
	A_UINT32 rateBin = 0, i;
	for(i = 0; i < NUM_RATES; i++) {
		if(rateCode == rateCodes[i]) {
			rateBin = i+1;
			break;
		}
	}
	return rateBin;
}

A_UINT32 descRate2bin(A_UINT32 descRateCode) {
	A_UINT32 rateBin = 0, i;
	for(i = 0; i < NUM_RATES; i++) {
		if(descRateCode == rateValues[i]) {
			rateBin = i+1;
			break;
		}
	}
	return rateBin;
}

/**************************************************************************
* txDataSetup - create packet and descriptors for transmission
*
*/
MANLIB_API void txDataSetup
(
 A_UINT32 devNum, 
 A_UINT32 rateMask, 
 A_UCHAR *dest, 
 A_UINT32 numDescPerRate, 
 A_UINT32 dataBodyLength, 
 A_UCHAR *dataPattern, 
 A_UINT32 dataPatternLength, 
 A_UINT32 retries, 
 A_UINT32 antenna, 
 A_UINT32 broadcast
)
{
	LIB_DEV_INFO *pLibDev = gLibInfo.pLibDevArray[devNum];
	A_UCHAR 	rates[NUM_RATES];
	A_UINT32	mask = 0x01;
	A_UINT16	i, j, numRates, rateIndex, rateValue;
	A_UINT32	descAddress;
	A_UINT32	antMode = 0;
	A_UINT32	pktSize;
	A_UINT32	pktAddress;
	MDK_ATHEROS_DESC	localDesc;
	A_UINT16	 queueIndex;



	pLibDev->selQueueIndex = 0;
	pLibDev->tx[0].dcuIndex = 0;

	queueIndex = pLibDev->selQueueIndex;

	pLibDev->tx[queueIndex].retryValue = retries;		
	//verify some of the arguments
	if (checkDevNum(devNum) == FALSE) {
		mError(devNum, EINVAL, "Device Number %d:txDataSetup\n", devNum);
		return;
	}
	
	if(pLibDev->devState < RESET_STATE) {
		mError(devNum, EILSEQ, "Device Number %d:txDataSetup: device not in reset state - resetDevice must be run first\n", devNum);
		return;
	}

	if (0 == numDescPerRate) {
		mError(devNum, EINVAL, "Device Number %d:txDataSetup: must create at least 1 descriptor per rate\n", devNum);
		return;
	}

	/* we must take the MDK pkt header into consideration here otherwise it could make the 
	 * body size greater than an 802.11 pkt body
	 */
	if(dataBodyLength > (MAX_PKT_BODY_SIZE - sizeof(MDK_PACKET_HEADER) - sizeof(WLAN_DATA_MAC_HEADER3) - FCS_FIELD)) {
		mError(devNum, EINVAL, "Device Number %d:txDataSetup: packet body size must be less than %d [%d - (%d + %d + %d)]\n", devNum, 
								(MAX_PKT_BODY_SIZE - sizeof(MDK_PACKET_HEADER) - sizeof(WLAN_DATA_MAC_HEADER3) - FCS_FIELD), 
								MAX_PKT_BODY_SIZE,
								sizeof(MDK_PACKET_HEADER),
								sizeof(WLAN_DATA_MAC_HEADER3),
								FCS_FIELD);
		return;
	}

	// reset the txEnable. Only one queue is supported at a time for now 
	for( i = 0; i < MAX_TX_QUEUE; i++ )
	{
	 	pLibDev->tx[i].txEnable=0;
	}

	//cleanup any stuff from previous go round
	if (pLibDev->tx[queueIndex].pktAddress) {
		memFree(devNum, pLibDev->tx[queueIndex].pktAddress);
		pLibDev->tx[queueIndex].pktAddress = 0;
		memFree(devNum, pLibDev->tx[queueIndex].descAddress);
		pLibDev->tx[queueIndex].descAddress = 0;
		pLibDev->tx[queueIndex].txEnable = 0;
	}
	if(pLibDev->tx[queueIndex].endPktAddr) {
		memFree(devNum, pLibDev->tx[queueIndex].endPktAddr);
		memFree(devNum, pLibDev->tx[queueIndex].endPktDesc);
		pLibDev->tx[queueIndex].endPktAddr = 0;
		pLibDev->tx[queueIndex].endPktDesc = 0;
	}

	//create rate array and findout how many rates there are
	for (i = 0, numRates = 0; i < NUM_RATES; i++)
	{
		if (rateMask & mask) {
			rates[numRates] = rateValues[i];
			numRates++;
		}
		mask = (mask << 1) & 0xffffff;			
	}
	
	//create the required number of descriptors
	pLibDev->tx[queueIndex].numDesc = numDescPerRate * numRates;
	pLibDev->tx[queueIndex].descAddress = memAlloc( devNum, 
					pLibDev->tx[queueIndex].numDesc * sizeof(MDK_ATHEROS_DESC));

	if (0 == pLibDev->tx[queueIndex].descAddress) {
		mError(devNum, ENOMEM, "Device Number %d:txDataSetup: unable to allocate memory for descriptors\n", devNum);
		return;
	}

	//setup the transmit packets
	createTransmitPacket(devNum, MDK_NORMAL_PKT, dest, pLibDev->tx[queueIndex].numDesc, 
		dataBodyLength, dataPattern, dataPatternLength, broadcast, queueIndex,
		&pktSize, &(pLibDev->tx[queueIndex].pktAddress));

	//take a copy of the dest address
	memcpy(pLibDev->tx[queueIndex].destAddr.octets, dest, WLAN_MAC_ADDR_SIZE);
	pLibDev->tx[queueIndex].dataBodyLen = dataBodyLength;

	//setupAntennaAr5210( devNum, antenna, &antMode );
	if (!ar5kInitData[pLibDev->ar5kInitIndex].pMacAPI->setupAntenna(devNum, antenna, &antMode))
	{
		return;
	}

	rateIndex = 0;
	descAddress = pLibDev->tx[queueIndex].descAddress;
	pktAddress = pLibDev->tx[queueIndex].pktAddress;
	for (i = 0, j = 0; i < pLibDev->tx[queueIndex].numDesc; i++)
	{
		rateValue = rates[rateIndex];

		//write buffer ptr to descriptor
		localDesc.bufferPhysPtr = pktAddress;
		
		ar5kInitData[pLibDev->ar5kInitIndex].pMacAPI->setDescriptor( devNum, &localDesc, pktSize, 
							antMode, i, rateValue, broadcast );

		//increment rate index for next time round
		if(!(rateMask & RATE_GROUP)) {
			(rateIndex == numRates - 1) ? rateIndex = 0 : rateIndex++;
		}
		else {
			if (j == (numDescPerRate - 1)) {
				j = 0; 
				rateIndex++;
			}
			else {
				j++;
			}
		}

		//write link pointer
		if (i == (pLibDev->tx[queueIndex].numDesc - 1)) { //ie its the last descriptor 
			localDesc.nextPhysPtr = 0;
		}
		else {
			localDesc.nextPhysPtr = descAddress + sizeof(MDK_ATHEROS_DESC);
		}

		writeDescriptor(devNum, descAddress, &localDesc);

		//increment descriptor address
		descAddress += sizeof(MDK_ATHEROS_DESC);
	}

	//create the end packet
	createEndPacket(devNum, queueIndex, dest, antMode);

	// Set broadcast for Begin
	if(broadcast) {
		pLibDev->tx[queueIndex].broadcast = 1;
	}
	else {
		pLibDev->tx[queueIndex].broadcast = 0;
	}

	pLibDev->tx[queueIndex].txEnable = 1;
	ar5kInitData[pLibDev->ar5kInitIndex].pMacAPI->setRetryLimit( devNum, queueIndex );
	return;
}

MANLIB_API void cleanupTxRxMemory
(
 A_UINT32 devNum,
 A_UINT32 flags
)
{
	LIB_DEV_INFO *pLibDev = gLibInfo.pLibDevArray[devNum];
	A_UINT16	 queueIndex;



	pLibDev->selQueueIndex = 0;
	pLibDev->tx[0].dcuIndex = 0;

	queueIndex = pLibDev->selQueueIndex;

	if(flags & TX_CLEAN) {
		if (pLibDev->tx[queueIndex].pktAddress) {
			memFree(devNum, pLibDev->tx[queueIndex].pktAddress);
			pLibDev->tx[queueIndex].pktAddress = 0;
			memFree(devNum, pLibDev->tx[queueIndex].descAddress);
			pLibDev->tx[queueIndex].descAddress = 0;
			pLibDev->tx[queueIndex].txEnable = 0;
		}
		if(pLibDev->tx[queueIndex].endPktAddr) {
			memFree(devNum, pLibDev->tx[queueIndex].endPktAddr);
			memFree(devNum, pLibDev->tx[queueIndex].endPktDesc);
			pLibDev->tx[queueIndex].endPktAddr = 0;
			pLibDev->tx[queueIndex].endPktDesc = 0;
		}
	}
	if(flags & RX_CLEAN) {
		if (pLibDev->rx.rxEnable || pLibDev->rx.bufferAddress) {
			memFree(devNum, pLibDev->rx.bufferAddress);
			pLibDev->rx.bufferAddress = 0;
			memFree(devNum, pLibDev->rx.descAddress);
			pLibDev->rx.descAddress = 0;
			pLibDev->rx.rxEnable = 0;
		}
	}

}

void
createEndPacket
(
 A_UINT32 devNum,
 A_UINT16 queueIndex,
 A_UCHAR  *dest,
 A_UINT32 antMode
)
{
	LIB_DEV_INFO *pLibDev = gLibInfo.pLibDevArray[devNum];
	A_UINT32 pktSize;
	MDK_ATHEROS_DESC	localDesc;
	A_UINT32			retryValue;

	pLibDev->tx[queueIndex].endPktDesc = 
			memAlloc( devNum, 1 * sizeof(MDK_ATHEROS_DESC));

	// this is the special end descriptor
	createTransmitPacket(devNum, MDK_LAST_PKT, dest, 1, 0, NULL, 0, 0,
		queueIndex, &pktSize, &(pLibDev->tx[queueIndex].endPktAddr));

	//write buffer ptr to descriptor
	localDesc.bufferPhysPtr = pLibDev->tx[queueIndex].endPktAddr;
	
	//Venice needs to have the retries set for end packets
	//so take a copy and artificially set it
	retryValue = pLibDev->tx[queueIndex].retryValue;
	pLibDev->tx[queueIndex].retryValue = 0xf;


	if (pLibDev->libCfgParams.enableXR) {
		setDescriptorEndPacketAr5212( devNum, &localDesc, pktSize, 
								       antMode, 0, rateValues[15], 0);
	}
	else if (((pLibDev->swDevID & 0x00ff) >= 0x0013) && (pLibDev->mode == MODE_11G) && (!pLibDev->turbo)) {
		setDescriptorEndPacketAr5212( devNum, &localDesc, pktSize, 
								       antMode, 0, rateValues[8], 0);
	} else {
	  	ar5kInitData[pLibDev->ar5kInitIndex].pMacAPI->setDescriptor( devNum, &localDesc, pktSize, 
						antMode, 0, rateValues[0], 0);
	}
	//restore the retry value
	pLibDev->tx[queueIndex].retryValue = retryValue;
	
	localDesc.nextPhysPtr = 0;
	
	writeDescriptor(devNum, pLibDev->tx[queueIndex].endPktDesc, &localDesc);
}

void
sendEndPacket
(
 A_UINT32 devNum,
 A_UINT16 queueIndex
)
{
	LIB_DEV_INFO *pLibDev = gLibInfo.pLibDevArray[devNum];

	//successful transmission of frames, so send special end packet
	ar5kInitData[pLibDev->ar5kInitIndex].pMacAPI->sendTxEndPacket(devNum, queueIndex );

	//cleanup end packet memory allocation

⌨️ 快捷键说明

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