📄 sysgei82543end.c
字号:
* 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) pciIntConnect; pBoard->intDisConnect = (FUNCPTR) pciIntDisconnect; /* 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 */ sysIntEnablePIC (pRsrc->irq); 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' * usuage on system, user can tune the device's performace 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 usuage on system and/or, * 2: specific application task's usuage 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-interupt 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 */ /* retuen 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; UINT32 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 ) { int count; 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 1000ns */ for (count = 0; count < 2; count++) sysDelay (); /* raise the clk */ GEI_SYS_WRITE_REG(unit, INTEL_82543GC_EECD, (data | EECD_SK_BIT | reqBit)); /* wait 1000ns */ for (count = 0; count < 2; count++) sysDelay (); /* lower the clk */ GEI_SYS_WRITE_REG(unit, INTEL_82543GC_EECD, (data | reqBit)); /* wait 1000ns */ for (count = 0; count < 2; count++) sysDelay (); } }/*************************************************************************** sys543eepromReadWord - Read a word from EEPROM** RETURNS: value in WORD size*/LOCAL UINT16 sys543eepromReadWord ( int unit, UINT32 index ) { int count; 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 */ for (count = 0; count < 3; count++) sysDelay (); 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 */ for (count = 0; count < 2; count++) sysDelay (); /* 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 ( int unit ) { UINT32 ix; UINT32 count = 0; UINT16 val; UCHAR adr [ETHER_ADDRESS_SIZE]; GEI_RESOURCE * pReso = (GEI_RESOURCE *)(geiPciResources[unit].pExtended); for (ix = 0; ix < ETHER_ADDRESS_SIZE / sizeof(UINT16); ix++) { /* get word i from EEPROM */ val = sys543eepromReadWord (unit, (UINT16)(EEPROM_IA_ADDRESS + ix)); adr [count++] = (UCHAR)val; adr [count++] = (UCHAR) (val >> 8); } memcpy (&(pReso->enetAddr[0]), adr, ETHER_ADDRESS_SIZE); /* check IA is UCAST */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -