📄 hw_routines.c
字号:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory.h>
#include <assert.h>
#include <time.h>
#ifdef LINUX
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <stdarg.h>
#include <signal.h>
#endif
#ifdef ANWI
#include <windows.h>
#include <malloc.h>
#include <process.h>
#include <winioctl.h>
#ifndef LEGACY
#include <initguid.h>
#include <setupapi.h>
#endif
#endif
#ifdef __ATH_DJGPPDOS__
#include <dos.h>
#include <io.h>
//#include <limits.h>
//#include <stdio.h>
//#include <stdlib.h>
//#include <string.h>
#include <stdarg.h>
#include <unistd.h>
#define __int64 long long
#define HANDLE long
typedef unsigned long DWORD;
#define Sleep delay
#endif // #ifdef __ATH_DJGPPDOS__
#include "wlantype.h"
#include "dw16550reg.h"
#include "athreg.h"
#include "common_hw.h"
#include "dk_mem.h"
#ifdef SIM
#include "sim.h"
#endif
#include "dk_common.h"
/////////////////////////////////////////////////////////////////////////////
//GLOBAL VARIABLES
DRV_VERSION_INFO driverVer;
static FILE *logFile; /* file handle of logfile */
static FILE *yieldLogFile; /* file handle of yieldLogfile */
static A_BOOL logging; /* set to 1 if a log file open */
static A_BOOL enablePrint = 1;
static A_BOOL yieldLogging = 0; /* set to 1 if a log file open */
static A_BOOL yieldEnablePrint = 1;
static A_UINT16 quietMode; /* set to 1 for quiet mode, 0 for not */
static A_UINT16 yieldQuietMode; /* set to 1 for quiet mode, 0 for not */
static A_BOOL driverOpened;
A_UCHAR *pbuffMapBytes=NULL;
A_UINT16 *pnumBuffs=NULL;
MDK_WLAN_DRV_INFO globDrvInfo; /* Global driver info */
/////////////////////////////////////////////////////////////////////////////
// FORWARD DECLARATIONS
void deviceCleanup(A_UINT16 devIndex);
DLL_EXPORT void dk_quiet ( A_UINT16 Mode);
// Extern declarations
extern A_UINT16 driverOpen();
extern A_STATUS connectSigHandler();
extern void close_device(MDK_WLAN_DEV_INFO *pdevInfo);
extern void close_driver();
extern A_STATUS get_device_client_info(MDK_WLAN_DEV_INFO *pdevInfo, PDRV_VERSION_INFO pdrv, PCLI_INFO cliInfo);
/**************************************************************************
* envInit - performs any intialization needed by the environment
*
* For the windows NT hardware environment, need to open the driver and
* perform any other initialization required by it
*
* RETURNS: A_OK if it works, A_ERROR if not
*/
#ifdef ART_BUILD
A_STATUS envInit ( A_BOOL debugMode, A_BOOL openDriver)
#else
A_STATUS envInit ( A_BOOL debugMode)
#endif
{
A_UINT16 i;
#ifdef ART_BUILD
#else
//Define openDriver as it would not be defined for MDK
A_BOOL openDriver=1;
#endif
// quiet our optional uiPrintfs...
dk_quiet((A_UINT16)(debugMode ? 0 : 1));
#if defined(LINUX ) && !defined(SOC_LINUX)
ansi_init();
#endif
// open a handle to the driver
// need not open the driver if art is controlling a remote client
driverOpened = 0;
if (openDriver) {
if (!driverOpen()) {
return A_ERROR;
}
driverOpened = 1;
}
globDrvInfo.devCount = 0;
// set all the devInfo pointers to null
for(i = 0; i < WLAN_MAX_DEV; i++)
globDrvInfo.pDevInfoArray[i] = NULL;
return connectSigHandler();
}
void envCleanup
(
A_BOOL closeDriver
)
{
A_UINT16 i;
//uiPrintf("SNOOP:::envCleanup called \n");
#ifdef SIM
signal(SIGINT, SIG_DFL);
#endif
// cleanup all the devInfo structures
for ( i = 0; i < WLAN_MAX_DEV; i++ ) {
if ( globDrvInfo.pDevInfoArray[i] ) {
deviceCleanup(i);
}
}
globDrvInfo.devCount = 0;
// close the handle to the driver
if ((closeDriver) && (driverOpened)) {
close_driver();
driverOpened = 0;
}
}
#ifndef SOC_LINUX
void hwInit ( MDK_WLAN_DEV_INFO *pdevInfo, A_UINT32 resetMask)
{
A_UINT32 reg=0, i;
A_UINT32 devmapRegAddress = pdevInfo->pdkInfo->f2MapAddress;
A_UINT16 devIndex = (A_UINT16)pdevInfo->pdkInfo->devIndex;
A_UINT16 hwDevId;
hwDevId = (A_UINT16)( (hwCfgRead32(devIndex, 0) >> 16) & 0xffff);
/* Bring out of sleep mode */
hwMemWrite32(devIndex, F2_SCR + devmapRegAddress, F2_SCR_SLE_FWAKE);
mSleep(10);
reg = 0;
if (hwDevId && 0xff) {
if (resetMask & MAC_RESET) {
reg = reg | F2_RC_MAC | F2_RC_BB | F2_RC_RESV0;
}
if (resetMask & BB_RESET) {
reg = reg | F2_RC_RESV1;
}
if (resetMask & BUS_RESET) {
reg = reg | F2_RC_PCI;
}
}
else {
if (resetMask & MAC_RESET) {
reg = reg | F2_RC_MAC;
}
if (resetMask & BB_RESET) {
reg = reg | F2_RC_BB;
}
if (resetMask & BUS_RESET) {
reg = reg | F2_RC_PCI;
}
}
hwMemRead32(devIndex, F2_RXDP+devmapRegAddress); // To clear any pending writes, as per doc/mac_registers.txt
hwMemWrite32(devIndex, F2_RC+devmapRegAddress, reg);
mSleep(1);
//workaround for hainan 1.0
if((hwMemRead32(devIndex, F2_SREV+devmapRegAddress) & F2_SREV_ID_M)== 0x55) {
for (i = 0; i < 20; i++) {
hwMemRead32(devIndex, 0x4020);
}
}
// mSleep(10);
if(hwMemRead32(devIndex, F2_RC+devmapRegAddress) == 0) {
uiPrintf("hwInit: Device did not enter Reset \n");
return;
}
/* Bring out of sleep mode again */
hwMemWrite32(devIndex, F2_SCR+devmapRegAddress, F2_SCR_SLE_FWAKE);
mSleep(10);
/* Clear the reset */
hwMemWrite32(devIndex, F2_RC+devmapRegAddress, 0);
mSleep(10);
}
#endif
/**************************************************************************
* deviceInit - performs any initialization needed for a device
*
* Perform the initialization needed for a device. This includes creating a
* devInfo structure and initializing its contents
*
* RETURNS: A_OK if successful, A_ERROR if not
*/
A_STATUS deviceInit
(
A_UINT16 devIndex, /* index of globalDrvInfo which to add device to */
A_UINT16 device_fn,
DK_DEV_INFO *pdkInfo
)
{
MDK_WLAN_DEV_INFO *pdevInfo;
A_UINT32 regValue;
CLI_INFO cliInfo;
A_UINT32 iIndex;
A_UINT32 NumBuffBlocks;
A_UINT32 NumBuffMapBytes;
/* check to see if we already have a devInfo structure created for this device */
if (globDrvInfo.pDevInfoArray[devIndex]) {
uiPrintf("Error : Device already in use \n");
return A_ERROR;
}
pdevInfo = (MDK_WLAN_DEV_INFO *) A_MALLOC(sizeof(MDK_WLAN_DEV_INFO));
if(!pdevInfo) {
uiPrintf("Error: Unable to allocate MDK_WLAN_DEV_INFO struct!\n");
return(A_ERROR);
}
#ifdef WIN32
pdevInfo->hDevice = NULL;
#else
pdevInfo->hDevice = -1;
#endif
pdevInfo->pdkInfo = (DK_DEV_INFO *) A_MALLOC(sizeof(DK_DEV_INFO));
if(!pdevInfo->pdkInfo) {
A_FREE(pdevInfo);
uiPrintf("Error: Unable to allocate DK_DEV_INFO struct!\n");
return A_ERROR;
}
//uiPrintf("pdevInfo->pdkInfo=%x:\npdevInfo=%x:\n", pdevInfo->pdkInfo, pdevInfo);
if (!pdkInfo) {
/* zero out the dkInfo struct */
A_MEM_ZERO(pdevInfo->pdkInfo, sizeof(DK_DEV_INFO));
pdevInfo->pdkInfo->devIndex = devIndex;
pdevInfo->pdkInfo->device_fn = device_fn;
cliInfo.numBars = 1; //apparently anwi driver does not update this for eagle
//make sure it is initialized to a good default
if (get_device_client_info(pdevInfo, &driverVer, &cliInfo) == A_ERROR) {
return A_ERROR;
}
pdevInfo->pdkInfo->f2Mapped = 1;
if (driverVer.minorVersion >= 2) {
pdevInfo->pdkInfo->f2MapAddress = cliInfo.aregPhyAddr[0];
pdevInfo->pdkInfo->regMapRange = cliInfo.aregRange[0];
pdevInfo->pdkInfo->regVirAddr = cliInfo.aregVirAddr[0];
for(iIndex=0; iIndex<cliInfo.numBars; iIndex++) {
pdevInfo->pdkInfo->aregPhyAddr[iIndex] = cliInfo.aregPhyAddr[iIndex];
pdevInfo->pdkInfo->aregVirAddr[iIndex] = cliInfo.aregVirAddr[iIndex];
pdevInfo->pdkInfo->aregRange[iIndex] = cliInfo.aregRange[iIndex];
pdevInfo->pdkInfo->res_type[iIndex] = cliInfo.res_type[iIndex];
}
}
else {
pdevInfo->pdkInfo->aregPhyAddr[0] = cliInfo.regPhyAddr;
pdevInfo->pdkInfo->aregVirAddr[0] = cliInfo.regVirAddr;
pdevInfo->pdkInfo->aregRange[0] = cliInfo.regRange;
pdevInfo->pdkInfo->f2MapAddress = cliInfo.regPhyAddr;
pdevInfo->pdkInfo->regMapRange = cliInfo.regRange;
pdevInfo->pdkInfo->regVirAddr = cliInfo.regVirAddr;
}
pdevInfo->pdkInfo->numBars = (A_UINT16)cliInfo.numBars;
pdevInfo->pdkInfo->memPhyAddr = cliInfo.memPhyAddr;
pdevInfo->pdkInfo->memVirAddr = cliInfo.memVirAddr;
pdevInfo->pdkInfo->memSize = cliInfo.memSize;
pdevInfo->pdkInfo->bar_select = 0;
}
else {
memcpy(pdevInfo->pdkInfo, pdkInfo, sizeof(DK_DEV_INFO));
uiPrintf("Client Version = %d.%d Build %d\n", ((pdevInfo->pdkInfo->version&0xfff0)>> 4), (pdevInfo->pdkInfo->version & 0xf), (pdevInfo->pdkInfo->version >> 16));
}
q_uiPrintf("Num bars = %d\n", pdevInfo->pdkInfo->numBars);
q_uiPrintf("+ f2MapAddress = %08x\n", (A_UINT32)(pdevInfo->pdkInfo->f2MapAddress));
iIndex = 0;
for(iIndex=0; iIndex<pdevInfo->pdkInfo->numBars; iIndex++) {
q_uiPrintf("+ aregPhyAddr[%d]= %08x\n", iIndex, (A_UINT32)(pdevInfo->pdkInfo->aregPhyAddr[iIndex]));
q_uiPrintf("+ aregVirAddr[%d]= %08x\n", iIndex, (A_UINT32)(pdevInfo->pdkInfo->aregVirAddr[iIndex]));
q_uiPrintf("+ aregRange[%d]= %08x\n", iIndex, (A_UINT32)(pdevInfo->pdkInfo->aregRange[iIndex]));
}
q_uiPrintf("+ Allocated memory in the driver.\n");
q_uiPrintf("+ VirtAddress = %08x\n", (A_UINT32)(pdevInfo->pdkInfo->memVirAddr));
q_uiPrintf("+ PhysAddress = %08x\n", (A_UINT32)(pdevInfo->pdkInfo->memPhyAddr));
q_uiPrintf("+ Size = %08x\n", (A_UINT32)(pdevInfo->pdkInfo->memSize));
#ifdef ART_BUILD
NumBuffBlocks = 0; // to quiet compiler warnings
NumBuffMapBytes = 0; // to quiet compiler warnings
#else
NumBuffBlocks = pdevInfo->pdkInfo->memSize / BUFF_BLOCK_SIZE;
NumBuffMapBytes = NumBuffBlocks / 8;
/* initialize the map bytes for tracking memory management: calloc will init to 0 as well*/
#ifdef SIM
if (pbuffMapBytes == NULL)
pbuffMapBytes = (A_UCHAR *) calloc(NumBuffMapBytes, sizeof(A_UCHAR));
pdevInfo->pbuffMapBytes = pbuffMapBytes;
#else
pdevInfo->pbuffMapBytes = (A_UCHAR *) calloc(NumBuffMapBytes, sizeof(A_UCHAR));
#endif
if(!pdevInfo->pbuffMapBytes) {
close_device(pdevInfo);
A_FREE(pdevInfo->pdkInfo);
A_FREE(pdevInfo);
uiPrintf("Error: Unable to allocate buffMapBytes struct!\n");
return A_ERROR;
}
#ifdef SIM
if (pnumBuffs == NULL)
pnumBuffs = (A_UINT16 *) calloc(NumBuffBlocks, sizeof(A_UINT16));
pdevInfo->pnumBuffs = pnumBuffs;
#else
pdevInfo->pnumBuffs = (A_UINT16 *) calloc(NumBuffBlocks, sizeof(A_UINT16));
#endif
if(!pdevInfo->pnumBuffs) {
A_FREE(pdevInfo->pbuffMapBytes);
close_device(pdevInfo);
A_FREE(pdevInfo->pdkInfo);
A_FREE(pdevInfo);
uiPrintf("Error: Unable to allocate numBuffs struct!\n");
return A_ERROR;
}
#endif
globDrvInfo.pDevInfoArray[devIndex] = pdevInfo;
globDrvInfo.devCount++;
if (!pdkInfo) { // pdkInfo will be non-zero only for thin/usb clients
// Setup memory window, bus mastering, & SERR
regValue = hwCfgRead32(devIndex, F2_PCI_CMD);
regValue |= (MEM_ACCESS_ENABLE | MASTER_ENABLE | SYSTEMERROR_ENABLE);
regValue &= ~MEM_WRITE_INVALIDATE; // Disable write & invalidate for our device
hwCfgWrite32(devIndex, F2_PCI_CMD, regValue);
regValue = hwCfgRead32(devIndex, F2_PCI_CACHELINESIZE);
regValue = (regValue & 0xffff) | (0x40 << 8) | 0x08;
hwCfgWrite32(devIndex, F2_PCI_CACHELINESIZE, regValue);
#ifdef SOC_LINUX
//hwInit(pdevInfo, BUS_RESET | BB_RESET | MAC_RESET);
hwInit(pdevInfo, 0);
#endif
}
/*
// Test memaccesses
uiPrintf("Testing Reg accesses\n");
hwMemWrite32(devIndex, F2_RXDP+pdevInfo->pdkInfo->f2MapAddress, 0xbabecafc);
uiPrintf("RXDP Content exp=0xbabecafc:act=%x\n", hwMemRead32(devIndex, F2_RXDP+pdevInfo->pdkInfo->f2MapAddress));
uiPrintf("Testing Memory accesses\n");
hwMemWrite32(devIndex, pdevInfo->pdkInfo->memPhyAddr + 0x100, 0xdeadbeef);
uiPrintf("Memory Content exp=0xdeadbeef:act=%x\n", hwMemRead32(devIndex, pdevInfo->pdkInfo->memPhyAddr + 0x100));
*/
return A_OK;
}
/**************************************************************************
* deviceCleanup - performs any memory cleanup needed for a device
*
* Perform any cleanup needed for a device. This includes deleting any
* memory allocated by a device, and unregistering the card with the driver
*
* RETURNS: 1 if successful, 0 if not
*/
void deviceCleanup
(
A_UINT16 devIndex
)
{
MDK_WLAN_DEV_INFO *pdevInfo;
//printf("SNOOP::deviceCleanup::devIndex=%d\n", devIndex);
pdevInfo = globDrvInfo.pDevInfoArray[devIndex];
#ifdef SOC_LINUX
hwClose(pdevInfo);
#endif
close_device(pdevInfo);
A_FREE(pdevInfo->pdkInfo);
A_FREE(pdevInfo);
globDrvInfo.pDevInfoArray[devIndex] = NULL;
globDrvInfo.devCount--;
// printf("SNOOP::exit deviceCleanup::devIndex=%d:devCount=%d\n", devIndex, globDrvInfo.devCount);
}
/**************************************************************************
* checkRegSpace - Check to see if an address sits in the setup register space
*
* This internal routine checks to see if an address lies in the register space
*
* RETURNS: A_OK to signify a valid address or A_ENOENT
*/
A_STATUS checkRegSpace
(
MDK_WLAN_DEV_INFO *pdevInfo,
A_UINT32 address
)
{
A_UINT32 iIndex;
if (driverVer.minorVersion >= 2) {
for(iIndex=0; iIndex<pdevInfo->pdkInfo->numBars; iIndex++) {
if((address >= pdevInfo->pdkInfo->aregPhyAddr[iIndex]) &&
(address < pdevInfo->pdkInfo->aregPhyAddr[iIndex] + pdevInfo->pdkInfo->aregRange[iIndex]))
return A_OK;
}
}
else {
if((address >= pdevInfo->pdkInfo->aregPhyAddr[0]) && (address < pdevInfo->pdkInfo->aregPhyAddr[0] + pdevInfo->pdkInfo->regMapRange))
return A_OK;
}
return A_ENOENT;
}
/**************************************************************************
* checkMemSpace - Check to see if an address sits in the setup physical memory space
*
* This internal routine checks to see if an address lies in the physical memory space
*
* RETURNS: A_OK to signify a valid address or A_ENOENT
*/
A_STATUS checkMemSpace
(
MDK_WLAN_DEV_INFO *pdevInfo,
A_UINT32 address
)
{
if((address >= (A_UINT32)pdevInfo->pdkInfo->memPhyAddr) &&
(address < (A_UINT32)((A_UCHAR *)(pdevInfo->pdkInfo->memPhyAddr) + pdevInfo->pdkInfo->memSize)))
return A_OK;
else
return A_ENOENT;
}
/**************************************************************************
* checkIOSpace - Check to see if an address sits in the IO register space
*
* This internal routine checks to see if an address lies in the IO register space
*
* RETURNS: A_OK to signify a valid address or A_ENOENT
*/
A_STATUS checkIOSpace
(
MDK_WLAN_DEV_INFO *pdevInfo,
A_UINT32 address
)
{
A_UINT32 i;
for (i=0;i<pdevInfo->pdkInfo->numBars;i++) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -