📄 athreg.c
字号:
if((tempValue < 0) || (tempValue > 9)) {
mError(pLibDev->devNum, EINVAL, "software controlled flag should be between 0 and 9 on line %d\n", currentLineNumber);
fileError = 1;
break;
}
fieldInfoIn.softwareControlled = (A_BOOL)tempValue;
break;
case EEPROM_VALUE:
if (cfgVersion == 0) {
if (!getUnsignedFromStr(pLibDev->devNum, token, 0, 0, &tempValue)) {
mError(pLibDev->devNum, EINVAL, "problem with exists in eeprom flag on line %d\n", currentLineNumber);
fileError = 1;
break;
}
if((tempValue != 0) && (tempValue != 1)) {
mError(pLibDev->devNum, EINVAL, "exists in eeprom flag should be 0 or 1 on line %d\n", currentLineNumber);
fileError = 1;
break;
}
fieldInfoIn.existsInEepromOrMode = (A_BOOL)tempValue;
break;
}
else {
//this column does not exist in the version 2 file, so increment i
//and fall through to next line, hence no break.
i++;
}
case PUBLIC_NAME:
if (!getUnsignedFromStr(pLibDev->devNum, token, 0, 0, &tempValue)) {
mError(pLibDev->devNum, EINVAL, "problem with public flag on line %d\n", currentLineNumber);
fileError = 1;
break;
}
if((tempValue != 0) && (tempValue != 1)) {
mError(pLibDev->devNum, EINVAL, "public flag should be 0 or 1 on line %d\n", currentLineNumber);
fileError = 1;
break;
}
fieldInfoIn.publicText = (A_BOOL)tempValue;
break;
}
//get the next token
if (!fileError && (i != PUBLIC_NAME)) {
token = strtok( NULL, delimiters );
if (NULL == token) {
//bad line give an error and get out
mError(pLibDev->devNum, EINVAL, "Incomplete line at line number %d\n", currentLineNumber);
fileError = 1;
}
}
}
if (modeSpecific) {
//parse mode specific section
for(i = FIELD_NAME; (i <= BASE_11G_VALUE) && !fileError; i++) {
switch(i) {
case FIELD_NAME:
//zero out the local structure at start of new field
memset(&modeFieldInfoIn, 0, sizeof(MODE_INFO));
if(strlen(token) > MAX_NAME_LENGTH) {
printf("field name on line is more than %d characters\n",
currentLineNumber, MAX_NAME_LENGTH);
fileError = 1;
break;
}
//look for this field in the main array to get its index and other info
//search for this field within default array
tempSize = pLibDev->sizeModeArray;
pModeFieldDetails = (MODE_INFO *)_lfind(token, pLibDev->pModeArray, &tempSize,
sizeof(MODE_INFO), compareFields);
if(pModeFieldDetails == NULL) {
printf("%s fieldName at line number %d, in mode specific section, not found in original mode section\n",
token, currentLineNumber);
fileError = 1;
break;
}
//get pointer to field details in main array
pFieldDetails = &(pLibDev->regArray[pModeFieldDetails->indexToMainArray]);
break;
case BASE_11A_VALUE:
if (!getUnsignedFromStr(pLibDev->devNum, token, pFieldDetails->valueSigned,
pFieldDetails->fieldSize, &modeFieldInfoIn.value11a))
{
printf("problem with base 11a value in mode specific section on line %d\n", currentLineNumber);
fileError = 1;
}
break;
case TURBO_11A_VALUE:
if (!getUnsignedFromStr(pLibDev->devNum, token, pFieldDetails->valueSigned,
pFieldDetails->fieldSize, &modeFieldInfoIn.value11aTurbo))
{
printf("problem with turbo 11a value in mode specific section on line %d\n", currentLineNumber);
fileError = 1;
}
break;
case BASE_11B_VALUE:
if (!getUnsignedFromStr(pLibDev->devNum, token, pFieldDetails->valueSigned,
pFieldDetails->fieldSize, &modeFieldInfoIn.value11b))
{
printf("problem with base 11b value in mode specific section on line %d\n", currentLineNumber);
fileError = 1;
}
break;
case BASE_11G_VALUE:
if (!getUnsignedFromStr(pLibDev->devNum, token, pFieldDetails->valueSigned,
pFieldDetails->fieldSize, &modeFieldInfoIn.value11g))
{
printf("problem with base 11g value in mode specific section on line %d\n", currentLineNumber);
fileError = 1;
}
break;
} //end switch
//get the next token
if (!fileError && (i != BASE_11G_VALUE)) {
token = strtok( NULL, delimiters );
if (NULL == token) {
//bad line give an error and get out
printf("Incomplete line at line number %d, in mode specific section\n", currentLineNumber);
fileError = 1;
}
}
} //end for
}
if(!fileError) {
if(!modeSpecific) {
//overwrite the regArray with the field info
//incase this is a ver 2 config file, take a copy of 2 fields we don't want changed
tempSwField = pFieldDetails->softwareControlled;
tempModeField = pFieldDetails->existsInEepromOrMode;
memcpy(pFieldDetails, &fieldInfoIn, sizeof(ATHEROS_REG_FILE));
if(cfgVersion >= 2) {
//write back the 2 fields want to keep
pFieldDetails->softwareControlled = tempSwField;
pFieldDetails->existsInEepromOrMode = tempModeField;
}
}
else {
//update the info in the mode specific array
pModeFieldDetails->value11a = modeFieldInfoIn.value11a;
pModeFieldDetails->value11aTurbo = modeFieldInfoIn.value11aTurbo;
pModeFieldDetails->value11b = modeFieldInfoIn.value11b;
pModeFieldDetails->value11g = modeFieldInfoIn.value11g;
}
}
} //end while !fileError
if (fileError) {
returnValue = 0;
}
fclose(fileStream);
printf("Return from parsetAtherosRegFile()\n");
#endif //ifndef MDK_AP
return(returnValue);
}
/**************************************************************************
* getUnsignedFromStr - Given a string that will contain a value
* calculate the unsigned interger value. The string can be in hex
* or decimal format
*
* Returns: The unsigned integer extracted from the string. TRUE if converted
* false if not
*/
A_BOOL
getUnsignedFromStr
(
A_UINT32 devNum,
A_CHAR *pString,
A_BOOL signedValue,
A_UINT16 fieldSize,
A_UINT32 *pReturnValue
)
{
A_CHAR *pStopString;
A_UINT32 mask = 0x01;
A_BOOL negValue = 0;
A_UCHAR i;
//setting the base of strtoul and strtol will work out the base of the number
//however values that start with 0 but second char is not 'x' or 'X',
//are treated as octal values, adding a check so we don't
//have this problem
if((pString[0] == '0') && ((pString[1] == 'x') || (pString[1] == 'X'))) {
//assume hex values are unsigned.
*pReturnValue = strtoul(pString, (char **)&pStopString, 16);
}
else {
if(signedValue) {
if (pString[0] == '-') {
negValue = 1;
pString++; //move pointer beyond the - sign
}
}
*pReturnValue = strtoul(pString, (char **)&pStopString, 10);
if (negValue) {
//perform the 2's compliment to get the negative value
//first need to work out the mask for the field
if (fieldSize == 0) {
mError(devNum, EINVAL, "getUnsignedFromStr: field size can't be zero for negative values\n");
return(0);
}
for (i = 0; i < fieldSize; i++) {
mask |= 0x1 << i;
}
*pReturnValue = ((~(*pReturnValue) & mask) + 1) & mask;
}
}
#ifdef LINUX
if(pStopString == pString) {
//there was an error in the conversion, return error
mError(devNum, EINVAL, "unable to convert to unsigned integer\n");
return(0);
}
#else
if(*pStopString != '\0') {
//there was an error in the conversion, return error
mError(devNum, EINVAL, "unable to convert to unsigned integer\n");
return(0);
}
#endif
return(1);
}
/**************************************************************************
* getBitFieldValues - Given a string that contains the field information
* in the format msb:lsb, extract the starting bit position and the
* size of the field
*
* Returns: The start bit pos and size extracted from the string. TRUE if extracted
* false if not
*/
A_BOOL
getBitFieldValues
(
A_UINT32 devNum,
A_CHAR *pString,
ATHEROS_REG_FILE *pFieldDetails
)
{
A_CHAR *pEndField = NULL;
A_CHAR *pStopString;
A_UINT32 lengthString = sizeof(pString);
A_UINT32 i;
A_BOOL colonDetected = 0;
A_UINT16 firstValue;
A_UINT16 secondValue;
A_UINT16 temp;
//look for the :
for (i = 0; i < lengthString; i++) {
if (pString[i] == ':') {
pString[i] = '\0';
pEndField = pString + i + 1;
colonDetected = 1;
break;
}
}
//get the start position
firstValue = (A_UINT16)strtoul(pString, (char **)&pStopString, 10);
if(*pStopString != '\0') {
//there was an error in the conversion, return error
mError(devNum, EINVAL, "unable to convert to unsigned integer\n");
return(0);
}
if (!colonDetected) {
//this is a 1 bit field
pFieldDetails->fieldSize = 1;
pFieldDetails->fieldStartBitPos = firstValue;
}
else {
//get second value for start postion and size
secondValue = (A_UINT16)strtoul(pEndField, (char **)&pStopString, 10);
if(*pStopString != '\0') {
//there was an error in the conversion, return error
mError(devNum, EINVAL, "unable to convert to unsigned integer\n");
return(0);
}
if (firstValue < secondValue) {
if(pFieldDetails->radioRegister) {
//flag for later
pFieldDetails->dontReverse = 1;
//switch the order round
temp = firstValue;
firstValue = secondValue;
secondValue = temp;
}
else {
mError(devNum, EINVAL, "Bit fields must be in format msb:lsb\n");
return(0);
}
}
pFieldDetails->fieldSize =
(A_UINT16)((firstValue - secondValue) + 1);
pFieldDetails->fieldStartBitPos = secondValue;
}
return(1);
}
/**************************************************************************
* createPciRegWrites - Create the array that will contain the pci offset
* and write values for the register array
*
*
* Returns: True if the array was created, false if it was not
*/
A_BOOL
createPciRegWrites
(
A_UINT32 devNum
)
{
LIB_DEV_INFO *pLibDev = gLibInfo.pLibDevArray[devNum];
A_UINT16 currentField = 0;
A_UINT16 currentRegister = 0;
A_UINT32 baseValueToWrite;
A_UINT32 turboValueToWrite;
A_UINT32 addressToWrite;
A_UINT16 numRfPciWrites;
A_UINT32 regStartIndex, regEndIndex, iIndex, writableRegister, includeRegister;
/*
* create the pciValues array, create it for same number
* of entries as the regArray. This array will be smaller
* than this
*/
//create an array large enough to hold all the register fields
if(pLibDev->pciValuesArray) {
//free up previous allocation if there was one.
free(pLibDev->pciValuesArray);
pLibDev->pciValuesArray = NULL;
}
pLibDev->pciValuesArray = (PCI_REG_VALUES *)malloc(sizeof(PCI_REG_VALUES) * pLibDev->sizeRegArray);
//printf("1\n");
if (NULL == pLibDev->pciValuesArray) {
mError(devNum, ENOMEM, "Device Number %d:Unable to allocate memory for pciValuesArray\n", devNum);
return 0;
}
//printf("2\n");
//start off by doing the mac and baseband registers
while((currentField<pLibDev->sizeRegArray) && (!pLibDev->regArray[currentField].radioRegister)) {
baseValueToWrite = 0;
turboValueToWrite = 0;
regStartIndex=currentField;
do {
// printf("currentField=%d\n", currentField);
addressToWrite = pLibDev->regArray[currentField].regOffset;
baseValueToWrite |=
pLibDev->regArray[currentField].fieldBaseValue << pLibDev->regArray[currentField].fieldStartBitPos;
turboValueToWrite |=
pLibDev->regArray[currentField].fieldTurboValue << pLibDev->regArray[currentField].fieldStartBitPos;
// printf("addressToWrite=%x:currentField=%x\n", addressToWrite, currentField);
currentField++;
} while((currentField<pLibDev->sizeRegArray) && addressToWrite == pLibDev->regArray[currentField].regOffset);
regEndIndex=currentField;
writableRegister=0;
// printf("SNOOP::regStartIndex=%d:regEndIndex=%d\n", regStartIndex, regEndIndex);
for(iIndex=regStartIndex;iIndex<regEndIndex;iIndex++) {
// printf("SNOOP::writable=%d\n", pLibDev->regArray[iIndex].writable);
if (pLibDev->regArray[iIndex].writable) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -