?? sysfei82557end.c
字號:
/* update the board-specific resource table */ feiPciResources[feiUnits].bar[0] = memIo32; feiPciResources[feiUnits].bar[1] = ioBase; feiPciResources[feiUnits].bar[2] = flash32; feiPciResources[feiUnits].irq = irq; feiPciResources[feiUnits].irqvec = INT_NUM_GET (irq); feiPciResources[feiUnits].vendorID = vendorId; feiPciResources[feiUnits].deviceID = deviceId; feiPciResources[feiUnits].revisionID = revisionId; feiPciResources[feiUnits].boardType = boardType; /* the following support legacy interfaces and data structures */ feiPciResources[feiUnits].pciBus = pciBus; feiPciResources[feiUnits].pciDevice = pciDevice; feiPciResources[feiUnits].pciFunc = pciFunc; /* enable mapped memory and IO decoders */ pciConfigOutWord (pciBus, pciDevice, pciFunc, PCI_CFG_COMMAND, PCI_CMD_MEM_ENABLE | PCI_CMD_IO_ENABLE | PCI_CMD_MASTER_ENABLE); /* disable sleep mode */ pciConfigOutByte (pciBus, pciDevice, pciFunc, PCI_CFG_MODE, SLEEP_MODE_DIS); ++feiUnits; /* increment number of units initialized */ return (OK); }/********************************************************************************* sys557Init - prepare 82557 PCI ethernet device for initialization** This routine is expected to perform any adapter-specific or target-specific* initialization that must be done before an 82557 device is initialized* by the driver.** The 82557 drivers call this routine in the course of initializing driver* internal structures and the associated underlying physical device. The* drivers will call this routine every time there is a requirement to* [re]initialize the device.** INTERNAL* The fei82557End driver will call this function in the second pass of the* xxxEndLoad() routine.** RETURNS:* OK, or ERROR if the device could not be prepared for initialization.*/STATUS sys557Init ( int unit, /* END driver unit number */ FEI_BOARD_INFO * pBoard /* board information for the END driver */ ) { PCI_BOARD_RESOURCE * pRsrc; /* point to a board PCI resource entry */ FEI_RESOURCE * pReso; /* point to board extended resources */ /* alias BOARD_INFO <enetAddr> for a more efficient data copy */ UINT16 * const pBoardEnetAddr = (UINT16 * const)(pBoard->enetAddr); /* is there a PCI resource associated with this driver unit ? */ if (unit >= feiUnits) { /* This is an error - no physical devs available to this unit */ return ERROR; } /* associate the driver unit number with a PCI resource */ pRsrc = &feiPciResources [unit]; pReso = (FEI_RESOURCE *)(pRsrc->pExtended); /* perform one-time base initialization ? */ if (pReso->initDone == FALSE) { /* read the configuration in EEPROM */ UINT16 sum = 0; UINT16 value; int ix; for (ix = 0; ix < EE_SIZE; ix++) { value = sys557eepromRead (unit, ix); pReso->eeprom[ix] = value; sum += value; } if (sum != EE_CHECKSUM) { printf ("i8255x(%d): Invalid EEPROM checksum %#4.4x\n", unit, sum); } /* Handle Intel 82801BA/M ICH2 Errata ? */ if (pRsrc->boardType == TYPE_I82562ET_PCI) { value = pReso->eeprom[0x0A]; if (value & 0x02) { puts ("Found Intel 82562 with Standby Enable set. " "Fixing and rebooting ..."); sys557eepromWrite (unit, 0x0A, (value & ~0x02)); sys557eepromChecksumSet (unit); taskDelay (5 * sysClkRateGet ()); sysToMonitor (BOOT_COLD); } } /* NS DP83840 Physical Layer Device specific setup */ if (((pReso->eeprom[6] >> 8) & 0x3f) == DP83840) { UINT16 reg23 = sys557mdioRead (unit, pReso->eeprom[6] & 0x1f, 23); sys557mdioWrite (unit, pReso->eeprom[6] & 0x1f, 23, reg23 | 0x0420); } /* perform system self-test */ pReso->timeout = 16000; /* self-test timeout */ pReso->pResults = (volatile INT32 *)((((int) pReso->str) + 0xf) & ~0xf); pReso->pResults[0] = 0; pReso->pResults[1] = -1; sysOutLong ((pRsrc->bar[1]) + SCB_PORT, (int)(pReso->pResults) | 1); do { sysDelay (); /* delay for one IO read cycle */ } while ((pReso->pResults[1] == -1) && (--(pReso->timeout) >= 0)); /* bind driver-specific PCI interrupt connection routines */ feiEndIntConnect = (FUNCPTR) pciIntConnect; feiEndIntDisconnect = (FUNCPTR) pciIntDisconnect; pReso->initDone = TRUE; } /* initialize the board information structure */ /* pass along the PCI Device ID to support the fix for SPR# 69298 */ pBoard->spare1 = pRsrc->deviceID; pBoard->vector = INT_NUM_GET (pRsrc->irq); pBoard->baseAddr = pRsrc->bar[0]; /* copy the Ethernet address to the board information structure */ pBoardEnetAddr[0] = pReso->eeprom[0]; pBoardEnetAddr[1] = pReso->eeprom[1]; pBoardEnetAddr[2] = pReso->eeprom[2]; pBoard->intEnable = sys557IntEnable; pBoard->intDisable = sys557IntDisable; pBoard->intAck = sys557IntAck; pBoard->sysLocalToBus = NULL; pBoard->sysBusToLocal = NULL; #ifdef FEI_10MB pBoard->phySpeed = NULL; pBoard->phyDpx = NULL;#endif return (OK); }/********************************************************************************* sys557IntAck - acknowledge an 82557 PCI ethernet device 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 /* END driver unit number */ ) { return (OK); }/********************************************************************************* sys557IntEnable - enable 82557 PCI ethernet device 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 /* END driver unit number */ ) { return ((unit >= feiUnits) ? ERROR : (sysIntEnablePIC (feiPciResources[unit].irq))); }/********************************************************************************* sys557IntDisable - disable 82557 PCI ethernet device 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 /* END driver unit number */ ) { return ((unit >= feiUnits) ? ERROR : (sysIntDisablePIC (feiPciResources[unit].irq))); }/********************************************************************************* sys557eepromRead - read a word from 82557 PCI ethernet device EEPROM** RETURNS: The EEPROM data word read in.** NOMANUAL*/LOCAL UINT16 sys557eepromRead ( int unit, /* END driver unit number */ int location /* address of word to read */ ) { UINT16 iobase = (feiPciResources[unit].bar[1]); UINT16 retval = 0; UINT16 dataval; int ix; volatile UINT16 dummy; /* enable EEPROM */ sysOutWord (iobase + SCB_EEPROM, EE_CS); /* 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 IO READ cycle */ sysOutWord (iobase + SCB_EEPROM, EE_CS | dataval | EE_SK); sysDelay (); /* delay for one IO READ cycle */ sysOutWord (iobase + SCB_EEPROM, EE_CS | dataval); sysDelay (); /* delay for one IO 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 IO READ cycle */ sysOutWord (iobase + SCB_EEPROM, EE_CS | dataval | EE_SK); sysDelay (); /* delay for one IO READ cycle */ sysOutWord (iobase + SCB_EEPROM, EE_CS | dataval); sysDelay (); /* delay for one IO 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 IO READ cycle */ retval = (retval << 1) | ((sysInWord (iobase + SCB_EEPROM) & EE_DO) ? 1 : 0); sysOutWord (iobase + SCB_EEPROM, EE_CS); sysDelay (); /* delay for one IO READ cycle */ } /* disable EEPROM */ sysOutWord (iobase + SCB_EEPROM, 0x00); return (retval); }/********************************************************************************* sys557eepromWrite - write a word to 82557 PCI ethernet device EEPROM** RETURNS: N/A** NOMANUAL*/LOCAL void sys557eepromWrite ( int unit, /* END driver unit number */ int location, /* address of word to write */ UINT16 data /* the data to write */ ) { UINT16 iobase = (feiPciResources[unit].bar[1]); int i; int j; /* Enable the EEPROM for writing */ sysOutWord (iobase + SCB_EEPROM, FEI_EECS); sys557eepromWriteBits (unit, 0x4, 3); sys557eepromWriteBits (unit, 0x03 << (EE_SIZE_BITS - 2), EE_SIZE_BITS); sysOutWord (iobase + SCB_EEPROM, 0); sysDelay (); /* (1) Activite EEPROM by writing '1' to the EECS bit */ sysOutWord (iobase + SCB_EEPROM, FEI_EECS); /* (2) Write the WRITE Opcode */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -