📄 sysgei82543end.c
字号:
* * BAR2: if BAR0[2:1] == 01b, optional flash memory base * if BAR0[2:1] == 00b, behaves as BAR-1 when BAR-0 is * a 32-bit value */ pciConfigInLong (pciBus, pciDevice, pciFunc, PCI_CFG_BASE_ADDRESS_0, &memBaseLo); pReso->adr64 = ((memBaseLo & BAR0_64_BIT) == BAR0_64_BIT) ? TRUE : FALSE; if (pReso->adr64) { pciConfigInLong (pciBus, pciDevice, pciFunc, PCI_CFG_BASE_ADDRESS_1, &memBaseHi); pciConfigInLong (pciBus, pciDevice, pciFunc, PCI_CFG_BASE_ADDRESS_2, &flashBase); } else { memBaseHi = 0x0; pciConfigInLong (pciBus, pciDevice, pciFunc, PCI_CFG_BASE_ADDRESS_1, &flashBase); } memBaseLo &= PCI_MEMBASE_MASK; flashBase &= PCI_MEMBASE_MASK; /* map the memory-mapped IO (CSR) space into host CPU address space */ if (sysMmuMapAdd ((void *)(PCI_MEMIO2LOCAL(memBaseLo)), GEI_MEMSIZE_CSR, VM_STATE_MASK_FOR_ALL, VM_STATE_FOR_PCI) == ERROR) { return (ERROR); } /* get the device's interrupt line (IRQ) number */ pciConfigInByte (pciBus, pciDevice, pciFunc, PCI_CFG_DEV_INT_LINE, &irq); /* update the board-specific resource tables */ pReso->memBaseLow = memBaseLo; pReso->memBaseHigh = memBaseHi; pReso->flashBase = flashBase; geiPciResources[geiUnits].irq = irq; geiPciResources[geiUnits].irqvec = INT_NUM_GET (irq); geiPciResources[geiUnits].vendorID = vendorId; geiPciResources[geiUnits].deviceID = deviceId; geiPciResources[geiUnits].revisionID = revisionId; geiPciResources[geiUnits].boardType = boardType; /* the following support legacy interfaces and data structures */ geiPciResources[geiUnits].pciBus = pciBus; geiPciResources[geiUnits].pciDevice = pciDevice; geiPciResources[geiUnits].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); ++geiUnits; /* increment number of units initialized */ return (OK); }/******************************************************************************** sysGei8254xEndLoad - create load string and load a gei driver.** This routine will be invoked by the MUX for the purpose of loading an* gei82543End (gei) device with initial parameters. This routine is* constructed as an interface wrapper for the driver load routine. Thus,* the arguments and return values are consistent with any xxxEndLoad()* routine defined for an END driver and the MUX API.** INTERNAL* The muxDevLoad() operation calls this routine twice. A zero length* <pParamStr> parameter string indicates that this is the first time* through this routine. The driver load routine should return the* driver name in <pParamStr>.** On the second pass though this routine, the initialization parameter* string is constructed. Note that on the second pass, the <pParamStr>* consists of a colon-delimeted END device unit number and rudimentary* initialization string (often empty) constructed from entries in the* BSP END Device Table such that:** <pParamStr> = "<unit>:<default initialization string>"** In the process of building the rest of <pParamStr>, the prepended unit* number must be preserved and passed to the driver load routine. The* <default initialization string> portion mentioned above is discarded,* but future versions of this routine may use it.** The complete gei82543End driver load string has format:** <unit>:<shMemBase>:<shMemSize>:<rxDesNum>:<txDesNum>:<usrFlags>:* <offset>:<mtu>** RETURNS: An END object pointer, or NULL on error, or 0 and the name of the* device if the <pParamStr> was NULL.** SEE ALSO: gei82543EndLoad()*/END_OBJ * sysGei8254xEndLoad ( char * pParamStr, /* ptr to initialization parameter string */ void * unused /* unused optional argument */ ) { END_OBJ * pEnd; char paramStr [END_INIT_STR_MAX]; if (strlen (pParamStr) == 0) { /* PASS (1) * The driver load routine returns the driver name in <pParamStr>. */ pEnd = gei82543EndLoad (pParamStr); } else { /* PASS (2) * The END <unit> number is prepended to <pParamStr>. Construct * the rest of the driver load string based on physical devices * discovered in sys543PciInit(). When this routine is called * to process a particular END <unit> number, use the END <unit> as * an index into the PCI "resources" table to build the driver * parameter string. */ GEI_RESOURCE * pReso; char * holder = NULL; int unit = atoi (strtok_r (pParamStr, ":", &holder)); /* is there a PCI resource associated with this END unit ? */ if (unit >= geiUnits) { return NULL; } pReso = (GEI_RESOURCE *)(geiPciResources[unit].pExtended); /* finish off the initialization parameter string */ sprintf (paramStr,"%d:0x%x:0x%x:0x%x:0x%x:0x%x:%d:%d", unit, /* END unit number */ pReso->shMemBase, /* share memory base */ pReso->shMemSize, /* share memory size */ pReso->rxDesNum, /* RX Descriptor Number*/ pReso->txDesNum, /* TX Descriptor Number*/ pReso->usrFlags, /* user's flags */ GEI_OFFSET_VALUE, /* offset value */ GEI_JUMBO_MTU_VALUE /* mtu value */ ); if ((pEnd = gei82543EndLoad (paramStr)) == (END_OBJ *)NULL) { printf ("ERROR: sysGei8254xEndLoad fails to load gei %d\n", unit); } } return (pEnd); }/******************************************************************************* sys82543BoardInit - Adaptor initialization for 8254x chip** This routine is expected to perform any adapter-specific or target-specific* initialization that must be done prior to initializing the 8254x chip.** The 82543 driver calls this routine from the driver load routine before* any other routines.** RETURNS: OK or ERROR*/STATUS sys82543BoardInit ( int unit, /* unit number */ ADAPTOR_INFO * pBoard /* board information for the GEI driver */ ) { PCI_BOARD_RESOURCE * pRsrc; GEI_RESOURCE * pReso; BOOL lanB = FALSE; /* sanity check */ if (unit >= geiUnits) return (ERROR); pRsrc = &geiPciResources[unit]; pReso = (GEI_RESOURCE *)(pRsrc->pExtended); if (pRsrc->boardType != PRO1000_543_BOARD && pRsrc->boardType != PRO1000_544_BOARD && pRsrc->boardType != PRO1000_546_BOARD) return ERROR; if (pRsrc->boardType == PRO1000_546_BOARD) { UINT32 eecd; UINT16 devId; if (!((eecd = GEI_SYS_READ_REG(unit, INTEL_82543GC_EECD)) & EECD_PRES_BIT)) { printf ("ERROR: gei unit %d eeprom not presented\n", unit); return ERROR; } pReso->eepromSize = (eecd & EECD_SIZE_BIT)? 256 : 64; /* detect if this is one of 82546EB dual ports */ pciConfigInWord (pRsrc->pciBus, pRsrc->pciDevice, pRsrc->pciFunc, PCI_CFG_DEVICE_ID, &devId); if (devId == PRO1000_546_PCI_DEVICE_ID_XT || devId == PRO1000_546_PCI_DEVICE_ID_MF) { UINT8 headerType; pciConfigInByte (pRsrc->pciBus, pRsrc->pciDevice, pRsrc->pciFunc, PCI_CFG_HEADER_TYPE, &headerType); if (headerType == 0x80) lanB = (pRsrc->pciFunc == 1)? TRUE : FALSE; else if (pRsrc->pciFunc != 0) { printf ("Error in detecting 82546 dual port: header type =%2d, pci func=%2d\n", (UINT32)headerType, (UINT32)(pRsrc->pciFunc)); } } } /* perform EEPROM checksum */ if (sys543eepromCheckSum (unit) != OK) { printf ("ERROR: gei unit=%d, EEPROM checksum error!\n", unit); } /* get the Ethernet Address from eeprom */ if (sys543EtherAdrGet (unit) == OK) { if (pRsrc->boardType == PRO1000_546_BOARD && lanB == TRUE) { int ix; /* update LANB address */ for (ix = 5; ix >= 0; ix--) { if (pReso->enetAddr[ix] != 0xff) { pReso->enetAddr[ix]++; break; } else pReso->enetAddr[ix] = 0; } } } else printf ("ERROR: gei unit=%d, Invalid Ethernet Address!\n", unit); /* get the initialization control word 1 (ICW1) in EEPROM */ pReso->eeprom_icw1 = sys543eepromReadWord (unit, EEPROM_ICW1); /* get the initialization control word 2 (ICW2) in EEPROM */ pReso->eeprom_icw2 = sys543eepromReadWord (unit, EEPROM_ICW2); /* initializes the board information structure */ pBoard->boardType = pRsrc->boardType; pBoard->vector = INT_NUM_GET((pRsrc->irq)); pBoard->regBaseHigh = pReso->memBaseHigh; pBoard->regBaseLow = PCI_MEMIO2LOCAL(pReso->memBaseLow); pBoard->flashBase = PCI_MEMIO2LOCAL(pReso->flashBase); pBoard->adr64 = pReso->adr64; pBoard->intEnable = sys543IntEnable; pBoard->intDisable = sys543IntDisable; pBoard->intAck = sys543IntAck; /* Intel Copper-based adapter is based on GMII interface */ pBoard->phyType = GEI_PHY_GMII_TYPE; if (pBoard->boardType == PRO1000_544_BOARD && geiResources[unit].useShortCable) { miiPhyOptFuncSet ((FUNCPTR)sys544PhyPreInit); } pBoard->phySpecInit = sys543PhySpecRegsInit; /* BSP specific * delayFunc is BSP specific. We prefer a higher time resolution delay * delayUnit is the time of ns elapsed when calling delayFunc (). */ pBoard->delayFunc = (FUNCPTR) sysDelay; pBoard->delayUnit = 720; /* In x86, sysDelay() takes about 720ns */ /* BSP specific * phyDelayRtn is used as a delay function for PHY detection, if not set, * taskDelay will be used. */ pBoard->phyDelayRtn = (FUNCPTR) taskDelay; pBoard->phyMaxDelay = MII_PHY_DEF_DELAY; pBoard->phyDelayParm = 5; /* BSP/adapter specific * set the PHY address if you know it, otherwise set to zero * INTEL 82540/4/5/6-based adapters have a built-in phy with Addr of 1 */ pBoard->phyAddr = (pRsrc->boardType == PRO1000_544_BOARD || pRsrc->boardType == PRO1000_546_BOARD)? 1 : 0; /* BSP/adapter specific (for 82540/82545/82546 only) * allow users set up the device's internal timer based on their * application. sysGeiInitTimerSet() is called when the device * starts; sysGeiDynaTimerSet() is called every 2s in tNetTask if * GEI_END_SET_TIMER is set. */ if (pRsrc->boardType == PRO1000_546_BOARD) { pBoard->sysGeiDynaTimerSetup = sysGei82546DynaTimerSetup; pBoard->sysGeiInitTimerSetup = sysGei82546InitTimerSetup; } else { pBoard->sysGeiDynaTimerSetup = NULL; /* default */ pBoard->sysGeiInitTimerSetup = NULL; /* default */ } /* BSP specific * call back functions perform system physcial memory mapping in the PCI * address space. sysLocalToBus converts a system physical memory address * into the pci address space. sysBusToLocal converts a pci address which
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -