diff options
author | Jonathan Gray <jsg@cvs.openbsd.org> | 2010-06-21 21:11:54 +0000 |
---|---|---|
committer | Jonathan Gray <jsg@cvs.openbsd.org> | 2010-06-21 21:11:54 +0000 |
commit | 6efc9494c0e1e839e444f134fd91f4e33b511e77 (patch) | |
tree | db1fa9765f2b3966a18e3214ca200504319d4739 | |
parent | 53da2d96a39440a73d568a8e7389690e27d36c1c (diff) |
Initial support for PCH based em adapters with 82577 PHY,
from Laurence Tratt based on FreeBSD code. Confirmed to
work on lenovo t410i/t410s/x201.
Desktop machines with PCH tend to be paired with a 82578 PHY,
these will at some point be supported but not yet.
ok claudio@
-rw-r--r-- | sys/dev/pci/if_em.c | 11 | ||||
-rw-r--r-- | sys/dev/pci/if_em_hw.c | 171 | ||||
-rw-r--r-- | sys/dev/pci/if_em_hw.h | 16 |
3 files changed, 160 insertions, 38 deletions
diff --git a/sys/dev/pci/if_em.c b/sys/dev/pci/if_em.c index c7771e38666..fc75b239b21 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.237 2010/06/21 20:43:44 jsg Exp $ */ +/* $OpenBSD: if_em.c,v 1.238 2010/06/21 21:11:52 jsg Exp $ */ /* $FreeBSD: if_em.c,v 1.46 2004/09/29 18:28:28 mlaier Exp $ */ #include <dev/pci/if_em.h> @@ -131,6 +131,8 @@ const struct pci_matchid em_devices[] = { { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82576_NS }, { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82576_NS_SERDES }, { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82576_SERDES_QUAD }, + { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82577LC }, + { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82577LM }, { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_ICH8_82567V_3 }, { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_ICH8_IFE }, { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_ICH8_IFE_G }, @@ -399,6 +401,9 @@ em_attach(struct device *parent, struct device *self, void *aux) /* Limit Jumbo Frame size */ sc->hw.max_frame_size = 9234; break; + case em_pchlan: + sc->hw.max_frame_size = 4096; + break; case em_82542_rev2_0: case em_82542_rev2_1: case em_ich8lan: @@ -761,6 +766,7 @@ em_init(void *arg) break; case em_ich9lan: case em_ich10lan: + case em_pchlan: pba = E1000_PBA_10K; break; default: @@ -1593,7 +1599,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_ich10lan) { + sc->hw.mac_type == em_ich10lan || + sc->hw.mac_type == em_pchlan) { 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 29dd2827405..e199ba72802 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.48 2010/06/21 20:43:44 jsg Exp $ */ +/* $OpenBSD: if_em_hw.c,v 1.49 2010/06/21 21:11:52 jsg Exp $ */ /* * if_em_hw.c Shared functions for accessing and configuring the MAC */ @@ -229,6 +229,9 @@ em_set_phy_type(struct em_hw *hw) case M88E1141_E_PHY_ID: hw->phy_type = em_phy_oem; break; + case I82577_E_PHY_ID: + hw->phy_type = em_phy_82577; + break; case BME1000_E_PHY_ID: if (hw->phy_revision == 1) { hw->phy_type = em_phy_bm; @@ -509,6 +512,10 @@ em_set_mac_type(struct em_hw *hw) case E1000_DEV_ID_ICH10_D_BM_LM: hw->mac_type = em_ich10lan; break; + case E1000_DEV_ID_PCH_M_HV_LC: + case E1000_DEV_ID_PCH_M_HV_LM: + hw->mac_type = em_pchlan; + break; case E1000_DEV_ID_EP80579_LAN_1: hw->mac_type = em_icp_xxxx; hw->icp_xxxx_port_num = 0; @@ -530,6 +537,7 @@ em_set_mac_type(struct em_hw *hw) case em_ich8lan: case em_ich9lan: case em_ich10lan: + case em_pchlan: hw->swfwhw_semaphore_present = TRUE; hw->asf_firmware_present = TRUE; break; @@ -593,6 +601,7 @@ em_set_media_type(struct em_hw *hw) case em_ich8lan: case em_ich9lan: case em_ich10lan: + case em_pchlan: case em_82573: case em_82574: /* @@ -746,6 +755,7 @@ em_reset_hw(struct em_hw *hw) case em_ich8lan: case em_ich9lan: case em_ich10lan: + case em_pchlan: if (!hw->phy_reset_disable && em_check_phy_reset_block(hw) == E1000_SUCCESS) { /* @@ -827,6 +837,15 @@ em_reset_hw(struct em_hw *hw) led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE); E1000_WRITE_REG(hw, LEDCTL, led_ctrl); } + + /* + * For PCH, this write will make sure that any noise + * will be detected as a CRC error and be dropped rather than show up + * as a bad packet to the DMA engine. + */ + if (hw->mac_type == em_pchlan) + E1000_WRITE_REG(hw, CRC_OFFSET, 0x65656565); + /* Clear interrupt mask to stop board from generating interrupts */ DEBUGOUT("Masking off all interrupts\n"); E1000_WRITE_REG(hw, IMC, 0xffffffff); @@ -841,7 +860,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_ich10lan || + hw->mac_type == em_pchlan) { uint32_t kab = E1000_READ_REG(hw, KABGTXD); kab |= E1000_KABGTXD_BGSQLBIAS; E1000_WRITE_REG(hw, KABGTXD, kab); @@ -930,6 +950,7 @@ em_initialize_hardware_bits(struct em_hw *hw) case em_ich8lan: case em_ich9lan: case em_ich10lan: + case em_pchlan: if (hw->mac_type == em_ich8lan) /* Set TARC0 bits 29 and 28 */ reg_tarc0 |= 0x30000000; @@ -1014,7 +1035,8 @@ em_init_hw(struct em_hw *hw) /* VET hardcoded to standard value and VFTA removed in ICH8/ICH9 LAN */ if (hw->mac_type != em_ich8lan && hw->mac_type != em_ich9lan && - hw->mac_type != em_ich10lan) { + hw->mac_type != em_ich10lan && + hw->mac_type != em_pchlan) { if (hw->mac_type < em_82545_rev_3) E1000_WRITE_REG(hw, VET, 0); em_clear_vfta(hw); @@ -1046,7 +1068,8 @@ em_init_hw(struct em_hw *hw) mta_size = E1000_MC_TBL_SIZE; if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan || - hw->mac_type == em_ich10lan) + hw->mac_type == em_ich10lan || + hw->mac_type == em_pchlan) mta_size = E1000_MC_TBL_SIZE_ICH8LAN; for (i = 0; i < mta_size; i++) { E1000_WRITE_REG_ARRAY(hw, MTA, i, 0); @@ -1102,7 +1125,8 @@ 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 || - hw->mac_type == em_ich10lan) + hw->mac_type == em_ich10lan || + hw->mac_type == em_pchlan) msec_delay(15); /* Call a subroutine to configure the link and setup flow control. */ @@ -1149,6 +1173,7 @@ em_init_hw(struct em_hw *hw) case em_ich8lan: case em_ich9lan: case em_ich10lan: + case em_pchlan: ctrl = E1000_READ_REG(hw, TXDCTL1); ctrl = (ctrl & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB; @@ -1175,11 +1200,13 @@ em_init_hw(struct em_hw *hw) if (hw->mac_type == em_ich8lan) snoop = PCI_EX_82566_SNOOP_ALL; else if (hw->mac_type == em_ich9lan || - hw->mac_type == em_ich10lan) + hw->mac_type == em_ich10lan || + hw->mac_type == em_pchlan) snoop = (u_int32_t) ~ (PCI_EX_NO_SNOOP_ALL); if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan || - hw->mac_type == em_ich10lan) + hw->mac_type == em_ich10lan || + hw->mac_type == em_pchlan) em_set_pci_ex_no_snoop(hw, snoop); if (hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER || @@ -1277,6 +1304,7 @@ em_setup_link(struct em_hw *hw) case em_ich8lan: case em_ich9lan: case em_ich10lan: + case em_pchlan: case em_82573: case em_82574: hw->fc = E1000_FC_FULL; @@ -1367,7 +1395,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_ich10lan && + hw->mac_type != em_pchlan) { 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); @@ -2056,6 +2085,41 @@ em_copper_link_mgp_setup(struct em_hw *hw) } /****************************************************************************** + * Copper link setup for em_phy_82577 series. + * + * hw - Struct containing variables accessed by shared code + *****************************************************************************/ +static int32_t +em_copper_link_82577_setup(struct em_hw *hw) +{ + int32_t ret_val; + uint16_t phy_data; + uint32_t led_ctl; + DEBUGFUNC("em_copper_link_82577_setup"); + + if (hw->phy_reset_disable) + return E1000_SUCCESS; + + /* Enable CRS on TX for half-duplex operation. */ + ret_val = em_read_phy_reg(hw, I82577_PHY_CFG_REG, &phy_data); + if (ret_val) + return ret_val; + + phy_data |= I82577_PHY_CFG_ENABLE_CRS_ON_TX | + I82577_PHY_CFG_ENABLE_DOWNSHIFT; + + ret_val = em_write_phy_reg(hw, I82577_PHY_CFG_REG, phy_data); + if (ret_val) + return ret_val; + + /* Wait 15ms for MAC to configure PHY from eeprom settings */ + msec_delay(15); + led_ctl = hw->ledctl_mode1; + E1000_WRITE_REG(hw, LEDCTL, led_ctl); + return E1000_SUCCESS; +} + +/****************************************************************************** * Setup auto-negotiation and flow control advertisements, * and then perform auto-negotiation. * @@ -2182,6 +2246,7 @@ em_setup_copper_link(struct em_hw *hw) case em_ich8lan: case em_ich9lan: case em_ich10lan: + case em_pchlan: /* * Set the mac to wait the maximum time between each * iteration and increase the max iterations when polling the @@ -2239,6 +2304,10 @@ 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) { + ret_val = em_copper_link_82577_setup(hw); + if (ret_val) + return ret_val; } if (hw->autoneg) { /* @@ -4414,6 +4483,7 @@ em_match_gig_phy(struct em_hw *hw) case em_ich8lan: case em_ich9lan: case em_ich10lan: + case em_pchlan: if (hw->phy_id == IGP03E1000_E_PHY_ID) match = TRUE; if (hw->phy_id == IFE_E_PHY_ID) @@ -4424,6 +4494,8 @@ em_match_gig_phy(struct em_hw *hw) match = TRUE; if (hw->phy_id == BME1000_E_PHY_ID) match = TRUE; + if (hw->phy_id == I82577_E_PHY_ID) + match = TRUE; break; case em_icp_xxxx: if (hw->phy_id == M88E1141_E_PHY_ID) @@ -4685,6 +4757,7 @@ em_init_eeprom_params(struct em_hw *hw) case em_ich8lan: case em_ich9lan: case em_ich10lan: + case em_pchlan: { int32_t i = 0; uint32_t flash_size = @@ -5301,7 +5374,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_ich10lan || + hw->mac_type == em_pchlan) return FALSE; if ((hw->mac_type == em_82573) || (hw->mac_type == em_82574)) { @@ -5364,7 +5438,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_ich10lan || + hw->mac_type == em_pchlan) { /* * Drivers must allocate the shadow ram structure for the * EEPROM checksum to be updated. Otherwise, this bit as @@ -5947,7 +6022,8 @@ em_init_rx_addrs(struct em_hw *hw) rar_num -= 1; if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan || - hw->mac_type == em_ich10lan) + hw->mac_type == em_ich10lan || + hw->mac_type == em_pchlan) rar_num = E1000_RAR_ENTRIES_ICH8LAN; if (hw->mac_type == em_ich8lan) rar_num -= 1; @@ -5996,7 +6072,8 @@ em_mc_addr_list_update(struct em_hw *hw, uint8_t *mc_addr_list, num_rar_entry = E1000_RAR_ENTRIES; if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan || - hw->mac_type == em_ich10lan) + hw->mac_type == em_ich10lan || + hw->mac_type == em_pchlan) num_rar_entry = E1000_RAR_ENTRIES_ICH8LAN; if (hw->mac_type == em_ich8lan) num_rar_entry -= 1; @@ -6020,7 +6097,8 @@ em_mc_addr_list_update(struct em_hw *hw, uint8_t *mc_addr_list, num_mta_entry = E1000_NUM_MTA_REGISTERS; if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan || - hw->mac_type == em_ich10lan) + hw->mac_type == em_ich10lan || + hw->mac_type == em_pchlan) num_mta_entry = E1000_NUM_MTA_REGISTERS_ICH8LAN; for (i = 0; i < num_mta_entry; i++) { @@ -6081,7 +6159,8 @@ em_hash_mc_addr(struct em_hw *hw, uint8_t *mc_addr) case 0: if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan || - hw->mac_type == em_ich10lan) { + hw->mac_type == em_ich10lan || + hw->mac_type == em_pchlan) { /* [47:38] i.e. 0x158 for above example address */ hash_value = ((mc_addr[4] >> 6) | (((uint16_t) mc_addr[5]) << 2)); @@ -6094,7 +6173,8 @@ em_hash_mc_addr(struct em_hw *hw, uint8_t *mc_addr) case 1: if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan || - hw->mac_type == em_ich10lan) { + hw->mac_type == em_ich10lan || + hw->mac_type == em_pchlan) { /* [46:37] i.e. 0x2B1 for above example address */ hash_value = ((mc_addr[4] >> 5) | (((uint16_t) mc_addr[5]) << 3)); @@ -6107,7 +6187,8 @@ em_hash_mc_addr(struct em_hw *hw, uint8_t *mc_addr) case 2: if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan || - hw->mac_type == em_ich10lan) { + hw->mac_type == em_ich10lan || + hw->mac_type == em_pchlan) { /* [45:36] i.e. 0x163 for above example address */ hash_value = ((mc_addr[4] >> 4) | (((uint16_t) mc_addr[5]) << 4)); @@ -6120,7 +6201,8 @@ em_hash_mc_addr(struct em_hw *hw, uint8_t *mc_addr) case 3: if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan || - hw->mac_type == em_ich10lan) { + hw->mac_type == em_ich10lan || + hw->mac_type == em_pchlan) { /* [43:34] i.e. 0x18D for above example address */ hash_value = ((mc_addr[4] >> 2) | (((uint16_t) mc_addr[5]) << 6)); @@ -6135,7 +6217,8 @@ em_hash_mc_addr(struct em_hw *hw, uint8_t *mc_addr) hash_value &= 0xFFF; if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan || - hw->mac_type == em_ich10lan) + hw->mac_type == em_ich10lan || + hw->mac_type == em_pchlan) hash_value &= 0x3FF; return hash_value; @@ -6165,7 +6248,8 @@ em_mta_set(struct em_hw *hw, uint32_t hash_value) hash_reg = (hash_value >> 5) & 0x7F; if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan || - hw->mac_type == em_ich10lan) + hw->mac_type == em_ich10lan || + hw->mac_type == em_pchlan) hash_reg &= 0x1F; hash_bit = hash_value & 0x1F; @@ -6258,7 +6342,8 @@ em_clear_vfta(struct em_hw *hw) uint32_t vfta_bit_in_reg = 0; if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan || - hw->mac_type == em_ich10lan) + hw->mac_type == em_ich10lan || + hw->mac_type == em_pchlan) return; if ((hw->mac_type == em_82573) || (hw->mac_type == em_82574)) { @@ -6320,7 +6405,7 @@ em_id_led_init(struct em_hw *hw) (eeprom_data == ID_LED_RESERVED_FFFF)) { if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan || - hw->mac_type == em_ich10lan) + hw->mac_type == em_ich10lan) // XXX eeprom_data = ID_LED_DEFAULT_ICH8LAN; else eeprom_data = ID_LED_DEFAULT; @@ -6393,7 +6478,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_ich10lan && + hw->mac_type != em_pchlan) { temp = E1000_READ_REG(hw, PRC64); temp = E1000_READ_REG(hw, PRC127); temp = E1000_READ_REG(hw, PRC255); @@ -6423,7 +6509,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_ich10lan && + hw->mac_type != em_pchlan) { temp = E1000_READ_REG(hw, PTC64); temp = E1000_READ_REG(hw, PTC127); temp = E1000_READ_REG(hw, PTC255); @@ -6460,7 +6547,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_ich10lan || + hw->mac_type == em_pchlan) return; temp = E1000_READ_REG(hw, ICRXPTC); @@ -6594,6 +6682,7 @@ em_get_bus_info(struct em_hw *hw) case em_ich8lan: case em_ich9lan: case em_ich10lan: + case em_pchlan: hw->bus_type = em_bus_type_pci_express; hw->bus_speed = em_bus_speed_2500; hw->bus_width = em_bus_width_pciex_1; @@ -7165,7 +7254,8 @@ em_set_d3_lplu_state(struct em_hw *hw, boolean_t active) return ret_val; } else if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan || - hw->mac_type == em_ich10lan) { + hw->mac_type == em_ich10lan || + hw->mac_type == em_pchlan) { /* * MAC writes into PHY register based on the state transition * and start auto-negotiation. SW driver can overwrite the @@ -7190,7 +7280,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_ich10lan || + hw->mac_type == em_pchlan) { phy_ctrl &= ~E1000_PHY_CTRL_NOND0A_LPLU; E1000_WRITE_REG(hw, PHY_CTRL, phy_ctrl); } else { @@ -7244,7 +7335,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_ich10lan || + hw->mac_type == em_pchlan) { phy_ctrl |= E1000_PHY_CTRL_NOND0A_LPLU; E1000_WRITE_REG(hw, PHY_CTRL, phy_ctrl); } else { @@ -7298,7 +7390,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_ich10lan || + hw->mac_type == em_pchlan) { phy_ctrl = E1000_READ_REG(hw, PHY_CTRL); } else { ret_val = em_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, @@ -7310,7 +7403,8 @@ em_set_d0_lplu_state(struct em_hw *hw, boolean_t active) if (!active) { if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan || - hw->mac_type == em_ich10lan) { + hw->mac_type == em_ich10lan || + hw->mac_type == em_pchlan) { phy_ctrl &= ~E1000_PHY_CTRL_D0A_LPLU; E1000_WRITE_REG(hw, PHY_CTRL, phy_ctrl); } else { @@ -7352,7 +7446,8 @@ em_set_d0_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_ich10lan || + hw->mac_type == em_pchlan) { phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU; E1000_WRITE_REG(hw, PHY_CTRL, phy_ctrl); } else { @@ -7510,7 +7605,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_ich10lan || + hw->mac_type == em_pchlan) { if ((fwsm & E1000_FWSM_MODE_MASK) == (E1000_MNG_ICH_IAMT_MODE << E1000_FWSM_MODE_SHIFT)) return TRUE; @@ -7755,6 +7851,7 @@ em_get_auto_rd_done(struct em_hw *hw) case em_ich8lan: case em_ich9lan: case em_ich10lan: + case em_pchlan: while (timeout) { if (E1000_READ_REG(hw, EECD) & E1000_EECD_AUTO_RD) break; @@ -7983,7 +8080,8 @@ em_check_phy_reset_block(struct em_hw *hw) uint32_t fwsm = 0; if (hw->mac_type == em_ich8lan || hw->mac_type == em_ich9lan || - hw->mac_type == em_ich10lan) { + hw->mac_type == em_ich10lan || + hw->mac_type == em_pchlan) { fwsm = E1000_READ_REG(hw, FWSM); return (fwsm & E1000_FWSM_RSPCIPHY) ? E1000_SUCCESS : E1000_BLK_PHY_RESET; @@ -8023,7 +8121,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_ich10lan || + hw->mac_type == em_pchlan) { uint32_t ctrl_ext; ctrl_ext = E1000_READ_REG(hw, CTRL_EXT); ctrl_ext |= E1000_CTRL_EXT_RO_DIS; @@ -8050,7 +8149,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_ich10lan || + hw->mac_type == em_pchlan) { while (timeout) { extcnf_ctrl = E1000_READ_REG(hw, EXTCNF_CTRL); extcnf_ctrl |= E1000_EXTCNF_CTRL_SWFLAG; @@ -8088,7 +8188,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_ich10lan || + hw->mac_type == em_pchlan) { 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 45ca4f2f37b..cfb112583bf 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.38 2010/06/20 10:36:03 jsg Exp $ */ +/* $OpenBSD: if_em_hw.h,v 1.39 2010/06/21 21:11:53 jsg Exp $ */ /* $FreeBSD: if_em_hw.h,v 1.15 2005/05/26 23:32:02 tackerman Exp $ */ /* if_em_hw.h @@ -74,6 +74,7 @@ typedef enum { em_ich8lan, em_ich9lan, em_ich10lan, + em_pchlan, em_num_macs } em_mac_type; @@ -235,6 +236,7 @@ typedef enum { em_phy_ife, em_phy_bm, /* phy used in i82574L, ICH10 and some ICH9 */ em_phy_oem, + em_phy_82577, em_phy_undefined = 0xFF } em_phy_type; @@ -1104,6 +1106,7 @@ struct em_ffvt_entry { #define E1000_WUPL 0x05900 /* Wakeup Packet Length - RW */ #define E1000_WUPM 0x05A00 /* Wakeup Packet Memory - RO A */ #define E1000_FFLT 0x05F00 /* Flexible Filter Length Table - RW Array */ +#define E1000_CRC_OFFSET 0x05F50 /* CRC Offset Register */ #define E1000_HOST_IF 0x08800 /* Host Interface */ #define E1000_FFMT 0x09000 /* Flexible Filter Mask Table - RW Array */ #define E1000_FFVT 0x09800 /* Flexible Filter Value Table - RW Array */ @@ -1307,6 +1310,7 @@ struct em_ffvt_entry { #define E1000_82542_TDFT 0x08018 #define E1000_82542_FFMT E1000_FFMT #define E1000_82542_FFVT E1000_FFVT +#define E1000_82542_CRC_OFFSET E1000_CRC_OFFSET #define E1000_82542_HOST_IF E1000_HOST_IF #define E1000_82542_IAM E1000_IAM #define E1000_82542_EEMNGCTL E1000_EEMNGCTL @@ -2485,6 +2489,7 @@ struct em_host_command_info { #define E1000_PBA_16K 0x0010 /* 16KB, default TX allocation */ #define E1000_PBA_22K 0x0016 #define E1000_PBA_24K 0x0018 +#define E1000_PBA_26K 0x001A #define E1000_PBA_30K 0x001E #define E1000_PBA_32K 0x0020 #define E1000_PBA_34K 0x0022 @@ -2769,6 +2774,15 @@ struct em_host_command_info { GG82563_REG(194, 25) /* Link Partner Advertised Next page */ #define GG82563_PHY_KMRN_MISC \ GG82563_REG(194, 26) /* Misc. */ + +/* I82577 Specific Registers */ +#define I82577_PHY_ADDR_REG 16 +#define I82577_PHY_CFG_REG 22 +#define I82577_PHY_CTRL_REG 23 + +/* I82577 Config Register */ +#define I82577_PHY_CFG_ENABLE_CRS_ON_TX (1 << 15) +#define I82577_PHY_CFG_ENABLE_DOWNSHIFT ((1 << 10) + (1 << 11)) /* PHY Control Register */ #define MII_CR_SPEED_SELECT_MSB 0x0040 /* bits 6,13: 10=1000, 01=100, 00=10 */ |