浏览代码

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 17 年之前
父节点
当前提交
ac3315c26e
共有 4 个文件被更改,包括 98 次插入13 次删除
  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
 		CONFIG_E1000
 		Support for Intel 8254x gigabit chips.
 		Support for Intel 8254x gigabit chips.
 
 
+		CONFIG_E1000_FALLBACK_MAC
+		default MAC for empty eeprom after production.
+
 		CONFIG_EEPRO100
 		CONFIG_EEPRO100
 		Support for Intel 82557/82559/82559ER chips.
 		Support for Intel 82557/82559/82559ER chips.
 		Optional CONFIG_EEPRO100_SROM_WRITE enables eeprom
 		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
 Drivers are port from Intel's Linux driver e1000-4.3.15
 and from Etherboot pro 1000 driver by mrakes at vivato dot net
 and from Etherboot pro 1000 driver by mrakes at vivato dot net
 tested on both gig copper and gig fiber boards
 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_82545EM_FIBER},
 	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546EB_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_82540EM_LOM},
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82541ER},
 };
 };
 
 
 /* Function forward declarations */
 /* 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 */
 		/* Invert the last bit if this is the second device */
 		nic->enetaddr[5] += 1;
 		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
 #else
 	/*
 	/*
 	 * The AP1000's e1000 has no eeprom; the MAC address is stored in the
 	 * 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:
 	case E1000_DEV_ID_82546EB_FIBER:
 		hw->mac_type = e1000_82546;
 		hw->mac_type = e1000_82546;
 		break;
 		break;
+	case E1000_DEV_ID_82541ER:
+	        hw->mac_type = e1000_82541_rev_2;
+	        break;
 	default:
 	default:
 		/* Should never have loaded on this device */
 		/* Should never have loaded on this device */
 		return -E1000_ERR_MAC_TYPE;
 		return -E1000_ERR_MAC_TYPE;
@@ -2485,6 +2494,36 @@ e1000_phy_reset(struct e1000_hw *hw)
 	return 0;
 	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
 * Probes the expected PHY address for known PHY IDs
 *
 *
@@ -2493,6 +2532,7 @@ e1000_phy_reset(struct e1000_hw *hw)
 static int
 static int
 e1000_detect_gig_phy(struct e1000_hw *hw)
 e1000_detect_gig_phy(struct e1000_hw *hw)
 {
 {
+	int32_t phy_init_status;
 	uint16_t phy_id_high, phy_id_low;
 	uint16_t phy_id_high, phy_id_low;
 	int match = FALSE;
 	int match = FALSE;
 
 
@@ -2526,11 +2566,19 @@ e1000_detect_gig_phy(struct e1000_hw *hw)
 		if (hw->phy_id == M88E1011_I_PHY_ID)
 		if (hw->phy_id == M88E1011_I_PHY_ID)
 			match = TRUE;
 			match = TRUE;
 		break;
 		break;
+	case e1000_82541_rev_2:
+		if(hw->phy_id == IGP01E1000_I_PHY_ID)
+			match = TRUE;
+
+		break;
 	default:
 	default:
 		DEBUGOUT("Invalid MAC type %d\n", hw->mac_type);
 		DEBUGOUT("Invalid MAC type %d\n", hw->mac_type);
 		return -E1000_ERR_CONFIG;
 		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);
 		DEBUGOUT("PHY ID 0x%X detected\n", hw->phy_id);
 		return 0;
 		return 0;
 	}
 	}
@@ -2985,7 +3033,7 @@ e1000_initialize(bd_t * bis)
 			free(nic);
 			free(nic);
 			return 0;
 			return 0;
 		}
 		}
-#ifndef CONFIG_AP1000
+#if !(defined(CONFIG_AP1000) || defined(CONFIG_MVBC_1G))
 		if (e1000_validate_eeprom_checksum(nic) < 0) {
 		if (e1000_validate_eeprom_checksum(nic) < 0) {
 			printf("The EEPROM Checksum Is Not Valid\n");
 			printf("The EEPROM Checksum Is Not Valid\n");
 			free(hw);
 			free(hw);

+ 43 - 10
drivers/net/e1000.h

@@ -71,6 +71,8 @@ typedef enum {
 	e1000_82540,
 	e1000_82540,
 	e1000_82545,
 	e1000_82545,
 	e1000_82546,
 	e1000_82546,
+	e1000_82541,
+	e1000_82541_rev_2,
 	e1000_num_macs
 	e1000_num_macs
 } e1000_mac_type;
 } e1000_mac_type;
 
 
@@ -168,6 +170,13 @@ typedef enum {
 	e1000_1000t_rx_status_undefined = 0xFF
 	e1000_1000t_rx_status_undefined = 0xFF
 } e1000_1000t_rx_status;
 } 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 {
 struct e1000_phy_info {
 	e1000_cable_length cable_length;
 	e1000_cable_length cable_length;
 	e1000_10bt_ext_dist_enable extended_10bt_distance;
 	e1000_10bt_ext_dist_enable extended_10bt_distance;
@@ -184,14 +193,19 @@ struct e1000_phy_stats {
 };
 };
 
 
 /* Error Codes */
 /* 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 */
 /* PCI Device IDs */
 #define E1000_DEV_ID_82542          0x1000
 #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_82545EM_FIBER  0x1011
 #define E1000_DEV_ID_82546EB_COPPER 0x1010
 #define E1000_DEV_ID_82546EB_COPPER 0x1010
 #define E1000_DEV_ID_82546EB_FIBER  0x1012
 #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 NODE_ADDRESS_SIZE 6
 #define ETH_LENGTH_OF_ADDRESS 6
 #define ETH_LENGTH_OF_ADDRESS 6
@@ -799,6 +814,8 @@ struct e1000_hw {
 	pci_dev_t pdev;
 	pci_dev_t pdev;
 	uint8_t *hw_addr;
 	uint8_t *hw_addr;
 	e1000_mac_type mac_type;
 	e1000_mac_type mac_type;
+	e1000_phy_type phy_type;
+	uint32_t phy_init_script;
 	e1000_media_type media_type;
 	e1000_media_type media_type;
 	e1000_lan_loc lan_loc;
 	e1000_lan_loc lan_loc;
 	e1000_fc_type fc;
 	e1000_fc_type fc;
@@ -1517,7 +1534,22 @@ struct e1000_hw {
 #define M88E1000_EXT_PHY_SPEC_CTRL 0x14	/* Extended PHY Specific Control */
 #define M88E1000_EXT_PHY_SPEC_CTRL 0x14	/* Extended PHY Specific Control */
 #define M88E1000_RX_ERR_CNTR       0x15	/* Receive Error Counter */
 #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 */
 /* PHY Control Register */
 #define MII_CR_SPEED_SELECT_MSB 0x0040	/* bits 6,13: 10=1000, 01=100, 00=10 */
 #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 M88E1011_I_PHY_ID  0x01410C20
 #define M88E1000_12_PHY_ID M88E1000_E_PHY_ID
 #define M88E1000_12_PHY_ID M88E1000_E_PHY_ID
 #define M88E1000_14_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. */
 /* Miscellaneous PHY bit definitions. */
 #define PHY_PREAMBLE        0xFFFFFFFF
 #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_82434	0x04a3
 #define PCI_DEVICE_ID_INTEL_I960	0x0960
 #define PCI_DEVICE_ID_INTEL_I960	0x0960
 #define PCI_DEVICE_ID_INTEL_I960RM	0x0962
 #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_82542	0x1000
 #define PCI_DEVICE_ID_INTEL_82543GC_FIBER	0x1001
 #define PCI_DEVICE_ID_INTEL_82543GC_FIBER	0x1001
 #define PCI_DEVICE_ID_INTEL_82543GC_COPPER	0x1004
 #define PCI_DEVICE_ID_INTEL_82543GC_COPPER	0x1004