📄 artear.c
字号:
startBit = (A_UINT16)((pRH->regs[regLoc] & T3_START_M) >> T3_START_S);
numBits = (A_UINT16)(pRH->regs[regLoc] & T3_NUMB_M);
regLoc++;
/* Grab Address */
address = pRH->regs[regLoc++];
if (numBits > 16) {
reg32 = pRH->regs[regLoc++] << 16;
reg32 |= pRH->regs[regLoc++];
} else {
reg32 = pRH->regs[regLoc++];
}
mask = ((1 << numBits) - 1) << startBit;
regInit = REGR(devNum, address);
switch (opCode) {
case T3_OC_REPLACE:
reg32 = (regInit & ~mask) | ((reg32 << startBit) & mask);
break;
case T3_OC_ADD:
reg32 = (regInit & ~mask) |
(((regInit & mask) + (reg32 << startBit)) & mask);
break;
case T3_OC_SUB:
reg32 = (regInit & ~mask) |
(((regInit & mask) - (reg32 << startBit)) & mask);
break;
case T3_OC_MUL:
reg32 = (regInit & ~mask) |
(((regInit & mask) * (reg32 << startBit)) & mask);
break;
case T3_OC_XOR:
reg32 = (regInit & ~mask) |
(((regInit & mask) ^ (reg32 << startBit)) & mask);
break;
case T3_OC_OR:
reg32 = (regInit & ~mask) |
(((regInit & mask) | (reg32 << startBit)) & mask);
break;
case T3_OC_AND:
reg32 = (regInit & ~mask) |
(((regInit & mask) & (reg32 << startBit)) & mask);
break;
}
REGW(devNum, address, reg32);
if (EarDebugLevel >= EAR_DEBUG_VERBOSE) {
printf("ar5212EarDoRH: Type 3 EAR 32-bit rmw to 0x%04X : 0x%08x\n", address, reg32);
}
} while (!last);
break;
}
return rfBankMask;
}
/**************************************************************
* ar5212GetRfBank
*
* Get the UINT16 pointer to the start of the requested RF Bank
*/
static RF_REG_INFO *
ar5212GetRfBank(A_UINT32 devNum, A_UINT16 bank)
{
LIB_DEV_INFO *pLibDev = gLibInfo.pLibDevArray[devNum];
if((bank < 1) || (bank > 7)) {
mError(devNum, EINVAL, "ar5212GetRfBank: Illegal bank number = %d\n", bank);
return(NULL);
}
return(&(pLibDev->rfBankInfo[bank]));
}
/**************************************************************
* ar5212CFlagsToEarMode
*
* Convert from pLibDev info to the EAR bitmap format
*/
static A_UINT16
ar5212CFlagsToEarMode(A_UINT32 devNum)
{
LIB_DEV_INFO *pLibDev = gLibInfo.pLibDevArray[devNum];
if ((pLibDev->libCfgParams.enableXR) && (pLibDev->mode == MODE_11A) && (pLibDev->turbo == TURBO_ENABLE)) {
return EAR_5T | EAR_XR;
}
if ((pLibDev->libCfgParams.enableXR) && (pLibDev->mode == MODE_11G) && (pLibDev->turbo == TURBO_ENABLE)) {
return EAR_2T | EAR_XR;
}
if ((pLibDev->mode == MODE_11G) && (pLibDev->turbo == TURBO_ENABLE)) {
return EAR_2T;
}
if ((pLibDev->mode == MODE_11A) && (pLibDev->turbo == TURBO_ENABLE)) {
return EAR_5T;
}
if ((pLibDev->libCfgParams.enableXR) && (pLibDev->mode == MODE_11A) ) {
return EAR_11A | EAR_XR;
}
if ((pLibDev->libCfgParams.enableXR) && (pLibDev->mode == MODE_11G)) {
return EAR_11G | EAR_XR;
}
if (pLibDev->mode == MODE_11B) {
return EAR_11B;
}
if (pLibDev->mode == MODE_11G) {
return EAR_11G;
}
return EAR_11A;
}
/**************************************************************
* ar5212IsChannelInEarRegHead
*
* Check if EAR should be applied for current channel
*/
static A_BOOL
ar5212IsChannelInEarRegHead(A_UINT16 earChannel, A_UINT16 channelMhz)
{
int i;
const A_UINT16 earFlaggedChannels[14][2] = {
{2412, 2412}, {2417, 2437}, {2442, 2457}, {2462, 2467}, {2472, 2472}, {2484, 2484}, {2300, 2407},
{4900, 5160}, {5170, 5180}, {5190, 5250}, {5260, 5300}, {5310, 5320}, {5500, 5700}, {5725, 5825}
};
/* No channel specified - applies to all channels */
if (earChannel == 0) {
return TRUE;
}
/* Do we match the single channel check if its set? */
if (IS_CM_SINGLE(earChannel)) {
return (A_CHAR)(((earChannel & ~0x8000) == channelMhz) ? TRUE : FALSE);
}
/* Rest of the channel modifier bits can be set as one or more ranges - check them all */
if ((IS_CM_SPUR(earChannel)) && (IS_SPUR_CHAN(channelMhz))) {
return TRUE;
}
for (i = 0; i < 14; i++) {
if ((earChannel >> i) & 1) {
if ((earFlaggedChannels[0][i] <= channelMhz) && (earFlaggedChannels[1][i] >= channelMhz)) {
return TRUE;
}
}
}
return FALSE;
}
/**************************************************************
* ar5212ModifyRfBuffer
*
* Perform analog "swizzling" of parameters into their location
*/
static void
ar5212ModifyRfBuffer(RF_REG_INFO *pRfRegs, A_UINT32 reg32, A_UINT32 numBits,
A_UINT32 firstBit, A_UINT32 column)
{
A_UINT32 tmp32, mask, arrayEntry, lastBit;
A_INT32 bitPosition, bitsLeft;
// ASSERT(column <= 3);
// ASSERT(numBits <= 32);
// ASSERT(firstBit + numBits <= MAX_ANALOG_START);
tmp32 = reverseBits(reg32, numBits);
arrayEntry = (firstBit - 1) / 8;
bitPosition = (firstBit - 1) % 8;
bitsLeft = numBits;
while (bitsLeft > 0) {
lastBit = (bitPosition + bitsLeft > 8) ? (8) : (bitPosition + bitsLeft);
mask = (((1 << lastBit) - 1) ^ ((1 << bitPosition) - 1)) << (column * 8);
pRfRegs->pPciValues[arrayEntry].baseValue &= ~mask;
pRfRegs->pPciValues[arrayEntry].baseValue |= ((tmp32 << bitPosition) << (column * 8)) & mask;
bitsLeft -= (8 - bitPosition);
tmp32 = tmp32 >> (8 - bitPosition);
bitPosition = 0;
arrayEntry++;
}
}
/************ FORWARD SOFTWARE COMPATIBILITY EAR FUNCTIONS ************/
/**************************************************************************
* ar5212EarPreParse
*
* Parse the entire EAR saving away the size required for each EAR register header
* Allocation is only performed for matching version ID's.
*/
static int
ar5212EarPreParse(A_UINT32 *in, int numLocs, EAR_ALLOC *earAlloc)
{
A_UINT16 numFound = 0;
int curEarLoc = 0;
A_UINT16 numLocsConsumed;
A_UINT16 type, regHead, tag, last;
A_UINT32 verId;
A_BOOL verMaskMatch = FALSE;
/* Record the version Id */
verId = in[curEarLoc++];
while (curEarLoc < numLocs) {
/* Parse Version/Header/End */
if (IS_VER_MASK(in[curEarLoc])) {
verMaskMatch = IS_EAR_VMATCH(verId, in[curEarLoc]);
curEarLoc++;
} else if (IS_END_HEADER(in[curEarLoc])) {
break;
} else {
/* Must be a register header - find number of locations consumed */
regHead = (A_UINT16)(in[curEarLoc++]);
if (IS_CM_SET(regHead)) {
/* Bump location for channel modifier */
curEarLoc++;
}
if (IS_DISABLER_SET(regHead)) {
if (IS_PLL_SET(in[curEarLoc])) {
/* Bump location for PLL */
curEarLoc++;
}
/* Bump location for disabler */
curEarLoc++;
}
numLocsConsumed = 0;
/* Now into the actual register writes */
type = (A_UINT16)((regHead & RH_TYPE_M) >> RH_TYPE_S);
switch (type) {
case EAR_TYPE0:
do {
tag = (A_UINT16)(in[curEarLoc] & T0_TAG_M);
if ((tag == T0_TAG_32BIT) || (tag == T0_TAG_32BIT_LAST)) {
/* Full word writes */
numLocsConsumed += 3;
curEarLoc += 3;
} else {
/* Half word writes */
numLocsConsumed += 2;
curEarLoc += 2;
}
}
while ((tag != T0_TAG_32BIT_LAST) && (curEarLoc < numLocs));
break;
case EAR_TYPE1:
numLocsConsumed = (A_UINT16)(((in[curEarLoc] & T1_NUM_M) * sizeof(A_UINT16)) + 3);
curEarLoc += numLocsConsumed;
break;
case EAR_TYPE2:
do {
last = (A_UINT16)(IS_TYPE2_LAST(in[curEarLoc]));
if(IS_TYPE2_EXTENDED(in[curEarLoc])) {
numLocsConsumed = (A_UINT16)(numLocsConsumed + 2 + A_DIV_UP(in[curEarLoc+1], 16));
curEarLoc += 2 + A_DIV_UP(in[curEarLoc+1], 16);
} else {
numLocsConsumed += 2;
curEarLoc += 2;
}
} while (!last && (curEarLoc < numLocs));
break;
case EAR_TYPE3:
do {
last = (A_UINT16)(IS_TYPE3_LAST(in[curEarLoc]));
numLocsConsumed = (A_UINT16)(numLocsConsumed + 2 + A_DIV_UP(in[curEarLoc] & 0x1F, 16));
curEarLoc += 2 + A_DIV_UP(in[curEarLoc] & 0x1F, 16);
} while (!last && (curEarLoc < numLocs));
break;
}
/* Only record allocation information for matching versions */
if (verMaskMatch) {
if (numLocsConsumed > EAR_MAX_RH_REGS) {
printf("ar5212EarPreParse: A register header exceeds the max allowable size\n");
earAlloc->numRHs = 0;
return 0;
}
earAlloc->locsPerRH[numFound] = numLocsConsumed;
numFound++;
}
}
}
earAlloc->numRHs = numFound;
if (EarDebugLevel >= 1) {
printf("Number of locations parsed in preParse: %d\n", curEarLoc);
}
return curEarLoc;
}
/**************************************************************************
* ar5212EarAllocate
*
* Now that the Ear structure size is known, allocate the EAR header and
* the individual register headers
*/
static A_BOOL
ar5212EarAllocate(EAR_ALLOC *earAlloc, EAR_HEADER **ppEarHead)
{
int sizeForRHs;
int sizeForRegs = 0;
int i;
A_UINT16 *currentAlloc;
REGISTER_HEADER *pRH;
/* Return if no applicable EAR exists */
if (earAlloc->numRHs == 0) {
return TRUE;
}
/* Allocate the Ear Header */
*ppEarHead = (EAR_HEADER *)malloc(sizeof(EAR_HEADER));
if (*ppEarHead == NULL) {
printf("ar5212EarAllocate: Failed to retrieve space for EAR Header\n");
return FALSE;
}
memset(*ppEarHead, 0, sizeof(EAR_HEADER));
/* Save number of register headers */
(*ppEarHead)->numRHs = earAlloc->numRHs;
/* Size the malloc for the Ear Register Headers */
sizeForRHs = earAlloc->numRHs * sizeof(REGISTER_HEADER);
for (i = 0; i < earAlloc->numRHs; i++) {
sizeForRegs += earAlloc->locsPerRH[i] * sizeof(A_UINT16);
}
if (EarDebugLevel >= EAR_DEBUG_VERBOSE) {
printf("ar5212EarAllocate: Size for RH's %d, size for reg data %d\n", sizeForRHs, sizeForRegs);
}
/* Malloc and assign the space to the RH's */
(*ppEarHead)->pRH = (REGISTER_HEADER *) malloc(sizeForRegs + sizeForRHs);
if ((*ppEarHead)->pRH == NULL) {
printf("ar5212EarAllocate: Failed to retrieve space for EAR individual registers\n");
return 0;
}
memset((*ppEarHead)->pRH, 0, sizeForRegs + sizeForRHs);
(*ppEarHead)->earSize = sizeForRegs + sizeForRHs;
currentAlloc = (A_UINT16 *)(((A_UINT8 *)(*ppEarHead)->pRH) + sizeForRHs);
for (i = 0; i < earAlloc->numRHs; i++) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -