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

📄 athreg.c

📁 atheros ar5001 5002 driver
💻 C
📖 第 1 页 / 共 5 页
字号:

    //now do the radio registers.
    pLibDev->pRfPciValues = &pLibDev->pciValuesArray[currentRegister];
    pLibDev->rfRegArrayIndex = currentField;
	if(!ParseRfRegs(devNum, &pLibDev->regArray[currentField], 
		currentField, pLibDev->sizeRegArray, &pLibDev->pciValuesArray[currentRegister], pLibDev->rfBankInfo)) {
		mError(devNum, EIO, "Device Number %d:Unable to parseRfFields\n", devNum);
        free(pLibDev->pciValuesArray);
//		free(pLibDev->resetFieldValuesArray);
		return 0;
	}
//    numRfPciWrites = createRfPciValues(&pLibDev->regArray[currentField], 
//                currentField, pLibDev->sizeRegArray, &pLibDev->pciValuesArray[currentRegister]);

	numRfPciWrites = new_createRfPciValues(devNum, ALL_BANKS, 0);
    if(numRfPciWrites == 0) {
        mError(devNum, EIO, "Device Number %d:Error creating pci values for rf registers\n", devNum);
        free(pLibDev->pciValuesArray);
//		free(pLibDev->resetFieldValuesArray);
        return 0;
    }

    pLibDev->sizePciValuesArray = (A_UINT16)(numRfPciWrites + currentRegister);
    return 1;
}

A_UINT16
ParseRfRegs
(
 A_UINT32          devNum,
 ATHEROS_REG_FILE *pRfFields,
 A_UINT32         indexRfField,
 A_UINT32         sizeRegArray,
 PCI_REG_VALUES *pRfWriteValues,
 RF_REG_INFO	*pRfRegBanks
)
{
    A_UINT32 currentRegBank;
	A_UINT16 sizeRfReg;

	//loop round all remaining register fields
    while (indexRfField < sizeRegArray) {
        if((pRfFields->regOffset + 1) > NUM_RF_BANKS) {
			mError(devNum, EIO, "Num rf register banks exceeds number hard coded in software\n");
			return 0;
		}
        
        currentRegBank = pRfFields->regOffset;
		pRfRegBanks[currentRegBank].bankNum = currentRegBank;
		pRfRegBanks[currentRegBank].pRegFields = pRfFields;
		pRfRegBanks[currentRegBank].pPciValues = pRfWriteValues;
        pRfRegBanks[currentRegBank].numRegFields = 0;
		sizeRfReg = 0;
		//loop round all the fields of this register bank
		while (pRfFields->regOffset == currentRegBank) {
			//see if the end of the register is larger than current calculation of reg size
			if((A_UINT32)(pRfFields->fieldStartBitPos - 1 + pRfFields->fieldSize) > sizeRfReg) {
				sizeRfReg = (A_UINT16)(pRfFields->fieldSize + sizeRfReg);
			}
			pRfRegBanks[currentRegBank].numRegFields++;
			pRfFields++;
			indexRfField++;
		}
		//calculate number pci registers
		pRfRegBanks[currentRegBank].numPciRegs = (A_UINT16)(sizeRfReg/8); 
		if(sizeRfReg > pRfRegBanks[currentRegBank].numPciRegs * 8) {
			pRfRegBanks[currentRegBank].numPciRegs++;
		}
		pRfWriteValues += pRfRegBanks[currentRegBank].numPciRegs;
	}

	return 1;
} 

A_UINT16
createRfBankPciValues
(
 A_UINT32       devNum,
 RF_REG_INFO	*pRfRegBank
)
{
	ATHEROS_REG_FILE *pRfFields;
    PCI_REG_VALUES *pRfWriteValues;
	A_UCHAR         currentRfReg;
    A_UINT16        numRegBits;
    A_UCHAR         baseByteValue;
    A_UINT32        tempBaseValue = 0;
    A_UCHAR         turboByteValue;
    A_UINT32        tempTurboValue = 0;
    A_UCHAR         load;
    A_UCHAR         i, j;
	A_UINT32		x = 0;
    A_UINT32        pciAddress;
    A_BOOL          fieldLeftOver = 0;
    A_UCHAR         tempValueSize = 0;
    A_UCHAR         mask;

	pRfFields = pRfRegBank->pRegFields;
	if(pRfFields == NULL) {
		return 1;
	}
	pRfWriteValues = pRfRegBank->pPciValues;
	while( x < pRfRegBank->numRegFields ) {
		//loop round all the fields for this register
        currentRfReg = pRfFields->rfRegNumber;
        numRegBits = 0;
        while ((pRfFields->rfRegNumber == currentRfReg) &&
				( x < pRfRegBank->numRegFields )) {
            baseByteValue = 0;
            turboByteValue = 0;
            load = 0;
            //create 8 bit values to be written on Pci bus
            for(i = 0; i < 8; ) {
                //check for any fields left over from last time
                if (fieldLeftOver) {
                    //write the rest of the bit field 
                    if (tempValueSize > 8) {
                        baseByteValue = (A_UCHAR)(tempBaseValue & 0xff);
                        turboByteValue = (A_UCHAR)(tempTurboValue & 0xff);
                        tempBaseValue = tempBaseValue >> 8;
                        tempTurboValue = tempTurboValue >> 8;
                        i += 8;
                    }
                    else { 
                        baseByteValue |= tempBaseValue;
                        turboByteValue |= tempTurboValue;
                        i = (A_UCHAR)(i + tempValueSize);

                        fieldLeftOver = 0;
                        pRfFields++; 
						x++;
//                        indexRfField++;
                    }
                }
                else if((pRfFields->fieldStartBitPos - 1) > (i+numRegBits)) {
                    //Dont have anything to write, write 0
                    i++;
                }
                else {
                    if (i + pRfFields->fieldSize > 8) {
                        //note code is not setup to handle a field size > 32
                        if (pRfFields->fieldSize > 32) {
                            mError(devNum, EINVAL, "Rf field size is greater than 32, not currently supported by software\n");
                            return(0);
                        }
                        
                        //create a mask for the number of bits that will fit
                        mask = 0;
                        for (j = 0; j < (8 - i); j++) {
                            mask |= (0x1 << j);
                        }
                        tempBaseValue = reverseRfBits(pRfFields->fieldBaseValue, pRfFields->fieldSize, pRfFields->dontReverse);
                        tempTurboValue = reverseRfBits(pRfFields->fieldTurboValue, pRfFields->fieldSize, pRfFields->dontReverse);
                        baseByteValue |= (tempBaseValue & mask) << i;
                        turboByteValue |= (tempTurboValue & mask) << i;
                        fieldLeftOver = 1;
                        tempBaseValue = tempBaseValue >> (8 - i);
                        tempTurboValue = tempTurboValue >> (8 - i);
                        tempValueSize = (A_UCHAR)(pRfFields->fieldSize - (8 - i));
                        i = (A_UCHAR)(i + (8 - i));
                    }
                    else {

                        baseByteValue |= (reverseRfBits(pRfFields->fieldBaseValue, pRfFields->fieldSize, pRfFields->dontReverse) << i);
                        turboByteValue |= (reverseRfBits(pRfFields->fieldTurboValue, pRfFields->fieldSize, pRfFields->dontReverse) << i);

                        //check for the field going over 8 bits
                        i = (A_UCHAR)(i + pRfFields->fieldSize);
                        pRfFields++;
						x++;
//                        indexRfField++;
                    }
                }

                if( (pRfFields->rfRegNumber != currentRfReg) ||
                    (pRfFields->regOffset != pRfRegBank->bankNum)) {
                    load = 0x10;
                    break;
                }
            }

            numRegBits = (A_UINT16)(numRegBits + i);
            //should now have an 8 bit value to write
            //calculate the pci address to write to 
            pciAddress = (((i - 1) + load + 0x20 + 0x600)  << 2) + 0x8000;

            if(currentRfReg == 0) {
                //first register of bank so write address to pci array
                pRfWriteValues->offset = pciAddress;
                pRfWriteValues->baseValue = 0;
                pRfWriteValues->turboValue = 0;
                //pRfRegBank->numPciRegs++;
            }
            else {
                //we should be at the correct address, do a check
                if (pciAddress != pRfWriteValues->offset) {
                    mError(devNum, EIO, "createRfBankPciValues: unexpected internal software problem, bank %d, field %s\n", pRfRegBank->bankNum, pRfFields->fieldName);
                    return(0);
                }
            }

            //write the byte value into array
            pRfWriteValues->baseValue |= (baseByteValue << (currentRfReg * 8));
            pRfWriteValues->turboValue |= (turboByteValue << (currentRfReg * 8));
            pRfWriteValues++;
        } //end while same register

        //moved onto a new rf register,  move
        //pRfWriteValues back to the start of the writes for this bank
		pRfWriteValues = pRfRegBank->pPciValues;
	}
	return 1;
}

A_UINT16
new_createRfPciValues
(
 A_UINT32     devNum,
 A_UINT32	  bank,
 A_BOOL		  writePCI
)
{
	LIB_DEV_INFO *pLibDev = gLibInfo.pLibDevArray[devNum];
	A_UINT32 numPciWrites = 0;
	A_UINT32 bankIndex = 0;
	A_BOOL earHere = FALSE;
	A_UINT32 modifier;
	
	//mask off any bits set in error
	bank = bank & 0xff;
	while (bank) {
		if(bank & 0x01) {
			if(!createRfBankPciValues(devNum, &pLibDev->rfBankInfo[bankIndex])) {
				mError(devNum, EIO, "Device Number %d:new_createRfPciValues: unable to create writes for bank %d\n", devNum, bank);
				return 0;
			}
			if (pLibDev->eePromLoad && pLibDev->eepData.eepromChecked && writePCI) {
				if(pLibDev->p16kEepHeader->majorVersion >= 4) {
					earHere = ar5212IsEarEngaged(devNum, pLibDev->pEarHead, pLibDev->freqForResetDevice);
				}
				if (earHere) {
					ar5212EarModify(devNum, pLibDev->pEarHead, EAR_LC_RF_WRITE, pLibDev->freqForResetDevice, &modifier);
				}

			}
			numPciWrites += pLibDev->rfBankInfo[bankIndex].numPciRegs;
			if(writePCI) {
				writeRfBank(devNum, &pLibDev->rfBankInfo[bankIndex]);			
			}
		}
		bankIndex++;
		bank = bank >> 1;
	}
	
	return (A_UINT16)numPciWrites;
}

void
writeRfBank
(
 A_UINT32		devNum,
 RF_REG_INFO	*pRfRegBank
)
{
	LIB_DEV_INFO *pLibDev = gLibInfo.pLibDevArray[devNum];
    PCI_REG_VALUES *pRfWriteValues = pRfRegBank->pPciValues;
	A_UINT32		i;
	A_UINT32		regValue;
	A_UINT32		cfgVersion;

    cfgVersion = ar5kInitData[pLibDev->ar5kInitIndex].cfgVersion;
	for(i = 0; i < pRfRegBank->numPciRegs; i++) {
		if((pLibDev->turbo == TURBO_ENABLE) && (cfgVersion == 0)) {
			regValue = pRfWriteValues->turboValue;
		}
		else {
			regValue = pRfWriteValues->baseValue;
		}
	 	REGW(devNum, pRfWriteValues->offset, regValue);
		pRfWriteValues++;
	}
	return;
}


/* get the value held by the software array (ie does not read hardware) */
MANLIB_API void getField
(
 A_UINT32 devNum,
 A_CHAR   *fieldName,
 A_UINT32 *baseValue,		//base value out
 A_UINT32 *turboValue		//turbo value out
)
{
	LIB_DEV_INFO *pLibDev = gLibInfo.pLibDevArray[devNum];
    ATHEROS_REG_FILE *fieldDetails;
    size_t		     tempSize;
	A_UINT32		 cfgVersion;
	
    cfgVersion = ar5kInitData[pLibDev->ar5kInitIndex].cfgVersion;
	if (checkDevNum(devNum) == FALSE) {
		mError(devNum, EINVAL, "Device Number %d:getField\n", devNum);
		return;
	}

    //check for the existance of the regArray before we start
    if(pLibDev->regArray == NULL) {
        mError(devNum, EIO, "Device Number %d:Software has no register file values, run resetDevice before getField \n", devNum);
        return;
    }
    
    //search for the field name within the register array
    tempSize = pLibDev->sizeRegArray;
    fieldDetails = (ATHEROS_REG_FILE *)_lfind(fieldName, pLibDev->regArray, &tempSize, 
                sizeof(ATHEROS_REG_FILE), compareFields);



    if(fieldDetails == NULL) {
        mError(devNum, EINVAL, "Device Number %d:%s fieldName not found\n", devNum, fieldName);
        return;
    }

	*baseValue = fieldDetails->fieldBaseValue;
	if(cfgVersion == 0) {
		*turboValue = fieldDetails->fieldTurboValue;
	}
	else {
		*turboValue = fieldDetails->fieldBaseValue;
	}

	return;
}


MANLIB_API void changeField
(
 A_UINT32 devNum,
 A_CHAR *fieldName, 
 A_UINT32 newValue
)
{
	LIB_DEV_INFO *pLibDev = gLibInfo.pLibDevArray[devNum];
    ATHEROS_REG_FILE *fieldDetails;
    size_t     tempSize;

	if (checkDevNum(devNum) == FALSE) {
		mError(devNum, EINVAL, "Device Number %d:changeField\n", devNum);
		return;
	}

    //check for the existance of the regArray before we start
    if(pLibDev->regArray == NULL) {
        mError(devNum, EIO, "Device Number %d:Software has no register file values, run resetDevice before changeField \n", devNum);
        return;
    }
    
    //search for the field name within the register array
    tempSize = pLibDev->sizeRegArray;
    fieldDetails = (ATHEROS_REG_FILE *)_lfind(fieldName, pLibDev->regArray, &tempSize, 
                sizeof(ATHEROS_REG_FILE), compareFields);

    if(fieldDetails == NULL) {
        mError(devNum, EINVAL, "Device Number %d:%s fieldName not found\n", devNum, fieldName);
        return;
    }
    

	updateField(devNum, fieldDetails, newValue, 0);
	return;
}    
	
	

void updateField
(

⌨️ 快捷键说明

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