📄 mcont.c
字号:
/* mCont.c - contians continuous transmit functions */
/* Copyright (c) 2001 Atheros Communications, Inc., All Rights Reserved */
#ident "ACI $Id: //depot/sw/branches/ART_V45/sw/src/dk/mdk/devlib/mCont.c#1 $, $Header: //depot/sw/branches/ART_V45/sw/src/dk/mdk/devlib/mCont.c#1 $"
/*
Revsision history
--------------------
1.0 Created.
*/
// #include "vxdrv.h"
#ifdef __ATH_DJGPPDOS__
#include <unistd.h>
#ifndef EILSEQ
#define EILSEQ EIO
#endif // EILSEQ
#define __int64 long long
typedef unsigned long DWORD;
#define Sleep delay
#endif // #ifdef __ATH_DJGPPDOS__
#include "wlantype.h"
#include "ar5210reg.h"
#include "athreg.h"
#include "manlib.h"
#include "mdata.h"
#include "mEeprom.h"
#include "mConfig.h"
#include "mDevtbl.h"
#include <assert.h>
#include <math.h>
#include <time.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#define SINE_BUFFER_SIZE 2000
#ifndef PI
#define PI 3.14159265358979323846
#endif
void lclSineWave(A_UINT32 frequency, A_UINT32 amplitude,
A_UCHAR sine1[2000], A_UCHAR sine2[2000], A_UINT32 turbo);
static A_UCHAR PN7Data[] = {0xfe, 0xa9, 0x9d, 0xd2, 0xc6, 0xf6, 0xb6, 0x48,
0xe1, 0x7c, 0xae, 0x68, 0x9e, 0x28, 0x60, 0x80};
static A_UCHAR PN9Data[] = {0xff, 0x87, 0xb8, 0x59, 0xb7, 0xa1, 0xcc, 0x24,
0x57, 0x5e, 0x4b, 0x9c, 0x0e, 0xe9, 0xea, 0x50,
0x2a, 0xbe, 0xb4, 0x1b, 0xb6, 0xb0, 0x5d, 0xf1,
0xe6, 0x9a, 0xe3, 0x45, 0xfd, 0x2c, 0x53, 0x18,
0x0c, 0xca, 0xc9, 0xfb, 0x49, 0x37, 0xe5, 0xa8,
0x51, 0x3b, 0x2f, 0x61, 0xaa, 0x72, 0x18, 0x84,
0x02, 0x23, 0x23, 0xab, 0x63, 0x89, 0x51, 0xb3,
0xe7, 0x8b, 0x72, 0x90, 0x4c, 0xe8, 0xfb, 0xc0};
static A_BOOL stabilizePower(A_UINT32 devNum, A_UCHAR dataRate, A_UINT32 antenna,
A_UINT32 type);
/**************************************************************************
* txContBegin - Place device in continuous transmit mode
*
*/
MANLIB_API void txContBegin
(
A_UINT32 devNum,
A_UINT32 type,
A_UINT32 typeOption1,
A_UINT32 typeOption2,
A_UINT32 antenna
)
{
LIB_DEV_INFO *pLibDev;
A_UCHAR sineBuffer1[SINE_BUFFER_SIZE], sineBuffer2[SINE_BUFFER_SIZE];
A_UINT32 i, pktSize=0, dataPatLength;
A_UCHAR *pData, dataRate;
MDK_ATHEROS_DESC localDesc;
MDK_ATHEROS_DESC localDescRx;
A_UINT16 queueIndex;
A_UINT32 value;
A_UINT32 xpaaHigh = 0;
A_UINT32 xpabHigh = 0;
if (checkDevNum(devNum) == FALSE) {
mError(devNum, EINVAL, "Device Number %d:txContBegin\n", devNum);
return;
}
if (gLibInfo.pLibDevArray[devNum]->devState < RESET_STATE) {
mError(devNum, EILSEQ, "Device Number %d:txContBegin: Device should be out of Reset before continuous transmit\n", devNum);
return;
}
pLibDev = gLibInfo.pLibDevArray[devNum];
pLibDev->selQueueIndex = 0;
pLibDev->tx[0].dcuIndex = 0;
queueIndex = pLibDev->selQueueIndex;
dataRate = 0;
switch(type) {
case CONT_SINE:
mError(devNum, EINVAL, "Device Number %d:txContBegin: The SINE function is being retooled to provide more accurate\n \
data and is not available in this version of the library.\n", devNum);
return;
#if 0 //quiet compiler warnings
if((typeOption1 < 1) || (typeOption1 > 100)) {
mError(EINVAL,
"txContBegin: SINE amplitude must be between 1 and 100 inclusively - not: %d\n",
typeOption1);
return;
}
if((typeOption2 < 1000) || (typeOption2 > 10000)) {
mError(EINVAL,
"txContBegin: SINE frequency must be between 1000 kHz and 10,000 kHz - not: %d\n",
typeOption2);
return;
}
break;
#endif
case CONT_DATA:
case CONT_FRAMED_DATA:
if(typeOption1 > RANDOM_PATTERN) {
mError(devNum, EINVAL,
"Device Number %d:txContBegin: DATA pattern does not match a known value: %d\n", devNum,
typeOption1);
return;
}
//decode the rate code
for(dataRate = 0; dataRate < numRateCodes; dataRate++) {
if(typeOption2 == rateCodes[dataRate]) {
break; //dataRate should be set to the correct index
}
}
if(dataRate == numRateCodes) {
mError(devNum, EINVAL, "Device Number %d:txContBegin: DATA rate does not match a known rate: %d\n", devNum,
typeOption2);
return;
}
break;
case CONT_SINGLE_CARRIER:
//change xpa value
xpaaHigh = getFieldForMode(devNum, "bb_xpaa_active_high", pLibDev->mode, pLibDev->turbo);
xpabHigh = getFieldForMode(devNum, "bb_xpab_active_high", pLibDev->mode, pLibDev->turbo);
if(pLibDev->mode == MODE_11A) {
writeField(devNum, "bb_xpaa_active_high", !xpaaHigh);
}
else {
writeField(devNum, "bb_xpab_active_high", !xpabHigh);
}
// resetDevice(devNum, pLibDev->macAddr.octets, pLibDev->bssAddr.octets, pLibDev->freqForResetDevice, pLibDev->turbo);
if(typeOption1 > 511) {
mError(devNum, EINVAL, "Device Number %d:txContBegin: SINGLE_CARRIER constant I value greater than 511: %d\n", devNum, typeOption1);
return;
}
if(typeOption2 > 511) {
mError(devNum, EINVAL, "Device Number %d:txContBegin: SINGLE_CARRIER constant Q value greater than 511: %d\n", devNum, typeOption2);
return;
}
break;
default:
mError(devNum, EINVAL, "Device Number %d:txContBegin: type must be set to a valid pattern type\n", devNum);
return;
}
pLibDev->tx[queueIndex].contType = type;
//cleanup any stuff from previous transmit
if (pLibDev->tx[queueIndex].pktAddress || pLibDev->tx[queueIndex].descAddress) {
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;
}
//update antenna
//IF using Single carrier, then need to switch the antenna to the opposite
//to what is expected. This is because the baseband is in "receive" mode in the
//case of single carrier, and so uses the opposite antenna to what is set for
//transmit mode
if(type == CONT_SINGLE_CARRIER) {
antenna =
(antenna==(USE_DESC_ANT|DESC_ANT_A)) ? (USE_DESC_ANT|DESC_ANT_B) : (USE_DESC_ANT|DESC_ANT_A);
}
if (!ar5kInitData[pLibDev->ar5kInitIndex].pMacAPI->setupAntenna(devNum, antenna, &antenna))
{
return;
}
// send a few packets first to step-up the transmit power
// Setup the data packet
pData = sineBuffer1;
switch (typeOption1 ) {
case ONES_PATTERN:
*((A_UINT32 *)pData) = 0xFFFFFFFF;
dataPatLength = 4;
break;
case REPEATING_5A:
*((A_UINT32 *)pData) = 0x5A5A5A5A;
dataPatLength = 4;
break;
case COUNTING_PATTERN:
for(i = 0; i < 256; i++) {
pData[i] = (A_UCHAR)i;
}
dataPatLength = 256;
break;
case PN7_PATTERN:
pData = PN7Data;
dataPatLength = sizeof(PN7Data);
break;
case PN9_PATTERN:
pData = PN9Data;
dataPatLength = sizeof(PN9Data);
break;
case REPEATING_10:
*((A_UINT32 *)pData) = 0xAAAAAAAA;
dataPatLength = 4;
break;
case RANDOM_PATTERN:
srand( (unsigned)time( NULL ) );
for(i = 0; i < 256; i++) {
pData[i] = (A_UCHAR)(rand() & 0xFF);
}
dataPatLength = 256;
break;
default: // Use Zeroes Pattern
*((A_UINT32 *)pData) = 0;
dataPatLength = 4;
break;
}
// if((type != CONT_SINGLE_CARRIER)&&(type != CONT_SINE)) {
if(type != CONT_SINE) {
// Add a local self-linked rx descriptor and buffer to stop receive overrun
// cleanup descriptors created by the last begin
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;
pLibDev->rx.numDesc = 0;
pLibDev->rx.bufferSize = 0;
}
pLibDev->rx.descAddress = memAlloc( devNum, sizeof(MDK_ATHEROS_DESC));
if (0 == pLibDev->rx.descAddress) {
mError(devNum, ENOMEM, "Device Number %d:txContBegin: unable to allocate memory for rx-descriptor to prevent overrun\n", devNum);
return;
}
pLibDev->rx.bufferAddress = memAlloc(devNum, 512);
if (0 == pLibDev->rx.bufferAddress) {
mError(devNum, ENOMEM, "Device Number %d:txContBegin: unable to allocate memory for rx-buffer to prevent overrun\n", devNum);
return;
}
localDescRx.bufferPhysPtr = pLibDev->rx.bufferAddress;
localDescRx.nextPhysPtr = pLibDev->rx.descAddress;
localDescRx.hwControl[1] = pLibDev->rx.bufferSize;
localDescRx.hwControl[0] = 0;
writeDescriptor(devNum, pLibDev->rx.descAddress, &localDescRx);
//go into AGC deaf mode
ar5kInitData[pLibDev->ar5kInitIndex].pMacAPI->AGCDeaf(devNum);
//write RXDP
ar5kInitData[pLibDev->ar5kInitIndex].pMacAPI->writeRxDescriptor(devNum, pLibDev->rx.descAddress);
//stabilize the power before going into continuous mode
if(!stabilizePower(devNum, dataRate,antenna, type)) {
return;
}
//allocate memory for cont packet and descriptor
pLibDev->tx[queueIndex].descAddress = memAlloc( devNum, sizeof(MDK_ATHEROS_DESC) );
if (0 == pLibDev->tx[queueIndex].descAddress) {
mError(devNum, ENOMEM, "Device Number %d:stabilize: unable to allocate memory for descriptors\n", devNum);
return;
}
//setup the transmit packet
if(type == CONT_DATA) {
//set this flag so that the packet will be created without the header
pLibDev->specialTx100Pkt = 1;
}
createTransmitPacket(devNum, MDK_NORMAL_PKT, NULL, 1, 2300, pData,
dataPatLength, 1, queueIndex, &(pktSize), &(pLibDev->tx[queueIndex].pktAddress));
// Setup descriptor template - only the desc addresses change per descriptor
// write buffer ptr to descriptor
localDesc.bufferPhysPtr = pLibDev->tx[queueIndex].pktAddress;
ar5kInitData[pLibDev->ar5kInitIndex].pMacAPI->setContDescriptor( devNum, &localDesc, pktSize,
antenna, dataRate );
//set the next pointer to point to itself
localDesc.nextPhysPtr = pLibDev->tx[queueIndex].descAddress;
//descriptor will be written later
}
pLibDev->devState = CONT_ACTIVE_STATE;
pLibDev->rx.rxEnable = 0;
// The rest of the code is broken into three sections for the three different data transmit types.
switch(type) {
case CONT_SINE:
// memFree(devNum, pLibDev->tx[queueIndex].descAddress);
// memFree(devNum, pLibDev->tx[queueIndex].pktAddress);
pLibDev->tx[queueIndex].descAddress = memAlloc(devNum, sizeof(MDK_ATHEROS_DESC));
if (0 == pLibDev->tx[queueIndex].descAddress) {
mError(devNum, ENOMEM, "Device Number %d:txContBegin: unable to allocate memory for descriptors\n", devNum);
return;
}
//allocate enough memory for the packet and write it down
pLibDev->tx[queueIndex].pktAddress = memAlloc(devNum, SINE_BUFFER_SIZE * 2);
if (0 == pLibDev->tx[queueIndex].pktAddress) {
mError(devNum, ENOMEM, "Device Number %d:txContBegin: unable to allocate memory for SINE packet\n", devNum);
return;
}
pktSize = SINE_BUFFER_SIZE * 2;
lclSineWave(typeOption1, typeOption2, sineBuffer1, sineBuffer2, pLibDev->turbo);
pLibDev->devMap.OSmemWrite(devNum, pLibDev->tx[queueIndex].pktAddress,
sineBuffer1, SINE_BUFFER_SIZE);
pLibDev->devMap.OSmemWrite(devNum, pLibDev->tx[queueIndex].pktAddress + SINE_BUFFER_SIZE,
sineBuffer2, SINE_BUFFER_SIZE);
// Setup the SINE descriptor
localDesc.nextPhysPtr = 0;
// write buffer ptr to descriptor
localDesc.bufferPhysPtr = pLibDev->tx[queueIndex].pktAddress;
//create and write the 2 control words
localDesc.hwControl[0] = ( (rateValues[0] << BITS_TO_TX_XMIT_RATE) |
(0x18 << BITS_TO_TX_HDR_LEN) |
(antenna << BITS_TO_TX_ANT_MODE) |
(pktSize + FCS_FIELD) );
localDesc.hwControl[1] = pktSize;
writeDescriptor(devNum, pLibDev->tx[queueIndex].descAddress, &localDesc);
// Disable AGC to A2 traffic
REGW(devNum, 0x9808, REGR(devNum, 0x9808) | 0x08000000);
mSleep(1);
// Turn on Tx
REGW(devNum, PHY_BASE+(50<<2),0x00060406);
mSleep(1);
// Set PA on
REGW(devNum, PHY_BASE+(50<<2),0x00060606);
mSleep(1);
// Re-enable AGC to A2 traffic
REGW(devNum, 0x9808, REGR(devNum, 0x9808) & (~0x08000000));
// Program the num of lines to loop on
REGW(devNum, 0x8074, (1 << 14) | (((pktSize/2)-1) << 3) | 0x3);
mSleep(1);
// Turn on DAC
REGW(devNum, PHY_BASE+(11<<2), 0x0ffc0ffc);
mSleep(1);
// Enable PCU tstDAC
REGW(devNum, (PHY_BASE+(2<<2)),(REGR(devNum, PHY_BASE+(2<<2)) | 0x80) & ~0x3);
mSleep(1);
// Start the hardware
REGW(devNum, F2_TXDP0, pLibDev->tx[queueIndex].descAddress);
mSleep(1);
REGW(devNum, F2_TXCFG, REGR(devNum, F2_TXCFG) | F2_TXCFG_CONT_EN);
REGW(devNum, F2_CR, F2_CR_TXE0);
// Wait for loop to load
mSleep(2);
// Enable looping
REGW(devNum, 0x8074, REGR(devNum, 0x8074) | 0x4);
mSleep(1);
break;
case CONT_SINGLE_CARRIER:
// --------- set constant values -----------
REGW(devNum, PHY_BASE+(15<<2), (typeOption2 << 9) | typeOption1);
// --------- Force TSTDAC with value in Reg 15 -----
REGW(devNum, PHY_BASE+(2<<2),
(REGR(devNum, PHY_BASE+(2<<2)) & 0xffffff7d) | (0x1 << 7) | (0x1 << 1));
// --------- Manually Turn on the DAC -----------
REGW(devNum, PHY_BASE+(11<<2), 0x30ffc); // Turn on the DAC
// --------- turn on rf -----------
if((pLibDev->swDevID & 0x00ff) <= 0x0013) {
REGW(devNum, PHY_BASE+(0x36<<2), 0x0604066);
mSleep(10);
REGW(devNum, PHY_BASE+(0x36<<2), 0x0606066);
}
else if ((pLibDev->swDevID & 0x00ff) >= 0x0014){
value = 0x10a098c2;
if(pLibDev->mode != MODE_11A) {
value |= 0x400000;
}
REGW(devNum, PHY_BASE+(0x37<<2), value);
mSleep(10);
value |= 0x4000;
REGW(devNum, PHY_BASE+(0x37<<2), value);
}
//printf("SNOOP: dumping pci writes:\n");
//displayPciRegWrites(devNum);
//getch();
//revert back to existing xpa value.
changeField(devNum, "bb_xpaa_active_high", xpaaHigh);
changeField(devNum, "bb_xpab_active_high", xpabHigh);
break;
case CONT_DATA:
//reset data create flag
pLibDev->specialTx100Pkt = 0;
// Resetup the first transmit descriptor with the More flag set.
localDesc.hwControl[1] = (pktSize & 0xfff) | DESC_MORE;
writeDescriptor(devNum, pLibDev->tx[queueIndex].descAddress, &localDesc);
// start hardware
ar5kInitData[pLibDev->ar5kInitIndex].pMacAPI->txBeginContData(devNum, queueIndex);
break;
case CONT_FRAMED_DATA:
writeDescriptor(devNum, pLibDev->tx[queueIndex].descAddress, &localDesc);
ar5kInitData[pLibDev->ar5kInitIndex].pMacAPI->txBeginContFramedData(devNum, queueIndex, 0, 1);
break;
}
}
/**************************************************************************
* txContEnd - Remove device from continuous transmit mode
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -