Author: sbruno
Date: Sun Sep 13 18:26:05 2015
New Revision: 287762
URL: https://svnweb.freebsd.org/changeset/base/287762

Log:
  Update em(4) with D3162 after testing further on hardware that failed
  to attach with the last version of this commit. This commit fixes
  attach failures on "ICH8" class devices via modifications to
  e1000_init_nvm_params_ich8lan()
  
  -   Fix compiler warning in 80003es2lan.c
  -   Add return value handler for e1000_*_kmrn_reg_80003es2lan
  -   Fix usage of DEBUGOUT
  -   Remove unnecessary variable initializations.
  -   Removed unused variables (complaints from gcc).
  -   Edit defines in 82571.h.
  -   Add workaround for igb hw errata.
  -   Shared code changes for Skylake/I219 support.
  -   Remove unused OBFF and LTR functions.
  
  Tested by some of the folks that reported breakage in previous incarnation.
  Thanks to AllanJude, gjb, gnn, tijl for tempting fate with their machines.
  
  Submitted by: e...@freebsd.org
  MFC after:    2 weeks
  Differential Revision:        https://reviews.freebsd.org/D3162

Modified:
  head/sys/dev/e1000/e1000_80003es2lan.c
  head/sys/dev/e1000/e1000_82540.c
  head/sys/dev/e1000/e1000_82541.c
  head/sys/dev/e1000/e1000_82542.c
  head/sys/dev/e1000/e1000_82543.c
  head/sys/dev/e1000/e1000_82571.h
  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_nvm.c
  head/sys/dev/e1000/e1000_nvm.h
  head/sys/dev/e1000/e1000_osdep.h
  head/sys/dev/e1000/e1000_phy.c
  head/sys/dev/e1000/e1000_regs.h
  head/sys/dev/e1000/if_igb.c

Modified: head/sys/dev/e1000/e1000_80003es2lan.c
==============================================================================
--- head/sys/dev/e1000/e1000_80003es2lan.c      Sun Sep 13 17:17:52 2015        
(r287761)
+++ head/sys/dev/e1000/e1000_80003es2lan.c      Sun Sep 13 18:26:05 2015        
(r287762)
@@ -851,11 +851,17 @@ static s32 e1000_reset_hw_80003es2lan(st
        e1000_release_phy_80003es2lan(hw);
 
        /* Disable IBIST slave mode (far-end loopback) */
-       e1000_read_kmrn_reg_80003es2lan(hw, E1000_KMRNCTRLSTA_INBAND_PARAM,
-                                       &kum_reg_data);
-       kum_reg_data |= E1000_KMRNCTRLSTA_IBIST_DISABLE;
-       e1000_write_kmrn_reg_80003es2lan(hw, E1000_KMRNCTRLSTA_INBAND_PARAM,
-                                       kum_reg_data);
+       ret_val = e1000_read_kmrn_reg_80003es2lan(hw,
+                               E1000_KMRNCTRLSTA_INBAND_PARAM, &kum_reg_data);
+       if (!ret_val) {
+               kum_reg_data |= E1000_KMRNCTRLSTA_IBIST_DISABLE;
+               ret_val = e1000_write_kmrn_reg_80003es2lan(hw,
+                                                E1000_KMRNCTRLSTA_INBAND_PARAM,
+                                                kum_reg_data);
+               if (ret_val)
+                       DEBUGOUT("Error disabling far-end loopback\n");
+       } else
+               DEBUGOUT("Error disabling far-end loopback\n");
 
        ret_val = e1000_get_auto_rd_done_generic(hw);
        if (ret_val)
@@ -911,11 +917,18 @@ static s32 e1000_init_hw_80003es2lan(str
                return ret_val;
 
        /* Disable IBIST slave mode (far-end loopback) */
-       e1000_read_kmrn_reg_80003es2lan(hw, E1000_KMRNCTRLSTA_INBAND_PARAM,
-                                       &kum_reg_data);
-       kum_reg_data |= E1000_KMRNCTRLSTA_IBIST_DISABLE;
-       e1000_write_kmrn_reg_80003es2lan(hw, E1000_KMRNCTRLSTA_INBAND_PARAM,
-                                        kum_reg_data);
+       ret_val =
+           e1000_read_kmrn_reg_80003es2lan(hw, E1000_KMRNCTRLSTA_INBAND_PARAM,
+                                           &kum_reg_data);
+       if (!ret_val) {
+               kum_reg_data |= E1000_KMRNCTRLSTA_IBIST_DISABLE;
+               ret_val = e1000_write_kmrn_reg_80003es2lan(hw,
+                                                E1000_KMRNCTRLSTA_INBAND_PARAM,
+                                                kum_reg_data);
+               if (ret_val)
+                       DEBUGOUT("Error disabling far-end loopback\n");
+       } else
+               DEBUGOUT("Error disabling far-end loopback\n");
 
        /* Set the transmit descriptor write-back policy */
        reg_data = E1000_READ_REG(hw, E1000_TXDCTL(0));

Modified: head/sys/dev/e1000/e1000_82540.c
==============================================================================
--- head/sys/dev/e1000/e1000_82540.c    Sun Sep 13 17:17:52 2015        
(r287761)
+++ head/sys/dev/e1000/e1000_82540.c    Sun Sep 13 18:26:05 2015        
(r287762)
@@ -66,7 +66,7 @@ static s32  e1000_read_mac_addr_82540(st
 static s32 e1000_init_phy_params_82540(struct e1000_hw *hw)
 {
        struct e1000_phy_info *phy = &hw->phy;
-       s32 ret_val = E1000_SUCCESS;
+       s32 ret_val;
 
        phy->addr               = 1;
        phy->autoneg_mask       = AUTONEG_ADVERTISE_SPEED_DEFAULT;
@@ -329,7 +329,7 @@ static s32 e1000_init_hw_82540(struct e1
 {
        struct e1000_mac_info *mac = &hw->mac;
        u32 txdctl, ctrl_ext;
-       s32 ret_val = E1000_SUCCESS;
+       s32 ret_val;
        u16 i;
 
        DEBUGFUNC("e1000_init_hw_82540");
@@ -411,7 +411,7 @@ static s32 e1000_init_hw_82540(struct e1
 static s32 e1000_setup_copper_link_82540(struct e1000_hw *hw)
 {
        u32 ctrl;
-       s32 ret_val = E1000_SUCCESS;
+       s32 ret_val;
        u16 data;
 
        DEBUGFUNC("e1000_setup_copper_link_82540");
@@ -498,7 +498,7 @@ out:
  **/
 static s32 e1000_adjust_serdes_amplitude_82540(struct e1000_hw *hw)
 {
-       s32 ret_val = E1000_SUCCESS;
+       s32 ret_val;
        u16 nvm_data;
 
        DEBUGFUNC("e1000_adjust_serdes_amplitude_82540");
@@ -528,7 +528,7 @@ out:
  **/
 static s32 e1000_set_vco_speed_82540(struct e1000_hw *hw)
 {
-       s32  ret_val = E1000_SUCCESS;
+       s32  ret_val;
        u16 default_page = 0;
        u16 phy_data;
 

Modified: head/sys/dev/e1000/e1000_82541.c
==============================================================================
--- head/sys/dev/e1000/e1000_82541.c    Sun Sep 13 17:17:52 2015        
(r287761)
+++ head/sys/dev/e1000/e1000_82541.c    Sun Sep 13 18:26:05 2015        
(r287762)
@@ -85,7 +85,7 @@ static const u16 e1000_igp_cable_length_
 static s32 e1000_init_phy_params_82541(struct e1000_hw *hw)
 {
        struct e1000_phy_info *phy = &hw->phy;
-       s32 ret_val = E1000_SUCCESS;
+       s32 ret_val;
 
        DEBUGFUNC("e1000_init_phy_params_82541");
 
@@ -295,7 +295,7 @@ void e1000_init_function_pointers_82541(
  **/
 static s32 e1000_reset_hw_82541(struct e1000_hw *hw)
 {
-       u32 ledctl, ctrl, icr, manc;
+       u32 ledctl, ctrl, manc;
 
        DEBUGFUNC("e1000_reset_hw_82541");
 
@@ -317,6 +317,7 @@ static s32 e1000_reset_hw_82541(struct e
        /* Must reset the Phy before resetting the MAC */
        if ((hw->mac.type == e1000_82541) || (hw->mac.type == e1000_82547)) {
                E1000_WRITE_REG(hw, E1000_CTRL, (ctrl | E1000_CTRL_PHY_RST));
+               E1000_WRITE_FLUSH(hw);
                msec_delay(5);
        }
 
@@ -359,7 +360,7 @@ static s32 e1000_reset_hw_82541(struct e
        E1000_WRITE_REG(hw, E1000_IMC, 0xFFFFFFFF);
 
        /* Clear any pending interrupt events. */
-       icr = E1000_READ_REG(hw, E1000_ICR);
+       E1000_READ_REG(hw, E1000_ICR);
 
        return E1000_SUCCESS;
 }

Modified: head/sys/dev/e1000/e1000_82542.c
==============================================================================
--- head/sys/dev/e1000/e1000_82542.c    Sun Sep 13 17:17:52 2015        
(r287761)
+++ head/sys/dev/e1000/e1000_82542.c    Sun Sep 13 18:26:05 2015        
(r287762)
@@ -317,7 +317,7 @@ static s32 e1000_init_hw_82542(struct e1
 static s32 e1000_setup_link_82542(struct e1000_hw *hw)
 {
        struct e1000_mac_info *mac = &hw->mac;
-       s32 ret_val = E1000_SUCCESS;
+       s32 ret_val;
 
        DEBUGFUNC("e1000_setup_link_82542");
 
@@ -565,7 +565,7 @@ static void e1000_clear_hw_cntrs_82542(s
  *
  *  Reads the device MAC address from the EEPROM and stores the value.
  **/
-static s32 e1000_read_mac_addr_82542(struct e1000_hw *hw)
+s32 e1000_read_mac_addr_82542(struct e1000_hw *hw)
 {
        s32  ret_val = E1000_SUCCESS;
        u16 offset, nvm_data, i;

Modified: head/sys/dev/e1000/e1000_82543.c
==============================================================================
--- head/sys/dev/e1000/e1000_82543.c    Sun Sep 13 17:17:52 2015        
(r287761)
+++ head/sys/dev/e1000/e1000_82543.c    Sun Sep 13 18:26:05 2015        
(r287762)
@@ -900,7 +900,7 @@ static s32 e1000_phy_hw_reset_82543(stru
  **/
 static s32 e1000_reset_hw_82543(struct e1000_hw *hw)
 {
-       u32 ctrl, icr;
+       u32 ctrl;
        s32 ret_val = E1000_SUCCESS;
 
        DEBUGFUNC("e1000_reset_hw_82543");
@@ -942,7 +942,7 @@ static s32 e1000_reset_hw_82543(struct e
 
        /* Masking off and clearing any pending interrupts */
        E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
-       icr = E1000_READ_REG(hw, E1000_ICR);
+       E1000_READ_REG(hw, E1000_ICR);
 
        return ret_val;
 }

Modified: head/sys/dev/e1000/e1000_82571.h
==============================================================================
--- head/sys/dev/e1000/e1000_82571.h    Sun Sep 13 17:17:52 2015        
(r287761)
+++ head/sys/dev/e1000/e1000_82571.h    Sun Sep 13 18:26:05 2015        
(r287762)
@@ -50,9 +50,10 @@
 #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

Modified: head/sys/dev/e1000/e1000_82575.c
==============================================================================
--- head/sys/dev/e1000/e1000_82575.c    Sun Sep 13 17:17:52 2015        
(r287761)
+++ head/sys/dev/e1000/e1000_82575.c    Sun Sep 13 18:26:05 2015        
(r287762)
@@ -1235,7 +1235,7 @@ static s32 e1000_check_for_link_media_sw
 
        DEBUGFUNC("e1000_check_for_link_media_swap");
 
-       /* Check the copper medium. */
+       /* Check for copper. */
        ret_val = phy->ops.write_reg(hw, E1000_M88E1112_PAGE_ADDR, 0);
        if (ret_val)
                return ret_val;
@@ -1247,7 +1247,7 @@ static s32 e1000_check_for_link_media_sw
        if (data & E1000_M88E1112_STATUS_LINK)
                port = E1000_MEDIA_PORT_COPPER;
 
-       /* Check the other medium. */
+       /* Check for other. */
        ret_val = phy->ops.write_reg(hw, E1000_M88E1112_PAGE_ADDR, 1);
        if (ret_val)
                return ret_val;
@@ -1256,11 +1256,6 @@ static s32 e1000_check_for_link_media_sw
        if (ret_val)
                return ret_val;
 
-       /* reset page to 0 */
-       ret_val = phy->ops.write_reg(hw, E1000_M88E1112_PAGE_ADDR, 0);
-       if (ret_val)
-               return ret_val;
-
        if (data & E1000_M88E1112_STATUS_LINK)
                port = E1000_MEDIA_PORT_OTHER;
 
@@ -1268,8 +1263,20 @@ static s32 e1000_check_for_link_media_sw
        if (port && (hw->dev_spec._82575.media_port != port)) {
                hw->dev_spec._82575.media_port = port;
                hw->dev_spec._82575.media_changed = TRUE;
+       }
+
+       if (port == E1000_MEDIA_PORT_COPPER) {
+               /* reset page to 0 */
+               ret_val = phy->ops.write_reg(hw, E1000_M88E1112_PAGE_ADDR, 0);
+               if (ret_val)
+                       return ret_val;
+               e1000_check_for_link_82575(hw);
        } else {
-               ret_val = e1000_check_for_link_82575(hw);
+               e1000_check_for_link_82575(hw);
+               /* reset page to 0 */
+               ret_val = phy->ops.write_reg(hw, E1000_M88E1112_PAGE_ADDR, 0);
+               if (ret_val)
+                       return ret_val;
        }
 
        return E1000_SUCCESS;
@@ -2136,7 +2143,13 @@ void e1000_rx_fifo_flush_82575(struct e1
        u32 rctl, rlpml, rxdctl[4], rfctl, temp_rctl, rx_enabled;
        int i, ms_wait;
 
-       DEBUGFUNC("e1000_rx_fifo_workaround_82575");
+       DEBUGFUNC("e1000_rx_fifo_flush_82575");
+
+       /* disable IPv6 options as per hardware errata */
+       rfctl = E1000_READ_REG(hw, E1000_RFCTL);
+       rfctl |= E1000_RFCTL_IPV6_EX_DIS;
+       E1000_WRITE_REG(hw, E1000_RFCTL, rfctl);
+
        if (hw->mac.type != e1000_82575 ||
            !(E1000_READ_REG(hw, E1000_MANC) & E1000_MANC_RCV_TCO_EN))
                return;
@@ -2164,7 +2177,6 @@ void e1000_rx_fifo_flush_82575(struct e1
         * incoming packets are rejected.  Set enable and wait 2ms so that
         * any packet that was coming in as RCTL.EN was set is flushed
         */
-       rfctl = E1000_READ_REG(hw, E1000_RFCTL);
        E1000_WRITE_REG(hw, E1000_RFCTL, rfctl & ~E1000_RFCTL_LEF);
 
        rlpml = E1000_READ_REG(hw, E1000_RLPML);
@@ -2894,11 +2906,13 @@ out:
 /**
  *  e1000_set_eee_i350 - Enable/disable EEE support
  *  @hw: pointer to the HW structure
+ *  @adv1g: boolean flag enabling 1G EEE advertisement
+ *  @adv100m: boolean flag enabling 100M EEE advertisement
  *
  *  Enable/disable EEE based on setting in dev_spec structure.
  *
  **/
-s32 e1000_set_eee_i350(struct e1000_hw *hw)
+s32 e1000_set_eee_i350(struct e1000_hw *hw, bool adv1G, bool adv100M)
 {
        u32 ipcnfg, eeer;
 
@@ -2914,7 +2928,16 @@ s32 e1000_set_eee_i350(struct e1000_hw *
        if (!(hw->dev_spec._82575.eee_disable)) {
                u32 eee_su = E1000_READ_REG(hw, E1000_EEE_SU);
 
-               ipcnfg |= (E1000_IPCNFG_EEE_1G_AN | E1000_IPCNFG_EEE_100M_AN);
+               if (adv100M)
+                       ipcnfg |= E1000_IPCNFG_EEE_100M_AN;
+               else
+                       ipcnfg &= ~E1000_IPCNFG_EEE_100M_AN;
+
+               if (adv1G)
+                       ipcnfg |= E1000_IPCNFG_EEE_1G_AN;
+               else
+                       ipcnfg &= ~E1000_IPCNFG_EEE_1G_AN;
+
                eeer |= (E1000_EEER_TX_LPI_EN | E1000_EEER_RX_LPI_EN |
                         E1000_EEER_LPI_FC);
 
@@ -2938,11 +2961,13 @@ out:
 /**
  *  e1000_set_eee_i354 - Enable/disable EEE support
  *  @hw: pointer to the HW structure
+ *  @adv1g: boolean flag enabling 1G EEE advertisement
+ *  @adv100m: boolean flag enabling 100M EEE advertisement
  *
  *  Enable/disable EEE legacy mode based on setting in dev_spec structure.
  *
  **/
-s32 e1000_set_eee_i354(struct e1000_hw *hw)
+s32 e1000_set_eee_i354(struct e1000_hw *hw, bool adv1G, bool adv100M)
 {
        struct e1000_phy_info *phy = &hw->phy;
        s32 ret_val = E1000_SUCCESS;
@@ -2984,8 +3009,16 @@ s32 e1000_set_eee_i354(struct e1000_hw *
                if (ret_val)
                        goto out;
 
-               phy_data |= E1000_EEE_ADV_100_SUPPORTED |
-                           E1000_EEE_ADV_1000_SUPPORTED;
+               if (adv100M)
+                       phy_data |= E1000_EEE_ADV_100_SUPPORTED;
+               else
+                       phy_data &= ~E1000_EEE_ADV_100_SUPPORTED;
+
+               if (adv1G)
+                       phy_data |= E1000_EEE_ADV_1000_SUPPORTED;
+               else
+                       phy_data &= ~E1000_EEE_ADV_1000_SUPPORTED;
+
                ret_val = e1000_write_xmdio_reg(hw, E1000_EEE_ADV_ADDR_I354,
                                                E1000_EEE_ADV_DEV_I354,
                                                phy_data);

Modified: head/sys/dev/e1000/e1000_82575.h
==============================================================================
--- head/sys/dev/e1000/e1000_82575.h    Sun Sep 13 17:17:52 2015        
(r287761)
+++ head/sys/dev/e1000/e1000_82575.h    Sun Sep 13 18:26:05 2015        
(r287762)
@@ -495,8 +495,8 @@ void e1000_rlpml_set_vf(struct e1000_hw 
 s32 e1000_promisc_set_vf(struct e1000_hw *, enum e1000_promisc_type type);
 u16 e1000_rxpbs_adjust_82580(u32 data);
 s32 e1000_read_emi_reg(struct e1000_hw *hw, u16 addr, u16 *data);
-s32 e1000_set_eee_i350(struct e1000_hw *);
-s32 e1000_set_eee_i354(struct e1000_hw *);
+s32 e1000_set_eee_i350(struct e1000_hw *hw, bool adv1G, bool adv100M);
+s32 e1000_set_eee_i354(struct e1000_hw *hw, bool adv1G, bool adv100M);
 s32 e1000_get_eee_status_i354(struct e1000_hw *, bool *);
 s32 e1000_initialize_M88E1512_phy(struct e1000_hw *hw);
 

Modified: head/sys/dev/e1000/e1000_api.c
==============================================================================
--- head/sys/dev/e1000/e1000_api.c      Sun Sep 13 17:17:52 2015        
(r287761)
+++ head/sys/dev/e1000/e1000_api.c      Sun Sep 13 18:26:05 2015        
(r287762)
@@ -299,6 +299,12 @@ s32 e1000_set_mac_type(struct e1000_hw *
        case E1000_DEV_ID_PCH_I218_V3:
                mac->type = e1000_pch_lpt;
                break;
+       case E1000_DEV_ID_PCH_SPT_I219_LM:
+       case E1000_DEV_ID_PCH_SPT_I219_V:
+       case E1000_DEV_ID_PCH_SPT_I219_LM2:
+       case E1000_DEV_ID_PCH_SPT_I219_V2:
+               mac->type = e1000_pch_spt;
+               break;
        case E1000_DEV_ID_82575EB_COPPER:
        case E1000_DEV_ID_82575EB_FIBER_SERDES:
        case E1000_DEV_ID_82575GB_QUAD_COPPER:
@@ -449,6 +455,7 @@ s32 e1000_setup_init_funcs(struct e1000_
        case e1000_pchlan:
        case e1000_pch2lan:
        case e1000_pch_lpt:
+       case e1000_pch_spt:
                e1000_init_function_pointers_ich8lan(hw);
                break;
        case e1000_82575:
@@ -929,21 +936,6 @@ s32 e1000_mng_enable_host_if(struct e100
 }
 
 /**
- *  e1000_set_obff_timer - Set Optimized Buffer Flush/Fill timer
- *  @hw: pointer to the HW structure
- *  @itr: u32 indicating itr value
- *
- *  Set the OBFF timer based on the given interrupt rate.
- **/
-s32 e1000_set_obff_timer(struct e1000_hw *hw, u32 itr)
-{
-       if (hw->mac.ops.set_obff_timer)
-               return hw->mac.ops.set_obff_timer(hw, itr);
-
-       return E1000_SUCCESS;
-}
-
-/**
  *  e1000_check_reset_block - Verifies PHY can be reset
  *  @hw: pointer to the HW structure
  *
@@ -1216,6 +1208,21 @@ s32 e1000_read_pba_length(struct e1000_h
 }
 
 /**
+ *  e1000_read_pba_num - Read device part number
+ *  @hw: pointer to the HW structure
+ *  @pba_num: pointer to device part number
+ *
+ *  Reads the product board assembly (PBA) number from the EEPROM and stores
+ *  the value in pba_num.
+ *  Currently no func pointer exists and all implementations are handled in the
+ *  generic version of this function.
+ **/
+s32 e1000_read_pba_num(struct e1000_hw *hw, u32 *pba_num)
+{
+       return e1000_read_pba_num_generic(hw, pba_num);
+}
+
+/**
  *  e1000_validate_nvm_checksum - Verifies NVM (EEPROM) checksum
  *  @hw: pointer to the HW structure
  *

Modified: head/sys/dev/e1000/e1000_api.h
==============================================================================
--- head/sys/dev/e1000/e1000_api.h      Sun Sep 13 17:17:52 2015        
(r287761)
+++ head/sys/dev/e1000/e1000_api.h      Sun Sep 13 18:26:05 2015        
(r287762)
@@ -97,6 +97,7 @@ s32 e1000_phy_commit(struct e1000_hw *hw
 void e1000_power_up_phy(struct e1000_hw *hw);
 void e1000_power_down_phy(struct e1000_hw *hw);
 s32 e1000_read_mac_addr(struct e1000_hw *hw);
+s32 e1000_read_pba_num(struct e1000_hw *hw, u32 *part_num);
 s32 e1000_read_pba_string(struct e1000_hw *hw, u8 *pba_num, u32 pba_num_size);
 s32 e1000_read_pba_length(struct e1000_hw *hw, u32 *pba_num_size);
 void e1000_reload_nvm(struct e1000_hw *hw);

Modified: head/sys/dev/e1000/e1000_defines.h
==============================================================================
--- head/sys/dev/e1000/e1000_defines.h  Sun Sep 13 17:17:52 2015        
(r287761)
+++ head/sys/dev/e1000/e1000_defines.h  Sun Sep 13 18:26:05 2015        
(r287762)
@@ -197,6 +197,8 @@
 #define E1000_RCTL_LBM_TCVR    0x000000C0 /* tcvr loopback mode */
 #define E1000_RCTL_DTYP_PS     0x00000400 /* Packet Split descriptor */
 #define E1000_RCTL_RDMTS_HALF  0x00000000 /* Rx desc min thresh size */
+#define E1000_RCTL_RDMTS_HEX   0x00010000
+#define E1000_RCTL_RDMTS1_HEX  E1000_RCTL_RDMTS_HEX
 #define E1000_RCTL_MO_SHIFT    12 /* multicast offset shift */
 #define E1000_RCTL_MO_3                0x00003000 /* multicast offset 15:4 */
 #define E1000_RCTL_BAM         0x00008000 /* broadcast enable */
@@ -565,9 +567,6 @@
 #define E1000_ICR_THS          0x00800000 /* ICR.THS: Thermal Sensor Event*/
 #define E1000_ICR_MDDET                0x10000000 /* Malicious Driver Detect */
 
-#define E1000_ITR_MASK         0x000FFFFF /* ITR value bitfield */
-#define E1000_ITR_MULT         256 /* ITR mulitplier in nsec */
-
 /* PBA ECC Register */
 #define E1000_PBA_ECC_COUNTER_MASK     0xFFF00000 /* ECC counter mask */
 #define E1000_PBA_ECC_COUNTER_SHIFT    20 /* ECC counter shift value */
@@ -753,6 +752,12 @@
 #define E1000_TSYNCTXCTL_VALID         0x00000001 /* Tx timestamp valid */
 #define E1000_TSYNCTXCTL_ENABLED       0x00000010 /* enable Tx timestamping */
 
+/* HH Time Sync */
+#define E1000_TSYNCTXCTL_MAX_ALLOWED_DLY_MASK  0x0000F000 /* max delay */
+#define E1000_TSYNCTXCTL_SYNC_COMP_ERR         0x20000000 /* sync err */
+#define E1000_TSYNCTXCTL_SYNC_COMP             0x40000000 /* sync complete */
+#define E1000_TSYNCTXCTL_START_SYNC            0x80000000 /* initiate sync */
+
 #define E1000_TSYNCRXCTL_VALID         0x00000001 /* Rx timestamp valid */
 #define E1000_TSYNCRXCTL_TYPE_MASK     0x0000000E /* Rx type mask */
 #define E1000_TSYNCRXCTL_TYPE_L2_V2    0x00
@@ -1020,9 +1025,7 @@
 /* NVM Addressing bits based on type 0=small, 1=large */
 #define E1000_EECD_ADDR_BITS   0x00000400
 #define E1000_EECD_TYPE                0x00002000 /* NVM Type (1-SPI, 
0-Microwire) */
-#ifndef E1000_NVM_GRANT_ATTEMPTS
 #define E1000_NVM_GRANT_ATTEMPTS       1000 /* NVM # attempts to gain grant */
-#endif
 #define E1000_EECD_AUTO_RD             0x00000200  /* NVM Auto Read done */
 #define E1000_EECD_SIZE_EX_MASK                0x00007800  /* NVM Size */
 #define E1000_EECD_SIZE_EX_SHIFT       11
@@ -1059,11 +1062,44 @@
 /* NVM Word Offsets */
 #define NVM_COMPAT                     0x0003
 #define NVM_ID_LED_SETTINGS            0x0004
+#define NVM_VERSION                    0x0005
 #define NVM_SERDES_AMPLITUDE           0x0006 /* SERDES output amplitude */
 #define NVM_PHY_CLASS_WORD             0x0007
 #define E1000_I210_NVM_FW_MODULE_PTR   0x0010
 #define E1000_I350_NVM_FW_MODULE_PTR   0x0051
 #define NVM_FUTURE_INIT_WORD1          0x0019
+#define NVM_ETRACK_WORD                        0x0042
+#define NVM_ETRACK_HIWORD              0x0043
+#define NVM_COMB_VER_OFF               0x0083
+#define NVM_COMB_VER_PTR               0x003d
+
+/* NVM version defines */
+#define NVM_MAJOR_MASK                 0xF000
+#define NVM_MINOR_MASK                 0x0FF0
+#define NVM_IMAGE_ID_MASK              0x000F
+#define NVM_COMB_VER_MASK              0x00FF
+#define NVM_MAJOR_SHIFT                        12
+#define NVM_MINOR_SHIFT                        4
+#define NVM_COMB_VER_SHFT              8
+#define NVM_VER_INVALID                        0xFFFF
+#define NVM_ETRACK_SHIFT               16
+#define NVM_ETRACK_VALID               0x8000
+#define NVM_NEW_DEC_MASK               0x0F00
+#define NVM_HEX_CONV                   16
+#define NVM_HEX_TENS                   10
+
+/* FW version defines */
+/* Offset of "Loader patch ptr" in Firmware Header */
+#define E1000_I350_NVM_FW_LOADER_PATCH_PTR_OFFSET      0x01
+/* Patch generation hour & minutes */
+#define E1000_I350_NVM_FW_VER_WORD1_OFFSET             0x04
+/* Patch generation month & day */
+#define E1000_I350_NVM_FW_VER_WORD2_OFFSET             0x05
+/* Patch generation year */
+#define E1000_I350_NVM_FW_VER_WORD3_OFFSET             0x06
+/* Patch major & minor numbers */
+#define E1000_I350_NVM_FW_VER_WORD4_OFFSET             0x07
+
 #define NVM_MAC_ADDR                   0x0000
 #define NVM_SUB_DEV_ID                 0x000B
 #define NVM_SUB_VEN_ID                 0x000C
@@ -1440,8 +1476,6 @@
 #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 */
 
 /* Proxy Filter Control */
 #define E1000_PROXYFC_D0               0x00000001 /* Enable offload in D0 */

Modified: head/sys/dev/e1000/e1000_hw.h
==============================================================================
--- head/sys/dev/e1000/e1000_hw.h       Sun Sep 13 17:17:52 2015        
(r287761)
+++ head/sys/dev/e1000/e1000_hw.h       Sun Sep 13 18:26:05 2015        
(r287762)
@@ -137,6 +137,10 @@ struct e1000_hw;
 #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_PCH_SPT_I219_LM           0x156F /* Sunrise Point PCH */
+#define E1000_DEV_ID_PCH_SPT_I219_V            0x1570 /* Sunrise Point PCH */
+#define E1000_DEV_ID_PCH_SPT_I219_LM2          0x15B7 /* Sunrise Point-H PCH */
+#define E1000_DEV_ID_PCH_SPT_I219_V2           0x15B8 /* Sunrise Point-H PCH */
 #define E1000_DEV_ID_82576                     0x10C9
 #define E1000_DEV_ID_82576_FIBER               0x10E6
 #define E1000_DEV_ID_82576_SERDES              0x10E7
@@ -222,6 +226,7 @@ enum e1000_mac_type {
        e1000_pchlan,
        e1000_pch2lan,
        e1000_pch_lpt,
+       e1000_pch_spt,
        e1000_82575,
        e1000_82576,
        e1000_82580,
@@ -703,7 +708,6 @@ struct e1000_mac_operations {
        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);
        s32  (*acquire_swfw_sync)(struct e1000_hw *, u16);
        void (*release_swfw_sync)(struct e1000_hw *, u16);
 };
@@ -805,7 +809,7 @@ struct e1000_mac_info {
        enum e1000_serdes_link_state serdes_link_state;
        bool serdes_has_link;
        bool tx_pkt_filtering;
-       u32 max_frame_size;
+       u32  max_frame_size;
 };
 
 struct e1000_phy_info {

Modified: head/sys/dev/e1000/e1000_i210.c
==============================================================================
--- head/sys/dev/e1000/e1000_i210.c     Sun Sep 13 17:17:52 2015        
(r287761)
+++ head/sys/dev/e1000/e1000_i210.c     Sun Sep 13 18:26:05 2015        
(r287762)
@@ -489,6 +489,105 @@ static s32 e1000_read_invm_i210(struct e
 }
 
 /**
+ *  e1000_read_invm_version - Reads iNVM version and image type
+ *  @hw: pointer to the HW structure
+ *  @invm_ver: version structure for the version read
+ *
+ *  Reads iNVM version and image type.
+ **/
+s32 e1000_read_invm_version(struct e1000_hw *hw,
+                           struct e1000_fw_version *invm_ver)
+{
+       u32 *record = NULL;
+       u32 *next_record = NULL;
+       u32 i = 0;
+       u32 invm_dword = 0;
+       u32 invm_blocks = E1000_INVM_SIZE - (E1000_INVM_ULT_BYTES_SIZE /
+                                            E1000_INVM_RECORD_SIZE_IN_BYTES);
+       u32 buffer[E1000_INVM_SIZE];
+       s32 status = -E1000_ERR_INVM_VALUE_NOT_FOUND;
+       u16 version = 0;
+
+       DEBUGFUNC("e1000_read_invm_version");
+
+       /* Read iNVM memory */
+       for (i = 0; i < E1000_INVM_SIZE; i++) {
+               invm_dword = E1000_READ_REG(hw, E1000_INVM_DATA_REG(i));
+               buffer[i] = invm_dword;
+       }
+
+       /* Read version number */
+       for (i = 1; i < invm_blocks; i++) {
+               record = &buffer[invm_blocks - i];
+               next_record = &buffer[invm_blocks - i + 1];
+
+               /* Check if we have first version location used */
+               if ((i == 1) && ((*record & E1000_INVM_VER_FIELD_ONE) == 0)) {
+                       version = 0;
+                       status = E1000_SUCCESS;
+                       break;
+               }
+               /* Check if we have second version location used */
+               else if ((i == 1) &&
+                        ((*record & E1000_INVM_VER_FIELD_TWO) == 0)) {
+                       version = (*record & E1000_INVM_VER_FIELD_ONE) >> 3;
+                       status = E1000_SUCCESS;
+                       break;
+               }
+               /*
+                * Check if we have odd version location
+                * used and it is the last one used
+                */
+               else if ((((*record & E1000_INVM_VER_FIELD_ONE) == 0) &&
+                        ((*record & 0x3) == 0)) || (((*record & 0x3) != 0) &&
+                        (i != 1))) {
+                       version = (*next_record & E1000_INVM_VER_FIELD_TWO)
+                                 >> 13;
+                       status = E1000_SUCCESS;
+                       break;
+               }
+               /*
+                * Check if we have even version location
+                * used and it is the last one used
+                */
+               else if (((*record & E1000_INVM_VER_FIELD_TWO) == 0) &&
+                        ((*record & 0x3) == 0)) {
+                       version = (*record & E1000_INVM_VER_FIELD_ONE) >> 3;
+                       status = E1000_SUCCESS;
+                       break;
+               }
+       }
+
+       if (status == E1000_SUCCESS) {
+               invm_ver->invm_major = (version & E1000_INVM_MAJOR_MASK)
+                                       >> E1000_INVM_MAJOR_SHIFT;
+               invm_ver->invm_minor = version & E1000_INVM_MINOR_MASK;
+       }
+       /* Read Image Type */
+       for (i = 1; i < invm_blocks; i++) {
+               record = &buffer[invm_blocks - i];
+               next_record = &buffer[invm_blocks - i + 1];
+
+               /* Check if we have image type in first location used */
+               if ((i == 1) && ((*record & E1000_INVM_IMGTYPE_FIELD) == 0)) {
+                       invm_ver->invm_img_type = 0;
+                       status = E1000_SUCCESS;
+                       break;
+               }
+               /* Check if we have image type in first location used */
+               else if ((((*record & 0x3) == 0) &&
+                        ((*record & E1000_INVM_IMGTYPE_FIELD) == 0)) ||
+                        ((((*record & 0x3) != 0) && (i != 1)))) {
+                       invm_ver->invm_img_type =
+                               (*next_record & E1000_INVM_IMGTYPE_FIELD) >> 23;
+                       status = E1000_SUCCESS;
+                       break;
+               }
+       }
+       return status;
+}
+
+/**
  *  e1000_validate_nvm_checksum_i210 - Validate EEPROM checksum
  *  @hw: pointer to the HW structure
  *

Modified: head/sys/dev/e1000/e1000_i210.h
==============================================================================
--- head/sys/dev/e1000/e1000_i210.h     Sun Sep 13 17:17:52 2015        
(r287761)
+++ head/sys/dev/e1000/e1000_i210.h     Sun Sep 13 18:26:05 2015        
(r287762)
@@ -43,6 +43,8 @@ s32 e1000_write_nvm_srwr_i210(struct e10
                              u16 words, u16 *data);
 s32 e1000_read_nvm_srrd_i210(struct e1000_hw *hw, u16 offset,
                             u16 words, u16 *data);
+s32 e1000_read_invm_version(struct e1000_hw *hw,
+                           struct e1000_fw_version *invm_ver);
 s32 e1000_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask);
 void e1000_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask);
 s32 e1000_read_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr,

Modified: head/sys/dev/e1000/e1000_ich8lan.c
==============================================================================
--- head/sys/dev/e1000/e1000_ich8lan.c  Sun Sep 13 17:17:52 2015        
(r287761)
+++ head/sys/dev/e1000/e1000_ich8lan.c  Sun Sep 13 18:26:05 2015        
(r287762)
@@ -92,10 +92,13 @@ static s32  e1000_set_d3_lplu_state_ich8
                                            bool active);
 static s32  e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset,
                                   u16 words, u16 *data);
+static s32  e1000_read_nvm_spt(struct e1000_hw *hw, u16 offset, u16 words,
+                              u16 *data);
 static s32  e1000_write_nvm_ich8lan(struct e1000_hw *hw, u16 offset,
                                    u16 words, u16 *data);
 static s32  e1000_validate_nvm_checksum_ich8lan(struct e1000_hw *hw);
 static s32  e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw);
+static s32  e1000_update_nvm_checksum_spt(struct e1000_hw *hw);
 static s32  e1000_valid_led_default_ich8lan(struct e1000_hw *hw,
                                            u16 *data);
 static s32 e1000_id_led_init_pchlan(struct e1000_hw *hw);
@@ -123,6 +126,14 @@ static s32  e1000_read_flash_byte_ich8la
                                          u32 offset, u8 *data);
 static s32  e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset,
                                          u8 size, u16 *data);
+static s32  e1000_read_flash_data32_ich8lan(struct e1000_hw *hw, u32 offset,
+                                           u32 *data);
+static s32  e1000_read_flash_dword_ich8lan(struct e1000_hw *hw,
+                                          u32 offset, u32 *data);
+static s32  e1000_write_flash_data32_ich8lan(struct e1000_hw *hw,
+                                            u32 offset, u32 data);
+static s32  e1000_retry_write_flash_dword_ich8lan(struct e1000_hw *hw,
+                                                 u32 offset, u32 dword);
 static s32  e1000_read_flash_word_ich8lan(struct e1000_hw *hw,
                                          u32 offset, u16 *data);
 static s32  e1000_retry_write_flash_byte_ich8lan(struct e1000_hw *hw,
@@ -133,7 +144,6 @@ static s32 e1000_check_for_copper_link_i
 static s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw);
 static s32 e1000_k1_workaround_lv(struct e1000_hw *hw);
 static void e1000_gate_hw_phy_config_ich8lan(struct e1000_hw *hw, bool gate);
-static s32 e1000_set_obff_timer_pch_lpt(struct e1000_hw *hw, u32 itr);
 
 /* ICH GbE Flash Hardware Sequencing Flash Status Register bit breakdown */
 /* Offset 04h HSFSTS */
@@ -232,16 +242,21 @@ static bool e1000_phy_is_accessible_pchl
        if (ret_val)
                return FALSE;
 out:
-       if (hw->mac.type == e1000_pch_lpt) {
-               /* Unforce SMBus mode in PHY */
-               hw->phy.ops.read_reg_locked(hw, CV_SMB_CTRL, &phy_reg);
-               phy_reg &= ~CV_SMB_CTRL_FORCE_SMBUS;
-               hw->phy.ops.write_reg_locked(hw, CV_SMB_CTRL, phy_reg);
+       if ((hw->mac.type == e1000_pch_lpt) ||
+           (hw->mac.type == e1000_pch_spt)) {
+               /* Only unforce SMBus if ME is not active */
+               if (!(E1000_READ_REG(hw, E1000_FWSM) &
+                   E1000_ICH_FWSM_FW_VALID)) {
+                       /* Unforce SMBus mode in PHY */
+                       hw->phy.ops.read_reg_locked(hw, CV_SMB_CTRL, &phy_reg);
+                       phy_reg &= ~CV_SMB_CTRL_FORCE_SMBUS;
+                       hw->phy.ops.write_reg_locked(hw, CV_SMB_CTRL, phy_reg);
 
-               /* Unforce 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);
+                       /* Unforce 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);
+               }
        }
 
        return TRUE;
@@ -328,6 +343,7 @@ static s32 e1000_init_phy_workarounds_pc
         */
        switch (hw->mac.type) {
        case e1000_pch_lpt:
+       case e1000_pch_spt:
                if (e1000_phy_is_accessible_pchlan(hw))
                        break;
 
@@ -475,6 +491,7 @@ static s32 e1000_init_phy_params_pchlan(
                        /* fall-through */
                case e1000_pch2lan:
                case e1000_pch_lpt:
+               case e1000_pch_spt:
                        /* In case the PHY needs to be in mdio slow mode,
                         * set slow mode and try to get the PHY id again.
                         */
@@ -617,36 +634,53 @@ static s32 e1000_init_nvm_params_ich8lan
        struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan;
        u32 gfpreg, sector_base_addr, sector_end_addr;
        u16 i;
+       u32 nvm_size;
 
        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;
-       }
+       /* in SPT, gfpreg doesn't exist. NVM size is taken from the
+        * STRAP register
+        */
+       if (hw->mac.type == e1000_pch_spt) {
+               nvm->flash_base_addr = 0;
+               nvm_size =
+                   (((E1000_READ_REG(hw, E1000_STRAP) >> 1) & 0x1F) + 1)
+                   * NVM_SIZE_MULTIPLIER;
+               nvm->flash_bank_size = nvm_size / 2;
+               /* Adjust to word count */
+               nvm->flash_bank_size /= sizeof(u16);
+               /* Set the base address for flash register access */
+               hw->flash_address = hw->hw_addr + E1000_FLASH_BASE_ADDR;
+       } else {
+               if (!hw->flash_address) {
+                       DEBUGOUT("ERROR: Flash registers not mapped\n");
+                       return -E1000_ERR_CONFIG;
+               }
+
+               gfpreg = E1000_READ_FLASH_REG(hw, ICH_FLASH_GFPREG);
+
+               /* sector_X_addr is a "sector"-aligned address (4096 bytes)
+                * Add 1 to sector_end_addr since this sector is included in
+                * the overall size.
+                */
+               sector_base_addr = gfpreg & FLASH_GFPREG_BASE_MASK;
+               sector_end_addr = ((gfpreg >> 16) & FLASH_GFPREG_BASE_MASK) + 1;
 
-       gfpreg = E1000_READ_FLASH_REG(hw, ICH_FLASH_GFPREG);
+               /* flash_base_addr is byte-aligned */
+               nvm->flash_base_addr = sector_base_addr
+                                      << FLASH_SECTOR_ADDR_SHIFT;
 
-       /* sector_X_addr is a "sector"-aligned address (4096 bytes)
-        * Add 1 to sector_end_addr since this sector is included in
-        * the overall size.
-        */
-       sector_base_addr = gfpreg & FLASH_GFPREG_BASE_MASK;
-       sector_end_addr = ((gfpreg >> 16) & FLASH_GFPREG_BASE_MASK) + 1;
-
-       /* flash_base_addr is byte-aligned */
-       nvm->flash_base_addr = sector_base_addr << FLASH_SECTOR_ADDR_SHIFT;
-
-       /* find total size of the NVM, then cut in half since the total
-        * size represents two separate NVM banks.
-        */
-       nvm->flash_bank_size = ((sector_end_addr - sector_base_addr)
-                               << FLASH_SECTOR_ADDR_SHIFT);
-       nvm->flash_bank_size /= 2;
-       /* Adjust to word count */
-       nvm->flash_bank_size /= sizeof(u16);
+               /* find total size of the NVM, then cut in half since the total
+                * size represents two separate NVM banks.
+                */
+               nvm->flash_bank_size = ((sector_end_addr - sector_base_addr)
+                                       << FLASH_SECTOR_ADDR_SHIFT);
+               nvm->flash_bank_size /= 2;
+               /* Adjust to word count */
+               nvm->flash_bank_size /= sizeof(u16);
+       }
 
        nvm->word_size = E1000_SHADOW_RAM_WORDS;
 
@@ -662,8 +696,13 @@ static s32 e1000_init_nvm_params_ich8lan
        /* Function Pointers */
        nvm->ops.acquire        = e1000_acquire_nvm_ich8lan;
        nvm->ops.release        = e1000_release_nvm_ich8lan;
-       nvm->ops.read           = e1000_read_nvm_ich8lan;
-       nvm->ops.update         = e1000_update_nvm_checksum_ich8lan;
+       if (hw->mac.type == e1000_pch_spt) {
+               nvm->ops.read   = e1000_read_nvm_spt;
+               nvm->ops.update = e1000_update_nvm_checksum_spt;
+       } else {
+               nvm->ops.read   = e1000_read_nvm_ich8lan;
+               nvm->ops.update = e1000_update_nvm_checksum_ich8lan;
+       }
        nvm->ops.valid_led_default = e1000_valid_led_default_ich8lan;
        nvm->ops.validate       = e1000_validate_nvm_checksum_ich8lan;
        nvm->ops.write          = e1000_write_nvm_ich8lan;
@@ -681,9 +720,7 @@ 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");
 
@@ -752,15 +789,21 @@ static s32 e1000_init_mac_params_ich8lan
                mac->ops.rar_set = e1000_rar_set_pch2lan;
                /* fall-through */
        case e1000_pch_lpt:
+       case e1000_pch_spt:
                /* multicast address update for pch2 */
                mac->ops.update_mc_addr_list =
                        e1000_update_mc_addr_list_pch2lan;
+               /* fall-through */
        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) */
+               /* SPT uses full byte for revision ID,
+                * as opposed to previous generations
+                */
+               if (hw->mac.type >= e1000_pch_spt)
+                       hw->revision_id = (u8)(pci_cfg &= 0x00FF);
+               else
+                       hw->revision_id = (u8)(pci_cfg &= 0x000F);
                /* check management mode */
                mac->ops.check_mng_mode = e1000_check_mng_mode_pchlan;
                /* ID LED init */
@@ -777,11 +820,11 @@ static s32 e1000_init_mac_params_ich8lan
                break;
        }
 
-       if (mac->type == e1000_pch_lpt) {
+       if ((mac->type == e1000_pch_lpt) ||
+           (mac->type == e1000_pch_spt)) {
                mac->rar_entry_count = E1000_PCH_LPT_RAR_ENTRIES;
                mac->ops.rar_set = e1000_rar_set_pch_lpt;
                mac->ops.setup_physical_interface = 
e1000_setup_copper_link_pch_lpt;
-               mac->ops.set_obff_timer = e1000_set_obff_timer_pch_lpt;
        }
 
        /* Enable PCS Lock-loss workaround for ICH8 */
@@ -1007,8 +1050,9 @@ release:
                /* clear FEXTNVM6 bit 8 on link down or 10/100 */
                fextnvm6 &= ~E1000_FEXTNVM6_REQ_PLL_CLK;
 
-               if (!link || ((status & E1000_STATUS_SPEED_100) &&
-                             (status & E1000_STATUS_FD)))
+               if ((hw->phy.revision > 5) || !link ||
+                   ((status & E1000_STATUS_SPEED_100) &&
+                    (status & E1000_STATUS_FD)))
                        goto update_fextnvm6;
 
                ret_val = hw->phy.ops.read_reg(hw, I217_INBAND_CTRL, &reg);
@@ -1044,168 +1088,6 @@ update_fextnvm6:
        return ret_val;
 }
 
-static u64 e1000_ltr2ns(u16 ltr)
-{
-       u32 value, scale;
-
-       /* Determine the latency in nsec based on the LTR value & scale */
-       value = ltr & E1000_LTRV_VALUE_MASK;
-       scale = (ltr & E1000_LTRV_SCALE_MASK) >> E1000_LTRV_SCALE_SHIFT;
-
-       return value * (1 << (scale * E1000_LTRV_SCALE_FACTOR));
-}
-
-/**
- *  e1000_platform_pm_pch_lpt - Set platform power management values
- *  @hw: pointer to the HW structure
- *  @link: bool indicating link status
- *
- *  Set the Latency Tolerance Reporting (LTR) values for the "PCIe-like"
- *  GbE MAC in the Lynx Point PCH based on Rx buffer size and link speed
- *  when link is up (which must not exceed the maximum latency supported
- *  by the platform), otherwise specify there is no LTR requirement.
- *  Unlike TRUE-PCIe devices which set the LTR maximum snoop/no-snoop
- *  latencies in the LTR Extended Capability Structure in the PCIe Extended
- *  Capability register set, on this device LTR is set by writing the
- *  equivalent snoop/no-snoop latencies in the LTRV register in the MAC and
- *  set the SEND bit to send an Intel On-chip System Fabric sideband (IOSF-SB)
- *  message to the PMC.
- *
- *  Use the LTR value to calculate the Optimized Buffer Flush/Fill (OBFF)
- *  high-water mark.
- **/
-static s32 e1000_platform_pm_pch_lpt(struct e1000_hw *hw, bool link)
-{
-       u32 reg = link << (E1000_LTRV_REQ_SHIFT + E1000_LTRV_NOSNOOP_SHIFT) |
-                 link << E1000_LTRV_REQ_SHIFT | E1000_LTRV_SEND;
-       u16 lat_enc = 0;        /* latency encoded */
-       s32 obff_hwm = 0;
-
-       DEBUGFUNC("e1000_platform_pm_pch_lpt");
-
-       if (link) {
-               u16 speed, duplex, scale = 0;
-               u16 max_snoop, max_nosnoop;
-               u16 max_ltr_enc;        /* max LTR latency encoded */
-               s64 lat_ns;
-               s64 value;
-               u32 rxa;
-
-               if (!hw->mac.max_frame_size) {
-                       DEBUGOUT("max_frame_size not set.\n");
-                       return -E1000_ERR_CONFIG;
-               }
-
-               hw->mac.ops.get_link_up_info(hw, &speed, &duplex);
-               if (!speed) {
-                       DEBUGOUT("Speed not set.\n");
-                       return -E1000_ERR_CONFIG;
-               }
-
-               /* Rx Packet Buffer Allocation size (KB) */
-               rxa = E1000_READ_REG(hw, E1000_PBA) & E1000_PBA_RXA_MASK;
-
-               /* Determine the maximum latency tolerated by the device.
-                *
-                * Per the PCIe spec, the tolerated latencies are encoded as
-                * a 3-bit encoded scale (only 0-5 are valid) multiplied by
-                * a 10-bit value (0-1023) to provide a range from 1 ns to
-                * 2^25*(2^10-1) ns.  The scale is encoded as 0=2^0ns,
-                * 1=2^5ns, 2=2^10ns,...5=2^25ns.
-                */
-               lat_ns = ((s64)rxa * 1024 -
-                         (2 * (s64)hw->mac.max_frame_size)) * 8 * 1000;
-               if (lat_ns < 0)
-                       lat_ns = 0;
-               else
-                       lat_ns /= speed;
-               value = lat_ns;
-
-               while (value > E1000_LTRV_VALUE_MASK) {
-                       scale++;

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to