Author: jfv
Date: Mon Jul 28 21:11:18 2014
New Revision: 269196
URL: http://svnweb.freebsd.org/changeset/base/269196

Log:
  MFC of R267935: Sync the E1000 shared code to Intel internal, and
                more importantly add new I218 adapter support to em.

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

Modified: stable/10/sys/dev/e1000/e1000_82542.c
==============================================================================
--- stable/10/sys/dev/e1000/e1000_82542.c       Mon Jul 28 19:01:25 2014        
(r269195)
+++ stable/10/sys/dev/e1000/e1000_82542.c       Mon Jul 28 21:11:18 2014        
(r269196)
@@ -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: stable/10/sys/dev/e1000/e1000_82571.c
==============================================================================
--- stable/10/sys/dev/e1000/e1000_82571.c       Mon Jul 28 19:01:25 2014        
(r269195)
+++ stable/10/sys/dev/e1000/e1000_82571.c       Mon Jul 28 21:11:18 2014        
(r269196)
@@ -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: stable/10/sys/dev/e1000/e1000_82571.h
==============================================================================
--- stable/10/sys/dev/e1000/e1000_82571.h       Mon Jul 28 19:01:25 2014        
(r269195)
+++ stable/10/sys/dev/e1000/e1000_82571.h       Mon Jul 28 21:11:18 2014        
(r269196)
@@ -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 
@@ -35,29 +35,30 @@
 #ifndef _E1000_82571_H_
 #define _E1000_82571_H_
 
-#define ID_LED_RESERVED_F746 0xF746
-#define ID_LED_DEFAULT_82573 ((ID_LED_DEF1_DEF2 << 12) | \
-                              (ID_LED_OFF1_ON2  <<  8) | \
-                              (ID_LED_DEF1_DEF2 <<  4) | \
-                              (ID_LED_DEF1_DEF2))
+#define ID_LED_RESERVED_F746   0xF746
+#define ID_LED_DEFAULT_82573   ((ID_LED_DEF1_DEF2 << 12) | \
+                                (ID_LED_OFF1_ON2  <<  8) | \
+                                (ID_LED_DEF1_DEF2 <<  4) | \
+                                (ID_LED_DEF1_DEF2))
 
-#define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000
-#define AN_RETRY_COUNT          5 /* Autoneg Retry Count value */
+#define E1000_GCR_L1_ACT_WITHOUT_L0S_RX        0x08000000
+#define AN_RETRY_COUNT         5 /* Autoneg Retry Count value */
 
 /* Intr Throttling - RW */
-#define E1000_EITR_82574(_n)    (0x000E8 + (0x4 * (_n)))
+#define E1000_EITR_82574(_n)   (0x000E8 + (0x4 * (_n)))
 
-#define E1000_EIAC_82574        0x000DC /* Ext. Interrupt Auto Clear - RW */
-#define E1000_EIAC_MASK_82574   0x01F00000
+#define E1000_EIAC_82574       0x000DC /* Ext. Interrupt Auto Clear - RW */
+#define E1000_EIAC_MASK_82574  0x01F00000
 
-#define E1000_NVM_INIT_CTRL2_MNGM 0x6000 /* Manageability Operation Mode mask 
*/
+#define E1000_IVAR_INT_ALLOC_VALID     0x8
 
-#define E1000_RXCFGL    0x0B634 /* TimeSync Rx EtherType & Msg Type Reg - RW */
+/* Manageability Operation Mode mask */
+#define E1000_NVM_INIT_CTRL2_MNGM      0x6000
 
-#define E1000_BASE1000T_STATUS 10
-#define E1000_IDLE_ERROR_COUNT_MASK 0xFF
-#define E1000_RECEIVE_ERROR_COUNTER 21
-#define E1000_RECEIVE_ERROR_MAX 0xFFFF
+#define E1000_BASE1000T_STATUS         10
+#define E1000_IDLE_ERROR_COUNT_MASK    0xFF
+#define E1000_RECEIVE_ERROR_COUNTER    21
+#define E1000_RECEIVE_ERROR_MAX                0xFFFF
 bool e1000_check_phy_82574(struct e1000_hw *hw);
 bool e1000_get_laa_state_82571(struct e1000_hw *hw);
 void e1000_set_laa_state_82571(struct e1000_hw *hw, bool state);

Modified: stable/10/sys/dev/e1000/e1000_82575.c
==============================================================================
--- stable/10/sys/dev/e1000/e1000_82575.c       Mon Jul 28 19:01:25 2014        
(r269195)
+++ stable/10/sys/dev/e1000/e1000_82575.c       Mon Jul 28 21:11:18 2014        
(r269196)
@@ -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: stable/10/sys/dev/e1000/e1000_82575.h
==============================================================================
--- stable/10/sys/dev/e1000/e1000_82575.h       Mon Jul 28 19:01:25 2014        
(r269195)
+++ stable/10/sys/dev/e1000/e1000_82575.h       Mon Jul 28 21:11:18 2014        
(r269196)
@@ -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: stable/10/sys/dev/e1000/e1000_api.c
==============================================================================
--- stable/10/sys/dev/e1000/e1000_api.c Mon Jul 28 19:01:25 2014        
(r269195)
+++ stable/10/sys/dev/e1000/e1000_api.c Mon Jul 28 21:11:18 2014        
(r269196)
@@ -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: stable/10/sys/dev/e1000/e1000_api.h
==============================================================================
--- stable/10/sys/dev/e1000/e1000_api.h Mon Jul 28 19:01:25 2014        
(r269195)
+++ stable/10/sys/dev/e1000/e1000_api.h Mon Jul 28 21:11:18 2014        
(r269196)
@@ -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: stable/10/sys/dev/e1000/e1000_defines.h
==============================================================================
--- stable/10/sys/dev/e1000/e1000_defines.h     Mon Jul 28 19:01:25 2014        
(r269195)
+++ stable/10/sys/dev/e1000/e1000_defines.h     Mon Jul 28 21:11:18 2014        
(r269196)
@@ -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
@@ -157,6 +158,7 @@
        E1000_RXDEXT_STATERR_CXE |      \
        E1000_RXDEXT_STATERR_RXE)
 
+#define E1000_MRQC_ENABLE_RSS_2Q               0x00000001
 #define E1000_MRQC_RSS_FIELD_MASK              0xFFFF0000
 #define E1000_MRQC_RSS_FIELD_IPV4_TCP          0x00010000
 #define E1000_MRQC_RSS_FIELD_IPV4              0x00020000
@@ -464,6 +466,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 +856,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 +1436,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 +1465,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: stable/10/sys/dev/e1000/e1000_hw.h
==============================================================================
--- stable/10/sys/dev/e1000/e1000_hw.h  Mon Jul 28 19:01:25 2014        
(r269195)
+++ stable/10/sys/dev/e1000/e1000_hw.h  Mon Jul 28 21:11:18 2014        
(r269196)
@@ -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: stable/10/sys/dev/e1000/e1000_i210.c
==============================================================================
--- stable/10/sys/dev/e1000/e1000_i210.c        Mon Jul 28 19:01:25 2014        
(r269195)
+++ stable/10/sys/dev/e1000/e1000_i210.c        Mon Jul 28 21:11:18 2014        
(r269196)
@@ -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: stable/10/sys/dev/e1000/e1000_i210.h
==============================================================================
--- stable/10/sys/dev/e1000/e1000_i210.h        Mon Jul 28 19:01:25 2014        
(r269195)
+++ stable/10/sys/dev/e1000/e1000_i210.h        Mon Jul 28 21:11:18 2014        
(r269196)
@@ -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: stable/10/sys/dev/e1000/e1000_ich8lan.c
==============================================================================
--- stable/10/sys/dev/e1000/e1000_ich8lan.c     Mon Jul 28 19:01:25 2014        
(r269195)
+++ stable/10/sys/dev/e1000/e1000_ich8lan.c     Mon Jul 28 21:11:18 2014        
(r269196)
@@ -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)
@@ -915,6 +924,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 +1199,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) {

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

Reply via email to