?? meep6000.c
字號:
/*
* Copyright (c) 2002-2005 Atheros Communications, Inc.
* All rights reserved.
*
*/
#ident "ACI $Id: //depot/sw/branches/ART_V53_dragon/sw/src/dk/mdk/devlib/ar6000/mEep6000.c#5 $, $Header: //depot/sw/branches/ART_V53_dragon/sw/src/dk/mdk/devlib/ar6000/mEep6000.c#5 $"
#ifdef VXWORKS
#include "vxworks.h"
#endif
#ifdef __ATH_DJGPPDOS__
#define __int64 long long
typedef unsigned long DWORD;
#define Sleep delay
#endif // #ifdef __ATH_DJGPPDOS__
#include <errno.h>
#include <stdio.h>
#include <string.h>
#ifndef VXWORKS
#include <malloc.h>
#include <assert.h>
#endif
#include "wlantype.h"
#include "mCfg6000.h"
#include "mEep6000.h"
#include "ar6000reg.h"
#include "mConfig.h"
//#include "ar5211reg.h"
#include "mEepStruct6000.h"
MANLIB_API A_UINT8 dummyEepromWriteArea[512];
static A_UINT16
fbin2freq(A_UINT8 fbin, A_BOOL is2GHz);
static A_INT16
interpolate(A_UINT16 target, A_UINT16 srcLeft, A_UINT16 srcRight,
A_INT16 targetLeft, A_INT16 targetRight);
static A_BOOL
getLowerUpperIndex(A_UINT8 target, A_UINT8 *pList, A_UINT16 listSize,
A_UINT16 *indexL, A_UINT16 *indexR);
/* Configuring the Transmit Power Per Rate Baseband Table */
static void
ar6000SetPowerPerRateTable(A_UINT32 devNum, A_UINT32 freq, A_UINT16 *ratesArray,
A_UINT16 cfgCtl, A_UINT16 AntennaReduction, A_UINT16 powerLimit);
static A_UINT16
ar6000GetMaxEdgePower(A_UINT32 freq, CAL_CTL_EDGES *pRdEdgesPower, A_BOOL is2GHz);
static void
ar6000GetTargetPowers(A_UINT32 freq, CAL_TARGET_POWER *powInfo,
A_UINT16 numChannels, CAL_TARGET_POWER *pNewPower, A_BOOL is2GHz);
/* Interpolating to get the txPower calibration data based on EEPROM values */
static void
ar6000SetPowerCalTable(A_UINT32 devNum, A_UINT32 freq, A_INT16 *pTxPowerIndexOffset);
static void
ar6000GetGainBoundariesAndPdadcs(A_UINT32 devNum, A_UINT32 freq, CAL_DATA_PER_FREQ * pRawDataSet,
A_UINT8 * bChans, A_UINT16 availPiers,
A_UINT16 tPdGainOverlap, A_INT16 *pMinCalPower, A_UINT16 * pPdGainBoundaries,
A_UINT8 * pPDADCValues, A_UINT16 * xpdGainValues, A_UINT16 numXpdGains);
static A_BOOL
ar6000FillVpdTable(A_UINT8 pMin, A_UINT8 pMax, A_UINT8 *pwrList,
A_UINT8 *vpdList, A_UINT16 numIntercepts, A_UINT8 *pRetVpdList);
static void readEepromOldStyle (
A_UINT32 devNum
);
static void readEepromLocs (
A_UINT32 devNum
);
/**************************************************************
* ar6000EepromAttach
*
* Attach either the provided data stream or EEPROM to the EEPROM data structure
*/
A_BOOL
ar6000EepromAttach(A_UINT32 devNum)
{
LIB_DEV_INFO *pLibDev = gLibInfo.pLibDevArray[devNum];
A_UINT16 sum = 0;
A_UINT16 *pHalf;
A_UINT32 i;
//readEepromOldStyle(devNum);
readEepromLocs(devNum);
pLibDev->ar6kEep = (AR6K_EEPROM *)dummyEepromWriteArea;
pHalf = (A_UINT16 *)pLibDev->ar6kEep;
for (i = 0; i < sizeof(AR6K_EEPROM)/2; i++) {
sum ^= *pHalf++;
}
/* Check CRC - Attach should fail on a bad checksum */
if (sum != 0xffff) {
//mError(devNum, EIO, "%s: bad EEPROM checksum 0x%x\n", __func__, sum);
mError(devNum, EIO, "bad EEPROM checksum 0x%x\n", sum);
return FALSE;
}
/* Setup some values checked by common code */
pLibDev->eepData.version = pLibDev->ar6kEep->baseEepHeader.version;
pLibDev->eepData.protect = 0;
pLibDev->eepData.turboDisabled = TRUE;
pLibDev->eepData.currentRD = pLibDev->ar6kEep->baseEepHeader.regDmn;
/* Do we need to fill in the tpcMap? */
return TRUE;
}
static A_UINT32 newEepromArea[512];
void readEepromOldStyle (
A_UINT32 devNum
)
{
A_UINT32 jj;
A_UINT16 *tempPtr = (A_UINT16 *)dummyEepromWriteArea;
eepromReadBlock(devNum, 0, 256, newEepromArea);
for(jj=0; jj < 256; jj++) {
*(tempPtr+jj) = *(newEepromArea + jj);
}
}
void readEepromLocs (
A_UINT32 devNum
)
{
LIB_DEV_INFO *pLibDev = gLibInfo.pLibDevArray[devNum];
A_UINT32 jj;
A_UINT8 *tempPtr = (A_UINT8 *)dummyEepromWriteArea;
//eepromReadBlock(devNum, 0, 256, newEepromArea);
if (pLibDev->devMap.remoteLib && (pLibDev->devMap.r_eepromReadLocs != NULL)) {
pLibDev->devMap.r_eepromReadLocs(devNum, 0, 256, tempPtr);
}
/*
for(jj=0; jj < 256; jj++) {
*(tempPtr+jj) = *(newEepromArea + jj);
}
*/
}
/**************************************************************
* ar6000EepromSetBoardValues
*
* Read EEPROM header info and program the device for correct operation
* given the channel value.
*/
void
ar6000EepromSetBoardValues(A_UINT32 devNum, A_UINT32 freq)
{
LIB_DEV_INFO *pLibDev = gLibInfo.pLibDevArray[devNum];
int is2GHz = ((pLibDev->mode == MODE_11G) || (pLibDev->mode == MODE_11B));
MODAL_EEP_HEADER *pModal;
A_UINT16 antWrites[11];
assert(((pLibDev->eepData.version >> 12) & 0xF) == AR6000_EEP_VER);
pModal = &(pLibDev->ar6kEep->modalHeader[is2GHz]);
/* Set the antenna register(s) correctly for the chip revision */
antWrites[0] = pModal->antCtrl0;
antWrites[1] = pModal->antCtrl[0] & 0x3F;
antWrites[2] = (pModal->antCtrl[0] >> 6) & 0x3F;
antWrites[3] = (pModal->antCtrl[0] >> 12) & 0x3F;
antWrites[4] = (pModal->antCtrl[0] >> 18) & 0x3F;
antWrites[5] = (pModal->antCtrl[0] >> 24) & 0x3F;
antWrites[6] = pModal->antCtrl[1] & 0x3F;
antWrites[7] = (pModal->antCtrl[1] >> 6) & 0x3F;
antWrites[8] = (pModal->antCtrl[1] >> 12) & 0x3F;
antWrites[9] = (pModal->antCtrl[1] >> 18) & 0x3F;
antWrites[10] = (pModal->antCtrl[1] >> 24) & 0x3F;
forceAntennaTbl5211(devNum, antWrites);
writeField(devNum, "bb_switch_settling", pModal->switchSettling);
writeField(devNum, "bb_adc_desired_size", pModal->adcDesiredSize);
writeField(devNum, "bb_pga_desired_size", pModal->pgaDesiredSize);
writeField(devNum, "bb_txrxatten", pModal->txRxAtten);
writeField(devNum, "bb_rxtx_margin_2ghz", pModal->rxTxMargin);
writeField(devNum, "bb_tx_end_to_xpaa_off", pModal->txEndToXpaOff);
writeField(devNum, "bb_tx_end_to_xpab_off", pModal->txEndToXpaOff);
writeField(devNum, "bb_tx_frame_to_xpaa_on", pModal->txFrameToXpaOn);
writeField(devNum, "bb_tx_frame_to_xpab_on", pModal->txFrameToXpaOn);
writeField(devNum, "bb_tx_end_to_xlna_on",pModal->txEndToXlnaOn);
writeField(devNum, "bb_thresh62", pModal->thresh62);
/* write previous IQ results */
writeField(devNum, "bb_iqcorr_q_i_coff", pModal->iqCalI);
writeField(devNum, "bb_iqcorr_q_q_coff", pModal->iqCalQ);
// writeField(devNum, "bb_do_iqcal", 1);
pLibDev->eepromHeaderApplied[pLibDev->mode] = TRUE;
return;
}
/**************************************************************
* ar6000EepromSetTransmitPower
*
* Set the transmit power in the baseband for the given
* operating channel and mode.
*/
void
ar6000EepromSetTransmitPower(A_UINT32 devNum, A_UINT32 freq, A_UINT16 *pRates)
{
#define POW_SM(_r, _s) (((_r) & 0x3f) << (_s))
#define N(a) (sizeof (a) / sizeof (a[0]))
LIB_DEV_INFO *pLibDev = gLibInfo.pLibDevArray[devNum];
A_UINT16 ratesArray[NUM_RATES];
A_UINT16 powerLimit = AR6000_MAX_RATE_POWER;
A_INT16 txPowerIndexOffset = 0;
A_UINT16 cfgCtl;
A_UINT16 twiceAntennaReduction = (cfgCtl = 0x10) ? 6 : 0;
int i;
memset(ratesArray, 0, sizeof(ratesArray));
if (pRates) {
memcpy(ratesArray, pRates, sizeof(A_UINT16) * NUM_RATES);
}
if(pLibDev->eePromLoad) {
assert(((pLibDev->eepData.version >> 12) & 0xF) == AR6000_EEP_VER);
cfgCtl = pLibDev->ar6kEep->baseEepHeader.regDmn & 0xFF;
switch (pLibDev->mode) {
case MODE_11A:
cfgCtl |= CTL_11A;
break;
case MODE_11G:
case MODE_11O:
cfgCtl |= CTL_11G;
break;
case MODE_11B:
cfgCtl |= CTL_11B;
break;
default:
assert(0);
}
if (!pRates) {
ar6000SetPowerPerRateTable(devNum, freq, ratesArray, cfgCtl, twiceAntennaReduction, powerLimit);
}
ar6000SetPowerCalTable(devNum, freq, &txPowerIndexOffset);
}
/*
* txPowerIndexOffset is set by the SetPowerTable() call -
* adjust the rate table (0 offset if rates EEPROM not loaded)
*/
for (i = 0; i < N(ratesArray); i++) {
ratesArray[i] += txPowerIndexOffset;
if (ratesArray[i] > AR6000_MAX_RATE_POWER)
ratesArray[i] = AR6000_MAX_RATE_POWER;
}
pLibDev->pwrIndexOffset = txPowerIndexOffset;
/* Write the OFDM power per rate set */
REGW(devNum, 0x9934,
POW_SM(ratesArray[3], 24)
| POW_SM(ratesArray[2], 16)
| POW_SM(ratesArray[1], 8)
| POW_SM(ratesArray[0], 0)
);
REGW(devNum, 0x9938,
POW_SM(ratesArray[7], 24)
| POW_SM(ratesArray[6], 16)
| POW_SM(ratesArray[5], 8)
| POW_SM(ratesArray[4], 0)
);
/* Write the CCK power per rate set */
REGW(devNum, 0xa234,
POW_SM(ratesArray[10], 24)
| POW_SM(ratesArray[9], 16)
| POW_SM(ratesArray[15], 8) /* XR target power */
| POW_SM(ratesArray[8], 0)
);
REGW(devNum, 0xa238,
POW_SM(ratesArray[14], 24)
| POW_SM(ratesArray[13], 16)
| POW_SM(ratesArray[12], 8)
| POW_SM(ratesArray[11], 0)
);
/*
* Set max power to 31.5 dBm and, optionally,
* enable TPC in tx descriptors.
*/
REGW(devNum, 0x993c, AR6000_MAX_RATE_POWER);
return;
#undef N
#undef POW_SM
}
/**************************************************************
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -