summaryrefslogtreecommitdiff
path: root/sys/dev/pci
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2011-04-22 10:09:58 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2011-04-22 10:09:58 +0000
commit8d25bab8671b0806e6ded1c09bd5cba62a9fcbab (patch)
tree02165381afbe61abc91f8e1a011555e222033ca5 /sys/dev/pci
parent1366352376f1311ca2317b2b23aaae682ff2f500 (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.c10
-rw-r--r--sys/dev/pci/if_em_hw.c213
-rw-r--r--sys/dev/pci/if_em_hw.h9
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