?? artear.c
字號:
/* artEar.c - contians functions for managing EAR in ART */
/* Copyright (c) 2003 Atheros Communications, Inc., All Rights Reserved */
#ident "ACI $Id: //depot/sw/branches/ART_V53_dragon/sw/src/dk/mdk/devlib/artEar.c#1 $, $Header: //depot/sw/branches/ART_V53_dragon/sw/src/dk/mdk/devlib/artEar.c#1 $"
#ifdef __ATH_DJGPPDOS__
#include <unistd.h>
#ifndef EILSEQ
#define EILSEQ EIO
#endif // EILSEQ
#define __int64 long long
#define HANDLE long
typedef unsigned long DWORD;
#define Sleep delay
#endif // #ifdef __ATH_DJGPPDOS__
#include <stdlib.h>
#include <string.h> // For memset() call
#include "wlantype.h"
#include "athreg.h"
#include "manlib.h"
#include "mConfig.h"
#include <errno.h>
#include "artEar.h"
int EarDebugLevel = EAR_DEBUG_OFF; //EAR_DEBUG_VERBOSE;
static A_UINT16
ar5212EarDoRH(A_UINT32 devNum, REGISTER_HEADER *pRH);
static RF_REG_INFO *
ar5212GetRfBank(A_UINT32 devNum, A_UINT16 bank);
static A_UINT16
ar5212CFlagsToEarMode(A_UINT32 devNum);
static A_BOOL
ar5212IsChannelInEarRegHead(A_UINT16 earChannel, A_UINT16 channelMhz);
static void
ar5212ModifyRfBuffer(RF_REG_INFO *pRfRegs, A_UINT32 reg32, A_UINT32 numBits,
A_UINT32 firstBit, A_UINT32 column);
static void
showEarAlloc(EAR_ALLOC *earAlloc);
/******************** EAR Entry Routines ********************/
/**************************************************************
* ar5212IsEarEngaged
*
* Given the reset mode and channel - does the EAR exist and
* does it have any changes for this mode and channel
*/
A_BOOL
ar5212IsEarEngaged(A_UINT32 devNum, EAR_HEADER *pEarHead, A_UINT32 freq)
{
int i;
LIB_DEV_INFO *pLibDev = gLibInfo.pLibDevArray[devNum];
if(!pLibDev->libCfgParams.loadEar)
{
// printf("In ar5212IsEarEngaged pLibDev->libCfgParams.loadEar\n");
return FALSE;
}
/* Check for EAR */
if (!pEarHead)
{
// printf("pEarHead\n");
return FALSE;
}
/* Check for EAR found some reg headers */
if (pEarHead->numRHs == 0)
{
// printf("pEarHead->numRHs\n");
return FALSE;
}
/* Check register headers for match on channel and mode */
for (i = 0; i < pEarHead->numRHs; i++)
{
if ((pEarHead->pRH[i].modes & ar5212CFlagsToEarMode(devNum)) &&
ar5212IsChannelInEarRegHead(pEarHead->pRH[i].channel, (A_UINT16)freq))
{
//printf("ar5212IsChannelInEarRegHead\n");
return TRUE;
}
}
devNum = 0; //quiet warnings
// printf("ar5212IsearEngaged\n");
return FALSE;
}
/**************************************************************
* ar5212EarModify
*
* The location sensitive call the can enable/disable calibrations
* or check for additive register changes
*/
A_BOOL
ar5212EarModify(A_UINT32 devNum, EAR_HEADER *pEarHead, EAR_LOC_CHECK loc, A_UINT32 freq, A_UINT32 *modifier)
{
int i;
if(pEarHead == NULL) {
mError(devNum, EINVAL, "ar5212EarModify: earHead is NULL\n");
return FALSE;
}
/* Should only be called if EAR is engaged */
if(!ar5212IsEarEngaged(devNum, pEarHead, freq)) {
mError(devNum, EINVAL, "ar5212EarModify: ear is not engaged\n");
return FALSE;
}
/* Check to see if there are any EAR modifications for the given code location */
for (i = 0; i < pEarHead->numRHs; i++) {
/* Check register headers for match on channel and mode */
if (pEarHead->pRH[i].modes & ar5212CFlagsToEarMode(devNum) &&
ar5212IsChannelInEarRegHead(pEarHead->pRH[i].channel, (A_UINT16)freq))
{
switch (loc) {
/* Stage: 0 */
case EAR_LC_RF_WRITE:
if (pEarHead->pRH[i].stage == EAR_STAGE_ANALOG_WRITE) {
if (EarDebugLevel >= EAR_DEBUG_VERBOSE) {
printf("ar5212EarModify: Performing stage 0 ops on RH %d\n", i);
}
ar5212EarDoRH(devNum, &(pEarHead->pRH[i]));
}
break;
/* Stage: 1 */
case EAR_LC_PHY_ENABLE:
if (pEarHead->pRH[i].stage == EAR_STAGE_PRE_PHY_ENABLE) {
if (EarDebugLevel >= EAR_DEBUG_VERBOSE) {
printf("ar5212EarModify: Performing stage 1 ops on RH %d\n", i);
}
ar5212EarDoRH(devNum, &(pEarHead->pRH[i]));
}
break;
/* Stage: 2 */
case EAR_LC_POST_RESET:
if (pEarHead->pRH[i].stage == EAR_STAGE_POST_RESET) {
if (EarDebugLevel >= EAR_DEBUG_VERBOSE) {
printf("ar5212EarModify: Performing stage 2 ops on RH %d\n", i);
}
ar5212EarDoRH(devNum, &(pEarHead->pRH[i]));
}
break;
/* Stage: 3 */
case EAR_LC_POST_PER_CAL:
if (pEarHead->pRH[i].stage == EAR_STAGE_POST_PER_CAL) {
if (EarDebugLevel >= EAR_DEBUG_VERBOSE) {
printf("ar5212EarModify: Performing stage 3 ops on RH %d\n", i);
}
ar5212EarDoRH(devNum, &(pEarHead->pRH[i]));
}
break;
/* Stage: Any */
case EAR_LC_PLL:
if (IS_PLL_SET(pEarHead->pRH[i].disabler.disableField)) {
*modifier = pEarHead->pRH[i].disabler.pllValue;
if (EarDebugLevel >= EAR_DEBUG_VERBOSE) {
printf("ar5212EarModify: Modifying PLL value!!! to %d\n", *modifier);
}
return TRUE;
}
break;
/* Stage: Any */
case EAR_LC_RESET_OFFSET:
if ((pEarHead->pRH[i].disabler.valid) &&
!((pEarHead->pRH[i].disabler.disableField >> 8) & 0x1))
{
if (EarDebugLevel >= EAR_DEBUG_VERBOSE) {
printf("ar5212EarModify: Disabling reset code Offset cal\n");
}
return TRUE;
}
break;
/* Stage: Any */
case EAR_LC_RESET_NF:
if ((pEarHead->pRH[i].disabler.valid) &&
!((pEarHead->pRH[i].disabler.disableField >> 9) & 0x1))
{
if (EarDebugLevel >= EAR_DEBUG_VERBOSE) {
printf("ar5212EarModify: Disabling reset code Noise Floor cal\n");
}
return TRUE;
}
break;
/* Stage: Any */
case EAR_LC_RESET_IQ:
if ((pEarHead->pRH[i].disabler.valid) &&
!((pEarHead->pRH[i].disabler.disableField >> 10) & 0x1))
{
if (EarDebugLevel >= EAR_DEBUG_VERBOSE) {
printf("ar5212EarModify: Disabling reset code IQ cal\n");
}
return TRUE;
}
break;
/* Stage: Any */
case EAR_LC_PER_FIXED_GAIN:
if ((pEarHead->pRH[i].disabler.valid) &&
!((pEarHead->pRH[i].disabler.disableField >> 11) & 0x1))
{
if (EarDebugLevel >= EAR_DEBUG_VERBOSE) {
printf("ar5212EarModify: Disabling periodic fixed gain calibration\n");
}
return TRUE;
}
break;
/* Stage: Any */
case EAR_LC_PER_NF:
if ((pEarHead->pRH[i].disabler.valid) &&
!((pEarHead->pRH[i].disabler.disableField >> 12) & 0x1))
{
if (EarDebugLevel >= EAR_DEBUG_VERBOSE) {
printf("ar5212EarModify: Disabling periodic noise floor cal\n");
}
return TRUE;
}
break;
/* Stage: Any */
case EAR_LC_PER_GAIN_CIRC:
if ((pEarHead->pRH[i].disabler.valid) &&
!((pEarHead->pRH[i].disabler.disableField >> 13) & 0x1))
{
if (EarDebugLevel >= EAR_DEBUG_VERBOSE) {
printf("ar5212EarModify: Disabling gain circulation\n");
}
return TRUE;
}
break;
}
}
}
/* TODO: Track modified analog registers outside of stage 0 and write them with protection */
return FALSE;
}
/******************** EAR Support Routines ********************/
/**************************************************************
* ar5212EarDoRH
*
* The given register header needs to be executed by performing
* a register write, modify, or analog bank modify
*
* If an ananlog bank is modified - return the bank number as a
* bit mask. (bit 0 is bank 0)
*/
static A_UINT16
ar5212EarDoRH(A_UINT32 devNum, REGISTER_HEADER *pRH)
{
A_UINT16 tag, regLoc = 0, num, opCode;
A_UINT16 bitsThisWrite, numBits, startBit, bank, column, last, i;
A_UINT32 address, reg32, mask, regInit;
RF_REG_INFO *pRfRegs;
A_UINT16 rfBankMask = 0;
switch (pRH->type) {
case EAR_TYPE0:
do {
address = pRH->regs[regLoc] & ~T0_TAG_M;
tag = (A_UINT16)(pRH->regs[regLoc] & T0_TAG_M);
regLoc++;
if ((tag == T0_TAG_32BIT) || (tag == T0_TAG_32BIT_LAST)) {
/* Full word writes */
reg32 = pRH->regs[regLoc++] << 16;
reg32 |= pRH->regs[regLoc++];
if (EarDebugLevel >= EAR_DEBUG_VERBOSE) {
printf("ar5212EarDoRH: Type 0 EAR 32-bit write to 0x%04X : 0x%08x\n", address, reg32);
}
REGW(devNum, address, reg32);
} else if (tag == T0_TAG_16BIT_LOW) {
/* Half word read/modify/write low data */
if (EarDebugLevel >= EAR_DEBUG_VERBOSE) {
printf("ar5212EarDoRH: Type 0 EAR 16-bit low write to 0x%04X : 0x%04x\n",
address, pRH->regs[regLoc]);
}
REG_RMW(devNum, address, 0xFFFF, pRH->regs[regLoc++]);
} else {
/* Half word read/modify/write high data */
if (EarDebugLevel >= EAR_DEBUG_VERBOSE) {
printf("ar5212EarDoRH: Type 0 EAR 16-bit high write to 0x%04X : 0x%04x\n",
address, pRH->regs[regLoc]);
}
REG_RMW(devNum, address, 0xFFFF0000, pRH->regs[regLoc++] << 16);
}
} while (tag != T0_TAG_32BIT_LAST);
break;
case EAR_TYPE1:
address = pRH->regs[regLoc] & ~T1_NUM_M;
num = (A_UINT16)(pRH->regs[regLoc] & T1_NUM_M);
regLoc++;
for (i = 0; i < num + 1; i++) {
/* Sequential Full word writes */
reg32 = pRH->regs[regLoc++] << 16;
reg32 |= pRH->regs[regLoc++];
if (EarDebugLevel >= EAR_DEBUG_VERBOSE) {
printf("ar5212EarDoRH: Type 1 EAR 32-bit write to 0x%04X : 0x%08x\n", address, reg32);
}
REGW(devNum, address, reg32);
address += sizeof(A_UINT32);
}
break;
case EAR_TYPE2:
do {
last = (A_UINT16)(IS_TYPE2_LAST(pRH->regs[regLoc]));
bank = (A_UINT16)((pRH->regs[regLoc] & T2_BANK_M) >> T2_BANK_S);
/* Record which bank is written */
rfBankMask |= 1 << bank;
column = (A_UINT16)((pRH->regs[regLoc] & T2_COL_M) >> T2_COL_S);
startBit = (A_UINT16)(pRH->regs[regLoc] & T2_START_M);
pRfRegs = ar5212GetRfBank(devNum, bank);
if (IS_TYPE2_EXTENDED(pRH->regs[regLoc++])) {
num = (A_UINT16)(A_DIV_UP(pRH->regs[regLoc], 16));
numBits = pRH->regs[regLoc];
regLoc++;
for (i = 0; i < num; i++) {
/* Modify the bank 16 bits at a time */
bitsThisWrite = (numBits > 16) ? (A_UINT16)16 : numBits;
numBits = (A_UINT16)(numBits - bitsThisWrite);
reg32 = pRH->regs[regLoc++];
if (EarDebugLevel >= EAR_DEBUG_VERBOSE) {
printf("ar5212EarDoRH: Type 2 EAR E analog modify bank %d, startBit %d, column %d numBits %d data %d\n",
bank, startBit, column, bitsThisWrite, reg32);
}
ar5212ModifyRfBuffer(pRfRegs, reg32, bitsThisWrite, startBit, column);
startBit = (A_UINT16)(startBit + bitsThisWrite);
}
} else {
numBits = (A_UINT16)((pRH->regs[regLoc] & T2_NUMB_M) >> T2_NUMB_S);
reg32 = pRH->regs[regLoc++] & T2_DATA_M;
if (EarDebugLevel >= EAR_DEBUG_VERBOSE) {
printf("ar5212EarDoRH: Type 2 EAR analog modify bank %d, startBit %d, column %d numBits %d data %d\n",
bank, startBit, column, numBits, reg32);
}
ar5212ModifyRfBuffer(pRfRegs, reg32, numBits, startBit, column);
}
} while (!last);
break;
case EAR_TYPE3:
do {
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -