📄 athreg.c
字号:
updateField(devNum, fieldDetails, newValue, 0);
//put mode back to what it was
pLibDev->turbo = !(pLibDev->turbo);
}
if(pLibDev->mdkErrno) {
return;
}
}
}
MANLIB_API A_INT32 getFieldForMode
(
A_UINT32 devNum,
A_CHAR *fieldName,
A_UINT32 mode, //desired mode
A_UINT32 turbo //Flag for base or turbo value
)
{
LIB_DEV_INFO *pLibDev = gLibInfo.pLibDevArray[devNum];
ATHEROS_REG_FILE *fieldDetails;
size_t tempSize;
A_INT32 tempVal=0xdeadbeef;
A_UINT32 modeIndex;
A_UINT32 cfgVersion;
cfgVersion = ar5kInitData[pLibDev->ar5kInitIndex].cfgVersion;
// if ((mode != MODE_11A) && (turbo == 1))
// {
// mError(EINVAL, "Device Number %d:Turbo not supported for this 802.11 mode\n", devNum);
// return(0xdeadbeef);
// }
if (checkDevNum(devNum) == FALSE) {
mError(devNum, EINVAL, "Device Number %d:getField\n", devNum);
return(0xdeadbeef);
}
//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(0xdeadbeef);
}
//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(EINVAL, "Device Number %d:%s fieldName not found\n", devNum, fieldName);
return(0xdeadbeef);
}
if(cfgVersion == 0) {
if(mode != MODE_11A) {
mError(devNum, EIO, "Device Number %d:Modes other than 11a are not supported for older style config files\n", devNum);
return(0xdeadbeef);
}
if(turbo == TURBO_ENABLE) {
tempVal = fieldDetails->fieldTurboValue;
}
else {
tempVal = fieldDetails->fieldBaseValue;
}
}
else {
if (!(fieldDetails->existsInEepromOrMode))
{
tempVal = fieldDetails->fieldBaseValue;
} else
{
modeIndex = fieldDetails->softwareControlled;
// half_speed and quarter_speed get the config values of base mode
switch(mode) {
case MODE_11A: //11a
if(turbo != TURBO_ENABLE) { //11a base or half_speed or quarter_speed
tempVal = pLibDev->pModeArray[modeIndex].value11a;
}
else { //11a turbo
tempVal = pLibDev->pModeArray[modeIndex].value11aTurbo;
}
break;
case MODE_11G: //11g
case MODE_11O: //ofdm@2.4
if(turbo != TURBO_ENABLE) { //11g base or half_speed or quarter_speed
tempVal = pLibDev->pModeArray[modeIndex].value11g;
}
else { //11a turbo
tempVal = pLibDev->pModeArray[modeIndex].value11gTurbo;
}
break;
case MODE_11B: //11b
tempVal = pLibDev->pModeArray[modeIndex].value11b;
break;
} //end switch
}
}
if (fieldDetails->valueSigned) {
//see if the value is negative
if(tempVal & (1 << (fieldDetails->fieldSize - 1))) {
tempVal = ((~(tempVal) & fieldDetails->maxValue) + 1) & fieldDetails->maxValue;
tempVal *= -1;
}
}
return(tempVal);
}
MANLIB_API void setKeepAGCDisable(void) {
keepAGCDisable = 1;
}
MANLIB_API void clearKeepAGCDisable(void) {
keepAGCDisable = 0;
}
MANLIB_API void changeMultipleFieldsAllModes
(
A_UINT32 devNum,
PARSE_MODE_INFO *pFieldsToChange,
A_UINT32 numFields
)
{
LIB_DEV_INFO *pLibDev = gLibInfo.pLibDevArray[devNum];
MODE_INFO *pFieldDetails;
ATHEROS_REG_FILE *pFullFieldDetails;
size_t tempSize = pLibDev->sizeModeArray;
A_UINT32 i, j;
A_UINT32 newValue = 0xdeadbeef;
A_UCHAR bankMask;
A_UINT32 *pValue = NULL;
A_UINT32 clearMask;
for(i = 0; i < numFields; i++) {
pFieldDetails = (MODE_INFO *)_lfind(pFieldsToChange[i].fieldName, pLibDev->pModeArray, &tempSize,
sizeof(MODE_INFO), compareFields);
if(pFieldDetails == NULL) {
mError(devNum, EINVAL, "Device Number %d:changeMultiFieldsAllModes: %s fieldName not found\n", devNum, pFieldsToChange[i].fieldName);
return;
}
pFullFieldDetails = &(pLibDev->regArray[pFieldDetails->indexToMainArray]);
//set all the mode values to those passed in
if (!getUnsignedFromStr(devNum, pFieldsToChange[i].value11aStr, (A_BOOL)pFullFieldDetails->valueSigned,
pFullFieldDetails->fieldSize,
&pFieldDetails->value11a)) {
mError(devNum, EINVAL, "Device Number %d:problem with mode specific 11a base value on line %d\n", devNum, i);
return;
}
if (!getUnsignedFromStr(devNum, pFieldsToChange[i].value11aTurboStr, (A_BOOL)pFullFieldDetails->valueSigned,
pFullFieldDetails->fieldSize,
&pFieldDetails->value11aTurbo)) {
mError(devNum, EINVAL, "Device Number %d:problem with mode specific 11a turbo value on line %d\n", devNum, i);
return;
}
if (!getUnsignedFromStr(devNum, pFieldsToChange[i].value11bStr, (A_BOOL)pFullFieldDetails->valueSigned,
pFullFieldDetails->fieldSize,
&pFieldDetails->value11b)) {
mError(devNum, EINVAL, "Device Number %d:problem with mode specific 11b value on line %d\n", devNum, i);
return;
}
if (!getUnsignedFromStr(devNum, pFieldsToChange[i].value11gStr, (A_BOOL)pFullFieldDetails->valueSigned,
pFullFieldDetails->fieldSize,
&pFieldDetails->value11g)) {
mError(devNum, EINVAL, "Device Number %d:problem with mode specific 11g value on line %d\n", devNum, i);
return;
}
if(pFieldsToChange[i].value11gTurboStr[0] != '\0') {
if (!getUnsignedFromStr(devNum, pFieldsToChange[i].value11gTurboStr, (A_BOOL)pFullFieldDetails->valueSigned,
pFullFieldDetails->fieldSize,
&pFieldDetails->value11gTurbo)) {
mError(devNum, EINVAL, "Device Number %d:problem with mode specific 11g turbo value on line %d\n", devNum, i);
return;
}
}
//set the correct value in the main array based on mode
switch(pLibDev->mode) {
case MODE_11A: //11a
if(pLibDev->turbo != TURBO_ENABLE) { //11a base
pFullFieldDetails->fieldBaseValue = pFieldDetails->value11a;
newValue = pFieldDetails->value11a;
}
else { //11a turbo
pFullFieldDetails->fieldBaseValue = pFieldDetails->value11aTurbo;
newValue = pFieldDetails->value11aTurbo;
}
break;
case MODE_11G: //11g
case MODE_11O: //ofdm@2.4
if(pLibDev->turbo != TURBO_ENABLE) { //11g base
pFullFieldDetails->fieldBaseValue = pFieldDetails->value11g;
newValue = pFieldDetails->value11g;
}
else {
if(pFieldsToChange[i].value11gTurboStr[0] != '\0') {
pFullFieldDetails->fieldBaseValue = pFieldDetails->value11gTurbo;
newValue = pFieldDetails->value11gTurbo;
}
}
break;
case MODE_11B: //11b
pFullFieldDetails->fieldBaseValue = pFieldDetails->value11b;
newValue = pFieldDetails->value11b;
break;
} //end switch
//modify the value in the pci writes array
if(pFullFieldDetails->radioRegister) {
//work out the mask for this bank
bankMask = 0x01;
for(j = 0; j < pFullFieldDetails->regOffset; j++) {
bankMask = (A_UCHAR)((bankMask << 1) & 0xff);
}
new_createRfPciValues(devNum, bankMask, 0);
}
else {
//find address and update value
for (j = 0; j < pLibDev->sizePciValuesArray; j++) {
if(pFullFieldDetails->regOffset == pLibDev->pciValuesArray[j].offset) {
pValue = &(pLibDev->pciValuesArray[j].baseValue);
break;
}
}
if(NULL == pValue) {
//don't expect to get here, means we didn't find the address of reg in pci array
mError(devNum, EIO, "Device Number %d:changeMultipleFieldsAllModes: Unexpected internal software error\n", devNum);
return;
}
//do a modify on the value
clearMask = ~(pFullFieldDetails->maxValue << pFullFieldDetails->fieldStartBitPos);
*pValue = *pValue & clearMask | (newValue << pFullFieldDetails->fieldStartBitPos);
}
}
}
int
compareFields
(
const void *arg1,
const void *arg2
)
{
return(strcmp( (A_CHAR *)arg1, ((ATHEROS_REG_FILE *)arg2)->fieldName ));
// return(strcmp( , (A_CHAR *)arg2));
}
#ifndef LIB_NO_PRINT
MANLIB_API void dumpPciRegValues
(
A_UINT32 devNum
)
{
A_UINT32 regValue;
LIB_DEV_INFO *pLibDev = gLibInfo.pLibDevArray[devNum];
PCI_REG_VALUES *pPciValues;
if (checkDevNum(devNum) == FALSE) {
mError(devNum, EINVAL, "dumpPciRegValues\n");
return;
}
//don't support the rf registers yet
printf("Note rf register reads not currently supported\n");
printf(" offset value\n");
pPciValues = pLibDev->pciValuesArray;
while (pPciValues != pLibDev->pRfPciValues) {
#ifdef SPIRIT_AP
if (pPciValues->offset == 0x987c) {
pPciValues++;
continue;
}
#endif
#if defined(SPIRIT_AP) || defined(FREEDOM_AP)
#ifdef EMULATION
if (pPciValues->offset == 0x9928) {
pPciValues++;
continue;
}
#endif
#endif
regValue = REGR(devNum, pPciValues->offset);
printf(" 0x%04lx 0x%08lx\n", pPciValues->offset,
regValue);
pPciValues++;
}
return;
}
/**************************************************************************
* reverseRfBits - Reverses bit_count bits in val
*
* RETURNS: Bit reversed value
*/
A_UINT32 reverseRfBits
(
A_UINT32 val,
A_UINT16 bit_count,
A_BOOL dontReverse
)
{
A_UINT32 retval = 0;
A_UINT32 bit;
int i;
if(dontReverse) {
return(val);
}
for (i = 0; i < bit_count; i++)
{
bit = (val >> i) & 1;
retval = (retval << 1) | bit;
}
return retval;
}
MANLIB_API void displayPciRegWrites(A_UINT32 devNum)
{
A_UINT32 i;
LIB_DEV_INFO *pLibDev = gLibInfo.pLibDevArray[devNum];
printf(" offset base value turbo value\n");
for(i = 0; i < pLibDev->sizePciValuesArray; i++) {
#ifdef SPIRIT_AP
if (pLibDev->pciValuesArray[i].offset == 0x987c) continue;
#endif
printf(" 0x%04lx 0x%08lx 0x%08lx\n", pLibDev->pciValuesArray[i].offset,
pLibDev->pciValuesArray[i].baseValue, pLibDev->pciValuesArray[i].turboValue);
}
return;
}
#endif //NO_LIB_PRINT
#if defined (VXWORKS) || defined (__ATH_DJGPPDOS__)
void *_lfind
(
const void * key, /* element to match */
const void * base0, /* initial element in array */
size_t * nmemb, /* array to search */
size_t size, /* size of array element */
int (* compar) (const void * ,
const void * ) /* comparison function */
)
{
A_INT32 i;
A_INT32 ret;
A_CHAR *arrayPtr;
A_INT32 noElements;
arrayPtr = (A_CHAR *)base0;
noElements = *nmemb;
for (i=0;i<noElements;i++)
{
ret = compar((const char *)key,arrayPtr);
if (ret == 0) return arrayPtr;
arrayPtr += size;
}
return NULL;
}
#endif
void sendPciWrites(A_UINT32 devNum, PCI_VALUES *pciValues, A_UINT32 nRegs)
{
A_UIN
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -