📄 sysgei82544end.c
字号:
** 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.** ERRNO: N/A** 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.** ERRNO: N/A** 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** ERRNO: N/A** RETURNS: value in WORD size*/LOCAL UINT16 sys543eepromReadBits ( int unit, int bitsNum ) { int count; UINT32 ix; volatile UINT16 val = 0; UINT16 reqBit = 0; GEI_RESOURCE * pRsrc; pRsrc = &geiResources[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 3000ns */ for (count = 0; count < 3; count++) sys543Delay (); 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 3000 ns */ for (count = 0; count < 3; count++) sys543Delay (); } return (val); }/*************************************************************************** sys543eepromWriteBits - write bits out to EEPROM** This routine writes bits out to EEPROM** ERRNO: N/A** RETURNS: N/A*/LOCAL void sys543eepromWriteBits ( int unit, UINT16 value, UINT16 bitNum ) { int count; volatile UINT16 data; UINT16 reqBit = 0; GEI_RESOURCE * pRsrc; pRsrc = &geiResources[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 */ for (count = 0; count < 2; count++) sys543Delay (); /* raise the clk */ GEI_SYS_WRITE_REG(unit, INTEL_82543GC_EECD, (data | EECD_SK_BIT | reqBit)); /* wait 2000ns */ for (count = 0; count < 2; count++) sys543Delay (); /* lower the clk */ GEI_SYS_WRITE_REG(unit, INTEL_82543GC_EECD, (data | reqBit)); /* wait 2000ns */ for (count = 0; count < 2; count++) sys543Delay (); } }/*************************************************************************** sys543eepromReadWord - Read a word from EEPROM** This routine reads a word from the EEPROM** ERRNO: N/A** RETURNS: value in WORD size*/LOCAL UINT16 sys543eepromReadWord ( int unit, UINT32 index ) { int count; UINT16 val; UINT32 tmp; GEI_RESOURCE * pRsrc; pRsrc = &geiResources[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 3us */ for (count = 0; count < 3; count++) sys543Delay (); 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 2000ns */ for (count = 0; count < 2; count++) sys543Delay (); /* 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); } tmp = 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; }/*************************************************************************** sys543EtherAddrGet - Get Ethernet address from EEPROM** This routine get an Ethernet address from EEPROM** ERRNO: N/A** RETURNS: OK or ERROR*/LOCAL STATUS sys543EtherAddrGet ( int unit ) { UINT32 ix, count=0; UINT16 val; UCHAR adr [ETHER_ADDRESS_SIZE]; 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); } /* check IA is UCAST */ if (adr[0] & 0x1) return (ERROR); memcpy (&geiResources[unit].enetAddr[0], adr, ETHER_ADDRESS_SIZE); return (OK); }/**************************************************************************** sys543eepromCheckSum - calculate checksum** This routine perform EEPROM checksum. The checksum is calculated* by summing all 16 bit words in the EEPROM but the carry bit is* ignored. The result should be 0xBABA.** ERRNO: N/A** RETURNS: N/A*/LOCAL STATUS sys543eepromCheckSum ( int unit ) { UINT16 checkSum = 0 ; UINT32 ix; for (ix = 0; ix < EEPROM_WORD_SIZE; ix++) { UINT16 val16; val16 = sys543eepromReadWord(unit, ix); /* printf("checksum word %d is 0x%x\n", ix, val16); debugging */ checkSum += val16; } if (checkSum == (UINT16)EEPROM_SUM) return OK; else return ERROR; }/***************************************************************************** sys544PhyPreInit -- Init 82544's specific PHY regs before link setup** This routine initializes some 82544's PHY regs before set up link* Basically, it fixed short cable/backplane problem, Errata 21** RETURN: N/A*/LOCAL void sys544PhyPreInit ( PHY_INFO * pPhyInfo /* PHY's info structure pointer */ ) { UINT16 regVal; /* register value */ UINT16 phyId1; /* phy Id 1 */ UINT16 phyId2; /* phy ID 2 */ UINT32 retVal; /* return value */ UINT32 phyOui = 0; /* PHY's manufacture ID */ UINT32 phyMode; /* PHY mode number */ UINT8 phyAddr; /* PHY's bus number */ phyAddr = pPhyInfo->phyAddr; MII_READ (phyAddr, MII_PHY_ID1_REG, &phyId1, retVal); MII_READ (phyAddr, MII_PHY_ID2_REG, &phyId2, retVal); phyOui = phyId1 << 6 | phyId2 >> 10; phyMode = (phyId2 & MII_ID2_MODE_MASK) >> 4; if (phyOui == INTEL_82544PHY_OUI_ID && (phyMode == INTEL_82544PHY_MODEL)) { regVal = 0x0004; MII_WRITE (phyAddr, 29, 0x4, retVal); MII_READ (phyAddr, 30, ®Val, retVal); regVal |= 0x0200; MII_WRITE (phyAddr, 30, regVal, retVal); } }/**************************************************************************** sys543PhySpecRegsInit - Initialize PHY specific registers** This routine initialize PHY specific registers** RETURN: N/A*/LOCAL void sys543PhySpecRegsInit ( PHY_INFO * pPhyInfo, /* PHY's info structure pointer */ UINT8 phyAddr /* PHY's bus number */ ) { UINT16 regVal; /* register value */ UINT16 phyId1; /* phy Id 1 */ UINT16 phyId2; /* phy ID 2 */ UINT32 retVal; /* return value */ UINT32 phyOui = 0; /* PHY's manufacture ID */ UINT32 phyMode; /* PHY mode number */ /* Intel Pro1000T adaptor uses Alaska transceiver */ /* read device ID to check Alaska chip available */ MII_READ (phyAddr, MII_PHY_ID1_REG, &phyId1, retVal); MII_READ (phyAddr, MII_PHY_ID2_REG, &phyId2, retVal); phyOui = phyId1 << 6 | phyId2 >> 10; phyMode = (phyId2 & MII_ID2_MODE_MASK) >> 4; if (phyOui == MARVELL_OUI_ID && (phyMode == MARVELL_ALASKA_88E1000 || phyMode == MARVELL_ALASKA_88E1000S)) { /* This is actually a Marvell Alaska 1000T transceiver */ /* disable PHY's interrupt */ MII_READ (phyAddr, ALASKA_INT_ENABLE_REG, ®Val, retVal); regVal = 0; MII_WRITE (phyAddr, ALASKA_INT_ENABLE_REG, regVal, retVal); /* CRS assert on transmit */ MII_READ (phyAddr, ALASKA_PHY_SPEC_CTRL_REG, ®Val, retVal); regVal |= ALASKA_PSCR_ASSERT_CRS_ON_TX; MII_WRITE (phyAddr, ALASKA_PHY_SPEC_CTRL_REG, regVal, retVal); /* set the clock rate when operate in 1000T mode */ MII_READ (phyAddr, ALASKA_EXT_PHY_SPEC_CTRL_REG, ®Val, retVal); regVal |= ALASKA_EPSCR_TX_CLK_25; MII_WRITE (phyAddr, ALASKA_EXT_PHY_SPEC_CTRL_REG, regVal, retVal); } else if (phyOui == INTEL_82544PHY_OUI_ID && (phyMode == INTEL_82544PHY_MODEL)) { /* This is INTEL 82544GC/EI internal PHY */ /* disable PHY's interrupt */ MII_READ (phyAddr, INTEL_82544PHY_INT_ENABLE_REG, ®Val, retVal); regVal = 0; MII_WRITE (phyAddr, INTEL_82544PHY_INT_ENABLE_REG, regVal, retVal); /* CRS assert on transmit */ MII_READ (phyAddr, INTEL_82544PHY_PHY_SPEC_CTRL_REG, ®Val, retVal); regVal |= INTEL_82544PHY_PSCR_ASSERT_CRS_ON_TX; MII_WRITE (phyAddr, INTEL_82544PHY_PHY_SPEC_CTRL_REG, regVal, retVal);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -