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

📄 artear.c

📁 atheros ar5001 5002 driver
💻 C
📖 第 1 页 / 共 3 页
字号:
/* 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_V45/sw/src/dk/mdk/devlib/artEar.c#3 $, $Header: //depot/sw/branches/ART_V45/sw/src/dk/mdk/devlib/artEar.c#3 $"


#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) {
		return FALSE;
	}

	/* Check for EAR */
    if (!pEarHead) {
        return FALSE;
    }

    /* Check for EAR found some reg headers */
    if (pEarHead->numRHs == 0) {
        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))
        {
            return TRUE;
        }
    }

    devNum = 0;   //quiet warnings
	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 {
            opCode = (A_UINT16)((pRH->regs[regLoc] & T3_OPCODE_M) >> T3_OPCODE_S);
            last = (A_UINT16)(IS_TYPE3_LAST(pRH->regs[regLoc]));

⌨️ 快捷键说明

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