summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2010-06-21 21:11:54 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2010-06-21 21:11:54 +0000
commit6efc9494c0e1e839e444f134fd91f4e33b511e77 (patch)
treedb1fa9765f2b3966a18e3214ca200504319d4739
parent53da2d96a39440a73d568a8e7389690e27d36c1c (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.c11
-rw-r--r--sys/dev/pci/if_em_hw.c171
-rw-r--r--sys/dev/pci/if_em_hw.h16
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 */