This is the mail archive of the
ecos-patches@sources.redhat.com
mailing list for the eCos project.
more i82546 eeprom fixes
- From: Mark Salter <msalter at redhat dot com>
- To: ecos-patches at sources dot redhat dot com
- Date: Wed, 19 Mar 2003 14:56:26 -0500 (EST)
- Subject: more i82546 eeprom fixes
Index: devs/eth/intel/i82544/current/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/eth/intel/i82544/current/ChangeLog,v
retrieving revision 1.7
diff -u -p -5 -r1.7 ChangeLog
--- devs/eth/intel/i82544/current/ChangeLog 18 Mar 2003 02:47:45 -0000 1.7
+++ devs/eth/intel/i82544/current/ChangeLog 19 Mar 2003 19:45:16 -0000
@@ -1,5 +1,10 @@
+2003-03-19 Mark Salter <msalter at redhat dot com>
+
+ * src/if_i82544.c (i82544_setup): More 82546 EEPROM fixes (EE_PRES
+ appears to be unreliable).
+
2003-03-17 Mark Salter <msalter at redhat dot com>
* src/if_i82544.c: Fix 82546 EEPROM access. Fix ESA address for second
port of 82546.
Index: devs/eth/intel/i82544/current/src/if_i82544.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/eth/intel/i82544/current/src/if_i82544.c,v
retrieving revision 1.7
diff -u -p -5 -r1.7 if_i82544.c
--- devs/eth/intel/i82544/current/src/if_i82544.c 18 Mar 2003 02:47:45 -0000 1.7
+++ devs/eth/intel/i82544/current/src/if_i82544.c 19 Mar 2003 19:45:18 -0000
@@ -898,16 +898,16 @@ static void show_phy( struct i82544 *p_i
# define EE_PRINTF( foo )
# define EE_STUFF
#endif
-static inline void ee_select( int ioaddr )
+static inline void ee_select( int ioaddr, struct i82544 *p_i82544 )
{
cyg_uint32 l;
l = INL( ioaddr + I82544_EECD );
- if (l & EE_PRES) {
- // i82546 has EE_PRES bit and requires REQ/GNT before EEPROM access
+ if (p_i82544->device == 0x1010) {
+ // i82546 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 );
@@ -992,11 +992,11 @@ static inline void ee_write_data_bit( in
EE_PRINTF( "ee_write_data : " EE_STUFF );
EE_DELAY();
}
// Pass ioaddr around "invisibly"
-#define EE_SELECT() ee_select(ioaddr)
+#define EE_SELECT() ee_select(ioaddr, p_i82544)
#define EE_DESELECT() ee_deselect(ioaddr)
#define EE_CLOCK_UP() ee_clock_up(ioaddr)
#define EE_CLOCK_DOWN() ee_clock_down(ioaddr)
#define EE_READ_DATA_BIT() ee_read_data_bit(ioaddr)
#define EE_WRITE_DATA_BIT( _d_ ) ee_write_data_bit(ioaddr,(_d_))
@@ -1005,21 +1005,80 @@ static inline void ee_write_data_bit( in
static int
get_eeprom_size( struct i82544 *p_i82544 )
{
cyg_uint32 l, ioaddr = p_i82544->io_address;
+ int i, tmp, addrbits;
+
+ l = INL( ioaddr + I82544_EECD );
#ifdef DEBUG_EE
diag_printf( "get_eeprom_size\n" );
#endif
- l = INL( ioaddr + I82544_EECD );
- if (l & EE_PRES) {
-#ifdef DEBUG_EE
- diag_printf("eeprom size: %d\n", (l & EE_SIZE) ? 8 : 6 );
-#endif
- return (l & EE_SIZE) ? 8 : 6;
+ if (p_i82544->device == 0x1010) {
+
+ 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;
+ OUTL( l, ioaddr + I82544_EECD );
+ l = INL( ioaddr + I82544_EECD );
+ EE_DELAY();
+
+ 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();
+ }
+ // Now clock out address zero, looking for the dummy 0 data bit
+ for ( i = 1; i <= 10; i++ ) {
+ EE_WRITE_DATA_BIT(0);
+ EE_CLOCK_UP();
+ EE_CLOCK_DOWN();
+ if (EE_READ_DATA_BIT() == 0)
+ break; // The dummy zero est arrive'
+ }
+
+ if (6 != i && 8 != i)
+ diag_printf("no EEPROM found\n");
+
+ addrbits = i;
+
+ tmp = 0;
+ for (i = 15; i >= 0; i--) {
+ EE_CLOCK_UP();
+ if (EE_READ_DATA_BIT())
+ tmp |= (1<<i);
+ EE_CLOCK_DOWN();
+ }
+
+ l = INL( ioaddr + I82544_EECD ) & ~0x3f;
+ l |= EE_ENB;
+ OUTL( l, ioaddr + I82544_EECD );
+ EE_DELAY();
+ EE_DELAY();
+ EE_DELAY();
+ l &= ~EE_CS;
+ OUTL( l, ioaddr + I82544_EECD );
+ l = INL( ioaddr + I82544_EECD );
+ EE_DELAY();
+ EE_DELAY();
+ EE_DELAY();
+
+ l &= ~EE_REQ;
+ OUTL( l, ioaddr + I82544_EECD );
+ EE_DELAY();
+
+ return addrbits;
}
return 6;
}
@@ -1286,11 +1345,10 @@ i82544_setup( struct i82544 *p_i82544 )
cyg_uint32 ctrl;
cyg_uint32 ctrl_ext;
ioaddr = p_i82544->io_address; // get 82544's I/O address
-
#ifdef CYGHWR_DEVS_ETH_INTEL_I82544_USE_ASD
// Use Auto-negotiation
ctrl = INL( ioaddr + I82544_CTRL );
@@ -2462,11 +2520,11 @@ pci_init_find_82544s( void )
p_i82544->index = device_index;
// See above for find_82544s_match_func
if (cyg_pci_find_matching( &find_82544s_match_func, NULL, &devid )) {
#ifdef DEBUG
- db_printf("eth%d = 82544\n", device_index);
+ db_printf("eth%d = 8254x\n", device_index);
#endif
cyg_pci_get_device_info(devid, &dev_info);
p_i82544->interrupt_handle = 0; // Flag not attached.
if (cyg_pci_translate_interrupt(&dev_info, &p_i82544->vector)) {