📄 sysend.c
字号:
pciConfigOutWord (pciBus, pciDevice, pciFunc,
PCI_CFG_COMMAND, PCI_CMD_IO_ENABLE |
PCI_CMD_MASTER_ENABLE);
}
#endif /* INCLUDE_FEI82557END */
/* Configured the maximum number of adaptors? */
if (currentEndDevice == KS8695P_MAX_END_DEVS)
{
return OK;
}
} /* for (iy = 0; iy < KS8695P_MAX_END_DEVS; iy++) */
} /* for (ix = 0; ix < BOARD_TYPE_NB; ix++) */
if ((unit == 0) || (pciDevice > PCI_MAX_DEV))
{
return ERROR;
}
return OK;
}
#ifdef INCLUDE_DEC21X40END
/*******************************************************************************
*
* sysLanIntEnable - enable dec21X4X interrupts
*
* This routine enables dec21X4X interrupts. This may involve operations on
* interrupt control hardware.
*
* RETURNS: OK or ERROR for invalid arguments.
*/
STATUS sysLanIntEnable
(
int level /* level number */
)
{
return (intEnable(level));
}
/*******************************************************************************
*
* sysLanIntDisable - disable dec21X4X interrupts
*
* This routine disables dec21X4X interrupts. This may involve operations on
* interrupt control hardware.
*
* RETURNS: OK or ERROR for invalid arguments.
*/
STATUS sysLanIntDisable
(
int level /* level number */
)
{
return (intDisable(level));
}
/*******************************************************************************
*
* sysDec21x40EnetAddrGet - get Ethernet address
*
* This routine provides a target-specific interface for accessing a
* device Ethernet address.
*
* RETURNS: OK or ERROR if could not be obtained.
*/
STATUS sysDec21x40EnetAddrGet
(
int unit,
char * enetAdrs
)
{
/*
* There isn't a target-specific interface for accessing a
* device Ethernet address.
*/
return (ERROR);
}
#endif /* INCLUDE_DEC21X40END */
#ifdef INCLUDE_FEI82557END
#ifndef KS8695P_ENET_FIXED_BUF_ADRS
/*******************************************************************************
*
* sys557CpuToPci - Convert a CPU memory address to a PCI address
*
* Must convert virtual address to a physical address, then convert the
* physical address to a PCI address (PCI2DRAM_BASE_ADRS is the offset of the
* CPU's memory on the PCI bus,
* i.e. PCI address = (CPU physical address + PCI2DRAM_BASE_ADRS)
*
* This routine works only for addresses in SDRAM.
*
* WARNING: No attempt is made to ensure that the address passed into this
* function is valid.
*
* RETURNS: PCI address corresponding to the CPU virtual address provided
*/
UINT32 sys557CpuToPci
(
int unit, /* ignored */
UINT32 addr
)
{
unit = unit; /* silence compiler */
#ifdef SYS_FEI_DEBUG
logMsg ("sys557CpuToPci %#x -> %#x\n", addr, addr + PCI2DRAM_BASE_ADRS,
0,0,0,0);
#endif
return (UINT32)((CACHE_DMA_VIRT_TO_PHYS(addr)) + PCI2DRAM_BASE_ADRS);
}
/*******************************************************************************
*
* sys557PciToCpu - Convert a PCI memory address to a CPU address
*
* This is the reverse of the previous function. Here we convert from a PCI
* address to a physical address in the CPU's address space, then use the
* current translation tables to find the corresponding virtual address.
*
* This routine works only for addresses in SDRAM.
*
* WARNING: No attempt is made to ensure that the address passed into this
* function is valid.
*
* RETURNS: CPU virtual address for specified PCI address
*/
UINT32 sys557PciToCpu
(
int unit, /* ignored */
UINT32 addr
)
{
unit = unit; /* silence compiler */
#ifdef SYS_FEI_DEBUG
logMsg ("sys557PciToCpu %#x -> %#x\n", addr, addr - PCI2DRAM_BASE_ADRS,
0,0,0,0);
#endif
return (UINT32)(CACHE_DMA_PHYS_TO_VIRT(addr - PCI2DRAM_BASE_ADRS));
}
#endif /* KS8695P_ENET_FIXED_BUF_ADRS */
/*******************************************************************************
*
* sysDelay - a small delay
*
*/
void sysDelay (void)
{
volatile UINT32 p;
/* Read from ROM, a known timing */
p = *(volatile UINT32 *)ROM_TEXT_ADRS;
/*
* Create a little more delay: some arithmetic operations that
* involve immediate constants that cannot be performed in one
* instruction. Clearly it is possible that compiler changes will
* affect this code and leave this no longer calibrated.
*/
p &=0xffff;
p +=0xff11;
p +=0xff51;
return;
}
/*******************************************************************************
*
* sys557Init - prepare LAN adapter for 82557 initialization
*
* This routine is expected to perform any adapter-specific or target-specific
* initialization that must be done prior to initializing the 82557.
*
* The 82557 driver calls this routine from the driver attach routine before
* any other routines in this library.
*
* This routine returns the interrupt level the <pIntLvl> parameter.
*
* RETURNS: OK or ERROR if the adapter could not be prepared for initialization.
*/
STATUS sys557Init
(
int unit, /* unit number */
FEI_BOARD_INFO * pBoard /* board information for the end driver */
)
{
volatile FEI_RESOURCE * pReso = &feiResources [unit];
UINT16 sum = 0;
int ix;
int iy;
UINT16 value;
#ifndef KS8695P_ENET_FIXED_BUF_ADRS
void * testbuf = 0; /* keep compiler quite */
#endif
/*
* Locate the 82557 based adapter - PRO100B, INBUSINESS and XXX.
* Note that since the INBUSINESS adapter is based upon the PRO100B
* board type, it is initialised and driven like one.
*/
#ifdef SYS_FEI_DEBUG
printf ("fei%d: I/O %08X membase %08X irq %d\n", unit, pReso->iobaseCsr,
pReso->membaseCsr, pReso->irq);
#endif
if (pReso->boardType == PRO100B) /* only setup once */
{
}
else
{
/* read the configuration in EEPROM */
for (ix = 0; ix < EE_SIZE; ix++)
{
value = sys557eepromRead (unit, ix);
pReso->eeprom[ix] = value;
sum += value;
}
if (sum != EE_CHECKSUM)
printf ("fei%d: Invalid EEPROM checksum %#4.4x\n", unit, sum);
/* DP83840 specific setup */
if (((pReso->eeprom[6]>>8) & 0x3f) == DP83840)
{
int reg23 = sys557mdioRead (unit, pReso->eeprom[6] & 0x1f, 23);
sys557mdioWrite (unit, pReso->eeprom[6] & 0x1f, 23, reg23 | 0x0420);
}
/* perform a system self-test. */
pReso->timeout = 16000; /* Timeout for self-test. */
/*
* We require either a cache-line sized buffer in order to be
* able to flush the cache, or use a buffer that is marked as
* non-cacheable. If the driver is configured to use a defined
* area of memory, we assume that it will be marked as
* non-cacheable. We will use that (temporarily).
*/
#ifdef KS8695P_ENET_FIXED_BUF_ADRS
pReso->pResults = (volatile INT32 *)sysEnetBufAdrs [unit];
#else
/*
* No specific area specified, so we assume that cacheDmaMalloc() will
* return a pointer to a suitable area. If the data cache is on,
* this will be page-aligned, but if the data cache is off, then we
* will just get whatever malloc returns.
*/
if (testbuf = cacheDmaMalloc (32), testbuf == 0)
{
printf("fei%d cacheDmaMalloc failed\n", unit);
return ERROR;
}
pReso->pResults = (volatile INT32 *)testbuf;
#endif /* KS8695P_ENET_FIXED_BUF_ADRS */
/* The chip requires the results buffer to be 16-byte aligned. */
pReso->pResults = (volatile INT32 *)
((((int) pReso->pResults) + 0xf) & ~0xf);
/* initialise results buffer */
pReso->pResults[0] = 0;
pReso->pResults[1] = -1;
/* Issue the self-test command */
#ifdef KS8695P_ENET_FIXED_BUF_ADRS
/* If fixed address specified, no address conversion will be required */
#ifdef IO_MEM_MAPPING
sysOutLong (pReso->iobaseCsr + SCB_PORT, (int)pReso->pResults | 1);
#else
sysOutLong (pReso->membaseCsr + SCB_PORT, (int)pReso->pResults | 1);
#endif
#else /* KS8695P_ENET_FIXED_BUF_ADRS */
/*
* If using cacheDmaMalloc() it will return a "low-alias" address in
* SDRAM, and this will need converting to a "high-alias"
* address, so it can be accessed from the PCI bus.
*/
#ifdef IO_MEM_MAPPING
sysOutLong (pReso->iobaseCsr + SCB_PORT,
sys557CpuToPci(unit, (int)pReso->pResults) | 1);
#else
sysOutLong (pReso->membaseCsr + SCB_PORT,
sys557CpuToPci(unit, (int)pReso->pResults) | 1);
#endif
#endif /* KS8695P_ENET_FIXED_BUF_ADRS */
/* wait for results */
do
{
sysDelay(); /* cause a delay of at least an I/O cycle */
} while ((pReso->pResults[1] == -1) && (--pReso->timeout >= 0));
pReso->boardType = PRO100B; /* note that it is now initialised */
/* Save results so we can refer to them again later */
pReso->str[0] = pReso->pResults[0];
pReso->str[1] = pReso->pResults[1];
#ifndef KS8695P_ENET_FIXED_BUF_ADRS
cacheDmaFree (testbuf);
#endif
pReso->pResults = pReso->str;
} /* if (pReso->boardType == PRO100B) */
/* initialise the board information structure */
/* 05/13/2004 pcd
pBoard->vector = IVEC_TO_INUM(pReso->irq);
*/
/* used 'external interrupt 0' as PCI interrupt */
pBoard->vector = INT_LVL_EXTI0S ;
#ifdef IO_MEM_MAPPING
pBoard->baseAddr = pReso->iobaseCsr;
#else
pBoard->baseAddr = pReso->membaseCsr;
#endif
for (ix = 0, iy = 0; ix < 3; ix++)
{
pBoard->enetAddr[iy++] = pReso->eeprom[ix] & 0xff;
pBoard->enetAddr[iy++] = (pReso->eeprom[ix] >> 8) & 0xff;
}
pBoard->intEnable = sys557IntEnable;
pBoard->intDisable = sys557IntDisable;
pBoard->intAck = sys557IntAck;
/* install address conversion routines for driver, if appropriate */
#ifndef KS8695P_ENET_FIXED_BUF_ADRS
pBoard->sysLocalToBus = sys557CpuToPci;
pBoard->sysBusToLocal = sys557PciToCpu;
#else
pBoard->sysLocalToBus = NULL;
pBoard->sysBusToLocal = NULL;
#endif
#ifdef FEI_10MB
pBoard->phySpeed = NULL;
pBoard->phyDpx = NULL;
#endif
/* 05/13/2004 pcd */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -