# HG changeset patch # User msalter # Date 1047955665 0 # Node ID da5d1a18f69cecef80f5edceb012fee5fe7d3095 # Parent 71beb8096c6708922d898243cc0d81fd29ceaa3b 82546 eeprom fixes diff --git a/packages/devs/eth/intel/i82544/current/ChangeLog b/packages/devs/eth/intel/i82544/current/ChangeLog --- a/packages/devs/eth/intel/i82544/current/ChangeLog +++ b/packages/devs/eth/intel/i82544/current/ChangeLog @@ -1,3 +1,8 @@ +2003-03-17 Mark Salter + + * src/if_i82544.c: Fix 82546 EEPROM access. Fix ESA address for second + port of 82546. + 2003-03-11 Mark Salter * src/if_i82544.c (find_82544s_match_func): Add 82546 devid. diff --git a/packages/devs/eth/intel/i82544/current/src/if_i82544.c b/packages/devs/eth/intel/i82544/current/src/if_i82544.c --- a/packages/devs/eth/intel/i82544/current/src/if_i82544.c +++ b/packages/devs/eth/intel/i82544/current/src/if_i82544.c @@ -394,6 +394,10 @@ static inline cyg_uint32 bus_to_virt(cyg #define EE_CS 0x02 // EEPROM chip select. #define EE_DATA_WRITE 0x04 // EEPROM chip data in. #define EE_DATA_READ 0x08 // EEPROM chip data out. +#define EE_REQ 0x40 // EEPROM request (82546 only) +#define EE_GNT 0x80 // EEPROM grant (82546 only) +#define EE_PRES 0x100 // EEPROM present (82546 only) +#define EE_SIZE 0x200 // EEPROM size (82546 only) #define EE_ENB (0x10|EE_CS) @@ -793,10 +797,9 @@ static int mii_read_register( struct i82 value = MII_READ_REGVAL(); MII_IDLE(); } - else if( p_i82544->device == 0x1008 ) + else { - // An 82544, read MII register via MDIC register. - // UNTESTED + // Others, read MII register via MDIC register. cyg_uint32 mdic = (2<<26) | (phy<<21) | (regnum<<16); @@ -832,10 +835,9 @@ static void mii_write_register( struct i MII_WRITE_REGVAL( value ); MII_IDLE(); } - else if( p_i82544->device == 0x1008 ) + else { - // An 82544, write MII register via MDIC register. - // UNTESTED + // Others, write MII register via MDIC register. cyg_uint32 mdic = (1<<26) | (phy<<21) | (regnum<<16) | (value&0xFFFF); @@ -901,7 +903,17 @@ static void show_phy( struct i82544 *p_i static inline void ee_select( int ioaddr ) { cyg_uint32 l; - l = EE_ENB; + l = INL( ioaddr + I82544_EECD ); + if (l & EE_PRES) { + // i82546 has EE_PRES bit and requires REQ/GNT before EEPROM access + l |= EE_REQ; + OUTL( l, ioaddr + I82544_EECD ); + EE_DELAY(); + while ((l & EE_GNT) == 0) + l = INL( ioaddr + I82544_EECD ); + } + l &= ~0x3f; + l |= EE_ENB; OUTL( l, ioaddr + I82544_EECD ); EE_DELAY(); l |= EE_CS; @@ -914,19 +926,25 @@ static inline void ee_select( int ioaddr static inline void ee_deselect( int ioaddr ) { cyg_uint32 l; - l = EE_ENB; + l = INL( ioaddr + I82544_EECD ) & ~0x3f; + l |= EE_ENB; OUTL( l, ioaddr + I82544_EECD ); EE_PRINTF( "ee_deselect 1 : " EE_STUFF ); EE_DELAY(); EE_DELAY(); EE_DELAY(); - l = EE_ENB & ~EE_CS; + l &= ~EE_CS; OUTL( l, ioaddr + I82544_EECD ); l = INL( ioaddr + I82544_EECD ); EE_PRINTF( "ee_deselect 2 : " EE_STUFF ); EE_DELAY(); EE_DELAY(); EE_DELAY(); + if (l & EE_REQ) { + l &= ~EE_REQ; + OUTL( l, ioaddr + I82544_EECD ); + EE_DELAY(); + } } static inline void ee_clock_up( int ioaddr ) @@ -988,74 +1006,21 @@ static inline void ee_write_data_bit( in static int get_eeprom_size( struct i82544 *p_i82544 ) { -// int i, addrbits, tmp; -// cyg_uint32 ioaddr = p_i82544->io_address; + cyg_uint32 l, ioaddr = p_i82544->io_address; #ifdef DEBUG_EE diag_printf( "get_eeprom_size\n" ); #endif -#if 1 - return 6; -#else - // Should already be not-selected, but anyway: - EE_SELECT(); - -#ifdef DEBUG_EE - diag_printf( "send command\n" ); -#endif - - // Shift the read command bits out. - for (i = 3; i >= 0; i--) { // Doc says to shift out a zero then: - tmp = (6 & (1 << i)) ? 1 : 0; // "6" is the "read" command. - EE_WRITE_DATA_BIT(tmp); - EE_CLOCK_UP(); - EE_CLOCK_DOWN(); - } -#ifdef DEBUG_EE - diag_printf( "send address zero\n" ); -#endif - // Now clock out address zero, looking for the dummy 0 data bit - for ( i = 1; i <= 12; i++ ) { - EE_WRITE_DATA_BIT(0); - EE_CLOCK_UP(); - tmp = EE_READ_DATA_BIT(); - EE_CLOCK_DOWN(); - if ( !tmp ) - break; - } - + l = INL( ioaddr + I82544_EECD ); + if (l & EE_PRES) { #ifdef DEBUG_EE - diag_printf( "eeprom data bits %d\n", i ); + diag_printf("eeprom size: %d\n", (l & EE_SIZE) ? 8 : 6 ); #endif - - if ( 6 != i && 8 != i && 1 != i) { -#ifdef DEBUG_EE - diag_printf( "*****EEPROM data bits not 6, 8 or 1*****\n" ); -#endif - addrbits = 1; // Flag no eeprom here. + return (l & EE_SIZE) ? 8 : 6; } - else - addrbits = i; - - // read in the data regardless - tmp = 0; - for (i = 15; i >= 0; i--) { - EE_CLOCK_UP(); - if ( EE_READ_DATA_BIT() ) - tmp |= (1<device == 0x1010) { + cyg_uint8 devfn = CYG_PCI_DEV_GET_DEVFN(p_i82544->devid); + if (CYG_PCI_DEV_GET_FN(devfn) == 1) + mac_address[5] |= 1; + } eth_set_mac_address(p_i82544, mac_address, 0); } }