diff options
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/pci/if_em.c | 20 | ||||
-rw-r--r-- | sys/dev/pci/if_em_hw.c | 350 | ||||
-rw-r--r-- | sys/dev/pci/if_em_hw.h | 3 |
3 files changed, 256 insertions, 117 deletions
diff --git a/sys/dev/pci/if_em.c b/sys/dev/pci/if_em.c index 8e0f3ec112d..2670ea5ec58 100644 --- a/sys/dev/pci/if_em.c +++ b/sys/dev/pci/if_em.c @@ -31,7 +31,7 @@ POSSIBILITY OF SUCH DAMAGE. ***************************************************************************/ -/* $OpenBSD: if_em.c,v 1.221 2009/08/21 22:54:10 dms Exp $ */ +/* $OpenBSD: if_em.c,v 1.222 2009/09/04 22:13:51 dms Exp $ */ /* $FreeBSD: if_em.c,v 1.46 2004/09/29 18:28:28 mlaier Exp $ */ #include <dev/pci/if_em.h> @@ -132,13 +132,19 @@ const struct pci_matchid em_devices[] = { { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_ICH8_IGP_C }, { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_ICH8_IGP_M }, { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_ICH8_IGP_M_AMT }, + { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_ICH9_BM }, { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_ICH9_IFE }, { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_ICH9_IFE_G }, { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_ICH9_IFE_GT }, { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_ICH9_IGP_AMT }, { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_ICH9_IGP_C }, { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_ICH9_IGP_M }, - { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_ICH9_IGP_M_AMT } + { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_ICH9_IGP_M_AMT }, + { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_ICH10_D_BM_LF }, + { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_ICH10_D_BM_LM }, + { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_ICH10_R_BM_LF }, + { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_ICH10_R_BM_LM }, + { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_ICH10_R_BM_V } }; /********************************************************************* @@ -333,13 +339,15 @@ em_attach(struct device *parent, struct device *self, void *aux) case em_82574: case em_82575: case em_ich9lan: - case em_80003es2lan: /* Limit Jumbo Frame size */ + case em_ich10lan: + case em_80003es2lan: + /* Limit Jumbo Frame size */ sc->hw.max_frame_size = 9234; break; - /* Adapters that do not support Jumbo frames */ case em_82542_rev2_0: case em_82542_rev2_1: case em_ich8lan: + /* Adapters that do not support Jumbo frames */ sc->hw.max_frame_size = ETHER_MAX_LEN; break; default: @@ -689,6 +697,7 @@ em_init(void *arg) pba = E1000_PBA_8K; break; case em_ich9lan: + case em_ich10lan: pba = E1000_PBA_10K; break; default: @@ -1517,7 +1526,8 @@ em_allocate_pci_resources(struct em_softc *sc) /* for ICH8 and family we need to find the flash memory */ if (sc->hw.mac_type == em_ich8lan || - sc->hw.mac_type == em_ich9lan) { + sc->hw.mac_type == em_ich9lan || + sc->hw.mac_type == em_ich10lan) { val = pci_conf_read(pa->pa_pc, pa->pa_tag, EM_FLASH); if (PCI_MAPREG_TYPE(val) != PCI_MAPREG_TYPE_MEM) { printf(": flash is not mem space\n"); diff --git a/sys/dev/pci/if_em_hw.c b/sys/dev/pci/if_em_hw.c index c2760b1a149..143f0a17ad8 100644 --- a/sys/dev/pci/if_em_hw.c +++ b/sys/dev/pci/if_em_hw.c @@ -31,7 +31,7 @@ *******************************************************************************/ -/* $OpenBSD: if_em_hw.c,v 1.37 2009/08/21 22:54:10 dms Exp $ */ +/* $OpenBSD: if_em_hw.c,v 1.38 2009/09/04 22:13:51 dms Exp $ */ /* if_em_hw.c * Shared functions for accessing and configuring the MAC @@ -85,6 +85,7 @@ static void em_clear_vfta(struct em_hw *hw); static int32_t em_commit_shadow_ram(struct em_hw *hw); static int32_t em_config_dsp_after_link_change(struct em_hw *hw, boolean_t link_up); static int32_t em_config_fc_after_link_up(struct em_hw *hw); +static int32_t em_match_gig_phy(struct em_hw *hw); static int32_t em_detect_gig_phy(struct em_hw *hw); static int32_t em_erase_ich8_4k_segment(struct em_hw *hw, uint32_t bank); static int32_t em_get_auto_rd_done(struct em_hw *hw); @@ -475,6 +476,7 @@ em_set_mac_type(struct em_hw *hw) case E1000_DEV_ID_ICH8_IGP_M_AMT: hw->mac_type = em_ich8lan; break; + case E1000_DEV_ID_ICH9_BM: case E1000_DEV_ID_ICH9_IFE: case E1000_DEV_ID_ICH9_IFE_G: case E1000_DEV_ID_ICH9_IFE_GT: @@ -482,8 +484,15 @@ em_set_mac_type(struct em_hw *hw) case E1000_DEV_ID_ICH9_IGP_C: case E1000_DEV_ID_ICH9_IGP_M: case E1000_DEV_ID_ICH9_IGP_M_AMT: + case E1000_DEV_ID_ICH10_R_BM_LF: + case E1000_DEV_ID_ICH10_R_BM_LM: + case E1000_DEV_ID_ICH10_R_BM_V: hw->mac_type = em_ich9lan; break; + case E1000_DEV_ID_ICH10_D_BM_LF: + case E1000_DEV_ID_ICH10_D_BM_LM: + hw->mac_type = em_ich10lan; + break; default: /* Should never have loaded on this device */ return -E1000_ERR_MAC_TYPE; @@ -492,6 +501,7 @@ em_set_mac_type(struct em_hw *hw) switch (hw->mac_type) { case em_ich8lan: case em_ich9lan: + case em_ich10lan: hw->swfwhw_semaphore_present = TRUE; hw->asf_firmware_present = TRUE; break; @@ -552,6 +562,7 @@ em_set_media_type(struct em_hw *hw) break; case em_ich8lan: case em_ich9lan: + case em_ich10lan: case em_82573: case em_82574: /* The STATUS_TBIMODE bit is reserved or reused for the this @@ -690,6 +701,7 @@ em_reset_hw(struct em_hw *hw) break; case em_ich8lan: case em_ich9lan: + case em_ich10lan: if (!hw->phy_reset_disable && em_check_phy_reset_block(hw) == E1000_SUCCESS) { /* PHY HW reset requires MAC CORE reset at the same @@ -781,7 +793,9 @@ em_reset_hw(struct em_hw *hw) em_pci_set_mwi(hw); } - if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan) { + if (hw->mac_type == em_ich8lan || + hw->mac_type == em_ich9lan || + hw->mac_type == em_ich10lan) { uint32_t kab = E1000_READ_REG(hw, KABGTXD); kab |= E1000_KABGTXD_BGSQLBIAS; E1000_WRITE_REG(hw, KABGTXD, kab); @@ -866,6 +880,7 @@ em_initialize_hardware_bits(struct em_hw *hw) break; case em_ich8lan: case em_ich9lan: + case em_ich10lan: if (hw->mac_type == em_ich8lan) reg_tarc0 |= 0x30000000; /* Set TARC0 bits 29 and 28 */ reg_ctrl_ext = E1000_READ_REG(hw, CTRL_EXT); @@ -945,7 +960,9 @@ em_init_hw(struct em_hw *hw) /* Disabling VLAN filtering. */ DEBUGOUT("Initializing the IEEE VLAN\n"); /* VET hardcoded to standard value and VFTA removed in ICH8/ICH9 LAN */ - if (hw->mac_type != em_ich8lan && hw->mac_type != em_ich9lan) { + if (hw->mac_type != em_ich8lan && + hw->mac_type != em_ich9lan && + hw->mac_type != em_ich10lan) { if (hw->mac_type < em_82545_rev_3) E1000_WRITE_REG(hw, VET, 0); em_clear_vfta(hw); @@ -977,7 +994,9 @@ em_init_hw(struct em_hw *hw) /* Zero out the Multicast HASH table */ DEBUGOUT("Zeroing the MTA\n"); mta_size = E1000_MC_TBL_SIZE; - if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan) + if (hw->mac_type == em_ich8lan || + hw->mac_type == em_ich9lan || + hw->mac_type == em_ich10lan) mta_size = E1000_MC_TBL_SIZE_ICH8LAN; for (i = 0; i < mta_size; i++) { E1000_WRITE_REG_ARRAY(hw, MTA, i, 0); @@ -1023,7 +1042,9 @@ em_init_hw(struct em_hw *hw) } /* More time needed for PHY to initialize */ - if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan) + if (hw->mac_type == em_ich8lan || + hw->mac_type == em_ich9lan || + hw->mac_type == em_ich10lan) msec_delay(15); /* Call a subroutine to configure the link and setup flow control. */ @@ -1070,6 +1091,7 @@ em_init_hw(struct em_hw *hw) case em_82575: case em_ich8lan: case em_ich9lan: + case em_ich10lan: ctrl = E1000_READ_REG(hw, TXDCTL1); ctrl = (ctrl & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB; E1000_WRITE_REG(hw, TXDCTL1, ctrl); @@ -1093,9 +1115,12 @@ em_init_hw(struct em_hw *hw) * Set to snoop by default after reset. */ if (hw->mac_type == em_ich8lan) snoop = PCI_EX_82566_SNOOP_ALL; - else if (hw->mac_type == em_ich9lan) + else if (hw->mac_type == em_ich9lan || + hw->mac_type == em_ich10lan) snoop = (u_int32_t)~(PCI_EX_NO_SNOOP_ALL); - if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan) + if (hw->mac_type == em_ich8lan || + hw->mac_type == em_ich9lan || + hw->mac_type == em_ich10lan) em_set_pci_ex_no_snoop(hw, snoop); if (hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER || @@ -1187,6 +1212,7 @@ em_setup_link(struct em_hw *hw) switch (hw->mac_type) { case em_ich8lan: case em_ich9lan: + case em_ich10lan: case em_82573: case em_82574: hw->fc = E1000_FC_FULL; @@ -1242,6 +1268,14 @@ em_setup_link(struct em_hw *hw) E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext); } + /* Make sure we have a valid PHY */ + ret_val = em_detect_gig_phy(hw); + if (ret_val) { + DEBUGOUT("Error, did not detect valid phy.\n"); + return ret_val; + } + DEBUGOUT1("Phy ID = %x \n", hw->phy_id); + /* Call the necessary subroutine to configure the link. */ ret_val = (hw->media_type == em_media_type_copper) ? em_setup_copper_link(hw) : @@ -1254,8 +1288,13 @@ em_setup_link(struct em_hw *hw) */ DEBUGOUT("Initializing the Flow Control address, type and timer regs\n"); - /* FCAL/H and FCT are hardcoded to standard values in em_ich8lan/em_ich9lan. */ - if (hw->mac_type != em_ich8lan && hw->mac_type != em_ich9lan) { + /* + * FCAL/H and FCT are hardcoded to standard values in + * em_ich8lan / em_ich9lan / em_ich10lan. + */ + if (hw->mac_type != em_ich8lan && + hw->mac_type != em_ich9lan && + hw->mac_type != em_ich10lan) { E1000_WRITE_REG(hw, FCT, FLOW_CONTROL_TYPE); E1000_WRITE_REG(hw, FCAH, FLOW_CONTROL_ADDRESS_HIGH); E1000_WRITE_REG(hw, FCAL, FLOW_CONTROL_ADDRESS_LOW); @@ -1469,14 +1508,6 @@ em_copper_link_preconfig(struct em_hw *hw) return ret_val; } - /* Make sure we have a valid PHY */ - ret_val = em_detect_gig_phy(hw); - if (ret_val) { - DEBUGOUT("Error, did not detect valid phy.\n"); - return ret_val; - } - DEBUGOUT1("Phy ID = %x \n", hw->phy_id); - /* Set PHY to class A mode (if necessary) */ ret_val = em_set_phy_mode(hw); if (ret_val) @@ -1523,7 +1554,9 @@ em_copper_link_igp_setup(struct em_hw *hw) /* Wait 15ms for MAC to configure PHY from eeprom settings */ msec_delay(15); - if (hw->mac_type != em_ich8lan && hw->mac_type != em_ich9lan) { + if (hw->mac_type != em_ich8lan && + hw->mac_type != em_ich9lan && + hw->mac_type != em_ich10lan) { /* Configure activity LED after PHY reset */ led_ctrl = E1000_READ_REG(hw, LEDCTL); led_ctrl &= IGP_ACTIVITY_LED_MASK; @@ -1863,7 +1896,8 @@ em_copper_link_mgp_setup(struct em_hw *hw) return ret_val; if ((hw->phy_type == em_phy_m88) && - (hw->phy_revision < M88E1011_I_REV_4)) { + (hw->phy_revision < M88E1011_I_REV_4) && + (hw->phy_id != BME1000_E_PHY_ID)) { /* Force TX_CLK in the Extended PHY Specific Control Register * to 25MHz clock. */ @@ -2050,6 +2084,7 @@ em_setup_copper_link(struct em_hw *hw) case em_80003es2lan: case em_ich8lan: case em_ich9lan: + case em_ich10lan: /* Set the mac to wait the maximum time between each * iteration and increase the max iterations when * polling the phy; this fixes erroneous timeouts at 10Mbps. */ @@ -3628,7 +3663,6 @@ em_read_phy_reg_ex(struct em_hw *hw, uint32_t reg_addr, { uint32_t i; uint32_t mdic = 0; - const uint32_t phy_addr = 1; DEBUGFUNC("em_read_phy_reg_ex"); @@ -3643,7 +3677,7 @@ em_read_phy_reg_ex(struct em_hw *hw, uint32_t reg_addr, * PHY to retrieve the desired data. */ mdic = ((reg_addr << E1000_MDIC_REG_SHIFT) | - (phy_addr << E1000_MDIC_PHY_SHIFT) | + (hw->phy_addr << E1000_MDIC_PHY_SHIFT) | (E1000_MDIC_OP_READ)); E1000_WRITE_REG(hw, MDIC, mdic); @@ -3681,7 +3715,7 @@ em_read_phy_reg_ex(struct em_hw *hw, uint32_t reg_addr, * READ operation is performed. These two bits are thrown away * followed by a shift in of 16 bits which contains the desired data. */ - mdic = ((reg_addr) | (phy_addr << 5) | + mdic = ((reg_addr) | (hw->phy_addr << 5) | (PHY_OP_READ << 10) | (PHY_SOF << 12)); em_shift_out_mdi_bits(hw, mdic, 14); @@ -3773,7 +3807,6 @@ em_write_phy_reg_ex(struct em_hw *hw, uint32_t reg_addr, { uint32_t i; uint32_t mdic = 0; - const uint32_t phy_addr = 1; DEBUGFUNC("em_write_phy_reg_ex"); @@ -3789,7 +3822,7 @@ em_write_phy_reg_ex(struct em_hw *hw, uint32_t reg_addr, */ mdic = (((uint32_t) phy_data) | (reg_addr << E1000_MDIC_REG_SHIFT) | - (phy_addr << E1000_MDIC_PHY_SHIFT) | + (hw->phy_addr << E1000_MDIC_PHY_SHIFT) | (E1000_MDIC_OP_WRITE)); E1000_WRITE_REG(hw, MDIC, mdic); @@ -3818,7 +3851,7 @@ em_write_phy_reg_ex(struct em_hw *hw, uint32_t reg_addr, * format of a MII write instruction is as follows: * <Preamble><SOF><Op Code><Phy Addr><Reg Addr><Turnaround><Data>. */ - mdic = ((PHY_TURNAROUND) | (reg_addr << 2) | (phy_addr << 7) | + mdic = ((PHY_TURNAROUND) | (reg_addr << 2) | (hw->phy_addr << 7) | (PHY_OP_WRITE << 12) | (PHY_SOF << 14)); mdic <<= 16; mdic |= (uint32_t) phy_data; @@ -4093,52 +4126,19 @@ em_kumeran_lock_loss_workaround(struct em_hw *hw) } /****************************************************************************** -* Probes the expected PHY address for known PHY IDs +* Reads and matches the expected PHY address for known PHY IDs * * hw - Struct containing variables accessed by shared code ******************************************************************************/ STATIC int32_t -em_detect_gig_phy(struct em_hw *hw) +em_match_gig_phy(struct em_hw *hw) { int32_t phy_init_status, ret_val; uint16_t phy_id_high, phy_id_low; boolean_t match = FALSE; - DEBUGFUNC("em_detect_gig_phy"); - - if (hw->phy_id != 0) - return E1000_SUCCESS; + DEBUGFUNC("em_match_gig_phy"); - /* The 82571 firmware may still be configuring the PHY. In this - * case, we cannot access the PHY until the configuration is done. So - * we explicitly set the PHY values. */ - if (hw->mac_type == em_82571 || - hw->mac_type == em_82572 || - hw->mac_type == em_82575) { - hw->phy_id = IGP01E1000_I_PHY_ID; - hw->phy_type = em_phy_igp_2; - return E1000_SUCCESS; - } - - /* until something better comes along... makes the Lenovo X200 work */ - if (hw->mac_type == em_ich9lan && - (hw->device_id == E1000_DEV_ID_ICH9_IGP_M || - hw->device_id == E1000_DEV_ID_ICH9_IGP_M_AMT)) { - hw->phy_id = IGP03E1000_E_PHY_ID; - hw->phy_type = em_phy_igp_3; - return E1000_SUCCESS; - } - - /* ESB-2 PHY reads require em_phy_gg82563 to be set because of a work- - * around that forces PHY page 0 to be set or the reads fail. The rest of - * the code in this routine uses em_read_phy_reg to read the PHY ID. - * So for ESB-2 we need to have this set so our reads won't fail. If the - * attached PHY is not a em_phy_gg82563, the routines below will figure - * this out as well. */ - if (hw->mac_type == em_80003es2lan) - hw->phy_type = em_phy_gg82563; - - /* Read the PHY ID Registers to identify which PHY is onboard. */ ret_val = em_read_phy_reg(hw, PHY_ID1, &phy_id_high); if (ret_val) return ret_val; @@ -4154,55 +4154,126 @@ em_detect_gig_phy(struct em_hw *hw) switch (hw->mac_type) { case em_82543: - if (hw->phy_id == M88E1000_E_PHY_ID) match = TRUE; - break; + if (hw->phy_id == M88E1000_E_PHY_ID) match = TRUE; + break; case em_82544: - if (hw->phy_id == M88E1000_I_PHY_ID) match = TRUE; - break; + if (hw->phy_id == M88E1000_I_PHY_ID) match = TRUE; + break; case em_82540: case em_82545: case em_82545_rev_3: case em_82546: case em_82546_rev_3: - if (hw->phy_id == M88E1011_I_PHY_ID) match = TRUE; - break; + if (hw->phy_id == M88E1011_I_PHY_ID) match = TRUE; + break; case em_82541: case em_82541_rev_2: case em_82547: case em_82547_rev_2: - if (hw->phy_id == IGP01E1000_I_PHY_ID) match = TRUE; - break; + if (hw->phy_id == IGP01E1000_I_PHY_ID) match = TRUE; + break; case em_82573: - if (hw->phy_id == M88E1111_I_PHY_ID) match = TRUE; - break; + if (hw->phy_id == M88E1111_I_PHY_ID) match = TRUE; + break; case em_82574: - if (hw->phy_id == BME1000_E_PHY_ID) match = TRUE; - break; + if (hw->phy_id == BME1000_E_PHY_ID) match = TRUE; + break; case em_80003es2lan: - if (hw->phy_id == GG82563_E_PHY_ID) match = TRUE; - break; + if (hw->phy_id == GG82563_E_PHY_ID) match = TRUE; + break; case em_ich8lan: case em_ich9lan: - if (hw->phy_id == IGP03E1000_E_PHY_ID) match = TRUE; - if (hw->phy_id == IFE_E_PHY_ID) match = TRUE; - if (hw->phy_id == IFE_PLUS_E_PHY_ID) match = TRUE; - if (hw->phy_id == IFE_C_E_PHY_ID) match = TRUE; - break; + case em_ich10lan: + if (hw->phy_id == IGP03E1000_E_PHY_ID) match = TRUE; + if (hw->phy_id == IFE_E_PHY_ID) match = TRUE; + if (hw->phy_id == IFE_PLUS_E_PHY_ID) match = TRUE; + if (hw->phy_id == IFE_C_E_PHY_ID) match = TRUE; + if (hw->phy_id == BME1000_E_PHY_ID) match = TRUE; + break; default: - DEBUGOUT1("Invalid MAC type %d\n", hw->mac_type); - return -E1000_ERR_CONFIG; + DEBUGOUT1("Invalid MAC type %d\n", hw->mac_type); + return -E1000_ERR_CONFIG; } phy_init_status = em_set_phy_type(hw); if ((match) && (phy_init_status == E1000_SUCCESS)) { - DEBUGOUT1("PHY ID 0x%X detected\n", hw->phy_id); - return E1000_SUCCESS; + DEBUGOUT1("PHY ID 0x%X detected\n", hw->phy_id); + return E1000_SUCCESS; } DEBUGOUT1("Invalid PHY ID 0x%X\n", hw->phy_id); return -E1000_ERR_PHY; } /****************************************************************************** +* Probes the expected PHY address for known PHY IDs +* +* hw - Struct containing variables accessed by shared code +******************************************************************************/ +STATIC int32_t +em_detect_gig_phy(struct em_hw *hw) +{ + int32_t ret_val; + + DEBUGFUNC("em_detect_gig_phy"); + + if (hw->phy_id != 0) + return E1000_SUCCESS; + + /* default phy address, most phys reside here, but not all (ICH10) */ + hw->phy_addr = 1; + + /* The 82571 firmware may still be configuring the PHY. In this + * case, we cannot access the PHY until the configuration is done. So + * we explicitly set the PHY values. */ + if (hw->mac_type == em_82571 || + hw->mac_type == em_82572 || + hw->mac_type == em_82575) { + hw->phy_id = IGP01E1000_I_PHY_ID; + hw->phy_type = em_phy_igp_2; + return E1000_SUCCESS; + } + + /* Some of the fiber cards dont have a phy, so we must exit cleanly here */ + if ((hw->media_type == em_media_type_fiber) && + (hw->mac_type == em_82542_rev2_0 || + hw->mac_type == em_82542_rev2_1 || + hw->mac_type == em_82543 || + hw->mac_type == em_82574 || + hw->mac_type == em_82573 || + hw->mac_type == em_82574 || + hw->mac_type == em_80003es2lan)) { + hw->phy_type = em_phy_undefined; + return E1000_SUCCESS; + } + + /* until something better comes along... makes the Lenovo X200 work */ + if (hw->mac_type == em_ich9lan && + (hw->device_id == E1000_DEV_ID_ICH9_IGP_M || + hw->device_id == E1000_DEV_ID_ICH9_IGP_M_AMT)) { + hw->phy_id = IGP03E1000_E_PHY_ID; + hw->phy_type = em_phy_igp_3; + return E1000_SUCCESS; + } + + /* ESB-2 PHY reads require em_phy_gg82563 to be set because of a work- + * around that forces PHY page 0 to be set or the reads fail. The rest of + * the code in this routine uses em_read_phy_reg to read the PHY ID. + * So for ESB-2 we need to have this set so our reads won't fail. If the + * attached PHY is not a em_phy_gg82563, the routines below will figure + * this out as well. */ + if (hw->mac_type == em_80003es2lan) + hw->phy_type = em_phy_gg82563; + + /* Read the PHY ID Registers to identify which PHY is onboard. */ + for (hw->phy_addr = 1; (hw->phy_addr < 4); hw->phy_addr++) { + ret_val = em_match_gig_phy(hw); + if (ret_val == E1000_SUCCESS) + return E1000_SUCCESS; + } + return -E1000_ERR_PHY; +} + +/****************************************************************************** * Resets the PHY's DSP * * hw - Struct containing variables accessed by shared code @@ -4362,6 +4433,7 @@ em_init_eeprom_params(struct em_hw *hw) break; case em_ich8lan: case em_ich9lan: + case em_ich10lan: { int32_t i = 0; uint32_t flash_size = E1000_READ_ICH_FLASH_REG(hw, ICH_FLASH_GFPREG); @@ -4981,7 +5053,9 @@ em_is_onboard_nvm_eeprom(struct em_hw *hw) DEBUGFUNC("em_is_onboard_nvm_eeprom"); - if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan) + if (hw->mac_type == em_ich8lan || + hw->mac_type == em_ich9lan || + hw->mac_type == em_ich10lan) return FALSE; if ((hw->mac_type == em_82573) || (hw->mac_type == em_82574)) { @@ -5034,7 +5108,9 @@ em_validate_eeprom_checksum(struct em_hw *hw) } } - if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan) { + if (hw->mac_type == em_ich8lan || + hw->mac_type == em_ich9lan || + hw->mac_type == em_ich10lan) { /* Drivers must allocate the shadow ram structure for the * EEPROM checksum to be updated. Otherwise, this bit as well * as the checksum must both be set correctly for this @@ -5591,7 +5667,9 @@ em_init_rx_addrs(struct em_hw *hw) * the other port. */ if ((hw->mac_type == em_82571) && (hw->laa_is_present == TRUE)) rar_num -= 1; - if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan) + if (hw->mac_type == em_ich8lan || + hw->mac_type == em_ich9lan || + hw->mac_type == em_ich10lan) rar_num = E1000_RAR_ENTRIES_ICH8LAN; if (hw->mac_type == em_ich8lan) rar_num -= 1; @@ -5640,7 +5718,9 @@ em_mc_addr_list_update(struct em_hw *hw, /* Clear RAR[1-15] */ DEBUGOUT(" Clearing RAR[1-15]\n"); num_rar_entry = E1000_RAR_ENTRIES; - if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan) + if (hw->mac_type == em_ich8lan || + hw->mac_type == em_ich9lan || + hw->mac_type == em_ich10lan) num_rar_entry = E1000_RAR_ENTRIES_ICH8LAN; if (hw->mac_type == em_ich8lan) num_rar_entry -= 1; @@ -5661,7 +5741,9 @@ em_mc_addr_list_update(struct em_hw *hw, /* Clear the MTA */ DEBUGOUT(" Clearing MTA\n"); num_mta_entry = E1000_NUM_MTA_REGISTERS; - if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan) + if (hw->mac_type == em_ich8lan || + hw->mac_type == em_ich9lan || + hw->mac_type == em_ich10lan) num_mta_entry = E1000_NUM_MTA_REGISTERS_ICH8LAN; for (i = 0; i < num_mta_entry; i++) { @@ -5722,7 +5804,9 @@ em_hash_mc_addr(struct em_hw *hw, * LSB MSB */ case 0: - if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan) { + if (hw->mac_type == em_ich8lan || + hw->mac_type == em_ich9lan || + hw->mac_type == em_ich10lan) { /* [47:38] i.e. 0x158 for above example address */ hash_value = ((mc_addr[4] >> 6) | (((uint16_t) mc_addr[5]) << 2)); } else { @@ -5731,7 +5815,9 @@ em_hash_mc_addr(struct em_hw *hw, } break; case 1: - if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan) { + if (hw->mac_type == em_ich8lan || + hw->mac_type == em_ich9lan || + hw->mac_type == em_ich10lan) { /* [46:37] i.e. 0x2B1 for above example address */ hash_value = ((mc_addr[4] >> 5) | (((uint16_t) mc_addr[5]) << 3)); } else { @@ -5740,7 +5826,9 @@ em_hash_mc_addr(struct em_hw *hw, } break; case 2: - if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan) { + if (hw->mac_type == em_ich8lan || + hw->mac_type == em_ich9lan || + hw->mac_type == em_ich10lan) { /*[45:36] i.e. 0x163 for above example address */ hash_value = ((mc_addr[4] >> 4) | (((uint16_t) mc_addr[5]) << 4)); } else { @@ -5749,7 +5837,9 @@ em_hash_mc_addr(struct em_hw *hw, } break; case 3: - if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan) { + if (hw->mac_type == em_ich8lan || + hw->mac_type == em_ich9lan || + hw->mac_type == em_ich10lan) { /* [43:34] i.e. 0x18D for above example address */ hash_value = ((mc_addr[4] >> 2) | (((uint16_t) mc_addr[5]) << 6)); } else { @@ -5760,7 +5850,9 @@ em_hash_mc_addr(struct em_hw *hw, } hash_value &= 0xFFF; - if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan) + if (hw->mac_type == em_ich8lan || + hw->mac_type == em_ich9lan || + hw->mac_type == em_ich10lan) hash_value &= 0x3FF; return hash_value; @@ -5789,7 +5881,9 @@ em_mta_set(struct em_hw *hw, * register are determined by the lower 5 bits of the value. */ hash_reg = (hash_value >> 5) & 0x7F; - if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan) + if (hw->mac_type == em_ich8lan || + hw->mac_type == em_ich9lan || + hw->mac_type == em_ich10lan) hash_reg &= 0x1F; hash_bit = hash_value & 0x1F; @@ -5885,7 +5979,9 @@ em_clear_vfta(struct em_hw *hw) uint32_t vfta_offset = 0; uint32_t vfta_bit_in_reg = 0; - if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan) + if (hw->mac_type == em_ich8lan || + hw->mac_type == em_ich9lan || + hw->mac_type == em_ich10lan) return; if ((hw->mac_type == em_82573) || (hw->mac_type == em_82574)) { @@ -5943,7 +6039,9 @@ em_id_led_init(struct em_hw * hw) eeprom_data = ID_LED_DEFAULT_82573; else if ((eeprom_data == ID_LED_RESERVED_0000) || (eeprom_data == ID_LED_RESERVED_FFFF)) { - if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan) + if (hw->mac_type == em_ich8lan || + hw->mac_type == em_ich9lan || + hw->mac_type == em_ich10lan) eeprom_data = ID_LED_DEFAULT_ICH8LAN; else eeprom_data = ID_LED_DEFAULT; @@ -6016,7 +6114,9 @@ em_clear_hw_cntrs(struct em_hw *hw) temp = E1000_READ_REG(hw, XOFFTXC); temp = E1000_READ_REG(hw, FCRUC); - if (hw->mac_type != em_ich8lan && hw->mac_type != em_ich9lan) { + if (hw->mac_type != em_ich8lan && + hw->mac_type != em_ich9lan && + hw->mac_type != em_ich10lan) { temp = E1000_READ_REG(hw, PRC64); temp = E1000_READ_REG(hw, PRC127); temp = E1000_READ_REG(hw, PRC255); @@ -6045,7 +6145,9 @@ em_clear_hw_cntrs(struct em_hw *hw) temp = E1000_READ_REG(hw, TPR); temp = E1000_READ_REG(hw, TPT); - if (hw->mac_type != em_ich8lan && hw->mac_type != em_ich9lan) { + if (hw->mac_type != em_ich8lan && + hw->mac_type != em_ich9lan && + hw->mac_type != em_ich10lan) { temp = E1000_READ_REG(hw, PTC64); temp = E1000_READ_REG(hw, PTC127); temp = E1000_READ_REG(hw, PTC255); @@ -6077,7 +6179,9 @@ em_clear_hw_cntrs(struct em_hw *hw) temp = E1000_READ_REG(hw, IAC); temp = E1000_READ_REG(hw, ICRXOC); - if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan) + if (hw->mac_type == em_ich8lan || + hw->mac_type == em_ich9lan || + hw->mac_type == em_ich10lan) return; temp = E1000_READ_REG(hw, ICRXPTC); @@ -6207,6 +6311,7 @@ em_get_bus_info(struct em_hw *hw) break; case em_ich8lan: case em_ich9lan: + case em_ich10lan: hw->bus_type = em_bus_type_pci_express; hw->bus_speed = em_bus_speed_2500; hw->bus_width = em_bus_width_pciex_1; @@ -6768,7 +6873,9 @@ em_set_d3_lplu_state(struct em_hw *hw, ret_val = em_read_phy_reg(hw, IGP01E1000_GMII_FIFO, &phy_data); if (ret_val) return ret_val; - } else if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan) { + } else if (hw->mac_type == em_ich8lan || + hw->mac_type == em_ich9lan || + hw->mac_type == em_ich10lan) { /* MAC writes into PHY register based on the state transition * and start auto-negotiation. SW driver can overwrite the settings * in CSR PHY power control E1000_PHY_CTRL register. */ @@ -6787,7 +6894,9 @@ em_set_d3_lplu_state(struct em_hw *hw, if (ret_val) return ret_val; } else { - if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan) { + if (hw->mac_type == em_ich8lan || + hw->mac_type == em_ich9lan || + hw->mac_type == em_ich10lan) { phy_ctrl &= ~E1000_PHY_CTRL_NOND0A_LPLU; E1000_WRITE_REG(hw, PHY_CTRL, phy_ctrl); } else { @@ -6838,7 +6947,9 @@ em_set_d3_lplu_state(struct em_hw *hw, if (ret_val) return ret_val; } else { - if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan) { + if (hw->mac_type == em_ich8lan || + hw->mac_type == em_ich9lan || + hw->mac_type == em_ich10lan) { phy_ctrl |= E1000_PHY_CTRL_NOND0A_LPLU; E1000_WRITE_REG(hw, PHY_CTRL, phy_ctrl); } else { @@ -6890,7 +7001,9 @@ em_set_d0_lplu_state(struct em_hw *hw, if (hw->mac_type <= em_82547_rev_2) return E1000_SUCCESS; - if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan) { + if (hw->mac_type == em_ich8lan || + hw->mac_type == em_ich9lan || + hw->mac_type == em_ich10lan) { phy_ctrl = E1000_READ_REG(hw, PHY_CTRL); } else { ret_val = em_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, &phy_data); @@ -6899,7 +7012,9 @@ em_set_d0_lplu_state(struct em_hw *hw, } if (!active) { - if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan) { + if (hw->mac_type == em_ich8lan || + hw->mac_type == em_ich9lan || + hw->mac_type == em_ich10lan) { phy_ctrl &= ~E1000_PHY_CTRL_D0A_LPLU; E1000_WRITE_REG(hw, PHY_CTRL, phy_ctrl); } else { @@ -6940,7 +7055,9 @@ em_set_d0_lplu_state(struct em_hw *hw, } else { - if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan) { + if (hw->mac_type == em_ich8lan || + hw->mac_type == em_ich9lan || + hw->mac_type == em_ich10lan) { phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU; E1000_WRITE_REG(hw, PHY_CTRL, phy_ctrl); } else { @@ -7099,7 +7216,9 @@ em_check_mng_mode(struct em_hw *hw) fwsm = E1000_READ_REG(hw, FWSM); - if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan) { + if (hw->mac_type == em_ich8lan || + hw->mac_type == em_ich9lan || + hw->mac_type == em_ich10lan) { if ((fwsm & E1000_FWSM_MODE_MASK) == (E1000_MNG_ICH_IAMT_MODE << E1000_FWSM_MODE_SHIFT)) return TRUE; @@ -7347,6 +7466,7 @@ em_get_auto_rd_done(struct em_hw *hw) case em_80003es2lan: case em_ich8lan: case em_ich9lan: + case em_ich10lan: while (timeout) { if (E1000_READ_REG(hw, EECD) & E1000_EECD_AUTO_RD) break; @@ -7574,7 +7694,9 @@ em_check_phy_reset_block(struct em_hw *hw) uint32_t manc = 0; uint32_t fwsm = 0; - if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan) { + if (hw->mac_type == em_ich8lan || + hw->mac_type == em_ich9lan || + hw->mac_type == em_ich10lan) { fwsm = E1000_READ_REG(hw, FWSM); return (fwsm & E1000_FWSM_RSPCIPHY) ? E1000_SUCCESS : E1000_BLK_PHY_RESET; @@ -7615,7 +7737,9 @@ em_set_pci_ex_no_snoop(struct em_hw *hw, uint32_t no_snoop) E1000_WRITE_REG(hw, GCR, gcr_reg); } - if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan) { + if (hw->mac_type == em_ich8lan || + hw->mac_type == em_ich9lan || + hw->mac_type == em_ich10lan) { uint32_t ctrl_ext; ctrl_ext = E1000_READ_REG(hw, CTRL_EXT); @@ -7643,7 +7767,9 @@ em_get_software_flag(struct em_hw *hw) DEBUGFUNC("em_get_software_flag"); - if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan) { + if (hw->mac_type == em_ich8lan || + hw->mac_type == em_ich9lan || + hw->mac_type == em_ich10lan) { while (timeout) { extcnf_ctrl = E1000_READ_REG(hw, EXTCNF_CTRL); extcnf_ctrl |= E1000_EXTCNF_CTRL_SWFLAG; @@ -7681,7 +7807,9 @@ em_release_software_flag(struct em_hw *hw) DEBUGFUNC("em_release_software_flag"); - if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan) { + if (hw->mac_type == em_ich8lan || + hw->mac_type == em_ich9lan || + hw->mac_type == em_ich10lan) { extcnf_ctrl= E1000_READ_REG(hw, EXTCNF_CTRL); extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG; E1000_WRITE_REG(hw, EXTCNF_CTRL, extcnf_ctrl); diff --git a/sys/dev/pci/if_em_hw.h b/sys/dev/pci/if_em_hw.h index 13b43a95100..2bec83a44d4 100644 --- a/sys/dev/pci/if_em_hw.h +++ b/sys/dev/pci/if_em_hw.h @@ -31,7 +31,7 @@ *******************************************************************************/ -/* $OpenBSD: if_em_hw.h,v 1.32 2009/08/21 22:54:10 dms Exp $ */ +/* $OpenBSD: if_em_hw.h,v 1.33 2009/09/04 22:13:51 dms Exp $ */ /* $FreeBSD: if_em_hw.h,v 1.15 2005/05/26 23:32:02 tackerman Exp $ */ /* if_em_hw.h @@ -72,6 +72,7 @@ typedef enum { em_80003es2lan, em_ich8lan, em_ich9lan, + em_ich10lan, em_num_macs } em_mac_type; |