📄 sysgei82543end.c
字号:
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 = 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) sys1000NsDelay; pBoard->delayUnit = 1000; /* 1000 ns */ /* BSP specific * phyDelayRtn is used as a delay function for PHY detection, if not set, * taskDelay will be used. */ pBoard->phyDelayRtn = (FUNCPTR) sys1000NsDelay; 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 physical 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 * actually reflects a system physical memory back to the system memory * address. The sysBusToLocal here in this driver is NOT used for mapping * PCI device's memory (e.g. PCI device's control/status registers) * to the host address space. */ pBoard->sysLocalToBus = NULL; /* for 1:1 mapping */ pBoard->sysBusToLocal = NULL; /* for 1:1 mapping */ /* specify the interrupt connect/disconnect routines to be used */ pBoard->intConnect = (FUNCPTR) intConnect; pBoard->intDisConnect = (FUNCPTR) NULL; /* get the ICW1 and ICW2 stored in EEPROM */ pBoard->eeprom_icw1 = pReso->eeprom_icw1; pBoard->eeprom_icw2 = pReso->eeprom_icw2; /* copy Ether address */ memcpy (&pBoard->enetAddr[0], &(pReso->enetAddr[0]), ETHER_ADDRESS_SIZE); /* we finish adaptor initialization */ pReso->iniStatus = OK; /* enable adaptor interrupt */ intEnable (pRsrc->irq); /* show the card info */ sys543Show(0); return (OK); }/*************************************************************************** sysGei82546DynaTimerSetup - setup device internal timer value dynamically** This routine will be called every 2 seconds by default if GEI_END_SET_TIMER* flag is set. The available timers to adjust include RDTR(unit of ns),* RADV(unit of us), and ITR(unit of 256ns). Based on CPU's and/or tasks'* usage on system, user can tune the device's performance dynamically.* This routine would be called in the tNetTask context, and is only* available for 82540/82545/82546 MACs. Any timer value greater than* 0xffff won't be used to change corresponding timer register.** RETURNS: TRUE if timer value should change, or FALSE*/LOCAL BOOL sysGei82546DynaTimerSetup ( ADAPTOR_INFO * pBoard /* board information for the GEI driver */ ) { /* user's specific code to decide what value should be used. * For example, depending on * 1: CPU usage on system and/or, * 2: specific application task's usage and/or, * 3: RX/TX packet processing per second, and/or * 4: RX/TX interrupt counter per second, and/or * 5: RX packet processing for each calling gei82543RxTxIntHandle(), * users can choose optimal timer values from a predefined table to * reduce interrupt rates. The statistic of 3,4,and 5 items above * may be obtained from pBoard->devDrvStat. * * NOTE: * ITR: Interrupt throttling register (unit of 256ns) * inter-interrupt delay between chip's interrupts * * RADV: receive interrupt absolute delay timer register (unit of 1.024us) * a RX interrupt will absolutely occur at this defined value * after the first packet is received. * * RDTR: receive delay timer register (unit of 1.024us) * a RX interrupt will occur if device has not received a subsequent * packet within this defined value. */ /* value > 0xffff would not be used for corresponding timer registers */ /* pBoard->devTimerUpdate.rdtrVal = 0xffffffff; /@ unit of 1.024ns */ /* pBoard->devTimerUpdate.radvVal = 0xffffffff; /@ unit of 1.024us */ /* pBoard->devTimerUpdate.itrVal = 0xffffffff; /@ unit of 256 ns */ /* pBoard->devTimerUpdate.watchDogIntVal = 2; /@ 2 second default */ /* return TRUE; */ return FALSE; }/*************************************************************************** sysGei82546InitTimerSetup - initially setup device internal timer value** The device's internal timers include RDTR(unit of ns),* RADV(unit of us), and ITR(unit of 256ns). The function is* called before device starts up, and it is only available for* 82540/82545/82546 MACs. Any timer value greater than 0xffff will* be discarded.** RETURNS: TRUE if timer value should change, or FALSE*/LOCAL BOOL sysGei82546InitTimerSetup ( ADAPTOR_INFO * pBoard /* board information for the GEI driver */ ) { /* value > 0xffff would not change corresponding timer registers */ /* pBoard->devTimerUpdate.rdtrVal = 0xffffffff; /@ unit of 1.024ns */ /* pBoard->devTimerUpdate.radvVal = 0xffffffff; /@ unit of 1.024us */ /* pBoard->devTimerUpdate.itrVal = 0xffffffff; /@ unit of 256 ns */ /* pBoard->devTimerUpdate.watchDogIntVal = 2; /@ 2 second default */ /* return TRUE; */ return FALSE; }/*************************************************************************** sys543eepromReadBits - read bits from EEPROM** This routine reads bit data from EEPROM** RETURNS: value in WORD size*/LOCAL UINT16 sys543eepromReadBits ( int unit, int bitsNum ) { int count; int ix; UINT16 val = 0; UINT16 reqBit = 0; PCI_BOARD_RESOURCE * pRsrc; pRsrc = &geiPciResources[unit]; if (pRsrc->boardType == PRO1000_546_BOARD) reqBit = EECD_REQ_BIT; for (ix = 0; ix < bitsNum; ix++) { /* raise the clk */ GEI_SYS_WRITE_REG(unit, INTEL_82543GC_EECD, (EECD_CS_BIT | EECD_SK_BIT | reqBit)); /* wait 2000ns */ for (count = 0; count < 3; count++) sysDelay (); val = ( val << 1) | ((GEI_SYS_READ_REG(unit, INTEL_82543GC_EECD) & EECD_DO_BIT)? 1 : 0); /* lower the clk */ GEI_SYS_WRITE_REG(unit, INTEL_82543GC_EECD, (EECD_CS_BIT | reqBit)); /* wait 2000 ns */ for (count = 0; count < 3; count++) sysDelay (); } return (val); }/*************************************************************************** sys543eepromWriteBits - write bits out to EEPROM** This routine writes bits out to EEPROM** RETURNS: N/A*/LOCAL void sys543eepromWriteBits ( int unit, UINT16 value, UINT16 bitNum ) { volatile UINT16 data; UINT16 reqBit = 0; PCI_BOARD_RESOURCE * pRsrc; pRsrc = &geiPciResources[unit]; if (pRsrc->boardType == PRO1000_546_BOARD) reqBit = EECD_REQ_BIT; if (bitNum == 0) return; while (bitNum--) { data = (value & (0x1 << bitNum )) ? EECD_DI_BIT : 0; data |= EECD_CS_BIT; /* write the data */ GEI_SYS_WRITE_REG(unit, INTEL_82543GC_EECD, (data | reqBit)); /* wait 2000ns */ sysUsDelay (2); /* raise the clk */ GEI_SYS_WRITE_REG(unit, INTEL_82543GC_EECD, (data | EECD_SK_BIT | reqBit)); /* wait 2000ns */ sysUsDelay (2); /* lower the clk */ GEI_SYS_WRITE_REG(unit, INTEL_82543GC_EECD, (data | reqBit)); /* wait 2000ns */ sysUsDelay (2); } }/*************************************************************************** sys543eepromReadWord - Read a word from EEPROM** RETURNS: value in WORD size*/LOCAL UINT16 sys543eepromReadWord ( int unit, UINT32 index ) { UINT16 val; UINT32 tmp; PCI_BOARD_RESOURCE * pRsrc; pRsrc = &geiPciResources[unit]; if (pRsrc->boardType == PRO1000_546_BOARD) { int ix = 0; BOOL accessGet = FALSE; tmp = GEI_SYS_READ_REG(unit, INTEL_82543GC_EECD); tmp |= EECD_REQ_BIT; /* request EEPROM access */ GEI_SYS_WRITE_REG(unit, INTEL_82543GC_EECD, tmp); do { /* wait 2us */ sysUsDelay (3); if ((tmp = GEI_SYS_READ_REG(unit, INTEL_82543GC_EECD)) & EECD_GNT_BIT) { accessGet = TRUE; break; } } while (ix++ < 500000); if (!accessGet) { /* timeout in a second */ printf ("ERROR: timeout to grant access to gei unit %d EEPROM\n", unit); return 0; } } if (index >= geiResources[(unit)].eepromSize) { printf ("ERROR: gei unit %d Invalid index %d to EEPROM\n", unit, index); return 0; } tmp = GEI_SYS_READ_REG(unit, INTEL_82543GC_EECD); GEI_SYS_WRITE_REG(unit, INTEL_82543GC_EECD, EECD_CS_BIT); /* wait 1000ns */ sysUsDelay (2); /* write the opcode out */ sys543eepromWriteBits (unit, EEPROM_READ_OPCODE, EEPROM_CMD_BITS); /* write the index out */ if (geiResources[(unit)].eepromSize == 64) sys543eepromWriteBits (unit, index, 6); else if (geiResources[(unit)].eepromSize == 256) sys543eepromWriteBits (unit, index, 8); else /* unsupported, but still try 64 words */ { sys543eepromWriteBits (unit, index, 6); printf ("ERROR: gei unit %d unsupported EEPROM size\n", unit); } GEI_SYS_READ_REG(unit, INTEL_82543GC_EECD); /* read the data */ val = sys543eepromReadBits (unit, EEPROM_DATA_BITS); /* clean up access to EEPROM */ if (pRsrc->boardType == PRO1000_546_BOARD) tmp &= ~(EECD_DI_BIT | EECD_DO_BIT | EECD_CS_BIT | EECD_REQ_BIT); else tmp &= ~(EECD_DI_BIT | EECD_DO_BIT | EECD_CS_BIT); GEI_SYS_WRITE_REG(unit, INTEL_82543GC_EECD, tmp); return val; }/*************************************************************************** sys543EtherAdrGet - Get Ethernet address from EEPROM** This routine get an Ethernet address from EEPROM** RETURNS: OK or ERROR*/LOCAL STATUS sys543EtherAdrGet (
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -