⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 artear.c

📁 atheros ar5001 5002 driver
💻 C
📖 第 1 页 / 共 3 页
字号:
        if (EarDebugLevel >= EAR_DEBUG_EXTREME) {
             printf("ar5212EarAllocate: reg data %2d memory location 0x%08X\n", i, (A_UINT32)currentAlloc);
        }
        pRH = &((*ppEarHead)->pRH[i]);
        pRH->regs = currentAlloc;
        currentAlloc += earAlloc->locsPerRH[i];
    }
    return TRUE;
}

void
ar5212EarFree(EAR_HEADER *pEarHead) 
{
	if(pEarHead == NULL) {
		//already free
		return;
	}
	if(pEarHead->pRH) {
		free(pEarHead->pRH);
		pEarHead->pRH = NULL;
	}

	free(pEarHead);
	pEarHead = NULL;
	return;
}

/**************************************************************************
 * ar5212EarCheckAndFill
 *
 * Save away EAR contents
 */
static A_BOOL
ar5212EarCheckAndFill(EAR_HEADER *earHead, A_UINT32 *in, int totalLocs, EAR_ALLOC *pEarAlloc)
{
    int             curEarLoc = 0, currentRH = 0, regLoc, i;
    A_UINT16        regHead, tag, last, currentVerMask, addr, num, numBits, startBit;
    REGISTER_HEADER *pRH, tempRH;
    A_UINT16        tempRHregs[EAR_MAX_RH_REGS], *pReg16;
    A_BOOL          verMaskUsed, verMaskMatch;

    /* Setup the temporary register header */

    /* Save the version Id */
    earHead->versionId = (A_UINT16)in[curEarLoc++];

    /* Save the first version mask */
    verMaskUsed = 0;
    verMaskMatch = IS_EAR_VMATCH(earHead->versionId, in[curEarLoc]);
    currentVerMask = (A_UINT16)in[curEarLoc++];
    if (!IS_VER_MASK(currentVerMask)) {
        printf("ar5212EarCheckAndFill: ERROR: First entry after Version ID is not a Version Mask\n");
        return FALSE;
    }

    while (curEarLoc < totalLocs) {
        /* Parse Version/Header/End */
        if (IS_VER_MASK(in[curEarLoc])) {
            if (!verMaskUsed) {
                printf("ar5212EarCheckAndFill: ERROR: Multiple version masks setup with no register headers location %d\n",
                         curEarLoc);
                return FALSE;
            }
            verMaskUsed = 0;
            verMaskMatch = IS_EAR_VMATCH(earHead->versionId, in[curEarLoc]);
            currentVerMask = (A_UINT16)in[curEarLoc++];
        } else if (IS_END_HEADER(in[curEarLoc])) {
            printf("ar5212EarCheckAndFill: ERROR: Somehow we've hit the END location but parse shouldn't let us get here. loc %d\n",
                     curEarLoc);
            return FALSE;
        } else {
            if (currentRH > earHead->numRHs) {
                printf("ar5212EarCheckAndFill: ERROR: Exceeded number of register headers found in preParse. loc %d\n",
                         curEarLoc);
                return FALSE;
            }
            memset(&tempRH, 0, sizeof(REGISTER_HEADER));
            memset(&tempRHregs, 0, sizeof(A_UINT16) * EAR_MAX_RH_REGS);
            tempRH.regs = tempRHregs;
            pRH = &tempRH;

            /* Must be a register header - save last version mask */
            pRH->versionMask = currentVerMask;
            regHead = (A_UINT16)in[curEarLoc++];
            pRH->modes = (A_UINT16)(regHead & RH_MODES_M);
            if ((pRH->modes != RH_ALL_MODES) && (pRH->modes & RH_RESERVED_MODES)) {
                printf("ar5212EarCheckAndFill: WARNING: Detected that reserved modes have been set. loc %d\n", curEarLoc);
            }
            pRH->type = (A_UINT16)((regHead & RH_TYPE_M) >> RH_TYPE_S);
            pRH->stage = (A_UINT16)((regHead & RH_STAGE_M) >> RH_STAGE_S);
            if (IS_CM_SET(regHead)) {
                pRH->channel = (A_UINT16)in[curEarLoc++];
                if (IS_CM_SINGLE(pRH->channel) && !IS_5GHZ_CHAN(pRH->channel) &&
                    !IS_2GHZ_CHAN(pRH->channel))
                {
                    printf("ar5212EarCheckAndFill: WARNING: Specified single channel %d is not within tunable range. loc %d\n",
                             pRH->channel & CM_SINGLE_CHAN_M, curEarLoc);
                }
            }

            if (IS_DISABLER_SET(regHead)) {
                pRH->disabler.valid = TRUE;
                pRH->disabler.disableField = (A_UINT16)in[curEarLoc++];
                if (IS_PLL_SET(pRH->disabler.disableField)) {
                    pRH->disabler.pllValue = (A_UINT16)in[curEarLoc++];
                    if (pRH->disabler.pllValue & RH_RESERVED_PLL_BITS) {
                        printf("ar5212EarCheckAndFill: WARNING: Detected that reserved pll bits have been set. loc %d\n", curEarLoc);
                    }
                }
            }

            /* Now into the actual register writes */
            regLoc = 0;
            switch (pRH->type) {
            case EAR_TYPE0:
                do {
                    pRH->regs[regLoc] = (A_UINT16)in[curEarLoc++];
                    tag = (A_UINT16)(pRH->regs[regLoc] & T0_TAG_M);
                    if (!IS_VALID_ADDR(pRH->regs[regLoc] & ~T0_TAG_M)) {
                        printf("ar5212EarCheckAndFill: WARNING: Detected invalid register address 0x%04X at loc %d\n",
                                 pRH->regs[regLoc] & ~T0_TAG_M, curEarLoc);
                    }
                    regLoc++;
                    if ((tag == T0_TAG_32BIT) || (tag == T0_TAG_32BIT_LAST)) {
                        /* Full word writes */
                        pRH->regs[regLoc++] = (A_UINT16)in[curEarLoc++];
                        pRH->regs[regLoc++] = (A_UINT16)in[curEarLoc++];
                    } else {
                        /* Half word writes */
                        pRH->regs[regLoc++] = (A_UINT16)in[curEarLoc++];
                    }
                } while ((tag != T0_TAG_32BIT_LAST) && (curEarLoc < totalLocs));
                break;
            case EAR_TYPE1:
                pRH->regs[regLoc] = (A_UINT16)in[curEarLoc++];
                addr = (A_UINT16)(pRH->regs[regLoc] & ~T1_NUM_M);
                num = (A_UINT16)(pRH->regs[regLoc] & T1_NUM_M);
                regLoc++;
                for (i = 0; i < num + 1; i++) {
                    /* Full word writes */
                    if (!IS_VALID_ADDR(addr + (sizeof(A_UINT32) * i))) {
                        printf("ar5212EarCheckAndFill: WARNING: Detected invalid register address 0x%04X at loc %d\n",
                                 addr + (sizeof(A_UINT32) * i), curEarLoc);
                    }
                    pRH->regs[regLoc++] = (A_UINT16)in[curEarLoc++];
                    pRH->regs[regLoc++] = (A_UINT16)in[curEarLoc++];
                }
                break;
            case EAR_TYPE2:
                do {
                    pRH->regs[regLoc] = (A_UINT16)in[curEarLoc++];
                    last = (A_UINT16)(IS_TYPE2_LAST(pRH->regs[regLoc]));
                    if (((pRH->regs[regLoc] & T2_BANK_M) >> T2_BANK_S) == 0) {
                        printf("ar5212EarCheckAndFill: WARNING: Bank 0 update found in Type2 write at loc %d\n", curEarLoc);
                    }
                    startBit = (A_UINT16)(pRH->regs[regLoc] & T2_START_M);
                    if (IS_TYPE2_EXTENDED(pRH->regs[regLoc])) {
                        regLoc++;
                        pRH->regs[regLoc] = (A_UINT16)in[curEarLoc++];
                        if (pRH->regs[regLoc] < 12) {
                            printf("ar5212EarCheckAndFill: WARNING: Type2 Extended Write used when number of bits is under 12 at loc %d\n",
                                     curEarLoc);
                        }
                        num = (A_UINT16)(A_DIV_UP(pRH->regs[regLoc], 16));
                        numBits = pRH->regs[regLoc];
                        if (startBit + numBits > MAX_ANALOG_START) {
                            printf("ar5212EarCheckAndFill: ERROR: Type2 write will exceed analog buffer limits (at loc %d)\n", curEarLoc);
                            return FALSE;
                        }
                        regLoc++;
                        for (i = 0; i < num; i++) {
                            /* Add check data exceeds num bits check? */
                            pRH->regs[regLoc++] = (A_UINT16)in[curEarLoc++];
                        }
                        if (~((1 << (numBits % 16)) - 1) & in[curEarLoc - 1]) {
                            printf("ar5212EarCheckAndFill: WARNING: Type2 extended Write data exceeds number of bits specified at loc %d\n",
                                     curEarLoc);
                        }
                    } else {
                        regLoc++;
                        pRH->regs[regLoc] = (A_UINT16)in[curEarLoc++];
                        numBits = (A_UINT16)((pRH->regs[regLoc] & T2_NUMB_M) >> T2_NUMB_S);
                        if (startBit + numBits > MAX_ANALOG_START) {
                            printf("ar5212EarCheckAndFill: ERROR: Type2 write will exceed analog buffer limits (at loc %d)\n", curEarLoc);
                            return FALSE;
                        }
                        if (~((1 << numBits) - 1) &
                            (pRH->regs[regLoc] & T2_DATA_M))
                        {
                            printf("ar5212EarCheckAndFill: WARNING: Type2 Write data exceeds number of bits specified at loc %d\n",
                                     curEarLoc);
                        }
                        regLoc++;
                    }
                } while (!last && (curEarLoc < totalLocs));
                break;
            case EAR_TYPE3:
                do {
                    pRH->regs[regLoc] = (A_UINT16)in[curEarLoc++];
                    last = (A_UINT16)(IS_TYPE3_LAST(pRH->regs[regLoc]));
                    num = (A_UINT16)(A_DIV_UP((pRH->regs[regLoc] & T3_NUMB_M), 16));
                    if (((pRH->regs[regLoc] & T3_START_M) >> T3_START_S) +
                        (pRH->regs[regLoc] & T3_NUMB_M) > 31)
                    {
                        printf("ar5212EarCheckAndFill: WARNING: Type4 StartBit plus Number of Bits > 31 at loc %d\n",
                                 curEarLoc);
                    }
                    if (((pRH->regs[regLoc] & T3_OPCODE_M) >> T3_OPCODE_S) > T3_MAX_OPCODE) {
                        printf("ar5212EarCheckAndFill: WARNING: Type4 OpCode exceeds largest selectable opcode at loc %d\n",
                                 curEarLoc);
                    }
                    if (pRH->regs[regLoc] & T3_RESERVED_BITS) {
                        printf("ar5212EarCheckAndFill: WARNING: Type4 Reserved bits used at loc %d\n",
                                 curEarLoc);
                    }
                    numBits = (A_UINT16)(pRH->regs[regLoc] & T3_NUMB_M);
                    regLoc++;
                    /* Grab Address */
                    pRH->regs[regLoc] = (A_UINT16)in[curEarLoc++];
                    if (!IS_VALID_ADDR(pRH->regs[regLoc])) {
                        printf("ar5212EarCheckAndFill: WARNING: Detected invalid register address 0x%04X at loc %d\n",
                                 pRH->regs[regLoc], curEarLoc);
                    }
                    regLoc++;
                    for (i = 0; i < num; i++) {
                        pRH->regs[regLoc++] = (A_UINT16)in[curEarLoc++];
                    }
                    if (~((1 << (numBits % 16)) - 1) & in[curEarLoc - 1])
                    {
//                        printf("ar5212EarCheckAndFill: WARNING: Type3 write data exceeds number of bits specified at loc %d\n",
//                                 curEarLoc);
                    }
                } while (!last && (curEarLoc < totalLocs));
                break;
            }
            verMaskUsed = 1;
            /* Save any register headers that match the version mask*/
            if (verMaskMatch) {
                if (regLoc != pEarAlloc->locsPerRH[currentRH]) {
                    printf("ar5212EarCheckAndFill: Ear Allocation did not match Ear Usage\n");
                    return FALSE;
                }
                /*
                 * Copy stack register header to real register header on match
                 * BCOPY the regs, save away the reg16 ptr as the struct copy will overwrite it
                 * finally restore the reg16 ptr.
                 */
                memcpy(earHead->pRH[currentRH].regs, pRH->regs, regLoc * sizeof(A_UINT16));
                pReg16 = earHead->pRH[currentRH].regs;
                earHead->pRH[currentRH] = *pRH;
                earHead->pRH[currentRH].regs = pReg16;

                currentRH++;
            }
        } /* End Register Header Parse */
    } /* End Location Reading */
    return TRUE;
}

static void
showEarAlloc(EAR_ALLOC *earAlloc)
{
    int i;

    printf("Found %d register headers\n", earAlloc->numRHs);
    for (i = 0; i < earAlloc->numRHs; i++) {
        printf("Register Header %3d requires %2d 16-bit locations\n", i + 1,
                 earAlloc->locsPerRH[i]);
    }
}


A_BOOL
readEar
(
 A_UINT32 devNum,
 A_UINT32 earStartLocation
)
{
    EAR_ALLOC earAlloc;
    int       earLocs = 0, parsedLocs;
    A_UINT32  *earBuffer = NULL;
	LIB_DEV_INFO *pLibDev = gLibInfo.pLibDevArray[devNum];

    if(!pLibDev->libCfgParams.loadEar) {
//		printf("Information: Called readEar and loadEar was not set, returning\n");
		return TRUE;
	}

    if (earStartLocation) {
        if((earStartLocation < ATHEROS_EEPROM_OFFSET) ||
			(earStartLocation > ATHEROS_EEPROM_END)) {
			mError(devNum, EINVAL, "Illegal EAR start location\n");
			return FALSE;
		}
        
		//allocation a block of memory to take the eeprom locations

        earLocs = ATHEROS_EEPROM_END - earStartLocation;
		earBuffer = (A_UINT32 *)malloc(sizeof(A_UINT32) * earLocs);
		if(earBuffer == NULL) {
			mError(devNum, ENOMEM, "readEar: Unable to allocate memory for earBuffer\n");
			return FALSE;
		}
		eepromReadBlock(devNum, earStartLocation, earLocs, earBuffer);
    }

    if (earBuffer) {
		memset(&earAlloc, 0, sizeof(EAR_ALLOC));
        parsedLocs = ar5212EarPreParse(earBuffer, earLocs, &earAlloc);

//#ifdef DEBUG
        if (EarDebugLevel >= EAR_DEBUG_VERBOSE) {
            showEarAlloc(&earAlloc);
        }
//#endif

        /* Do not allocate EAR if no registers exist */
        if (earAlloc.numRHs) {
			if(pLibDev->pEarHead) {
				//free up previous allocation first
				ar5212EarFree(pLibDev->pEarHead);
			}
            if (ar5212EarAllocate(&earAlloc, &(pLibDev->pEarHead)) == FALSE) {
                printf("ar5212Attach: Could not allocate memory for EAR structures\n");
                return FALSE;
            }

            if(!ar5212EarCheckAndFill(pLibDev->pEarHead, earBuffer, parsedLocs, &earAlloc)) {
                /* Ear is bad */
                printf("ar5212Attach: An unrecoverable EAR error was detected\n");
                return FALSE;
            }
#ifdef DEBUG
//            if (EarDebugLevel >= EAR_DEBUG_BASIC) {
//                printEar(pDev->pHalInfo->pEarHead, &earAlloc);
//            }
#endif
        }
    }
	free(earBuffer);
	return TRUE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -