?? athreg.c
字號:
/* athreg.c - contians functions for managing Atheros register files */
/* Copyright (c) 2002 Atheros Communications, Inc., All Rights Reserved */
#ident "ACI $Id: //depot/sw/branches/ART_V53_dragon/sw/src/dk/mdk/devlib/athreg.c#3 $, $Header: //depot/sw/branches/ART_V53_dragon/sw/src/dk/mdk/devlib/athreg.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 <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "wlantype.h"
#include "athreg.h"
#include "manlib.h"
#include "mEeprom.h"
#include "mConfig.h"
#include "mDevtbl.h"
#include "artEar.h"
#include <errno.h>
#ifndef VXWORKS
#include <search.h>
#endif
#if defined(SOC_LINUX)
#define _lfind lfind
#endif
#if defined (VXWORKS) || defined (__ATH_DJGPPDOS__)
void *_lfind(const void *key,const void *base0,size_t *nmemb,size_t size,int (* compar)(const void *,const void *));
#endif
static A_BOOL getUnsignedFromStr( A_UINT32 devNum, A_CHAR *inString, A_BOOL signedValue, A_UINT16 fieldSize, A_UINT32 *returnValue);
static A_BOOL getBitFieldValues( A_UINT32 devNum, A_CHAR *pString, ATHEROS_REG_FILE *pFieldDetails);
static A_UINT16 createRfPciValues(const ATHEROS_REG_FILE *pRfFields, A_UINT32 indexRfField, A_UINT32 sizeRegArray, PCI_REG_VALUES *pRfWriteValues);
static int compareFields(const void *arg1, const void *arg2);
static A_UINT16 ParseRfRegs(A_UINT32 devNum, ATHEROS_REG_FILE *pRfFields, A_UINT32 indexRfField, A_UINT32 sizeRegArray,
PCI_REG_VALUES *pRfWriteValues, RF_REG_INFO *pRfRegBanks);
static A_UINT16 createRfBankPciValues(A_UINT32 devNum, RF_REG_INFO *pRfRegBank);
static A_UINT16 new_createRfPciValues(A_UINT32 devNum, A_UINT32 bank, A_BOOL writePCI);
static void writeRfBank(A_UINT32 devNum, RF_REG_INFO *pRfRegBank);
// non-ansi functions are mapped to some equivalent functions
#ifdef LINUX
#include <ctype.h>
#include "linux_ansi.h"
#endif
static A_BOOL keepAGCDisable = 0;
A_UINT32 reverseRfBits(A_UINT32 val, A_UINT16 bit_count, A_BOOL dontReverse);
char delimiters[] = " \t\n";
A_INT8 start_strcmp(A_CHAR *substring, A_CHAR *string) {
A_UINT32 iIndex, ssLen, sLen;
ssLen = strlen(substring);
sLen = strlen(string);
if (sLen < ssLen) return 1;
for(iIndex=0;iIndex<ssLen;iIndex++) {
if (tolower(string[iIndex]) == tolower(substring[iIndex]))
continue;
else
return 1;
}
return 0;
}
/**************************************************************************
* parseAtherosRegFile - Parse the register file to produce C array
*
* Returns: TRUE if file parsed successfully, FALSE otherwise.
*/
A_BOOL
parseAtherosRegFile
(
LIB_DEV_INFO *pLibDev,
char *filename
)
{
FILE *fileStream;
A_CHAR lineBuffer[MAX_FILE_WIDTH];
A_CHAR fieldBaseValueString[MAX_FILE_WIDTH];
A_CHAR fieldTurboValueString[MAX_FILE_WIDTH];
A_CHAR *token;
A_UINT32 currentLineNumber = 0;
A_BOOL returnValue = 1;
A_BOOL fileError = 0;
A_UINT32 signedValue;
A_UINT16 i, j;
A_UINT32 tempValue;
ATHEROS_REG_FILE fieldInfoIn;
ATHEROS_REG_FILE *pFieldDetails = NULL;
MODE_INFO modeFieldInfoIn;
MODE_INFO *pModeFieldDetails = NULL;
size_t tempSize;
A_BOOL modeSpecific = 0;
A_UINT32 tempSwField;
A_BOOL tempModeField;
A_UINT32 cfgVersion = 0;
#ifndef MDK_AP
if(*filename == '\0') {
#ifndef NO_LIB_PRINT
printf("Using defaults from : \n\t%s\n\n", ar5kInitData[pLibDev->ar5kInitIndex].pCfgFileVersion);
#endif
return 1;
}
// file processing removed till flash filesystem is up
//open file
fileStream = fopen(filename, "r");
if (NULL == fileStream) {
mError(pLibDev->devNum, EINVAL, "Unable to open atheros text file - %s\n", filename);
return 0;
}
#ifndef NO_LIB_PRINT
printf("Using the values from configuration file %s\n\n", filename);
#endif
memset(&fieldInfoIn, 0, sizeof(ATHEROS_REG_FILE));
memset(&modeFieldInfoIn, 0, sizeof(MODE_INFO));
//start reading lines and parsing info
while (!fileError) {
if (fgets( lineBuffer, MAX_FILE_WIDTH, fileStream ) == NULL) {
break;
}
currentLineNumber++;
//check for this being a comment line
if (lineBuffer[0] == '#') {
//comment line
continue;
}
//extract value from the line
token = strtok( lineBuffer, delimiters );
if (NULL == token) {
//blank line
continue;
}
//process command lines
if(token[0] == '@') {
if(strnicmp("@FORMAT:", token, strlen("@FORMAT:")) == 0) {
token = strtok( NULL, delimiters ); //get FORMAT number
if(NULL == token) {
printf("Bad @FORMAT syntax at line %d\n", currentLineNumber);
fclose(fileStream);
return 0;
}
if(!sscanf(token, "%ld", &cfgVersion)) {
printf("Bad @FORMAT syntax at line %d\n", currentLineNumber);
fclose(fileStream);
return 0;
}
}
else if(strnicmp("@MODE:", token, strlen("@MODE:")) == 0) {
token = strtok( NULL, delimiters ); //get MODE type
if(NULL == token) {
printf("Bad @MODE syntax at line %d\n", currentLineNumber);
fclose(fileStream);
return 0;
}
/*
* for now only care about finding the mode specific section,
* ignore everything else
*/
if(strnicmp("MODE_SPECIFIC", token, strlen("MODE_SPECIFIC")) == 0) {
modeSpecific = 1;
}
}
//continue and get next line
continue;
}
if(token[0] == '*') {
//set flag to create section in mode specific section, point past *
token++;
}
for(i = FIELD_NAME; (i <= PUBLIC_NAME) && !fileError && !modeSpecific; i++) {
switch(i) {
case FIELD_NAME:
//zero out the local structure at start or new field
memset(&fieldInfoIn, 0, sizeof(ATHEROS_REG_FILE));
if(strlen(token) > MAX_NAME_LENGTH) {
mError(pLibDev->devNum, EINVAL, "field name on line is more than %d characters\n",
currentLineNumber, MAX_NAME_LENGTH);
fileError = 1;
break;
}
//search for this field within default array
tempSize = pLibDev->sizeRegArray;
pFieldDetails = (ATHEROS_REG_FILE *)_lfind(token, pLibDev->regArray, &tempSize, sizeof(ATHEROS_REG_FILE), compareFields);
if(pFieldDetails == NULL) {
mError(pLibDev->devNum, EINVAL, "%s fieldName at line number %d not found\n",
token, currentLineNumber);
fileError = 1;
break;
}
strcpy(fieldInfoIn.fieldName, token);
if(strncmp((char *)strlwr(token), "rf", 2) == 0) {
//this is a radio register, needs special consideration later
fieldInfoIn.radioRegister = 1;
}
else {
fieldInfoIn.radioRegister = 0;
}
break;
case BASE_VALUE:
//store off the field value till later to see whether it is signed or not
strcpy(fieldBaseValueString, token);
break;
case TURBO_VALUE:
if(0 == cfgVersion) {
//store off the field value till later to see whether it is signed or not
strcpy(fieldTurboValueString, token);
break;
}
else {
//if this is version 2 cfg file, there is no turbo,
//so increment i and fall through to next column, hence no break.
i++;
}
case REG_NAME:
if(strlen(token) > MAX_NAME_LENGTH) {
mError(pLibDev->devNum, EINVAL, "register name on line is more than %d characters\n",
currentLineNumber, MAX_NAME_LENGTH);
printf("err C : %d > %d\n", strlen(token), MAX_NAME_LENGTH);
fileError = 1;
break;
}
strcpy(fieldInfoIn.regName, token);
break;
case REG_OFFSET:
if (!getUnsignedFromStr(pLibDev->devNum, token, 0, 0, &fieldInfoIn.regOffset)) {
mError(pLibDev->devNum, EINVAL, "problem with reg offset value on line %d\n", currentLineNumber);
printf("err D \n");
fileError = 1;
break;
}
break;
case BIT_RANGE:
if (!getBitFieldValues(pLibDev->devNum, token, &fieldInfoIn)) {
mError(pLibDev->devNum, EINVAL, "problem with bit range field on line %d\n", currentLineNumber);
printf("err E \n");
fileError = 1;
break;
}
//create and add maxValue/mask
fieldInfoIn.maxValue = 0;
for(j = 0; j < fieldInfoIn.fieldSize; j++) {
fieldInfoIn.maxValue |= (0x1 << j);
}
break;
case VALUE_SIGNED:
if (!getUnsignedFromStr(pLibDev->devNum, token, 0, 0, &signedValue)) {
mError(pLibDev->devNum, EINVAL, "problem with value is signed flag on line %d\n", currentLineNumber);
printf("err F \n");
fileError = 1;
break;
}
if((signedValue != 0) && (signedValue != 1) && !fieldInfoIn.radioRegister) {
mError(pLibDev->devNum, EINVAL, "value of signed flag should be 0 or 1 on line %d\n", currentLineNumber);
fileError = 1;
break;
}
fieldInfoIn.valueSigned = (A_BOOL)signedValue;
if(fieldInfoIn.radioRegister) {
if (signedValue > 3) {
mError(pLibDev->devNum, EINVAL, "bad rf register number on line %d\n", currentLineNumber);
fileError = 1;
break;
}
fieldInfoIn.rfRegNumber = (A_UCHAR)signedValue;
}
//can now do the conversions for base and turbo values
if (!getUnsignedFromStr(pLibDev->devNum, fieldBaseValueString, (A_BOOL)signedValue,
fieldInfoIn.fieldSize,
&fieldInfoIn.fieldBaseValue)) {
mError(pLibDev->devNum, EINVAL, "problem with base value on line %d\n", currentLineNumber);
fileError = 1;
}
if (fieldInfoIn.fieldBaseValue > fieldInfoIn.maxValue) {
mError(pLibDev->devNum, EINVAL,
"base value is too large for field size on line %d\n", currentLineNumber);
fileError = 1;
break;
}
if(0 == cfgVersion) {
if (strcmp((char *)strlwr(fieldTurboValueString), "nc") != 0) {
if (!getUnsignedFromStr(pLibDev->devNum, fieldTurboValueString, (A_BOOL)signedValue,
fieldInfoIn.fieldSize,
&fieldInfoIn.fieldTurboValue)) {
mError(pLibDev->devNum, EINVAL, "problem with turbo value on line %d\n", currentLineNumber);
fileError = 1;
break;
}
}
else {
//turbo value is the same as the base value
fieldInfoIn.fieldTurboValue = fieldInfoIn.fieldBaseValue;
}
if (fieldInfoIn.fieldTurboValue > fieldInfoIn.maxValue) {
mError(pLibDev->devNum, EINVAL,
"turbo value is too large for field size on line %d\n", currentLineNumber);
fileError = 1;
break;
}
}
else {
//Turbo value is not coming from this array, it will come from mode specific
fieldInfoIn.fieldTurboValue = 0;
}
break;
case REG_WRITABLE:
if (!getUnsignedFromStr(pLibDev->devNum, token, 0, 0, &tempValue)) {
mError(pLibDev->devNum, EINVAL, "problem with writable flag on line %d\n", currentLineNumber);
fileError = 1;
break;
}
if((tempValue != 0) && (tempValue != 1)) {
mError(pLibDev->devNum, EINVAL, "writable flag should be 0 or 1 on line %d\n", currentLineNumber);
fileError = 1;
break;
}
fieldInfoIn.writable = (A_BOOL)tempValue;
break;
case REG_READABLE:
if (!getUnsignedFromStr(pLibDev->devNum, token, 0, 0, &tempValue)) {
mError(pLibDev->devNum, EINVAL, "problem with readable flag on line %d\n", currentLineNumber);
fileError = 1;
break;
}
if((tempValue != 0) && (tempValue != 1)) {
mError(pLibDev->devNum, EINVAL, "readable flag should be 0 or on line %d\n", currentLineNumber);
fileError = 1;
break;
}
fieldInfoIn.readable = (A_BOOL)tempValue;
break;
case SW_CONTROLLED:
if (!getUnsignedFromStr(pLibDev->devNum, token, 0, 0, &tempValue)) {
mError(pLibDev->devNum, EINVAL, "problem with software controlled flag on line %d\n", currentLineNumber);
fileError = 1;
break;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -