?? mdata.c
字號:
/* mData.c - contains frame transmit functions */
/* Copyright (c) 2001 Atheros Communications, Inc., All Rights Reserved */
#ident "ACI $Id: //depot/sw/branches/ART_V53_dragon/sw/src/dk/mdk/devlib/mData.c#3 $, $Header: //depot/sw/branches/ART_V53_dragon/sw/src/dk/mdk/devlib/mData.c#3 $"
/*
Revsision history
--------------------
1.0 Created.
*/
//#define DEBUG_MEMORY
#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 "stats_routines.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 "..\ar5513\mData513.h"
#include "mDevtbl.h"
#include "mIds.h"
//#ifdef LINUX
//#undef ARCH_BIG_ENDIAN
//#endif
#ifdef ARCH_BIG_ENDIAN
#include "endian_func.h"
#endif
#if defined(COBRA_AP) && defined(PCI_INTERFACE)
#include "ar531xPlusreg.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);
static void fillRxDescAndFrame(A_UINT32 devNum, RX_STATS_TEMP_INFO *statsInfo);
#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);
A_UINT32 buf_ptr;
A_UCHAR *tmp_pktDataPtr;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
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])
/**************************************************************************
* txDataSetupNoEndPacket - create packet and descriptors for transmission
* with no end packet. added to be used for falcon
* 11g synthesizer phase offset.
*/
MANLIB_API void txDataSetupNoEndPacket
(
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];
pLibDev->noEndPacket = TRUE;
txDataSetup(devNum, rateMask, dest, numDescPerRate, dataBodyLength,
dataPattern, dataPatternLength, retries, antenna, broadcast);
}
/**************************************************************************
* 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, prevRateIndex, rateValue;
A_UINT32 descAddress, dIndex, descOp;
A_UINT32 antMode = 0;
A_UINT32 pktSize;
A_UINT32 pktAddress;
MDK_ATHEROS_DESC *localDescPtr; //pointer to current descriptor being filled
MDK_ATHEROS_DESC *localDescBuffer; //create a local buffer to create descriptors
A_UINT16 queueIndex;
A_BOOL probePkt = FALSE;
A_UINT16 mdkPktType = MDK_NORMAL_PKT;
A_UINT32 *dPtr, lastDesc = 0, intrBit ;
A_UINT32 falconAddrMod = 0;
#ifdef _TIME_PROFILE
A_UINT32 txDataSetup_start, txDataSetup_end;
txDataSetup_start=milliTime();
printf("txDataSetup_start=%u\n", txDataSetup_start);
#endif
//overloading the broadcast param with additional flags
if(broadcast & PROBE_PKT) {
probePkt = TRUE;
mdkPktType = MDK_PROBE_PKT;
//setup the probe packets on a different queue
pLibDev->txProbePacketNext = TRUE;
queueIndex = PROBE_QUEUE;
if(pLibDev->backupSelectQueueIndex != PROBE_QUEUE) { //safety check so we don't backup probe_queue index
pLibDev->backupSelectQueueIndex = pLibDev->selQueueIndex;
}
pLibDev->selQueueIndex = PROBE_QUEUE;
}
else {
pLibDev->selQueueIndex = 0;
queueIndex = pLibDev->selQueueIndex;
}
//cleanup broadcast flag after cleaning up overloaded flags
broadcast = broadcast & 0x1;
#ifdef DEBUG_MEMORY
printf("SNOOP::txDataSetup::broadcast=%x\n", broadcast);
printf("SNOOP::dest %x:%x:%x:%x:%x:%x\n", dest[6], dest[5], dest[4], dest[3], dest[2], dest[1], dest[0]);
#endif
pLibDev->tx[queueIndex].dcuIndex = 0;
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
//FJC removed this now that am using another queue for probe packets
//txEnable gets reset in cleanup below
// 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;
}
#ifdef DEBUG_MEMORY
printf("SNOOP::txDataSetup::mask=%x:rateMask=%x\n", mask, rateMask);
printf("SNOOP::txDataSetup::numRates=%d:numDescPerRate=%d\n", numRates, numDescPerRate);
#endif
//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 client memory for %d descriptors\n", devNum, pLibDev->tx[queueIndex].numDesc);
return;
}
//setup the transmit packets
if (pLibDev->noEndPacket) {
createTransmitPacket(devNum, MDK_SKIP_STATS_PKT, dest, pLibDev->tx[queueIndex].numDesc,
dataBodyLength, dataPattern, dataPatternLength, broadcast, queueIndex,
&pktSize, &(pLibDev->tx[queueIndex].pktAddress));
} else {
createTransmitPacket(devNum, mdkPktType, 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;
prevRateIndex = rateIndex;
descAddress = pLibDev->tx[queueIndex].descAddress;
pktAddress = pLibDev->tx[queueIndex].pktAddress;
if (isFalcon(devNum) || isDragon(devNum)) {
falconAddrMod = FALCON_MEM_ADDR_MASK ;
}
localDescBuffer = (MDK_ATHEROS_DESC *)malloc(sizeof(MDK_ATHEROS_DESC) * pLibDev->tx[queueIndex].numDesc);
if (!localDescBuffer) {
mError(devNum, ENOMEM, "Device Number %d:txDataSetup: unable to allocate host memory for %d tx descriptors\n", devNum, pLibDev->tx[queueIndex].numDesc);
return;
}
dIndex = 0;
localDescPtr = localDescBuffer;
for (i = 0, j = 0; i < pLibDev->tx[queueIndex].numDesc; i++)
{
rateValue = rates[rateIndex];
//write buffer ptr to descriptor
#if defined(COBRA_AP) && defined(PCI_INTERFACE)
if(isCobra(pLibDev->swDevID)) {
localDescPtr->bufferPhysPtr = pktAddress;
}
else {
localDescPtr->bufferPhysPtr = pktAddress | HOST_PCI_SDRAM_BASEADDR;
}
#else
localDescPtr->bufferPhysPtr = pktAddress;
#endif
ar5kInitData[pLibDev->ar5kInitIndex].pMacAPI->setDescriptor( devNum, localDescPtr, pktSize,
antMode, i, rateValue, broadcast );
//write link pointer
if (i == (pLibDev->tx[queueIndex].numDesc - 1)) { //ie its the last descriptor
localDescPtr->nextPhysPtr = 0;
// localDescPtr->nextPhysPtr = pLibDev->tx[queueIndex].descAddress;
}
else {
#if defined(COBRA_AP) && defined(PCI_INTERFACE)
if(isCobra(pLibDev->swDevID)) {
localDescPtr->nextPhysPtr = (descAddress + sizeof(MDK_ATHEROS_DESC));
}
else {
localDescPtr->nextPhysPtr = (descAddress + sizeof(MDK_ATHEROS_DESC)) | HOST_PCI_SDRAM_BASEADDR;
}
#else
localDescPtr->nextPhysPtr = falconAddrMod | (descAddress + sizeof(MDK_ATHEROS_DESC));
#endif
}
//writeDescriptor(devNum, descAddress, &localDesc);
// zeroDescriptorStatus(devNum, localDescPtr, pLibDev->swDevID);
//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++;
if (pLibDev->devMap.remoteLib) {
dPtr = (A_UINT32 *)localDescPtr;
lastDesc = LAST_DESC_NEXT << DESC_INFO_LAST_DESC_BIT_START;
localDescPtr->hwControl[0] &= ~DESC_TX_INTER_REQ;
intrBit = 0;
descOp = ((sizeof(MDK_ATHEROS_DESC)/sizeof(A_UINT32))+1) << DESC_OP_WORD_OFFSET_BIT_START;
if (i == (pLibDev->tx[queueIndex].numDesc-1)) {
lastDesc = LAST_DESC_NULL << DESC_INFO_LAST_DESC_BIT_START;
intrBit = DESC_TX_INTER_REQ_START << DESC_OP_INTR_BIT_START;
descOp = intrBit | \
((numDescPerRate-1) << DESC_OP_NDESC_OFFSET_BIT_START) | \
(2 << DESC_OP_WORD_OFFSET_BIT_START);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -