diff options
author | Jonathan Gray <jsg@cvs.openbsd.org> | 2011-04-22 10:09:58 +0000 |
---|---|---|
committer | Jonathan Gray <jsg@cvs.openbsd.org> | 2011-04-22 10:09:58 +0000 |
commit | 8d25bab8671b0806e6ded1c09bd5cba62a9fcbab (patch) | |
tree | 02165381afbe61abc91f8e1a011555e222033ca5 /sys/dev/pci | |
parent | 1366352376f1311ca2317b2b23aaae682ff2f500 (diff) |
Add support for PCH2 (Sandy Bridge) MAC with 82579 PHY.
From Laurence Tratt.
ok claudio@ deraadt@
Diffstat (limited to 'sys/dev/pci')
-rw-r--r-- | sys/dev/pci/if_em.c | 10 | ||||
-rw-r--r-- | sys/dev/pci/if_em_hw.c | 213 | ||||
-rw-r--r-- | sys/dev/pci/if_em_hw.h | 9 |
3 files changed, 182 insertions, 50 deletions
diff --git a/sys/dev/pci/if_em.c b/sys/dev/pci/if_em.c index 7d1a39b6065..43804c17872 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.255 2011/04/14 21:14:28 jsg Exp $ */ +/* $OpenBSD: if_em.c,v 1.256 2011/04/22 10:09:57 jsg Exp $ */ /* $FreeBSD: if_em.c,v 1.46 2004/09/29 18:28:28 mlaier Exp $ */ #include <dev/pci/if_em.h> @@ -128,6 +128,8 @@ const struct pci_matchid em_devices[] = { { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82577LM }, { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82578DC }, { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82578DM }, + { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82579LM }, + { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82579V }, { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82580_COPPER }, { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82580_FIBER }, { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82580_SERDES }, @@ -756,6 +758,9 @@ em_init(void *arg) case em_pchlan: pba = E1000_PBA_10K; break; + case em_pch2lan: + pba = E1000_PBA_26K; + break; default: /* Devices before 82547 had a Packet Buffer of 64K. */ if (sc->hw.max_frame_size > EM_RXBUFFER_8192) @@ -1594,7 +1599,8 @@ em_allocate_pci_resources(struct em_softc *sc) if (sc->hw.mac_type == em_ich8lan || sc->hw.mac_type == em_ich9lan || sc->hw.mac_type == em_ich10lan || - sc->hw.mac_type == em_pchlan) { + sc->hw.mac_type == em_pchlan || + sc->hw.mac_type == em_pch2lan) { 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 b029e50e32a..7e05b34844e 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.62 2011/04/14 21:14:28 jsg Exp $ */ +/* $OpenBSD: if_em_hw.c,v 1.63 2011/04/22 10:09:57 jsg Exp $ */ /* * if_em_hw.c Shared functions for accessing and configuring the MAC */ @@ -158,6 +158,7 @@ static void em_release_eeprom(struct em_hw *); static void em_standby_eeprom(struct em_hw *); static int32_t em_set_vco_speed(struct em_hw *); static int32_t em_polarity_reversal_workaround(struct em_hw *); +static void em_pch2lan_disable_hw_config(struct em_hw *, boolean_t); static int32_t em_set_phy_mode(struct em_hw *); static int32_t em_host_if_read_cookie(struct em_hw *, uint8_t *); static uint8_t em_calculate_mng_checksum(char *, uint32_t); @@ -251,6 +252,9 @@ em_set_phy_type(struct em_hw *hw) case I82578_E_PHY_ID: hw->phy_type = em_phy_82578; break; + case I82579_E_PHY_ID: + hw->phy_type = em_phy_82579; + break; case I82580_I_PHY_ID: hw->phy_type = em_phy_82580; break; @@ -549,6 +553,10 @@ em_set_mac_type(struct em_hw *hw) case E1000_DEV_ID_PCH_D_HV_DM: hw->mac_type = em_pchlan; break; + case E1000_DEV_ID_PCH2_LV_LM: + case E1000_DEV_ID_PCH2_LV_V: + hw->mac_type = em_pch2lan; + break; case E1000_DEV_ID_EP80579_LAN_1: hw->mac_type = em_icp_xxxx; hw->icp_xxxx_port_num = 0; @@ -571,6 +579,7 @@ em_set_mac_type(struct em_hw *hw) case em_ich9lan: case em_ich10lan: case em_pchlan: + case em_pch2lan: hw->swfwhw_semaphore_present = TRUE; hw->asf_firmware_present = TRUE; break; @@ -659,6 +668,7 @@ em_set_media_type(struct em_hw *hw) case em_ich9lan: case em_ich10lan: case em_pchlan: + case em_pch2lan: case em_82573: case em_82574: /* @@ -813,6 +823,7 @@ em_reset_hw(struct em_hw *hw) case em_ich9lan: case em_ich10lan: case em_pchlan: + case em_pch2lan: if (!hw->phy_reset_disable && em_check_phy_reset_block(hw) == E1000_SUCCESS) { /* @@ -821,6 +832,11 @@ em_reset_hw(struct em_hw *hw) * the external PHY is reset. */ ctrl |= E1000_CTRL_PHY_RST; + + if ((hw->mac_type == em_pch2lan) && + !(E1000_READ_REG(hw, FWSM) & E1000_FWSM_FW_VALID)) { + em_pch2lan_disable_hw_config(hw, TRUE); + } } em_get_software_flag(hw); E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_RST)); @@ -831,8 +847,17 @@ em_reset_hw(struct em_hw *hw) break; } - if (hw->mac_type == em_pchlan) { - em_hv_phy_workarounds_ich8lan(hw); + if (em_check_phy_reset_block(hw) == E1000_SUCCESS) { + if (hw->mac_type == em_pchlan) { + ret_val = em_hv_phy_workarounds_ich8lan(hw); + if (ret_val) + return ret_val; + } + else if (hw->mac_type == em_pch2lan) { + ret_val = em_set_mdio_slow_mode_hv(hw); + if (ret_val) + return ret_val; + } } /* @@ -923,7 +948,8 @@ em_reset_hw(struct em_hw *hw) if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan || hw->mac_type == em_ich10lan || - hw->mac_type == em_pchlan) { + hw->mac_type == em_pchlan || + hw->mac_type == em_pch2lan) { uint32_t kab = E1000_READ_REG(hw, KABGTXD); kab |= E1000_KABGTXD_BGSQLBIAS; E1000_WRITE_REG(hw, KABGTXD, kab); @@ -941,6 +967,8 @@ em_reset_hw(struct em_hw *hw) STATIC void em_initialize_hardware_bits(struct em_hw *hw) { + DEBUGFUNC("em_initialize_hardware_bits"); + if ((hw->mac_type >= em_82571) && (!hw->initialize_hw_bits_disable)) { /* Settings common to all silicon */ uint32_t reg_ctrl, reg_ctrl_ext; @@ -1013,6 +1041,7 @@ em_initialize_hardware_bits(struct em_hw *hw) case em_ich9lan: case em_ich10lan: case em_pchlan: + case em_pch2lan: if (hw->mac_type == em_ich8lan) /* Set TARC0 bits 29 and 28 */ reg_tarc0 |= 0x30000000; @@ -1075,6 +1104,7 @@ em_init_hw(struct em_hw *hw) uint32_t reg_data; uint32_t ctrl_ext; uint32_t snoop; + uint32_t fwsm; DEBUGFUNC("em_init_hw"); /* force full DMA clock frequency for ICH8 */ @@ -1084,14 +1114,16 @@ em_init_hw(struct em_hw *hw) E1000_WRITE_REG(hw, STATUS, reg_data); } - if (hw->mac_type == em_pchlan) { + if (hw->mac_type == em_pchlan || + hw->mac_type == em_pch2lan) { /* * The MAC-PHY interconnect may still be in SMBus mode * after Sx->S0. Toggle the LANPHYPC Value bit to force * the interconnect to PCIe mode, but only if there is no * firmware present otherwise firmware will have done it. */ - if ((E1000_READ_REG(hw, FWSM) & E1000_FWSM_FW_VALID) == 0) { + fwsm = E1000_READ_REG(hw, FWSM); + if ((fwsm & E1000_FWSM_FW_VALID) == 0) { ctrl = E1000_READ_REG(hw, CTRL); ctrl |= E1000_CTRL_LANPHYPC_OVERRIDE; ctrl &= ~E1000_CTRL_LANPHYPC_VALUE; @@ -1101,6 +1133,10 @@ em_init_hw(struct em_hw *hw) E1000_WRITE_REG(hw, CTRL, ctrl); msec_delay(50); } + + if (hw->mac_type == em_pch2lan) + em_pch2lan_disable_hw_config(hw, TRUE); + /* * Reset the PHY before any acccess to it. Doing so, * ensures that the PHY is in a known good state before @@ -1110,6 +1146,10 @@ em_init_hw(struct em_hw *hw) */ em_phy_reset(hw); + if (hw->mac_type == em_pch2lan && + (fwsm & E1000_FWSM_FW_VALID) == 0) + em_pch2lan_disable_hw_config(hw, FALSE); + /* Set MDIO slow mode before any other MDIO access */ ret_val = em_set_mdio_slow_mode_hv(hw); if (ret_val) @@ -1134,7 +1174,8 @@ em_init_hw(struct em_hw *hw) if (hw->mac_type != em_ich8lan && hw->mac_type != em_ich9lan && hw->mac_type != em_ich10lan && - hw->mac_type != em_pchlan) { + hw->mac_type != em_pchlan && + hw->mac_type != em_pch2lan) { if (hw->mac_type < em_82545_rev_3) E1000_WRITE_REG(hw, VET, 0); em_clear_vfta(hw); @@ -1167,7 +1208,8 @@ em_init_hw(struct em_hw *hw) if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan || hw->mac_type == em_ich10lan || - hw->mac_type == em_pchlan) + hw->mac_type == em_pchlan || + hw->mac_type == em_pch2lan) mta_size = E1000_MC_TBL_SIZE_ICH8LAN; for (i = 0; i < mta_size; i++) { E1000_WRITE_REG_ARRAY(hw, MTA, i, 0); @@ -1224,7 +1266,8 @@ em_init_hw(struct em_hw *hw) if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan || hw->mac_type == em_ich10lan || - hw->mac_type == em_pchlan) + hw->mac_type == em_pchlan || + hw->mac_type == em_pch2lan) msec_delay(15); /* @@ -1286,6 +1329,7 @@ em_init_hw(struct em_hw *hw) case em_ich9lan: case em_ich10lan: case em_pchlan: + case em_pch2lan: ctrl = E1000_READ_REG(hw, TXDCTL1); ctrl = (ctrl & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB; @@ -1318,7 +1362,8 @@ em_init_hw(struct em_hw *hw) if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan || hw->mac_type == em_ich10lan || - hw->mac_type == em_pchlan) + hw->mac_type == em_pchlan || + hw->mac_type == em_pch2lan) em_set_pci_ex_no_snoop(hw, snoop); if (hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER || @@ -1418,6 +1463,7 @@ em_setup_link(struct em_hw *hw) case em_ich9lan: case em_ich10lan: case em_pchlan: + case em_pch2lan: case em_82573: case em_82574: hw->fc = E1000_FC_FULL; @@ -1509,7 +1555,8 @@ em_setup_link(struct em_hw *hw) if (hw->mac_type != em_ich8lan && hw->mac_type != em_ich9lan && hw->mac_type != em_ich10lan && - hw->mac_type != em_pchlan) { + hw->mac_type != em_pchlan && + hw->mac_type != em_pch2lan) { 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); @@ -1517,7 +1564,8 @@ em_setup_link(struct em_hw *hw) E1000_WRITE_REG(hw, FCTTV, hw->fc_pause_time); if (hw->phy_type == em_phy_82577 || - hw->phy_type == em_phy_82578) { + hw->phy_type == em_phy_82578 || + hw->phy_type == em_phy_82579) { E1000_WRITE_REG(hw, FCRTV_PCH, 0x1000); em_write_phy_reg(hw, PHY_REG(BM_PORT_CTRL_PAGE, 27), hw->fc_pause_time); @@ -1867,7 +1915,8 @@ em_copper_link_igp_setup(struct em_hw *hw) } } /* disable lplu d0 during driver init */ - if (hw->mac_type == em_pchlan) + if (hw->mac_type == em_pchlan || + hw->mac_type == em_pch2lan) ret_val = em_set_lplu_state_pchlan(hw, FALSE); else ret_val = em_set_d0_lplu_state(hw, FALSE); @@ -2137,7 +2186,8 @@ em_copper_link_mgp_setup(struct em_hw *hw) return E1000_SUCCESS; /* disable lplu d0 during driver init */ - if (hw->mac_type == em_pchlan) + if (hw->mac_type == em_pchlan || + hw->mac_type == em_pch2lan) ret_val = em_set_lplu_state_pchlan(hw, FALSE); /* Enable CRS on TX. This must be set for half-duplex operation. */ @@ -2478,6 +2528,7 @@ em_setup_copper_link(struct em_hw *hw) case em_ich9lan: case em_ich10lan: case em_pchlan: + case em_pch2lan: /* * Set the mac to wait the maximum time between each * iteration and increase the max iterations when polling the @@ -2536,7 +2587,8 @@ em_setup_copper_link(struct em_hw *hw) ret_val = em_copper_link_ggp_setup(hw); if (ret_val) return ret_val; - } else if (hw->phy_type == em_phy_82577) { + } else if (hw->phy_type == em_phy_82577 || + hw->phy_type == em_phy_82579) { ret_val = em_copper_link_82577_setup(hw); if (ret_val) return ret_val; @@ -4355,7 +4407,8 @@ em_read_phy_reg(struct em_hw *hw, uint32_t reg_addr, uint16_t *phy_data) uint16_t swfw; DEBUGFUNC("em_read_phy_reg"); - if (hw->mac_type == em_pchlan) + if (hw->mac_type == em_pchlan || + hw->mac_type == em_pch2lan) return (em_access_phy_reg_hv(hw, reg_addr, phy_data, TRUE)); if (((hw->mac_type == em_80003es2lan) || (hw->mac_type == em_82575)) && @@ -4467,6 +4520,9 @@ em_read_phy_reg_ex(struct em_hw *hw, uint32_t reg_addr, uint16_t *phy_data) return -E1000_ERR_PHY; } *phy_data = (uint16_t) mdic; + + if (hw->mac_type == em_pch2lan) + usec_delay(100); } else { /* * We must first send a preamble through the MDIO pin to @@ -4515,7 +4571,8 @@ em_write_phy_reg(struct em_hw *hw, uint32_t reg_addr, uint16_t phy_data) uint16_t swfw; DEBUGFUNC("em_write_phy_reg"); - if (hw->mac_type == em_pchlan) + if (hw->mac_type == em_pchlan || + hw->mac_type == em_pch2lan) return (em_access_phy_reg_hv(hw, reg_addr, &phy_data, FALSE)); if (((hw->mac_type == em_80003es2lan) || (hw->mac_type == em_82575)) && @@ -4620,6 +4677,9 @@ em_write_phy_reg_ex(struct em_hw *hw, uint32_t reg_addr, uint16_t phy_data) DEBUGOUT("MDI Write did not complete\n"); return -E1000_ERR_PHY; } + + if (hw->mac_type == em_pch2lan) + usec_delay(100); } else { /* * We'll need to use the SW defined pins to shift the write @@ -4926,6 +4986,11 @@ em_phy_reset(struct em_hw *hw) if (ret_val) return ret_val; } + else if (hw->mac_type == em_pch2lan) { + ret_val = em_set_mdio_slow_mode_hv(hw); + if (ret_val) + return ret_val; + } return E1000_SUCCESS; } @@ -5069,6 +5134,7 @@ em_match_gig_phy(struct em_hw *hw) case em_ich9lan: case em_ich10lan: case em_pchlan: + case em_pch2lan: if (hw->phy_id == IGP03E1000_E_PHY_ID) match = TRUE; if (hw->phy_id == IFE_E_PHY_ID) @@ -5083,6 +5149,8 @@ em_match_gig_phy(struct em_hw *hw) match = TRUE; if (hw->phy_id == I82578_E_PHY_ID) match = TRUE; + if (hw->phy_id == I82579_E_PHY_ID) + match = TRUE; break; case em_icp_xxxx: if (hw->phy_id == M88E1141_E_PHY_ID) @@ -5354,6 +5422,7 @@ em_init_eeprom_params(struct em_hw *hw) case em_ich9lan: case em_ich10lan: case em_pchlan: + case em_pch2lan: { int32_t i = 0; uint32_t flash_size = @@ -5977,7 +6046,8 @@ em_is_onboard_nvm_eeprom(struct em_hw *hw) if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan || hw->mac_type == em_ich10lan || - hw->mac_type == em_pchlan) + hw->mac_type == em_pchlan || + hw->mac_type == em_pch2lan) return FALSE; if ((hw->mac_type == em_82573) || (hw->mac_type == em_82574)) { @@ -6041,7 +6111,8 @@ em_validate_eeprom_checksum(struct em_hw *hw) if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan || hw->mac_type == em_ich10lan || - hw->mac_type == em_pchlan) { + hw->mac_type == em_pchlan || + hw->mac_type == em_pch2lan) { /* * Drivers must allocate the shadow ram structure for the * EEPROM checksum to be updated. Otherwise, this bit as @@ -6626,7 +6697,8 @@ em_init_rx_addrs(struct em_hw *hw) if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan || hw->mac_type == em_ich10lan || - hw->mac_type == em_pchlan) + hw->mac_type == em_pchlan || + hw->mac_type == em_pch2lan) rar_num = E1000_RAR_ENTRIES_ICH8LAN; if (hw->mac_type == em_ich8lan) rar_num -= 1; @@ -6678,7 +6750,8 @@ em_mc_addr_list_update(struct em_hw *hw, uint8_t *mc_addr_list, if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan || hw->mac_type == em_ich10lan || - hw->mac_type == em_pchlan) + hw->mac_type == em_pchlan || + hw->mac_type == em_pch2lan) num_rar_entry = E1000_RAR_ENTRIES_ICH8LAN; if (hw->mac_type == em_ich8lan) num_rar_entry -= 1; @@ -6703,7 +6776,8 @@ em_mc_addr_list_update(struct em_hw *hw, uint8_t *mc_addr_list, if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan || hw->mac_type == em_ich10lan || - hw->mac_type == em_pchlan) + hw->mac_type == em_pchlan || + hw->mac_type == em_pch2lan) num_mta_entry = E1000_NUM_MTA_REGISTERS_ICH8LAN; for (i = 0; i < num_mta_entry; i++) { @@ -6765,7 +6839,8 @@ em_hash_mc_addr(struct em_hw *hw, uint8_t *mc_addr) if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan || hw->mac_type == em_ich10lan || - hw->mac_type == em_pchlan) { + hw->mac_type == em_pchlan || + hw->mac_type == em_pch2lan) { /* [47:38] i.e. 0x158 for above example address */ hash_value = ((mc_addr[4] >> 6) | (((uint16_t) mc_addr[5]) << 2)); @@ -6779,7 +6854,8 @@ em_hash_mc_addr(struct em_hw *hw, uint8_t *mc_addr) if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan || hw->mac_type == em_ich10lan || - hw->mac_type == em_pchlan) { + hw->mac_type == em_pchlan || + hw->mac_type == em_pch2lan) { /* [46:37] i.e. 0x2B1 for above example address */ hash_value = ((mc_addr[4] >> 5) | (((uint16_t) mc_addr[5]) << 3)); @@ -6793,7 +6869,8 @@ em_hash_mc_addr(struct em_hw *hw, uint8_t *mc_addr) if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan || hw->mac_type == em_ich10lan || - hw->mac_type == em_pchlan) { + hw->mac_type == em_pchlan || + hw->mac_type == em_pch2lan) { /* [45:36] i.e. 0x163 for above example address */ hash_value = ((mc_addr[4] >> 4) | (((uint16_t) mc_addr[5]) << 4)); @@ -6807,7 +6884,8 @@ em_hash_mc_addr(struct em_hw *hw, uint8_t *mc_addr) if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan || hw->mac_type == em_ich10lan || - hw->mac_type == em_pchlan) { + hw->mac_type == em_pchlan || + hw->mac_type == em_pch2lan) { /* [43:34] i.e. 0x18D for above example address */ hash_value = ((mc_addr[4] >> 2) | (((uint16_t) mc_addr[5]) << 6)); @@ -6823,7 +6901,8 @@ em_hash_mc_addr(struct em_hw *hw, uint8_t *mc_addr) if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan || hw->mac_type == em_ich10lan || - hw->mac_type == em_pchlan) + hw->mac_type == em_pchlan || + hw->mac_type == em_pch2lan) hash_value &= 0x3FF; return hash_value; @@ -6854,7 +6933,8 @@ em_mta_set(struct em_hw *hw, uint32_t hash_value) if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan || hw->mac_type == em_ich10lan || - hw->mac_type == em_pchlan) + hw->mac_type == em_pchlan || + hw->mac_type == em_pch2lan) hash_reg &= 0x1F; hash_bit = hash_value & 0x1F; @@ -6948,7 +7028,8 @@ em_clear_vfta(struct em_hw *hw) if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan || hw->mac_type == em_ich10lan || - hw->mac_type == em_pchlan) + hw->mac_type == em_pchlan || + hw->mac_type == em_pch2lan) return; if ((hw->mac_type == em_82573) || (hw->mac_type == em_82574)) { @@ -7084,7 +7165,8 @@ em_clear_hw_cntrs(struct em_hw *hw) if (hw->mac_type != em_ich8lan && hw->mac_type != em_ich9lan && hw->mac_type != em_ich10lan && - hw->mac_type != em_pchlan) { + hw->mac_type != em_pchlan && + hw->mac_type != em_pch2lan) { temp = E1000_READ_REG(hw, PRC64); temp = E1000_READ_REG(hw, PRC127); temp = E1000_READ_REG(hw, PRC255); @@ -7115,7 +7197,8 @@ em_clear_hw_cntrs(struct em_hw *hw) if (hw->mac_type != em_ich8lan && hw->mac_type != em_ich9lan && hw->mac_type != em_ich10lan && - hw->mac_type != em_pchlan) { + hw->mac_type != em_pchlan && + hw->mac_type != em_pch2lan) { temp = E1000_READ_REG(hw, PTC64); temp = E1000_READ_REG(hw, PTC127); temp = E1000_READ_REG(hw, PTC255); @@ -7151,7 +7234,8 @@ em_clear_hw_cntrs(struct em_hw *hw) temp = E1000_READ_REG(hw, ICRXOC); if (hw->phy_type == em_phy_82577 || - hw->phy_type == em_phy_82578) { + hw->phy_type == em_phy_82578 || + hw->phy_type == em_phy_82579) { uint16_t phy_data; em_read_phy_reg(hw, HV_SCC_UPPER, &phy_data); @@ -7173,7 +7257,8 @@ em_clear_hw_cntrs(struct em_hw *hw) if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan || hw->mac_type == em_ich10lan || - hw->mac_type == em_pchlan) + hw->mac_type == em_pchlan || + hw->mac_type != em_pch2lan) return; temp = E1000_READ_REG(hw, ICRXPTC); @@ -7311,6 +7396,7 @@ em_get_bus_info(struct em_hw *hw) case em_ich9lan: case em_ich10lan: case em_pchlan: + case em_pch2lan: hw->bus_type = em_bus_type_pci_express; hw->bus_speed = em_bus_speed_2500; hw->bus_width = em_bus_width_pciex_1; @@ -7885,7 +7971,8 @@ em_set_d3_lplu_state(struct em_hw *hw, boolean_t active) } else if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan || hw->mac_type == em_ich10lan || - hw->mac_type == em_pchlan) { + hw->mac_type == em_pchlan || + hw->mac_type == em_pch2lan) { /* * MAC writes into PHY register based on the state transition * and start auto-negotiation. SW driver can overwrite the @@ -7911,7 +7998,8 @@ em_set_d3_lplu_state(struct em_hw *hw, boolean_t active) if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan || hw->mac_type == em_ich10lan || - hw->mac_type == em_pchlan) { + hw->mac_type == em_pchlan || + hw->mac_type == em_pch2lan) { phy_ctrl &= ~E1000_PHY_CTRL_NOND0A_LPLU; E1000_WRITE_REG(hw, PHY_CTRL, phy_ctrl); } else { @@ -7966,7 +8054,8 @@ em_set_d3_lplu_state(struct em_hw *hw, boolean_t active) if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan || hw->mac_type == em_ich10lan || - hw->mac_type == em_pchlan) { + hw->mac_type == em_pchlan || + hw->mac_type == em_pch2lan) { phy_ctrl |= E1000_PHY_CTRL_NOND0A_LPLU; E1000_WRITE_REG(hw, PHY_CTRL, phy_ctrl); } else { @@ -8021,7 +8110,8 @@ em_set_d0_lplu_state(struct em_hw *hw, boolean_t active) if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan || hw->mac_type == em_ich10lan || - hw->mac_type == em_pchlan) { + hw->mac_type == em_pchlan || + hw->mac_type == em_pch2lan) { phy_ctrl = E1000_READ_REG(hw, PHY_CTRL); } else { ret_val = em_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, @@ -8034,7 +8124,8 @@ em_set_d0_lplu_state(struct em_hw *hw, boolean_t active) if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan || hw->mac_type == em_ich10lan || - hw->mac_type == em_pchlan) { + hw->mac_type == em_pchlan || + hw->mac_type == em_pch2lan) { phy_ctrl &= ~E1000_PHY_CTRL_D0A_LPLU; E1000_WRITE_REG(hw, PHY_CTRL, phy_ctrl); } else { @@ -8077,7 +8168,8 @@ em_set_d0_lplu_state(struct em_hw *hw, boolean_t active) if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan || hw->mac_type == em_ich10lan || - hw->mac_type == em_pchlan) { + hw->mac_type == em_pchlan || + hw->mac_type == em_pch2lan) { phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU; E1000_WRITE_REG(hw, PHY_CTRL, phy_ctrl); } else { @@ -8269,7 +8361,8 @@ em_check_mng_mode(struct em_hw *hw) if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan || hw->mac_type == em_ich10lan || - hw->mac_type == em_pchlan) { + hw->mac_type == em_pchlan || + hw->mac_type == em_pch2lan) { if ((fwsm & E1000_FWSM_MODE_MASK) == (E1000_MNG_ICH_IAMT_MODE << E1000_FWSM_MODE_SHIFT)) return TRUE; @@ -8423,6 +8516,24 @@ em_polarity_reversal_workaround(struct em_hw *hw) return E1000_SUCCESS; } +/* + * Set whether the PHY self-configures itself in hardware + */ +static void em_pch2lan_disable_hw_config(struct em_hw *hw, boolean_t sc) +{ + uint32_t ctrl_ext; + DEBUGFUNC("em_pch2lan_disable_hw_config"); + + ctrl_ext = E1000_READ_REG(hw, CTRL_EXT); + + if (sc) + ctrl_ext |= E1000_CTRL_EXT_SDP3_DATA; + else + ctrl_ext &= ~E1000_CTRL_EXT_SDP3_DATA; + + E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext); +} + /****************************************************************************** * * Disables PCI-Express master access. @@ -8516,6 +8627,7 @@ em_get_auto_rd_done(struct em_hw *hw) case em_ich9lan: case em_ich10lan: case em_pchlan: + case em_pch2lan: while (timeout) { if (E1000_READ_REG(hw, EECD) & E1000_EECD_AUTO_RD) break; @@ -8744,7 +8856,8 @@ em_check_phy_reset_block(struct em_hw *hw) if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan || hw->mac_type == em_ich10lan || - hw->mac_type == em_pchlan) { + hw->mac_type == em_pchlan || + hw->mac_type == em_pch2lan) { fwsm = E1000_READ_REG(hw, FWSM); return (fwsm & E1000_FWSM_RSPCIPHY) ? E1000_SUCCESS : E1000_BLK_PHY_RESET; @@ -8785,7 +8898,8 @@ em_set_pci_ex_no_snoop(struct em_hw *hw, uint32_t no_snoop) if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan || hw->mac_type == em_ich10lan || - hw->mac_type == em_pchlan) { + hw->mac_type == em_pchlan || + hw->mac_type == em_pch2lan) { uint32_t ctrl_ext; ctrl_ext = E1000_READ_REG(hw, CTRL_EXT); ctrl_ext |= E1000_CTRL_EXT_RO_DIS; @@ -8813,7 +8927,8 @@ em_get_software_flag(struct em_hw *hw) if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan || hw->mac_type == em_ich10lan || - hw->mac_type == em_pchlan) { + hw->mac_type == em_pchlan || + hw->mac_type == em_pch2lan) { while (timeout) { extcnf_ctrl = E1000_READ_REG(hw, EXTCNF_CTRL); extcnf_ctrl |= E1000_EXTCNF_CTRL_SWFLAG; @@ -8852,7 +8967,8 @@ em_release_software_flag(struct em_hw *hw) if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan || hw->mac_type == em_ich10lan || - hw->mac_type == em_pchlan) { + hw->mac_type == em_pchlan || + hw->mac_type == em_pch2lan) { extcnf_ctrl = E1000_READ_REG(hw, EXTCNF_CTRL); extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG; E1000_WRITE_REG(hw, EXTCNF_CTRL, extcnf_ctrl); @@ -9538,9 +9654,10 @@ em_init_lcd_from_nvm(struct em_hw *hw) return E1000_SUCCESS; /* Check if SW needs configure the PHY */ - if ((hw->device_id == E1000_DEV_ID_ICH8_IGP_M_AMT) || - (hw->device_id == E1000_DEV_ID_ICH8_IGP_M) || - (hw->mac_type == em_pchlan)) + if (hw->device_id == E1000_DEV_ID_ICH8_IGP_M_AMT || + hw->device_id == E1000_DEV_ID_ICH8_IGP_M || + hw->mac_type == em_pchlan || + hw->mac_type == em_pch2lan) sw_cfg_mask = FEXTNVM_SW_CONFIG_ICH8M; else sw_cfg_mask = FEXTNVM_SW_CONFIG; @@ -9661,6 +9778,7 @@ em_set_mdio_slow_mode_hv(struct em_hw *hw) { int32_t ret_val; uint16_t data; + DEBUGFUNC("em_set_mdio_slow_mode_hv"); ret_val = em_read_phy_reg(hw, HV_KMRN_MODE_CTRL, &data); if (ret_val) @@ -9682,6 +9800,7 @@ em_hv_phy_workarounds_ich8lan(struct em_hw *hw) int32_t ret_val = E1000_SUCCESS; uint16_t phy_data; uint16_t swfw; + DEBUGFUNC("em_hv_phy_workarounds_ich8lan"); if (hw->mac_type != em_pchlan) goto out; diff --git a/sys/dev/pci/if_em_hw.h b/sys/dev/pci/if_em_hw.h index e3857b4f708..cf750ae6c9d 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.49 2011/04/14 21:14:28 jsg Exp $ */ +/* $OpenBSD: if_em_hw.h,v 1.50 2011/04/22 10:09:57 jsg Exp $ */ /* $FreeBSD: if_em_hw.h,v 1.15 2005/05/26 23:32:02 tackerman Exp $ */ /* if_em_hw.h @@ -76,6 +76,7 @@ typedef enum { em_ich9lan, em_ich10lan, em_pchlan, + em_pch2lan, em_num_macs } em_mac_type; @@ -239,6 +240,7 @@ typedef enum { em_phy_oem, em_phy_82577, em_phy_82578, + em_phy_82579, em_phy_82580, em_phy_undefined = 0xFF } em_phy_type; @@ -531,6 +533,8 @@ int32_t em_check_phy_reset_block(struct em_hw *hw); #define E1000_DEV_ID_PCH_M_HV_LC 0x10EB #define E1000_DEV_ID_PCH_D_HV_DM 0x10EF #define E1000_DEV_ID_PCH_D_HV_DC 0x10F0 +#define E1000_DEV_ID_PCH2_LV_LM 0x1502 +#define E1000_DEV_ID_PCH2_LV_V 0x1503 #define E1000_DEV_ID_82575EB_PT 0x10A7 #define E1000_DEV_ID_82575EB_PF 0x10A9 #define E1000_DEV_ID_82575GB_QP 0x10D6 @@ -543,6 +547,8 @@ int32_t em_check_phy_reset_block(struct em_hw *hw); #define E1000_DEV_ID_82583V 0x150C #define E1000_DEV_ID_82576_NS_SERDES 0x1518 #define E1000_DEV_ID_82576_SERDES_QUAD 0x150D +#define E1000_DEV_ID_PCH2_LV_LM 0x1502 +#define E1000_DEV_ID_PCH2_LV_V 0x1503 #define E1000_DEV_ID_82580_COPPER 0x150E #define E1000_DEV_ID_82580_FIBER 0x150F #define E1000_DEV_ID_82580_SERDES 0x1510 @@ -3291,6 +3297,7 @@ struct em_host_command_info { #define BME1000_E_PHY_ID_R2 0x01410CB1 #define I82577_E_PHY_ID 0x01540050 #define I82578_E_PHY_ID 0x004DD040 +#define I82579_E_PHY_ID 0x01540090 #define I82580_I_PHY_ID 0x015403A0 #define I350_I_PHY_ID 0x015403B0 #define IGP04E1000_E_PHY_ID 0x02A80391 |