Browse Source

new PHY @ e1000 - 2nd try

Add 82541ER device with latest integrated IGP2 PHY.
Introduced CONFIG_E1000_FALLBACK_MAC for NIC bring-up with empty eeprom.

Signed-off-by: Andre Schwarz <andre.schwarz@matrix-vision.de>
Signed-off-by: Ben Warren <biggerbadderben@gmail.com>
Andre Schwarz 16 years ago
parent
commit
ac3315c26e
4 changed files with 98 additions and 13 deletions
  1. 3 0
      README
  2. 51 3
      drivers/net/e1000.c
  3. 43 10
      drivers/net/e1000.h
  4. 1 0
      include/pci_ids.h

+ 3 - 0
README

@@ -751,6 +751,9 @@ The following options need to be configured:
 		CONFIG_E1000
 		Support for Intel 8254x gigabit chips.
 
+		CONFIG_E1000_FALLBACK_MAC
+		default MAC for empty eeprom after production.
+
 		CONFIG_EEPRO100
 		Support for Intel 82557/82559/82559ER chips.
 		Optional CONFIG_EEPRO100_SROM_WRITE enables eeprom

+ 51 - 3
drivers/net/e1000.c

@@ -1,5 +1,5 @@
 /**************************************************************************
-Inter Pro 1000 for ppcboot/das-u-boot
+Intel Pro 1000 for ppcboot/das-u-boot
 Drivers are port from Intel's Linux driver e1000-4.3.15
 and from Etherboot pro 1000 driver by mrakes at vivato dot net
 tested on both gig copper and gig fiber boards
@@ -82,6 +82,7 @@ static struct pci_device_id supported[] = {
 	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82545EM_FIBER},
 	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546EB_FIBER},
 	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82540EM_LOM},
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82541ER},
 };
 
 /* Function forward declarations */
@@ -512,6 +513,11 @@ e1000_read_mac_addr(struct eth_device *nic)
 		/* Invert the last bit if this is the second device */
 		nic->enetaddr[5] += 1;
 	}
+#ifdef CONFIG_E1000_FALLBACK_MAC
+	if ( *(u32*)(nic->enetaddr) == 0 || *(u32*)(nic->enetaddr) == ~0 )
+		for ( i=0; i < NODE_ADDRESS_SIZE; i++ )
+			nic->enetaddr[i] = (CONFIG_E1000_FALLBACK_MAC >> (8*(5-i))) & 0xff;
+#endif
 #else
 	/*
 	 * The AP1000's e1000 has no eeprom; the MAC address is stored in the
@@ -639,6 +645,9 @@ e1000_set_mac_type(struct e1000_hw *hw)
 	case E1000_DEV_ID_82546EB_FIBER:
 		hw->mac_type = e1000_82546;
 		break;
+	case E1000_DEV_ID_82541ER:
+	        hw->mac_type = e1000_82541_rev_2;
+	        break;
 	default:
 		/* Should never have loaded on this device */
 		return -E1000_ERR_MAC_TYPE;
@@ -2485,6 +2494,36 @@ e1000_phy_reset(struct e1000_hw *hw)
 	return 0;
 }
 
+static int
+e1000_set_phy_type(struct e1000_hw *hw)
+{
+    DEBUGFUNC();
+
+    if(hw->mac_type == e1000_undefined)
+        return -E1000_ERR_PHY_TYPE;
+
+    switch(hw->phy_id) {
+    case M88E1000_E_PHY_ID:
+    case M88E1000_I_PHY_ID:
+    case M88E1011_I_PHY_ID:
+        hw->phy_type = e1000_phy_m88;
+        break;
+    case IGP01E1000_I_PHY_ID:
+        if(hw->mac_type == e1000_82541 ||
+           hw->mac_type == e1000_82541_rev_2) {
+            hw->phy_type = e1000_phy_igp;
+            break;
+        }
+        /* Fall Through */
+    default:
+        /* Should never have loaded on this device */
+        hw->phy_type = e1000_phy_undefined;
+        return -E1000_ERR_PHY_TYPE;
+    }
+
+    return E1000_SUCCESS;
+}
+
 /******************************************************************************
 * Probes the expected PHY address for known PHY IDs
 *
@@ -2493,6 +2532,7 @@ e1000_phy_reset(struct e1000_hw *hw)
 static int
 e1000_detect_gig_phy(struct e1000_hw *hw)
 {
+	int32_t phy_init_status;
 	uint16_t phy_id_high, phy_id_low;
 	int match = FALSE;
 
@@ -2526,11 +2566,19 @@ e1000_detect_gig_phy(struct e1000_hw *hw)
 		if (hw->phy_id == M88E1011_I_PHY_ID)
 			match = TRUE;
 		break;
+	case e1000_82541_rev_2:
+		if(hw->phy_id == IGP01E1000_I_PHY_ID)
+			match = TRUE;
+
+		break;
 	default:
 		DEBUGOUT("Invalid MAC type %d\n", hw->mac_type);
 		return -E1000_ERR_CONFIG;
 	}
-	if (match) {
+
+	phy_init_status = e1000_set_phy_type(hw);
+
+	if ((match) && (phy_init_status == E1000_SUCCESS)) {
 		DEBUGOUT("PHY ID 0x%X detected\n", hw->phy_id);
 		return 0;
 	}
@@ -2985,7 +3033,7 @@ e1000_initialize(bd_t * bis)
 			free(nic);
 			return 0;
 		}
-#ifndef CONFIG_AP1000
+#if !(defined(CONFIG_AP1000) || defined(CONFIG_MVBC_1G))
 		if (e1000_validate_eeprom_checksum(nic) < 0) {
 			printf("The EEPROM Checksum Is Not Valid\n");
 			free(hw);

+ 43 - 10
drivers/net/e1000.h

@@ -71,6 +71,8 @@ typedef enum {
 	e1000_82540,
 	e1000_82545,
 	e1000_82546,
+	e1000_82541,
+	e1000_82541_rev_2,
 	e1000_num_macs
 } e1000_mac_type;
 
@@ -168,6 +170,13 @@ typedef enum {
 	e1000_1000t_rx_status_undefined = 0xFF
 } e1000_1000t_rx_status;
 
+typedef enum {
+    e1000_phy_m88 = 0,
+    e1000_phy_igp,
+    e1000_phy_igp_2,
+    e1000_phy_undefined = 0xFF
+} e1000_phy_type;
+
 struct e1000_phy_info {
 	e1000_cable_length cable_length;
 	e1000_10bt_ext_dist_enable extended_10bt_distance;
@@ -184,14 +193,19 @@ struct e1000_phy_stats {
 };
 
 /* Error Codes */
-#define E1000_SUCCESS      0
-#define E1000_ERR_EEPROM   1
-#define E1000_ERR_PHY      2
-#define E1000_ERR_CONFIG   3
-#define E1000_ERR_PARAM    4
-#define E1000_ERR_MAC_TYPE 5
-#define E1000_ERR_NOLINK   6
-#define E1000_ERR_TIMEOUT  7
+#define E1000_SUCCESS      			0
+#define E1000_ERR_EEPROM   			1
+#define E1000_ERR_PHY      			2
+#define E1000_ERR_CONFIG   			3
+#define E1000_ERR_PARAM    			4
+#define E1000_ERR_MAC_TYPE 			5
+#define E1000_ERR_PHY_TYPE 			6
+#define E1000_ERR_NOLINK   			7
+#define E1000_ERR_TIMEOUT  			8
+#define E1000_ERR_RESET   			9
+#define E1000_ERR_MASTER_REQUESTS_PENDING 	10
+#define E1000_ERR_HOST_INTERFACE_COMMAND 	11
+#define E1000_BLK_PHY_RESET   			12
 
 /* PCI Device IDs */
 #define E1000_DEV_ID_82542          0x1000
@@ -207,7 +221,8 @@ struct e1000_phy_stats {
 #define E1000_DEV_ID_82545EM_FIBER  0x1011
 #define E1000_DEV_ID_82546EB_COPPER 0x1010
 #define E1000_DEV_ID_82546EB_FIBER  0x1012
-#define NUM_DEV_IDS 13
+#define E1000_DEV_ID_82541ER        0x1078
+#define NUM_DEV_IDS 14
 
 #define NODE_ADDRESS_SIZE 6
 #define ETH_LENGTH_OF_ADDRESS 6
@@ -799,6 +814,8 @@ struct e1000_hw {
 	pci_dev_t pdev;
 	uint8_t *hw_addr;
 	e1000_mac_type mac_type;
+	e1000_phy_type phy_type;
+	uint32_t phy_init_script;
 	e1000_media_type media_type;
 	e1000_lan_loc lan_loc;
 	e1000_fc_type fc;
@@ -1517,7 +1534,22 @@ struct e1000_hw {
 #define M88E1000_EXT_PHY_SPEC_CTRL 0x14	/* Extended PHY Specific Control */
 #define M88E1000_RX_ERR_CNTR       0x15	/* Receive Error Counter */
 
-#define MAX_PHY_REG_ADDRESS 0x1F	/* 5 bit address bus (0-0x1F) */
+#define MAX_PHY_REG_ADDRESS 	0x1F	/* 5 bit address bus (0-0x1F) */
+
+/* IGP01E1000 specifics */
+#define IGP01E1000_IEEE_REGS_PAGE  	0x0000
+#define IGP01E1000_IEEE_RESTART_AUTONEG 0x3300
+#define IGP01E1000_IEEE_FORCE_GIGA      0x0140
+
+/* IGP01E1000 Specific Registers */
+#define IGP01E1000_PHY_PORT_CONFIG 	0x10 /* PHY Specific Port Config Register */
+#define IGP01E1000_PHY_PORT_STATUS 	0x11 /* PHY Specific Status Register */
+#define IGP01E1000_PHY_PORT_CTRL   	0x12 /* PHY Specific Control Register */
+#define IGP01E1000_PHY_LINK_HEALTH 	0x13 /* PHY Link Health Register */
+#define IGP01E1000_GMII_FIFO       	0x14 /* GMII FIFO Register */
+#define IGP01E1000_PHY_CHANNEL_QUALITY 	0x15 /* PHY Channel Quality Register */
+#define IGP02E1000_PHY_POWER_MGMT      	0x19
+#define IGP01E1000_PHY_PAGE_SELECT     	0x1F /* PHY Page Select Core Register */
 
 /* PHY Control Register */
 #define MII_CR_SPEED_SELECT_MSB 0x0040	/* bits 6,13: 10=1000, 01=100, 00=10 */
@@ -1729,6 +1761,7 @@ struct e1000_hw {
 #define M88E1011_I_PHY_ID  0x01410C20
 #define M88E1000_12_PHY_ID M88E1000_E_PHY_ID
 #define M88E1000_14_PHY_ID M88E1000_E_PHY_ID
+#define IGP01E1000_I_PHY_ID  0x02A80380
 
 /* Miscellaneous PHY bit definitions. */
 #define PHY_PREAMBLE        0xFFFFFFFF

+ 1 - 0
include/pci_ids.h

@@ -1810,6 +1810,7 @@
 #define PCI_DEVICE_ID_INTEL_82434	0x04a3
 #define PCI_DEVICE_ID_INTEL_I960	0x0960
 #define PCI_DEVICE_ID_INTEL_I960RM	0x0962
+#define PCI_DEVICE_ID_INTEL_82541ER 0x1078
 #define PCI_DEVICE_ID_INTEL_82542	0x1000
 #define PCI_DEVICE_ID_INTEL_82543GC_FIBER	0x1001
 #define PCI_DEVICE_ID_INTEL_82543GC_COPPER	0x1004