new PHY @ e1000 - 2nd try
authorAndre Schwarz <andre.schwarz@matrix-vision.de>
Thu, 6 Mar 2008 15:45:44 +0000 (16:45 +0100)
committerBen Warren <biggerbadderben@gmail.com>
Sun, 30 Mar 2008 04:37:08 +0000 (00:37 -0400)
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>
README
drivers/net/e1000.c
drivers/net/e1000.h
include/pci_ids.h

diff --git a/README b/README
index 592d1d884208a55dc4a86d3b9f4df463e18f9c2e..64127ab9503b23e2b886f323a2b8d6b958ec903a 100644 (file)
--- a/README
+++ b/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
index f0741da82b29b49bc054b0d8b34a4798bc6131e4..4a7225202c179216529b0e3cdaf0bb910c68287c 100644 (file)
@@ -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);
index 0fbdc90b1f4c1523213fa0d3cb508b653e2e9f66..822afc566f1c096cbf4e2c7ca61d619902c112d2 100644 (file)
@@ -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
index b0c1957aea7f01d870b2cf69d0d24eb8e1de3157..593c074793607eafe906cb9319406a6de1cdbc8a 100644 (file)
 #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