This is the mail archive of the ecos-patches@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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)) {


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]