Author: jfv
Date: Thu Jun 26 21:33:32 2014
New Revision: 267935
URL: http://svnweb.freebsd.org/changeset/base/267935

Log:
  Sync the E1000 shared code with Intel internal, this adds fixes,
  and more importantly, new I218 adapter support to the em driver.
  
  MFC after: 1 week

Modified:
  head/sys/dev/e1000/e1000_82542.c
  head/sys/dev/e1000/e1000_82571.c
  head/sys/dev/e1000/e1000_82575.c
  head/sys/dev/e1000/e1000_82575.h
  head/sys/dev/e1000/e1000_api.c
  head/sys/dev/e1000/e1000_api.h
  head/sys/dev/e1000/e1000_defines.h
  head/sys/dev/e1000/e1000_hw.h
  head/sys/dev/e1000/e1000_i210.c
  head/sys/dev/e1000/e1000_i210.h
  head/sys/dev/e1000/e1000_ich8lan.c
  head/sys/dev/e1000/e1000_ich8lan.h
  head/sys/dev/e1000/e1000_mac.c
  head/sys/dev/e1000/e1000_mac.h
  head/sys/dev/e1000/e1000_manage.c
  head/sys/dev/e1000/e1000_mbx.c
  head/sys/dev/e1000/e1000_mbx.h
  head/sys/dev/e1000/e1000_nvm.c
  head/sys/dev/e1000/e1000_osdep.h
  head/sys/dev/e1000/e1000_phy.c
  head/sys/dev/e1000/e1000_phy.h
  head/sys/dev/e1000/e1000_regs.h
  head/sys/dev/e1000/e1000_vf.c
  head/sys/dev/e1000/e1000_vf.h
  head/sys/dev/e1000/if_em.c

Modified: head/sys/dev/e1000/e1000_82542.c
==============================================================================
--- head/sys/dev/e1000/e1000_82542.c    Thu Jun 26 20:12:38 2014        
(r267934)
+++ head/sys/dev/e1000/e1000_82542.c    Thu Jun 26 21:33:32 2014        
(r267935)
@@ -1,6 +1,6 @@
 /******************************************************************************
 
-  Copyright (c) 2001-2010, Intel Corporation 
+  Copyright (c) 2001-2014, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -47,7 +47,7 @@ static s32  e1000_init_hw_82542(struct e
 static s32  e1000_setup_link_82542(struct e1000_hw *hw);
 static s32  e1000_led_on_82542(struct e1000_hw *hw);
 static s32  e1000_led_off_82542(struct e1000_hw *hw);
-static void e1000_rar_set_82542(struct e1000_hw *hw, u8 *addr, u32 index);
+static int  e1000_rar_set_82542(struct e1000_hw *hw, u8 *addr, u32 index);
 static void e1000_clear_hw_cntrs_82542(struct e1000_hw *hw);
 static s32  e1000_read_mac_addr_82542(struct e1000_hw *hw);
 
@@ -409,7 +409,7 @@ static s32 e1000_led_off_82542(struct e1
  *  Sets the receive address array register at index to the address passed
  *  in by addr.
  **/
-static void e1000_rar_set_82542(struct e1000_hw *hw, u8 *addr, u32 index)
+static int e1000_rar_set_82542(struct e1000_hw *hw, u8 *addr, u32 index)
 {
        u32 rar_low, rar_high;
 
@@ -431,6 +431,7 @@ static void e1000_rar_set_82542(struct e
 
        E1000_WRITE_REG_ARRAY(hw, E1000_RA, (index << 1), rar_low);
        E1000_WRITE_REG_ARRAY(hw, E1000_RA, ((index << 1) + 1), rar_high);
+       return E1000_SUCCESS;
 }
 
 /**

Modified: head/sys/dev/e1000/e1000_82571.c
==============================================================================
--- head/sys/dev/e1000/e1000_82571.c    Thu Jun 26 20:12:38 2014        
(r267934)
+++ head/sys/dev/e1000/e1000_82571.c    Thu Jun 26 21:33:32 2014        
(r267935)
@@ -1,6 +1,6 @@
 /******************************************************************************
 
-  Copyright (c) 2001-2013, Intel Corporation 
+  Copyright (c) 2001-2014, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -1453,10 +1453,14 @@ static void e1000_clear_vfta_82571(struc
 static bool e1000_check_mng_mode_82574(struct e1000_hw *hw)
 {
        u16 data;
+       s32 ret_val;
 
        DEBUGFUNC("e1000_check_mng_mode_82574");
 
-       hw->nvm.ops.read(hw, NVM_INIT_CONTROL2_REG, 1, &data);
+       ret_val = hw->nvm.ops.read(hw, NVM_INIT_CONTROL2_REG, 1, &data);
+       if (ret_val)
+               return FALSE;
+
        return (data & E1000_NVM_INIT_CTRL2_MNGM) != 0;
 }
 

Modified: head/sys/dev/e1000/e1000_82575.c
==============================================================================
--- head/sys/dev/e1000/e1000_82575.c    Thu Jun 26 20:12:38 2014        
(r267934)
+++ head/sys/dev/e1000/e1000_82575.c    Thu Jun 26 21:33:32 2014        
(r267935)
@@ -1,6 +1,6 @@
 /******************************************************************************
 
-  Copyright (c) 2001-2013, Intel Corporation 
+  Copyright (c) 2001-2014, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -56,7 +56,6 @@ static s32  e1000_check_for_link_media_s
 static s32  e1000_get_cfg_done_82575(struct e1000_hw *hw);
 static s32  e1000_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed,
                                         u16 *duplex);
-static s32  e1000_init_hw_82575(struct e1000_hw *hw);
 static s32  e1000_phy_hw_reset_sgmii_82575(struct e1000_hw *hw);
 static s32  e1000_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset,
                                           u16 *data);
@@ -120,7 +119,8 @@ static bool e1000_get_i2c_data(u32 *i2cc
 static const u16 e1000_82580_rxpbs_table[] = {
        36, 72, 144, 1, 2, 4, 8, 16, 35, 70, 140 };
 #define E1000_82580_RXPBS_TABLE_SIZE \
-       (sizeof(e1000_82580_rxpbs_table)/sizeof(u16))
+       (sizeof(e1000_82580_rxpbs_table) / \
+        sizeof(e1000_82580_rxpbs_table[0]))
 
 
 /**
@@ -273,6 +273,11 @@ static s32 e1000_init_phy_params_82575(s
                                hw->mac.ops.check_for_link =
                                                e1000_check_for_link_media_swap;
                }
+               if (phy->id == M88E1512_E_PHY_ID) {
+                       ret_val = e1000_initialize_M88E1512_phy(hw);
+                       if (ret_val)
+                               goto out;
+               }
                break;
        case IGP03E1000_E_PHY_ID:
        case IGP04E1000_E_PHY_ID:
@@ -450,6 +455,9 @@ static s32 e1000_init_mac_params_82575(s
        else
        mac->ops.reset_hw = e1000_reset_hw_82575;
        /* hw initialization */
+       if ((mac->type == e1000_i210) || (mac->type == e1000_i211))
+               mac->ops.init_hw = e1000_init_hw_i210;
+       else
        mac->ops.init_hw = e1000_init_hw_82575;
        /* link setup */
        mac->ops.setup_link = e1000_setup_link_generic;
@@ -750,6 +758,7 @@ out:
 static s32 e1000_phy_hw_reset_sgmii_82575(struct e1000_hw *hw)
 {
        s32 ret_val = E1000_SUCCESS;
+       struct e1000_phy_info *phy = &hw->phy;
 
        DEBUGFUNC("e1000_phy_hw_reset_sgmii_82575");
 
@@ -772,7 +781,11 @@ static s32 e1000_phy_hw_reset_sgmii_8257
                goto out;
 
        ret_val = hw->phy.ops.commit(hw);
+       if (ret_val)
+               goto out;
 
+       if (phy->id == M88E1512_E_PHY_ID)
+               ret_val = e1000_initialize_M88E1512_phy(hw);
 out:
        return ret_val;
 }
@@ -879,7 +892,6 @@ out:
 static s32 e1000_set_d0_lplu_state_82580(struct e1000_hw *hw, bool active)
 {
        struct e1000_phy_info *phy = &hw->phy;
-       s32 ret_val = E1000_SUCCESS;
        u32 data;
 
        DEBUGFUNC("e1000_set_d0_lplu_state_82580");
@@ -907,7 +919,7 @@ static s32 e1000_set_d0_lplu_state_82580
        }
 
        E1000_WRITE_REG(hw, E1000_82580_PHY_POWER_MGMT, data);
-       return ret_val;
+       return E1000_SUCCESS;
 }
 
 /**
@@ -927,7 +939,6 @@ static s32 e1000_set_d0_lplu_state_82580
 s32 e1000_set_d3_lplu_state_82580(struct e1000_hw *hw, bool active)
 {
        struct e1000_phy_info *phy = &hw->phy;
-       s32 ret_val = E1000_SUCCESS;
        u32 data;
 
        DEBUGFUNC("e1000_set_d3_lplu_state_82580");
@@ -955,7 +966,7 @@ s32 e1000_set_d3_lplu_state_82580(struct
        }
 
        E1000_WRITE_REG(hw, E1000_82580_PHY_POWER_MGMT, data);
-       return ret_val;
+       return E1000_SUCCESS;
 }
 
 /**
@@ -969,7 +980,7 @@ s32 e1000_set_d3_lplu_state_82580(struct
  **/
 static s32 e1000_acquire_nvm_82575(struct e1000_hw *hw)
 {
-       s32 ret_val;
+       s32 ret_val = E1000_SUCCESS;
 
        DEBUGFUNC("e1000_acquire_nvm_82575");
 
@@ -991,6 +1002,7 @@ static s32 e1000_acquire_nvm_82575(struc
                        DEBUGOUT("Nvm bit banging access error detected and 
cleared.\n");
                }
        }
+
        if (hw->mac.type == e1000_82580) {
                u32 eecd = E1000_READ_REG(hw, E1000_EECD);
                if (eecd & E1000_EECD_BLOCKED) {
@@ -1001,7 +1013,6 @@ static s32 e1000_acquire_nvm_82575(struc
                }
        }
 
-
        ret_val = e1000_acquire_nvm_generic(hw);
        if (ret_val)
                e1000_release_swfw_sync_82575(hw, E1000_SWFW_EEP_SM);
@@ -1115,7 +1126,6 @@ static void e1000_release_swfw_sync_8257
 static s32 e1000_get_cfg_done_82575(struct e1000_hw *hw)
 {
        s32 timeout = PHY_CFG_TIMEOUT;
-       s32 ret_val = E1000_SUCCESS;
        u32 mask = E1000_NVM_CFG_DONE_PORT_0;
 
        DEBUGFUNC("e1000_get_cfg_done_82575");
@@ -1140,7 +1150,7 @@ static s32 e1000_get_cfg_done_82575(stru
            (hw->phy.type == e1000_phy_igp_3))
                e1000_phy_init_script_igp3(hw);
 
-       return ret_val;
+       return E1000_SUCCESS;
 }
 
 /**
@@ -1466,7 +1476,7 @@ static s32 e1000_reset_hw_82575(struct e
  *
  *  This inits the hardware readying it for operation.
  **/
-static s32 e1000_init_hw_82575(struct e1000_hw *hw)
+s32 e1000_init_hw_82575(struct e1000_hw *hw)
 {
        struct e1000_mac_info *mac = &hw->mac;
        s32 ret_val;
@@ -1985,7 +1995,7 @@ static s32 e1000_reset_init_script_82575
  **/
 static s32 e1000_read_mac_addr_82575(struct e1000_hw *hw)
 {
-       s32 ret_val = E1000_SUCCESS;
+       s32 ret_val;
 
        DEBUGFUNC("e1000_read_mac_addr_82575");
 
@@ -2478,11 +2488,17 @@ static s32 e1000_reset_hw_82580(struct e
                ctrl |= E1000_CTRL_RST;
 
        E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
-       E1000_WRITE_FLUSH(hw);
 
-       /* Add delay to insure DEV_RST has time to complete */
-       if (global_device_reset)
-               msec_delay(5);
+       switch (hw->device_id) {
+       case E1000_DEV_ID_DH89XXCC_SGMII:
+               break;
+       default:
+               E1000_WRITE_FLUSH(hw);
+               break;
+       }
+
+       /* Add delay to insure DEV_RST or RST has time to complete */
+       msec_delay(5);
 
        ret_val = e1000_get_auto_rd_done_generic(hw);
        if (ret_val) {
@@ -2617,7 +2633,7 @@ out:
  **/
 static s32 e1000_validate_nvm_checksum_82580(struct e1000_hw *hw)
 {
-       s32 ret_val = E1000_SUCCESS;
+       s32 ret_val;
        u16 eeprom_regions_count = 1;
        u16 j, nvm_data;
        u16 nvm_offset;
@@ -2757,7 +2773,7 @@ out:
 static s32 __e1000_access_emi_reg(struct e1000_hw *hw, u16 address,
                                  u16 *data, bool read)
 {
-       s32 ret_val = E1000_SUCCESS;
+       s32 ret_val;
 
        DEBUGFUNC("__e1000_access_emi_reg");
 
@@ -2787,6 +2803,95 @@ s32 e1000_read_emi_reg(struct e1000_hw *
 }
 
 /**
+ *  e1000_initialize_M88E1512_phy - Initialize M88E1512 PHY
+ *  @hw: pointer to the HW structure
+ *
+ *  Initialize Marverl 1512 to work correctly with Avoton.
+ **/
+s32 e1000_initialize_M88E1512_phy(struct e1000_hw *hw)
+{
+       struct e1000_phy_info *phy = &hw->phy;
+       s32 ret_val = E1000_SUCCESS;
+
+       DEBUGFUNC("e1000_initialize_M88E1512_phy");
+
+       /* Check if this is correct PHY. */
+       if (phy->id != M88E1512_E_PHY_ID)
+               goto out;
+
+       /* Switch to PHY page 0xFF. */
+       ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0x00FF);
+       if (ret_val)
+               goto out;
+
+       ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0x214B);
+       if (ret_val)
+               goto out;
+
+       ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x2144);
+       if (ret_val)
+               goto out;
+
+       ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0x0C28);
+       if (ret_val)
+               goto out;
+
+       ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x2146);
+       if (ret_val)
+               goto out;
+
+       ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0xB233);
+       if (ret_val)
+               goto out;
+
+       ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x214D);
+       if (ret_val)
+               goto out;
+
+       ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0xCC0C);
+       if (ret_val)
+               goto out;
+
+       ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x2159);
+       if (ret_val)
+               goto out;
+
+       /* Switch to PHY page 0xFB. */
+       ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0x00FB);
+       if (ret_val)
+               goto out;
+
+       ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_3, 0x000D);
+       if (ret_val)
+               goto out;
+
+       /* Switch to PHY page 0x12. */
+       ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0x12);
+       if (ret_val)
+               goto out;
+
+       /* Change mode to SGMII-to-Copper */
+       ret_val = phy->ops.write_reg(hw, E1000_M88E1512_MODE, 0x8001);
+       if (ret_val)
+               goto out;
+
+       /* Return the PHY to page 0. */
+       ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0);
+       if (ret_val)
+               goto out;
+
+       ret_val = phy->ops.commit(hw);
+       if (ret_val) {
+               DEBUGOUT("Error committing the PHY changes\n");
+               return ret_val;
+       }
+
+       msec_delay(1000);
+out:
+       return ret_val;
+}
+
+/**
  *  e1000_set_eee_i350 - Enable/disable EEE support
  *  @hw: pointer to the HW structure
  *
@@ -2795,7 +2900,6 @@ s32 e1000_read_emi_reg(struct e1000_hw *
  **/
 s32 e1000_set_eee_i350(struct e1000_hw *hw)
 {
-       s32 ret_val = E1000_SUCCESS;
        u32 ipcnfg, eeer;
 
        DEBUGFUNC("e1000_set_eee_i350");
@@ -2828,7 +2932,7 @@ s32 e1000_set_eee_i350(struct e1000_hw *
        E1000_READ_REG(hw, E1000_EEER);
 out:
 
-       return ret_val;
+       return E1000_SUCCESS;
 }
 
 /**

Modified: head/sys/dev/e1000/e1000_82575.h
==============================================================================
--- head/sys/dev/e1000/e1000_82575.h    Thu Jun 26 20:12:38 2014        
(r267934)
+++ head/sys/dev/e1000/e1000_82575.h    Thu Jun 26 21:33:32 2014        
(r267935)
@@ -1,6 +1,6 @@
 /******************************************************************************
 
-  Copyright (c) 2001-2013, Intel Corporation 
+  Copyright (c) 2001-2014, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -384,7 +384,7 @@ struct e1000_adv_tx_context_desc {
 #define E1000_ETQF_FILTER_ENABLE       (1 << 26)
 #define E1000_ETQF_IMM_INT             (1 << 29)
 #define E1000_ETQF_1588                        (1 << 30)
-#define E1000_ETQF_QUEUE_ENABLE                (1U << 31)
+#define E1000_ETQF_QUEUE_ENABLE                (1 << 31)
 /*
  * ETQF filter list: one static filter per filter consumer. This is
  *                   to avoid filter collisions later. Add new filters
@@ -411,7 +411,7 @@ struct e1000_adv_tx_context_desc {
 #define E1000_DTXSWC_LLE_MASK          0x00FF0000 /* Per VF Local LB enables */
 #define E1000_DTXSWC_VLAN_SPOOF_SHIFT  8
 #define E1000_DTXSWC_LLE_SHIFT         16
-#define E1000_DTXSWC_VMDQ_LOOPBACK_EN  (1U << 31)  /* global VF LB enable */
+#define E1000_DTXSWC_VMDQ_LOOPBACK_EN  (1 << 31)  /* global VF LB enable */
 
 /* Easy defines for setting default pool, would normally be left a zero */
 #define E1000_VT_CTL_DEFAULT_POOL_SHIFT        7
@@ -480,6 +480,7 @@ void e1000_vmdq_set_loopback_pf(struct e
 void e1000_vmdq_set_anti_spoofing_pf(struct e1000_hw *hw, bool enable, int pf);
 void e1000_vmdq_set_replication_pf(struct e1000_hw *hw, bool enable);
 s32 e1000_init_nvm_params_82575(struct e1000_hw *hw);
+s32  e1000_init_hw_82575(struct e1000_hw *hw);
 
 enum e1000_promisc_type {
        e1000_promisc_disabled = 0,   /* all promisc modes disabled */
@@ -497,6 +498,7 @@ s32 e1000_read_emi_reg(struct e1000_hw *
 s32 e1000_set_eee_i350(struct e1000_hw *);
 s32 e1000_set_eee_i354(struct e1000_hw *);
 s32 e1000_get_eee_status_i354(struct e1000_hw *, bool *);
+s32 e1000_initialize_M88E1512_phy(struct e1000_hw *hw);
 
 /* I2C SDA and SCL timing parameters for standard mode */
 #define E1000_I2C_T_HD_STA     4

Modified: head/sys/dev/e1000/e1000_api.c
==============================================================================
--- head/sys/dev/e1000/e1000_api.c      Thu Jun 26 20:12:38 2014        
(r267934)
+++ head/sys/dev/e1000/e1000_api.c      Thu Jun 26 21:33:32 2014        
(r267935)
@@ -1,6 +1,6 @@
 /******************************************************************************
 
-  Copyright (c) 2001-2013, Intel Corporation 
+  Copyright (c) 2001-2014, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -293,6 +293,10 @@ s32 e1000_set_mac_type(struct e1000_hw *
        case E1000_DEV_ID_PCH_LPT_I217_V:
        case E1000_DEV_ID_PCH_LPTLP_I218_LM:
        case E1000_DEV_ID_PCH_LPTLP_I218_V:
+       case E1000_DEV_ID_PCH_I218_LM2:
+       case E1000_DEV_ID_PCH_I218_V2:
+       case E1000_DEV_ID_PCH_I218_LM3:
+       case E1000_DEV_ID_PCH_I218_V3:
                mac->type = e1000_pch_lpt;
                break;
        case E1000_DEV_ID_82575EB_COPPER:
@@ -828,10 +832,12 @@ void e1000_config_collision_dist(struct 
  *
  *  Sets a Receive Address Register (RAR) to the specified address.
  **/
-void e1000_rar_set(struct e1000_hw *hw, u8 *addr, u32 index)
+int e1000_rar_set(struct e1000_hw *hw, u8 *addr, u32 index)
 {
        if (hw->mac.ops.rar_set)
-               hw->mac.ops.rar_set(hw, addr, index);
+               return hw->mac.ops.rar_set(hw, addr, index);
+
+       return E1000_SUCCESS;
 }
 
 /**

Modified: head/sys/dev/e1000/e1000_api.h
==============================================================================
--- head/sys/dev/e1000/e1000_api.h      Thu Jun 26 20:12:38 2014        
(r267934)
+++ head/sys/dev/e1000/e1000_api.h      Thu Jun 26 21:33:32 2014        
(r267935)
@@ -1,6 +1,6 @@
 /******************************************************************************
 
-  Copyright (c) 2001-2013, Intel Corporation 
+  Copyright (c) 2001-2014, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -69,7 +69,7 @@ s32 e1000_setup_link(struct e1000_hw *hw
 s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u16 *speed, u16 *duplex);
 s32 e1000_disable_pcie_master(struct e1000_hw *hw);
 void e1000_config_collision_dist(struct e1000_hw *hw);
-void e1000_rar_set(struct e1000_hw *hw, u8 *addr, u32 index);
+int e1000_rar_set(struct e1000_hw *hw, u8 *addr, u32 index);
 u32 e1000_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr);
 void e1000_update_mc_addr_list(struct e1000_hw *hw, u8 *mc_addr_list,
                               u32 mc_addr_count);

Modified: head/sys/dev/e1000/e1000_defines.h
==============================================================================
--- head/sys/dev/e1000/e1000_defines.h  Thu Jun 26 20:12:38 2014        
(r267934)
+++ head/sys/dev/e1000/e1000_defines.h  Thu Jun 26 21:33:32 2014        
(r267935)
@@ -1,6 +1,6 @@
 /******************************************************************************
 
-  Copyright (c) 2001-2013, Intel Corporation 
+  Copyright (c) 2001-2014, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -77,6 +77,7 @@
 #define E1000_CTRL_EXT_EE_RST  0x00002000 /* Reinitialize from EEPROM */
 /* Physical Func Reset Done Indication */
 #define E1000_CTRL_EXT_PFRSTD  0x00004000
+#define E1000_CTRL_EXT_SDLPE   0X00040000  /* SerDes Low Power Enable */
 #define E1000_CTRL_EXT_SPD_BYPS        0x00008000 /* Speed Select Bypass */
 #define E1000_CTRL_EXT_RO_DIS  0x00020000 /* Relaxed Ordering disable */
 #define E1000_CTRL_EXT_DMA_DYN_CLK_EN  0x00080000 /* DMA Dynamic Clk Gating */
@@ -131,7 +132,7 @@
 #define E1000_RXD_ERR_RXE      0x80    /* Rx Data Error */
 #define E1000_RXD_SPC_VLAN_MASK        0x0FFF  /* VLAN ID is in lower 12 bits 
*/
 
-#define E1000_RXDEXT_STATERR_TST       0x00010000 /* Time Stamp taken */
+#define E1000_RXDEXT_STATERR_TST       0x00000100 /* Time Stamp taken */
 #define E1000_RXDEXT_STATERR_LB                0x00040000
 #define E1000_RXDEXT_STATERR_CE                0x01000000
 #define E1000_RXDEXT_STATERR_SE                0x02000000
@@ -464,6 +465,7 @@
 
 #define ETHERNET_FCS_SIZE              4
 #define MAX_JUMBO_FRAME_SIZE           0x3F00
+#define E1000_TX_PTR_GAP               0x1F
 
 /* Extended Configuration Control and Size */
 #define E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP    0x00000020
@@ -853,6 +855,10 @@
 #define E1000_PCS_STATUS_ADDR_I354     1
 #define E1000_PCS_STATUS_RX_LPI_RCVD   0x0400
 #define E1000_PCS_STATUS_TX_LPI_RCVD   0x0800
+#define E1000_M88E1512_CFG_REG_1       0x0010
+#define E1000_M88E1512_CFG_REG_2       0x0011
+#define E1000_M88E1512_CFG_REG_3       0x0007
+#define E1000_M88E1512_MODE            0x0014
 #define E1000_EEE_SU_LPI_CLK_STP       0x00800000 /* EEE LPI Clock Stop */
 #define E1000_EEE_LP_ADV_DEV_I210      7          /* EEE LP Adv Device */
 #define E1000_EEE_LP_ADV_ADDR_I210     61         /* EEE LP Adv Register */
@@ -1429,6 +1435,9 @@
 #define E1000_RXPBS_CFG_TS_EN          0x80000000 /* Timestamp in Rx buffer */
 #define E1000_RXPBS_SIZE_I210_MASK     0x0000003F /* Rx packet buffer size */
 #define E1000_TXPB0S_SIZE_I210_MASK    0x0000003F /* Tx packet buffer 0 size */
+#define I210_RXPBSIZE_DEFAULT          0x000000A2 /* RXPBSIZE default */
+#define I210_TXPBSIZE_DEFAULT          0x04000014 /* TXPBSIZE default */
+
 #define E1000_DOBFFCTL_OBFFTHR_MASK    0x000000FF /* OBFF threshold */
 #define E1000_DOBFFCTL_EXIT_ACT_MASK   0x01000000 /* Exit active CB */
 
@@ -1455,5 +1464,7 @@
 #define E1000_STATUS_LAN_ID_OFFSET     2
 #define E1000_VFTA_ENTRIES             128
 #define E1000_UNUSEDARG
+#ifndef ERROR_REPORT
 #define ERROR_REPORT(fmt)      do { } while (0)
+#endif /* ERROR_REPORT */
 #endif /* _E1000_DEFINES_H_ */

Modified: head/sys/dev/e1000/e1000_hw.h
==============================================================================
--- head/sys/dev/e1000/e1000_hw.h       Thu Jun 26 20:12:38 2014        
(r267934)
+++ head/sys/dev/e1000/e1000_hw.h       Thu Jun 26 21:33:32 2014        
(r267935)
@@ -1,6 +1,6 @@
 /******************************************************************************
 
-  Copyright (c) 2001-2013, Intel Corporation 
+  Copyright (c) 2001-2014, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -133,6 +133,10 @@ struct e1000_hw;
 #define E1000_DEV_ID_PCH_LPT_I217_V            0x153B
 #define E1000_DEV_ID_PCH_LPTLP_I218_LM         0x155A
 #define E1000_DEV_ID_PCH_LPTLP_I218_V          0x1559
+#define E1000_DEV_ID_PCH_I218_LM2              0x15A0
+#define E1000_DEV_ID_PCH_I218_V2               0x15A1
+#define E1000_DEV_ID_PCH_I218_LM3              0x15A2 /* Wildcat Point PCH */
+#define E1000_DEV_ID_PCH_I218_V3               0x15A3 /* Wildcat Point PCH */
 #define E1000_DEV_ID_82576                     0x10C9
 #define E1000_DEV_ID_82576_FIBER               0x10E6
 #define E1000_DEV_ID_82576_SERDES              0x10E7
@@ -696,7 +700,7 @@ struct e1000_mac_operations {
        s32  (*setup_led)(struct e1000_hw *);
        void (*write_vfta)(struct e1000_hw *, u32, u32);
        void (*config_collision_dist)(struct e1000_hw *);
-       void (*rar_set)(struct e1000_hw *, u8*, u32);
+       int  (*rar_set)(struct e1000_hw *, u8*, u32);
        s32  (*read_mac_addr)(struct e1000_hw *);
        s32  (*validate_mdi_setting)(struct e1000_hw *);
        s32  (*set_obff_timer)(struct e1000_hw *, u32);
@@ -934,6 +938,13 @@ struct e1000_shadow_ram {
 
 #define E1000_SHADOW_RAM_WORDS         2048
 
+/* I218 PHY Ultra Low Power (ULP) states */
+enum e1000_ulp_state {
+       e1000_ulp_state_unknown,
+       e1000_ulp_state_off,
+       e1000_ulp_state_on,
+};
+
 struct e1000_dev_spec_ich8lan {
        bool kmrn_lock_loss_workaround_enabled;
        struct e1000_shadow_ram shadow_ram[E1000_SHADOW_RAM_WORDS];
@@ -942,6 +953,7 @@ struct e1000_dev_spec_ich8lan {
        bool nvm_k1_enabled;
        bool eee_disable;
        u16 eee_lp_ability;
+       enum e1000_ulp_state ulp_state;
 };
 
 struct e1000_dev_spec_82575 {

Modified: head/sys/dev/e1000/e1000_i210.c
==============================================================================
--- head/sys/dev/e1000/e1000_i210.c     Thu Jun 26 20:12:38 2014        
(r267934)
+++ head/sys/dev/e1000/e1000_i210.c     Thu Jun 26 21:33:32 2014        
(r267935)
@@ -1,6 +1,6 @@
 /******************************************************************************
 
-  Copyright (c) 2001-2013, Intel Corporation 
+  Copyright (c) 2001-2014, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -536,7 +536,7 @@ s32 e1000_validate_nvm_checksum_i210(str
  **/
 s32 e1000_update_nvm_checksum_i210(struct e1000_hw *hw)
 {
-       s32 ret_val = E1000_SUCCESS;
+       s32 ret_val;
        u16 checksum = 0;
        u16 i, nvm_data;
 
@@ -615,7 +615,7 @@ bool e1000_get_flash_presence_i210(struc
  **/
 s32 e1000_update_flash_i210(struct e1000_hw *hw)
 {
-       s32 ret_val = E1000_SUCCESS;
+       s32 ret_val;
        u32 flup;
 
        DEBUGFUNC("e1000_update_flash_i210");
@@ -671,7 +671,7 @@ s32 e1000_pool_flash_update_done_i210(st
  **/
 static s32 e1000_init_nvm_params_i210(struct e1000_hw *hw)
 {
-       s32 ret_val = E1000_SUCCESS;
+       s32 ret_val;
        struct e1000_nvm_info *nvm = &hw->nvm;
 
        DEBUGFUNC("e1000_init_nvm_params_i210");
@@ -756,7 +756,7 @@ out:
 static s32 __e1000_access_xmdio_reg(struct e1000_hw *hw, u16 address,
                                    u8 dev_addr, u16 *data, bool read)
 {
-       s32 ret_val = E1000_SUCCESS;
+       s32 ret_val;
 
        DEBUGFUNC("__e1000_access_xmdio_reg");
 
@@ -815,3 +815,90 @@ s32 e1000_write_xmdio_reg(struct e1000_h
 
        return __e1000_access_xmdio_reg(hw, addr, dev_addr, &data, FALSE);
 }
+
+/**
+ * e1000_pll_workaround_i210
+ * @hw: pointer to the HW structure
+ *
+ * Works around an errata in the PLL circuit where it occasionally
+ * provides the wrong clock frequency after power up.
+ **/
+static s32 e1000_pll_workaround_i210(struct e1000_hw *hw)
+{
+       s32 ret_val;
+       u32 wuc, mdicnfg, ctrl, ctrl_ext, reg_val;
+       u16 nvm_word, phy_word, pci_word, tmp_nvm;
+       int i;
+
+       /* Get and set needed register values */
+       wuc = E1000_READ_REG(hw, E1000_WUC);
+       mdicnfg = E1000_READ_REG(hw, E1000_MDICNFG);
+       reg_val = mdicnfg & ~E1000_MDICNFG_EXT_MDIO;
+       E1000_WRITE_REG(hw, E1000_MDICNFG, reg_val);
+
+       /* Get data from NVM, or set default */
+       ret_val = e1000_read_invm_word_i210(hw, E1000_INVM_AUTOLOAD,
+                                           &nvm_word);
+       if (ret_val != E1000_SUCCESS)
+               nvm_word = E1000_INVM_DEFAULT_AL;
+       tmp_nvm = nvm_word | E1000_INVM_PLL_WO_VAL;
+       for (i = 0; i < E1000_MAX_PLL_TRIES; i++) {
+               /* check current state directly from internal PHY */
+               e1000_read_phy_reg_gs40g(hw, (E1000_PHY_PLL_FREQ_PAGE |
+                                        E1000_PHY_PLL_FREQ_REG), &phy_word);
+               if ((phy_word & E1000_PHY_PLL_UNCONF)
+                   != E1000_PHY_PLL_UNCONF) {
+                       ret_val = E1000_SUCCESS;
+                       break;
+               } else {
+                       ret_val = -E1000_ERR_PHY;
+               }
+               /* directly reset the internal PHY */
+               ctrl = E1000_READ_REG(hw, E1000_CTRL);
+               E1000_WRITE_REG(hw, E1000_CTRL, ctrl|E1000_CTRL_PHY_RST);
+
+               ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
+               ctrl_ext |= (E1000_CTRL_EXT_PHYPDEN | E1000_CTRL_EXT_SDLPE);
+               E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
+
+               E1000_WRITE_REG(hw, E1000_WUC, 0);
+               reg_val = (E1000_INVM_AUTOLOAD << 4) | (tmp_nvm << 16);
+               E1000_WRITE_REG(hw, E1000_EEARBC_I210, reg_val);
+
+               e1000_read_pci_cfg(hw, E1000_PCI_PMCSR, &pci_word);
+               pci_word |= E1000_PCI_PMCSR_D3;
+               e1000_write_pci_cfg(hw, E1000_PCI_PMCSR, &pci_word);
+               msec_delay(1);
+               pci_word &= ~E1000_PCI_PMCSR_D3;
+               e1000_write_pci_cfg(hw, E1000_PCI_PMCSR, &pci_word);
+               reg_val = (E1000_INVM_AUTOLOAD << 4) | (nvm_word << 16);
+               E1000_WRITE_REG(hw, E1000_EEARBC_I210, reg_val);
+
+               /* restore WUC register */
+               E1000_WRITE_REG(hw, E1000_WUC, wuc);
+       }
+       /* restore MDICNFG setting */
+       E1000_WRITE_REG(hw, E1000_MDICNFG, mdicnfg);
+       return ret_val;
+}
+
+/**
+ *  e1000_init_hw_i210 - Init hw for I210/I211
+ *  @hw: pointer to the HW structure
+ *
+ *  Called to initialize hw for i210 hw family.
+ **/
+s32 e1000_init_hw_i210(struct e1000_hw *hw)
+{
+       s32 ret_val;
+
+       DEBUGFUNC("e1000_init_hw_i210");
+       if ((hw->mac.type >= e1000_i210) &&
+           !(e1000_get_flash_presence_i210(hw))) {
+               ret_val = e1000_pll_workaround_i210(hw);
+               if (ret_val != E1000_SUCCESS)
+                       return ret_val;
+       }
+       ret_val = e1000_init_hw_82575(hw);
+       return ret_val;
+}

Modified: head/sys/dev/e1000/e1000_i210.h
==============================================================================
--- head/sys/dev/e1000/e1000_i210.h     Thu Jun 26 20:12:38 2014        
(r267934)
+++ head/sys/dev/e1000/e1000_i210.h     Thu Jun 26 21:33:32 2014        
(r267935)
@@ -1,6 +1,6 @@
 /******************************************************************************
 
-  Copyright (c) 2001-2013, Intel Corporation 
+  Copyright (c) 2001-2014, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -49,6 +49,7 @@ s32 e1000_read_xmdio_reg(struct e1000_hw
                         u16 *data);
 s32 e1000_write_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr,
                          u16 data);
+s32 e1000_init_hw_i210(struct e1000_hw *hw);
 
 #define E1000_STM_OPCODE               0xDB00
 #define E1000_EEPROM_FLASH_SIZE_WORD   0x11
@@ -93,4 +94,16 @@ enum E1000_INVM_STRUCTURE_TYPE {
 #define NVM_INIT_CTRL_4_DEFAULT_I211   0x00C1
 #define NVM_LED_1_CFG_DEFAULT_I211     0x0184
 #define NVM_LED_0_2_CFG_DEFAULT_I211   0x200C
+
+/* PLL Defines */
+#define E1000_PCI_PMCSR                        0x44
+#define E1000_PCI_PMCSR_D3             0x03
+#define E1000_MAX_PLL_TRIES            5
+#define E1000_PHY_PLL_UNCONF           0xFF
+#define E1000_PHY_PLL_FREQ_PAGE                0xFC0000
+#define E1000_PHY_PLL_FREQ_REG         0x000E
+#define E1000_INVM_DEFAULT_AL          0x202F
+#define E1000_INVM_AUTOLOAD            0x0A
+#define E1000_INVM_PLL_WO_VAL          0x0010
+
 #endif

Modified: head/sys/dev/e1000/e1000_ich8lan.c
==============================================================================
--- head/sys/dev/e1000/e1000_ich8lan.c  Thu Jun 26 20:12:38 2014        
(r267934)
+++ head/sys/dev/e1000/e1000_ich8lan.c  Thu Jun 26 21:33:32 2014        
(r267935)
@@ -1,6 +1,6 @@
 /******************************************************************************
 
-  Copyright (c) 2001-2013, Intel Corporation 
+  Copyright (c) 2001-2014, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -63,6 +63,10 @@
  * Ethernet Connection I217-V
  * Ethernet Connection I218-V
  * Ethernet Connection I218-LM
+ * Ethernet Connection (2) I218-LM
+ * Ethernet Connection (2) I218-V
+ * Ethernet Connection (3) I218-LM
+ * Ethernet Connection (3) I218-V
  */
 
 #include "e1000_api.h"
@@ -73,8 +77,8 @@ static s32  e1000_acquire_nvm_ich8lan(st
 static void e1000_release_nvm_ich8lan(struct e1000_hw *hw);
 static bool e1000_check_mng_mode_ich8lan(struct e1000_hw *hw);
 static bool e1000_check_mng_mode_pchlan(struct e1000_hw *hw);
-static void e1000_rar_set_pch2lan(struct e1000_hw *hw, u8 *addr, u32 index);
-static void e1000_rar_set_pch_lpt(struct e1000_hw *hw, u8 *addr, u32 index);
+static int  e1000_rar_set_pch2lan(struct e1000_hw *hw, u8 *addr, u32 index);
+static int  e1000_rar_set_pch_lpt(struct e1000_hw *hw, u8 *addr, u32 index);
 static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw);
 static void e1000_update_mc_addr_list_pch2lan(struct e1000_hw *hw,
                                              u8 *mc_addr_list,
@@ -250,7 +254,7 @@ out:
  *  Toggling the LANPHYPC pin value fully power-cycles the PHY and is
  *  used to reset the PHY to a quiescent state when necessary.
  **/
-void e1000_toggle_lanphypc_pch_lpt(struct e1000_hw *hw)
+static void e1000_toggle_lanphypc_pch_lpt(struct e1000_hw *hw)
 {
        u32 mac_reg;
 
@@ -306,6 +310,12 @@ static s32 e1000_init_phy_workarounds_pc
         */
        e1000_gate_hw_phy_config_ich8lan(hw, TRUE);
 
+       /* It is not possible to be certain of the current state of ULP
+        * so forcibly disable it.
+        */
+       hw->dev_spec.ich8lan.ulp_state = e1000_ulp_state_unknown;
+       e1000_disable_ulp_lpt_lp(hw, TRUE);
+
        ret_val = hw->phy.ops.acquire(hw);
        if (ret_val) {
                DEBUGOUT("Failed to initialize PHY flow\n");
@@ -611,13 +621,12 @@ static s32 e1000_init_nvm_params_ich8lan
        DEBUGFUNC("e1000_init_nvm_params_ich8lan");
 
        /* Can't read flash registers if the register set isn't mapped. */
+       nvm->type = e1000_nvm_flash_sw;
        if (!hw->flash_address) {
                DEBUGOUT("ERROR: Flash registers not mapped\n");
                return -E1000_ERR_CONFIG;
        }
 
-       nvm->type = e1000_nvm_flash_sw;
-
        gfpreg = E1000_READ_FLASH_REG(hw, ICH_FLASH_GFPREG);
 
        /* sector_X_addr is a "sector"-aligned address (4096 bytes)
@@ -672,6 +681,9 @@ static s32 e1000_init_nvm_params_ich8lan
 static s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw)
 {
        struct e1000_mac_info *mac = &hw->mac;
+#if defined(QV_RELEASE) || !defined(NO_PCH_LPT_B0_SUPPORT)
+       u16 pci_cfg;
+#endif /* QV_RELEASE || !defined(NO_PCH_LPT_B0_SUPPORT) */
 
        DEBUGFUNC("e1000_init_mac_params_ich8lan");
 
@@ -744,6 +756,11 @@ static s32 e1000_init_mac_params_ich8lan
                mac->ops.update_mc_addr_list =
                        e1000_update_mc_addr_list_pch2lan;
        case e1000_pchlan:
+#if defined(QV_RELEASE) || !defined(NO_PCH_LPT_B0_SUPPORT)
+               /* save PCH revision_id */
+               e1000_read_pci_cfg(hw, E1000_PCI_REVISION_ID_REG, &pci_cfg);
+               hw->revision_id = (u8)(pci_cfg &= 0x000F);
+#endif /* QV_RELEASE || !defined(NO_PCH_LPT_B0_SUPPORT) */
                /* check management mode */
                mac->ops.check_mng_mode = e1000_check_mng_mode_pchlan;
                /* ID LED init */
@@ -915,6 +932,17 @@ s32 e1000_set_eee_pchlan(struct e1000_hw
                }
        }
 
+       if (hw->phy.type == e1000_phy_82579) {
+               ret_val = e1000_read_emi_reg_locked(hw, I82579_LPI_PLL_SHUT,
+                                                   &data);
+               if (ret_val)
+                       goto release;
+
+               data &= ~I82579_LPI_100_PLL_SHUT;
+               ret_val = e1000_write_emi_reg_locked(hw, I82579_LPI_PLL_SHUT,
+                                                    data);
+       }
+
        /* R/Clr IEEE MMD 3.1 bits 11:10 - Tx/Rx LPI Received */
        ret_val = e1000_read_emi_reg_locked(hw, pcs_status, &data);
        if (ret_val)
@@ -1179,6 +1207,256 @@ static s32 e1000_set_obff_timer_pch_lpt(
 }
 
 /**
+ *  e1000_enable_ulp_lpt_lp - configure Ultra Low Power mode for LynxPoint-LP
+ *  @hw: pointer to the HW structure
+ *  @to_sx: boolean indicating a system power state transition to Sx
+ *
+ *  When link is down, configure ULP mode to significantly reduce the power
+ *  to the PHY.  If on a Manageability Engine (ME) enabled system, tell the
+ *  ME firmware to start the ULP configuration.  If not on an ME enabled
+ *  system, configure the ULP mode by software.
+ */
+s32 e1000_enable_ulp_lpt_lp(struct e1000_hw *hw, bool to_sx)
+{
+       u32 mac_reg;
+       s32 ret_val = E1000_SUCCESS;
+       u16 phy_reg;
+
+       if ((hw->mac.type < e1000_pch_lpt) ||
+           (hw->device_id == E1000_DEV_ID_PCH_LPT_I217_LM) ||
+           (hw->device_id == E1000_DEV_ID_PCH_LPT_I217_V) ||
+           (hw->device_id == E1000_DEV_ID_PCH_I218_LM2) ||
+           (hw->device_id == E1000_DEV_ID_PCH_I218_V2) ||
+           (hw->dev_spec.ich8lan.ulp_state == e1000_ulp_state_on))
+               return 0;
+
+       if (E1000_READ_REG(hw, E1000_FWSM) & E1000_ICH_FWSM_FW_VALID) {
+               /* Request ME configure ULP mode in the PHY */
+               mac_reg = E1000_READ_REG(hw, E1000_H2ME);
+               mac_reg |= E1000_H2ME_ULP | E1000_H2ME_ENFORCE_SETTINGS;
+               E1000_WRITE_REG(hw, E1000_H2ME, mac_reg);
+
+               goto out;
+       }
+
+       if (!to_sx) {
+               int i = 0;
+
+               /* Poll up to 5 seconds for Cable Disconnected indication */
+               while (!(E1000_READ_REG(hw, E1000_FEXT) &
+                        E1000_FEXT_PHY_CABLE_DISCONNECTED)) {
+                       /* Bail if link is re-acquired */
+                       if (E1000_READ_REG(hw, E1000_STATUS) & E1000_STATUS_LU)
+                               return -E1000_ERR_PHY;
+
+                       if (i++ == 100)
+                               break;
+
+                       msec_delay(50);
+               }
+               DEBUGOUT2("CABLE_DISCONNECTED %s set after %dmsec\n",
+                        (E1000_READ_REG(hw, E1000_FEXT) &
+                         E1000_FEXT_PHY_CABLE_DISCONNECTED) ? "" : "not",
+                        i * 50);
+       }
+
+       ret_val = hw->phy.ops.acquire(hw);
+       if (ret_val)
+               goto out;
+
+       /* Force SMBus mode in PHY */
+       ret_val = e1000_read_phy_reg_hv_locked(hw, CV_SMB_CTRL, &phy_reg);
+       if (ret_val)
+               goto release;
+       phy_reg |= CV_SMB_CTRL_FORCE_SMBUS;
+       e1000_write_phy_reg_hv_locked(hw, CV_SMB_CTRL, phy_reg);
+
+       /* Force SMBus mode in MAC */
+       mac_reg = E1000_READ_REG(hw, E1000_CTRL_EXT);
+       mac_reg |= E1000_CTRL_EXT_FORCE_SMBUS;
+       E1000_WRITE_REG(hw, E1000_CTRL_EXT, mac_reg);
+
+       /* Set Inband ULP Exit, Reset to SMBus mode and
+        * Disable SMBus Release on PERST# in PHY
+        */
+       ret_val = e1000_read_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, &phy_reg);
+       if (ret_val)
+               goto release;
+       phy_reg |= (I218_ULP_CONFIG1_RESET_TO_SMBUS |
+                   I218_ULP_CONFIG1_DISABLE_SMB_PERST);
+       if (to_sx) {
+               if (E1000_READ_REG(hw, E1000_WUFC) & E1000_WUFC_LNKC)
+                       phy_reg |= I218_ULP_CONFIG1_WOL_HOST;
+
+               phy_reg |= I218_ULP_CONFIG1_STICKY_ULP;
+       } else {
+               phy_reg |= I218_ULP_CONFIG1_INBAND_EXIT;
+       }
+       e1000_write_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, phy_reg);
+
+       /* Set Disable SMBus Release on PERST# in MAC */
+       mac_reg = E1000_READ_REG(hw, E1000_FEXTNVM7);
+       mac_reg |= E1000_FEXTNVM7_DISABLE_SMB_PERST;
+       E1000_WRITE_REG(hw, E1000_FEXTNVM7, mac_reg);
+
+       /* Commit ULP changes in PHY by starting auto ULP configuration */
+       phy_reg |= I218_ULP_CONFIG1_START;
+       e1000_write_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, phy_reg);
+release:
+       hw->phy.ops.release(hw);
+out:
+       if (ret_val)
+               DEBUGOUT1("Error in ULP enable flow: %d\n", ret_val);
+       else
+               hw->dev_spec.ich8lan.ulp_state = e1000_ulp_state_on;
+
+       return ret_val;
+}
+
+/**
+ *  e1000_disable_ulp_lpt_lp - unconfigure Ultra Low Power mode for 
LynxPoint-LP
+ *  @hw: pointer to the HW structure
+ *  @force: boolean indicating whether or not to force disabling ULP
+ *
+ *  Un-configure ULP mode when link is up, the system is transitioned from
+ *  Sx or the driver is unloaded.  If on a Manageability Engine (ME) enabled
+ *  system, poll for an indication from ME that ULP has been un-configured.
+ *  If not on an ME enabled system, un-configure the ULP mode by software.
+ *
+ *  During nominal operation, this function is called when link is acquired
+ *  to disable ULP mode (force=FALSE); otherwise, for example when unloading
+ *  the driver or during Sx->S0 transitions, this is called with force=TRUE
+ *  to forcibly disable ULP.
+ */

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "[email protected]"

Reply via email to