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]

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.6
diff -u -p -5 -r1.6 ChangeLog
--- devs/eth/intel/i82544/current/ChangeLog	11 Mar 2003 19:56:15 -0000	1.6
+++ devs/eth/intel/i82544/current/ChangeLog	18 Mar 2003 02:37:55 -0000
@@ -1,5 +1,10 @@
+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.
+
 2003-03-11  Mark Salter  <msalter at redhat dot com>
 
 	* src/if_i82544.c (find_82544s_match_func): Add 82546 devid.
 
 2003-02-05  Nick Garnett  <nickg at calivar dot com>
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.6
diff -u -p -5 -r1.6 if_i82544.c
--- devs/eth/intel/i82544/current/src/if_i82544.c	11 Mar 2003 19:56:15 -0000	1.6
+++ devs/eth/intel/i82544/current/src/if_i82544.c	18 Mar 2003 02:37:57 -0000
@@ -392,10 +392,14 @@ static inline cyg_uint32 bus_to_virt(cyg
 //  EEPROM_Ctrl bits.
 #define EE_SHIFT_CLK	0x01            // EEPROM shift clock.
 #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)
 
 
 // ------------------------------------------------------------------------
 //
@@ -791,14 +795,13 @@ static int mii_read_register( struct i82
         MII_WRITE_REGNUM( regnum );
         MII_READ_TURNAROUND();
         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);
 
         OUTL( mdic, ioaddr + I82544_MDIC );
 
@@ -830,14 +833,13 @@ static void mii_write_register( struct i
         MII_WRITE_REGNUM( regnum );
         MII_WRITE_TURNAROUND();
         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);
 
         OUTL( mdic, ioaddr + I82544_MDIC );
 
@@ -899,11 +901,21 @@ 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;
     OUTL( l, ioaddr + I82544_EECD );
     l = INL( ioaddr + I82544_EECD );
@@ -912,23 +924,29 @@ 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 )
 {
     cyg_uint32 l;
@@ -986,78 +1004,25 @@ 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;
-    }
-
-#ifdef DEBUG_EE
-    diag_printf( "eeprom data bits %d\n", i );
-#endif
-    
-    if ( 6 != i && 8 != i && 1 != i) {
+    l = INL( ioaddr + I82544_EECD );
+    if (l & EE_PRES) {
 #ifdef DEBUG_EE
-        diag_printf( "*****EEPROM data bits not 6, 8 or 1*****\n" );
+	diag_printf("eeprom size: %d\n", (l & EE_SIZE) ? 8 : 6 );
 #endif
-        addrbits = 1; // Flag no eeprom here.
-    }
-    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<<i);
-        EE_CLOCK_DOWN();
+	return (l & EE_SIZE) ? 8 : 6;
     }
 
-#ifdef DEBUG_EE
-    diag_printf( "eeprom first data word %x\n", tmp );
-#endif
-   
-    // Terminate the EEPROM access.
-    EE_DESELECT();
-    
-    return addrbits;
-#endif    
+    return 6;
 }
 
 static int
 read_eeprom_word( struct i82544 *p_i82544, int addrbits, int address )
 {
@@ -1255,10 +1220,16 @@ i82544_init(struct cyg_netdevtab_entry *
             {
                 p_i82544->mac_addr_ok = 1;
 #ifdef DEBUG_EE
                 os_printf("Valid EEPROM checksum\n");
 #endif
+		// Second port of dual-port 82546 uses EEPROM ESA | 1
+		if (p_i82544->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);
             }
         }
 
         // record the MAC address in the device structure


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