📄 sysend.c
字号:
#ifndef INTEGRATOR_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 INTEGRATOR_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;
#ifdef INTEGRATOR_ENET_CHECK_BUFFERS
if (((UINT32)pReso->pResults) < INTEGRATOR_HDR_SSRAM_SIZE)
{
printf("fei%d: cacheDmaMalloc() returned address in \
header card SSRAM\n", unit);
return ERROR;
}
#endif /* INTEGRATOR_ENET_CHECK_BUFFERS */
#endif /* INTEGRATOR_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 INTEGRATOR_ENET_FIXED_BUF_ADRS
/* If fixed address specified, no address conversion will be required */
sysOutLong (pReso->iobaseCsr + SCB_PORT, (int)pReso->pResults | 1);
#else /* INTEGRATOR_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.
*/
sysOutLong (pReso->iobaseCsr + SCB_PORT,
sys557CpuToPci(unit, (int)pReso->pResults) | 1);
#endif /* INTEGRATOR_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 INTEGRATOR_ENET_FIXED_BUF_ADRS
cacheDmaFree (testbuf);
#endif
pReso->pResults = pReso->str;
}
/* initialise the board information structure */
pBoard->vector = IVEC_TO_INUM(pReso->irq);
pBoard->baseAddr = pReso->iobaseCsr;
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 INTEGRATOR_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
return (OK);
}
/*******************************************************************************
*
* sys557IntAck - acknowledge an 82557 interrupt
*
* This routine performs any 82557 interrupt acknowledge that may be
* required. This typically involves an operation to some interrupt
* control hardware.
*
* This routine gets called from the 82557 driver's interrupt handler.
*
* This routine assumes that the PCI configuration information has already
* been setup.
*
* RETURNS: OK, or ERROR if the interrupt could not be acknowledged.
*/
LOCAL STATUS sys557IntAck
(
int unit /* unit number */
)
{
FEI_RESOURCE * pReso = &feiResources [unit];
switch (pReso->boardType)
{
case PRO100B: /* handle PRO100B LAN Adapter */
/* no addition work necessary for the PRO100B */
break;
default:
return (ERROR);
}
return (OK);
}
/*******************************************************************************
*
* sys557IntEnable - enable 82557 interrupts
*
* This routine enables 82557 interrupts. This may involve operations on
* interrupt control hardware.
*
* The 82557 driver calls this routine throughout normal operation to terminate
* critical sections of code.
*
* This routine assumes that the PCI configuration information has already
* been setup.
*
* RETURNS: OK, or ERROR if interrupts could not be enabled.
*/
LOCAL STATUS sys557IntEnable
(
int unit /* unit number */
)
{
FEI_RESOURCE * pReso = &feiResources [unit];
switch (pReso->boardType)
{
case PRO100B: /* handle PRO100B LAN Adapter */
intEnable (pReso->irq);
break;
default:
return (ERROR);
}
return (OK);
}
/*******************************************************************************
*
* sys557IntDisable - disable 82557 interrupts
*
* This routine disables 82557 interrupts. This may involve operations on
* interrupt control hardware.
*
* The 82557 driver calls this routine throughout normal operation to enter
* critical sections of code.
*
* This routine assumes that the PCI configuration information has already
* been setup.
*
* RETURNS: OK, or ERROR if interrupts could not be disabled.
*/
LOCAL STATUS sys557IntDisable
(
int unit /* unit number */
)
{
FEI_RESOURCE * pReso = &feiResources [unit];
switch (pReso->boardType)
{
case PRO100B: /* handle PRO100B LAN Adapter */
intDisable (pReso->irq);
break;
default:
return (ERROR);
}
return (OK);
}
/*******************************************************************************
*
* sys557eepromRead - read a word from the 82557 EEPROM
*
* RETURNS: the EEPROM data word read in.
*/
LOCAL UINT16 sys557eepromRead
(
int unit, /* unit number */
int location /* address of word to be read */
)
{
UINT32 iobase = feiResources[unit].iobaseCsr;
UINT16 retval = 0;
UINT16 dataval;
volatile UINT16 dummy;
int ix;
sysOutWord (iobase + SCB_EEPROM, EE_CS); /* enable EEPROM */
/* write the READ opcode */
for (ix = EE_CMD_BITS - 1; ix >= 0; ix--)
{
dataval = (EE_CMD_READ & (1 << ix)) ? EE_DI : 0;
sysOutWord (iobase + SCB_EEPROM, EE_CS | dataval);
sysDelay (); /* delay for one I/O READ cycle */
sysOutWord (iobase + SCB_EEPROM, EE_CS | dataval | EE_SK);
sysDelay (); /* delay for one I/O READ cycle */
sysOutWord (iobase + SCB_EEPROM, EE_CS | dataval);
sysDelay (); /* delay for one I/O READ cycle */
}
/* write the location */
for (ix = EE_ADDR_BITS - 1; ix >= 0; ix--)
{
dataval = (location & (1 << ix)) ? EE_DI : 0;
sysOutWord (iobase + SCB_EEPROM, EE_CS | dataval);
sysDelay (); /* delay for one I/O READ cycle */
sysOutWord (iobase + SCB_EEPROM, EE_CS | dataval | EE_SK);
sysDelay (); /* delay for one I/O READ cycle */
sysOutWord (iobase + SCB_EEPROM, EE_CS | dataval);
sysDelay (); /* delay for one I/O READ cycle */
dummy = sysInWord (iobase + SCB_EEPROM);
}
if ((dummy & EE_DO) == 0) /* dummy read */
;
/* read the data */
for (ix = EE_DATA_BITS - 1; ix >= 0; ix--)
{
sysOutWord (iobase + SCB_EEPROM, EE_CS | EE_SK);
sysDelay (); /* delay for one I/O READ cycle */
retval = (retval << 1) |
((sysInWord (iobase + SCB_EEPROM) & EE_DO) ? 1 : 0);
sysOutWord (iobase + SCB_EEPROM, EE_CS);
sysDelay (); /* delay for one I/O READ cycle */
}
sysOutWord (iobase + SCB_EEPROM, 0x00); /* disable EEPROM */
return (retval);
}
/*******************************************************************************
*
* sys557mdioRead - read MDIO
*
* RETURNS: read value
*/
LOCAL UINT32 sys557mdioRead
(
int unit, /* unit number */
int phyId, /* PHY ID */
int location /* location to read */
)
{
UINT32 iobase = feiResources[unit].iobaseCsr;
int timeout = 64*4; /* <64 usec. to complete, typ 27 ticks */
int val;
sysOutLong (iobase + SCB_MDI, 0x08000000 | (location<<16) | (phyId<<21));
do {
sysDelay (); /* delay for one I/O READ cycle */
val = sysInLong (iobase + SCB_MDI);
if (--timeout < 0)
printf ("sys557mdioRead() timed out with val = %8.8x.\n", val);
} while (! (val & 0x10000000));
return (val & 0xffff);
}
/*******************************************************************************
*
* sys557mdioWrite - write MDIO
*
* RETURNS: write value
*/
LOCAL UINT32 sys557mdioWrite
(
int unit, /* unit number */
int phyId, /* PHY ID */
int location, /* location to write */
int value /* value to write */
)
{
UINT32 iobase = feiResources[unit].iobaseCsr;
int timeout = 64*4; /* <64 usec. to complete, typ 27 ticks */
int val;
sysOutLong (iobase + SCB_MDI,
0x04000000 | (location<<16) | (phyId<<21) | value);
do {
sysDelay (); /* delay for one I/O READ cycle */
val = sysInLong (iobase + SCB_MDI);
if (--timeout < 0)
printf ("sys557mdioWrite() timed out with val = %8.8x.\n", val);
} while (! (val & 0x10000000));
return (val & 0xffff);
}
/*******************************************************************************
*
* sys557Show - shows 82557 configuration
*
* This routine shows the (Intel Pro Express 100) configuration
*
* RETURNS: N/A
*/
void sys557Show
(
int unit /* unit number */
)
{
FEI_RESOURCE * pReso = &feiResources [unit];
UINT32 iobase = pReso->iobaseCsr;
UCHAR etheraddr[6];
int ix;
int iy;
if (unit > INTEGRATOR_MAX_END_DEVS)
{
printf ("Illegal unit number %d\n", unit);
return;
}
if (pReso->boardType != PRO100B)
{
printf ("Unit %d not an FEI device\n", unit);
return;
}
for (ix = 0, iy = 0; ix < 3; ix++)
{
etheraddr[iy++] = pReso->eeprom[ix];
etheraddr[iy++] = pReso->eeprom[ix] >> 8;
}
printf ("fei%d: Intel EtherExpress Pro 10/100 at %#8x ", unit, iobase);
for (ix = 0; ix < 5; ix++)
printf ("%2.2X:", etheraddr[ix]);
printf ("%2.2X\n", etheraddr[ix]);
printf ("CSR mem base address = %x, Flash mem base address = %x\n",
pReso->membaseCsr, pReso->membaseFlash);
if (pReso->eeprom[3] & 0x03)
printf ("Receiver lock-up bug exists -- enabling work-around.\n");
printf ("Board assembly %4.4x%2.2x-%3.3d, Physical connectors present:",
pReso->eeprom[8], pReso->eeprom[9]>>8, pReso->eeprom[9] & 0xff);
for (ix = 0; ix < 4; ix++)
if (pReso->eeprom[5] & (1 << ix))
printf ("%s", connectors [ix]);
printf ("\nPrimary interface chip %s PHY #%d.\n",
phys[(pReso->eeprom[6]>>8)&15], pReso->eeprom[6] & 0x1f);
if (pReso->eeprom[7] & 0x0700)
printf ("Secondary interface chip %s.\n",
phys[(pReso->eeprom[7]>>8)&7]);
#if FALSE /* we don't show PHY specific info at this time */
/* ToDo: Read and set PHY registers through MDIO port. */
for (ix = 0; ix < 2; ix++)
printf ("MDIO register %d is %4.4x.\n",
ix, sys557mdioRead (unit, pReso->eeprom[6] & 0x1f, ix));
for (ix = 5; ix < 7; ix++)
printf ("MDIO register %d is %4.4x.\n",
ix, sys557mdioRead (unit, pReso->eeprom[6] & 0x1f, ix));
printf ("MDIO register %d is %4.4x.\n",
25, sys557mdioRead (unit, pReso->eeprom[6] & 0x1f, 25));
#endif /* FALSE */
if (pReso->timeout < 0)
{ /* Test optimized out. */
printf ("Self test failed, status %8.8x:\n"
" Failure to initialize the 82557.\n"
" Verify that the card is a bus-master capable slot.\n",
pReso->pResults[1]);
}
else
{
printf ("General self-test: %s.\n"
" Serial sub-system self-test: %s.\n"
" Internal registers self-test: %s.\n"
" ROM checksum self-test: %s (%#8.8x).\n",
pReso->pResults[1] & 0x1000 ? "failed" : "passed",
pReso->pResults[1] & 0x0020 ? "failed" : "passed",
pReso->pResults[1] & 0x0008 ? "failed" : "passed",
pReso->pResults[1] & 0x0004 ? "failed" : "passed",
pReso->pResults[0]);
}
}
#endif /* INCLUDE_FEI82557END */
#endif /* INCLUDE_END */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -