ig_hal/igb: Merge Intel igb-2.4.3
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Sat, 19 Dec 2015 01:50:30 +0000 (09:50 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Mon, 21 Dec 2015 12:27:31 +0000 (20:27 +0800)
- Add one more device
- Fix settings for i354

Tested-by: dillon@ (I354, I217[emx]) me (I350, 82580, 82576, 82575)
21 files changed:
share/man/man4/igb.4
sys/dev/netif/ig_hal/e1000_82575.c
sys/dev/netif/ig_hal/e1000_82575.h
sys/dev/netif/ig_hal/e1000_api.c
sys/dev/netif/ig_hal/e1000_api.h
sys/dev/netif/ig_hal/e1000_defines.h
sys/dev/netif/ig_hal/e1000_hw.h
sys/dev/netif/ig_hal/e1000_i210.c
sys/dev/netif/ig_hal/e1000_i210.h
sys/dev/netif/ig_hal/e1000_mac.c
sys/dev/netif/ig_hal/e1000_mac.h
sys/dev/netif/ig_hal/e1000_mbx.c
sys/dev/netif/ig_hal/e1000_mbx.h
sys/dev/netif/ig_hal/e1000_nvm.c
sys/dev/netif/ig_hal/e1000_phy.c
sys/dev/netif/ig_hal/e1000_phy.h
sys/dev/netif/ig_hal/e1000_regs.h
sys/dev/netif/ig_hal/e1000_vf.c
sys/dev/netif/ig_hal/e1000_vf.h
sys/dev/netif/igb/if_igb.c
sys/dev/netif/igb/if_igb.h

index 252d5de..d8f4824 100644 (file)
@@ -31,7 +31,7 @@
 .\"
 .\" $FreeBSD: src/share/man/man4/igb.4,v 1.2 2010/05/14 20:11:30 marius Exp $
 .\"
-.Dd November 26, 2015
+.Dd December 19, 2015
 .Dt IGB 4
 .Os
 .Sh NAME
@@ -235,43 +235,55 @@ controller chips:
 .Pp
 .Bl -bullet -compact
 .It
-Intel 82575EB Gigabit Ethernet Controller
+Intel 82576EB Gigabit Ethernet Controller
 .It
-Intel 82576 Gigabit Ethernet Controller
+Intel 82576NS Gigabit Ethernet Controller
 .It
 Intel 82580EB Gigabit Ethernet Controller
 .It
-Intel Ethernet Controller I210 Series
+Intel Ethernet Server Adapter I340-F4
 .It
-Intel Ethernet Controller I211 Series
+Intel Ethernet Server Adapter I340-T4
 .It
-Intel Ethernet Controller I350
+Intel Gigabit ET2 Quad Port Server Adapter
 .It
-Intel Ethernet Controller I354
+Intel Gigabit VT Quad Port Server Adapter
 .It
-Intel Ethernet Server Adapter I210-T1
+Intel 82575EB Gigabit Ethernet Controller
 .It
-Intel Ethernet Server Adapter I340-F4
+Intel Gigabit EF Dual Port Server Adapter
 .It
-Intel Ethernet Server Adapter I340-T4
+Intel Gigabit ET Dual Port Server Adapter
 .It
-Intel Ethernet Server Adapter I350-F2
+Intel Gigabit ET Quad Port Server Adapter
 .It
-Intel Ethernet Server Adapter I350-F4
+Intel Ethernet Controller I350-AM4
+.It
+Intel Ethernet Controller I350-BT2
+.It
+Intel Ethernet Controller I350-AM2
 .It
 Intel Ethernet Server Adapter I350-T2
 .It
 Intel Ethernet Server Adapter I350-T4
 .It
-Intel Gigabit EF Dual Port Server Adapter
+Intel Ethernet Server Adapter I350-F2
 .It
-Intel Gigabit ET Dual Port Server Adapter
+Intel Ethernet Server Adapter I350-F4
 .It
-Intel Gigabit ET Quad Port Server Adapter
+Intel Ethernet Controller I210-AT
 .It
-Intel Gigabit ET2 Quad Port Server Adapter
+Intel Ethernet Controller I210-IS
 .It
-Intel Gigabit VT Quad Port Server Adapter
+Intel Ethernet Controller I210-IT
+.It
+Intel Ethernet Controller I211-AT
+.It
+Intel Ethernet Server Adapter I210-T1
+.It
+Intel Ethernet Controller I210-AS
+.It
+Intel Ethernet Controller I210-CS
 .El
 .Sh TUNABLES
 Tunables can be set at the
index 2cb2bdd..c047384 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
 
-  Copyright (c) 2001-2011, Intel Corporation 
+  Copyright (c) 2001-2013, 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_swap(struct e1000_hw *hw);
 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 *i2cctl);
 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]))
 
 
 /**
@@ -229,7 +229,8 @@ static s32 e1000_init_phy_params_82575(struct e1000_hw *hw)
 
        /* Verify phy id and set remaining function pointers */
        switch (phy->id) {
-       case M88E1545_E_PHY_ID:
+       case M88E1543_E_PHY_ID:
+       case M88E1512_E_PHY_ID:
        case I347AT4_E_PHY_ID:
        case M88E1112_E_PHY_ID:
        case M88E1340M_E_PHY_ID:
@@ -242,7 +243,8 @@ static s32 e1000_init_phy_params_82575(struct e1000_hw *hw)
                    phy->id == M88E1340M_E_PHY_ID)
                        phy->ops.get_cable_length =
                                         e1000_get_cable_length_m88_gen2;
-               else if (phy->id == M88E1545_E_PHY_ID)
+               else if (phy->id == M88E1543_E_PHY_ID ||
+                        phy->id == M88E1512_E_PHY_ID)
                        phy->ops.get_cable_length =
                                         e1000_get_cable_length_m88_gen2;
                else
@@ -264,11 +266,18 @@ static s32 e1000_init_phy_params_82575(struct e1000_hw *hw)
                        if (ret_val)
                                goto out;
 
-                       if (data == E1000_M88E1112_AUTO_A ||
-                           data == E1000_M88E1112_AUTO_B)
+                       data = (data & E1000_M88E1112_MAC_CTRL_1_MODE_MASK) >>
+                              E1000_M88E1112_MAC_CTRL_1_MODE_SHIFT;
+                       if (data == E1000_M88E1112_AUTO_COPPER_SGMII ||
+                           data == E1000_M88E1112_AUTO_COPPER_BASEX)
                                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:
@@ -446,6 +455,9 @@ static s32 e1000_init_mac_params_82575(struct e1000_hw *hw)
        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;
@@ -651,6 +663,10 @@ static s32 e1000_get_phy_id_82575(struct e1000_hw *hw)
 
        DEBUGFUNC("e1000_get_phy_id_82575");
 
+       /* some i354 devices need an extra read for phy id */
+       if (hw->mac.type == e1000_i354)
+               e1000_get_phy_id(hw);
+
        /*
         * For SGMII PHYs, we try the list of possible addresses until
         * we find one that works.  For non-SGMII PHYs
@@ -742,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");
 
@@ -764,7 +781,11 @@ static s32 e1000_phy_hw_reset_sgmii_82575(struct e1000_hw *hw)
                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;
 }
@@ -871,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");
@@ -899,7 +919,7 @@ static s32 e1000_set_d0_lplu_state_82580(struct e1000_hw *hw, bool active)
        }
 
        E1000_WRITE_REG(hw, E1000_82580_PHY_POWER_MGMT, data);
-       return ret_val;
+       return E1000_SUCCESS;
 }
 
 /**
@@ -919,7 +939,6 @@ static s32 e1000_set_d0_lplu_state_82580(struct e1000_hw *hw, bool active)
 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");
@@ -947,7 +966,7 @@ s32 e1000_set_d3_lplu_state_82580(struct e1000_hw *hw, bool active)
        }
 
        E1000_WRITE_REG(hw, E1000_82580_PHY_POWER_MGMT, data);
-       return ret_val;
+       return E1000_SUCCESS;
 }
 
 /**
@@ -961,7 +980,7 @@ s32 e1000_set_d3_lplu_state_82580(struct e1000_hw *hw, bool active)
  **/
 static s32 e1000_acquire_nvm_82575(struct e1000_hw *hw)
 {
-       s32 ret_val;
+       s32 ret_val = E1000_SUCCESS;
 
        DEBUGFUNC("e1000_acquire_nvm_82575");
 
@@ -983,6 +1002,7 @@ static s32 e1000_acquire_nvm_82575(struct e1000_hw *hw)
                        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) {
@@ -993,7 +1013,6 @@ static s32 e1000_acquire_nvm_82575(struct e1000_hw *hw)
                }
        }
 
-
        ret_val = e1000_acquire_nvm_generic(hw);
        if (ret_val)
                e1000_release_swfw_sync_82575(hw, E1000_SWFW_EEP_SM);
@@ -1032,7 +1051,7 @@ static s32 e1000_acquire_swfw_sync_82575(struct e1000_hw *hw, u16 mask)
        u32 swmask = mask;
        u32 fwmask = mask << 16;
        s32 ret_val = E1000_SUCCESS;
-       s32 i = 0, timeout = 200; /* FIXME: find real value to use here */
+       s32 i = 0, timeout = 200;
 
        DEBUGFUNC("e1000_acquire_swfw_sync_82575");
 
@@ -1107,7 +1126,6 @@ static void e1000_release_swfw_sync_82575(struct e1000_hw *hw, u16 mask)
 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");
@@ -1132,7 +1150,7 @@ static s32 e1000_get_cfg_done_82575(struct e1000_hw *hw)
            (hw->phy.type == e1000_phy_igp_3))
                e1000_phy_init_script_igp3(hw);
 
-       return ret_val;
+       return E1000_SUCCESS;
 }
 
 /**
@@ -1217,7 +1235,7 @@ static s32 e1000_check_for_link_media_swap(struct e1000_hw *hw)
 
        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;
@@ -1229,7 +1247,7 @@ static s32 e1000_check_for_link_media_swap(struct e1000_hw *hw)
        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;
@@ -1245,8 +1263,20 @@ static s32 e1000_check_for_link_media_swap(struct e1000_hw *hw)
        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;
@@ -1295,6 +1325,7 @@ static s32 e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw,
 {
        struct e1000_mac_info *mac = &hw->mac;
        u32 pcs;
+       u32 status;
 
        DEBUGFUNC("e1000_get_pcs_speed_and_duplex_82575");
 
@@ -1325,6 +1356,18 @@ static s32 e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw,
                else
                        *duplex = HALF_DUPLEX;
 
+               /* Check if it is an I354 2.5Gb backplane connection. */
+               if (mac->type == e1000_i354) {
+                       status = E1000_READ_REG(hw, E1000_STATUS);
+                       if ((status & E1000_STATUS_2P5_SKU) &&
+                           !(status & E1000_STATUS_2P5_SKU_OVER)) {
+                               *speed = SPEED_2500;
+                               *duplex = FULL_DUPLEX;
+                               DEBUGOUT("2500 Mbs, ");
+                               DEBUGOUT("Full Duplex\n");
+                       }
+               }
+
        } else {
                mac->serdes_has_link = FALSE;
                *speed = 0;
@@ -1440,7 +1483,7 @@ static s32 e1000_reset_hw_82575(struct e1000_hw *hw)
  *
  *  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;
@@ -1510,11 +1553,18 @@ static s32 e1000_setup_copper_link_82575(struct e1000_hw *hw)
        ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
        E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
 
-       /* Clear Go Link Disconnect bit */
-       if (hw->mac.type >= e1000_82580) {
+       /* Clear Go Link Disconnect bit on supported devices */
+       switch (hw->mac.type) {
+       case e1000_82580:
+       case e1000_i350:
+       case e1000_i210:
+       case e1000_i211:
                phpm_reg = E1000_READ_REG(hw, E1000_82580_PHY_POWER_MGMT);
                phpm_reg &= ~E1000_82580_PM_GO_LINKD;
                E1000_WRITE_REG(hw, E1000_82580_PHY_POWER_MGMT, phpm_reg);
+               break;
+       default:
+               break;
        }
 
        ret_val = e1000_setup_serdes_link_82575(hw);
@@ -1538,7 +1588,8 @@ static s32 e1000_setup_copper_link_82575(struct e1000_hw *hw)
                case I347AT4_E_PHY_ID:
                case M88E1112_E_PHY_ID:
                case M88E1340M_E_PHY_ID:
-               case M88E1545_E_PHY_ID:
+               case M88E1543_E_PHY_ID:
+               case M88E1512_E_PHY_ID:
                case I210_I_PHY_ID:
                        ret_val = e1000_copper_link_setup_m88_gen2(hw);
                        break;
@@ -1951,7 +2002,7 @@ static s32 e1000_reset_init_script_82575(struct e1000_hw *hw)
  **/
 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");
 
@@ -2082,7 +2133,7 @@ static void e1000_clear_hw_cntrs_82575(struct e1000_hw *hw)
  *  e1000_rx_fifo_flush_82575 - Clean rx fifo after Rx enable
  *  @hw: pointer to the HW structure
  *
- *  After rx enable if managability is enabled then there is likely some
+ *  After Rx enable, if manageability is enabled then there is likely some
  *  bad data at the start of the fifo and possibly in the DMA fifo.  This
  *  function clears the fifos and flushes any packets that came in as rx was
  *  being enabled.
@@ -2092,7 +2143,13 @@ void e1000_rx_fifo_flush_82575(struct e1000_hw *hw)
        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;
@@ -2120,7 +2177,6 @@ void e1000_rx_fifo_flush_82575(struct e1000_hw *hw)
         * 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);
@@ -2213,43 +2269,33 @@ out:
  **/
 void e1000_vmdq_set_anti_spoofing_pf(struct e1000_hw *hw, bool enable, int pf)
 {
-       u32 dtxswc;
+       u32 reg_val, reg_offset;
 
        switch (hw->mac.type) {
        case e1000_82576:
-               dtxswc = E1000_READ_REG(hw, E1000_DTXSWC);
-               if (enable) {
-                       dtxswc |= (E1000_DTXSWC_MAC_SPOOF_MASK |
-                                  E1000_DTXSWC_VLAN_SPOOF_MASK);
-                       /* The PF can spoof - it has to in order to
-                        * support emulation mode NICs */
-                       dtxswc ^= (1 << pf | 1 << (pf +
-                                  E1000_DTXSWC_VLAN_SPOOF_SHIFT));
-               } else {
-                       dtxswc &= ~(E1000_DTXSWC_MAC_SPOOF_MASK |
-                                   E1000_DTXSWC_VLAN_SPOOF_MASK);
-               }
-               E1000_WRITE_REG(hw, E1000_DTXSWC, dtxswc);
+               reg_offset = E1000_DTXSWC;
                break;
        case e1000_i350:
        case e1000_i354:
-               dtxswc = E1000_READ_REG(hw, E1000_TXSWC);
-               if (enable) {
-                       dtxswc |= (E1000_DTXSWC_MAC_SPOOF_MASK |
-                                  E1000_DTXSWC_VLAN_SPOOF_MASK);
-                       /* The PF can spoof - it has to in order to
-                        * support emulation mode NICs
-                        */
-                       dtxswc ^= (1 << pf | 1 << (pf +
-                                  E1000_DTXSWC_VLAN_SPOOF_SHIFT));
-               } else {
-                       dtxswc &= ~(E1000_DTXSWC_MAC_SPOOF_MASK |
-                                   E1000_DTXSWC_VLAN_SPOOF_MASK);
-               }
-               E1000_WRITE_REG(hw, E1000_TXSWC, dtxswc);
-       default:
+               reg_offset = E1000_TXSWC;
                break;
+       default:
+               return;
        }
+
+       reg_val = E1000_READ_REG(hw, reg_offset);
+       if (enable) {
+               reg_val |= (E1000_DTXSWC_MAC_SPOOF_MASK |
+                            E1000_DTXSWC_VLAN_SPOOF_MASK);
+               /* The PF can spoof - it has to in order to
+                * support emulation mode NICs
+                */
+               reg_val ^= (1 << pf | 1 << (pf + MAX_NUM_VFS));
+       } else {
+               reg_val &= ~(E1000_DTXSWC_MAC_SPOOF_MASK |
+                            E1000_DTXSWC_VLAN_SPOOF_MASK);
+       }
+       E1000_WRITE_REG(hw, reg_offset, reg_val);
 }
 
 /**
@@ -2454,11 +2500,17 @@ static s32 e1000_reset_hw_82580(struct e1000_hw *hw)
                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) {
@@ -2470,10 +2522,6 @@ static s32 e1000_reset_hw_82580(struct e1000_hw *hw)
                DEBUGOUT("Auto Read Done did not complete\n");
        }
 
-       /* If EEPROM is not present, run manual init scripts */
-       if (!(E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES))
-               e1000_reset_init_script_82575(hw);
-
        /* clear global device reset status bit */
        E1000_WRITE_REG(hw, E1000_STATUS, E1000_STAT_DEV_RST_SET);
 
@@ -2597,7 +2645,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;
@@ -2737,7 +2785,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");
 
@@ -2766,16 +2814,106 @@ s32 e1000_read_emi_reg(struct e1000_hw *hw, u16 addr, u16 *data)
        return __e1000_access_emi_reg(hw, addr, data, TRUE);
 }
 
+/**
+ *  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
+ *  @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)
 {
-       s32 ret_val = E1000_SUCCESS;
        u32 ipcnfg, eeer;
 
        DEBUGFUNC("e1000_set_eee_i350");
@@ -2790,7 +2928,16 @@ s32 e1000_set_eee_i350(struct e1000_hw *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);
 
@@ -2808,17 +2955,19 @@ s32 e1000_set_eee_i350(struct e1000_hw *hw)
        E1000_READ_REG(hw, E1000_EEER);
 out:
 
-       return ret_val;
+       return E1000_SUCCESS;
 }
 
 /**
  *  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;
@@ -2827,28 +2976,29 @@ s32 e1000_set_eee_i354(struct e1000_hw *hw)
        DEBUGFUNC("e1000_set_eee_i354");
 
        if ((hw->phy.media_type != e1000_media_type_copper) ||
-           (phy->id != M88E1545_E_PHY_ID))
+           ((phy->id != M88E1543_E_PHY_ID) &&
+           (phy->id != M88E1512_E_PHY_ID)))
                goto out;
 
        if (!hw->dev_spec._82575.eee_disable) {
                /* Switch to PHY page 18. */
-               ret_val = phy->ops.write_reg(hw, E1000_M88E1545_PAGE_ADDR, 18);
+               ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 18);
                if (ret_val)
                        goto out;
 
-               ret_val = phy->ops.read_reg(hw, E1000_M88E1545_EEE_CTRL_1,
+               ret_val = phy->ops.read_reg(hw, E1000_M88E1543_EEE_CTRL_1,
                                            &phy_data);
                if (ret_val)
                        goto out;
 
-               phy_data |= E1000_M88E1545_EEE_CTRL_1_MS;
-               ret_val = phy->ops.write_reg(hw, E1000_M88E1545_EEE_CTRL_1,
+               phy_data |= E1000_M88E1543_EEE_CTRL_1_MS;
+               ret_val = phy->ops.write_reg(hw, E1000_M88E1543_EEE_CTRL_1,
                                             phy_data);
                if (ret_val)
                        goto out;
 
                /* Return the PHY to page 0. */
-               ret_val = phy->ops.write_reg(hw, E1000_M88E1545_PAGE_ADDR, 0);
+               ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0);
                if (ret_val)
                        goto out;
 
@@ -2859,8 +3009,16 @@ s32 e1000_set_eee_i354(struct e1000_hw *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);
@@ -2901,7 +3059,8 @@ s32 e1000_get_eee_status_i354(struct e1000_hw *hw, bool *status)
 
        /* Check if EEE is supported on this device. */
        if ((hw->phy.media_type != e1000_media_type_copper) ||
-           (phy->id != M88E1545_E_PHY_ID))
+           ((phy->id != M88E1543_E_PHY_ID) &&
+           (phy->id != M88E1512_E_PHY_ID)))
                goto out;
 
        ret_val = e1000_read_xmdio_reg(hw, E1000_PCS_STATUS_ADDR_I354,
index ffef28c..00ad915 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
 
-  Copyright (c) 2001-2011, Intel Corporation 
+  Copyright (c) 2001-2013, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -245,6 +245,8 @@ union e1000_adv_rx_desc {
 #define E1000_RXDADV_RSSTYPE_IPV6_UDP_EX 0x00000009
 
 /* RSS Packet Types as indicated in the receive descriptor */
+#define E1000_RXDADV_PKTTYPE_ILMASK    0x000000F0
+#define E1000_RXDADV_PKTTYPE_TLMASK    0x00000F00
 #define E1000_RXDADV_PKTTYPE_NONE      0x00000000
 #define E1000_RXDADV_PKTTYPE_IPV4      0x00000010 /* IPV4 hdr present */
 #define E1000_RXDADV_PKTTYPE_IPV4_EX   0x00000020 /* IPV4 hdr + extensions */
@@ -478,6 +480,7 @@ void e1000_vmdq_set_loopback_pf(struct e1000_hw *hw, bool enable);
 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 */
@@ -492,9 +495,10 @@ void e1000_rlpml_set_vf(struct e1000_hw *, u16);
 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);
 
 /* I2C SDA and SCL timing parameters for standard mode */
 #define E1000_I2C_T_HD_STA     4
index f5d1e73..2bac61a 100644 (file)
@@ -360,6 +360,7 @@ s32 e1000_set_mac_type(struct e1000_hw *hw)
 
        case E1000_DEV_ID_I354_BACKPLANE_1GBPS:
        case E1000_DEV_ID_I354_SGMII:
+       case E1000_DEV_ID_I354_BACKPLANE_2_5GBPS:
                mac->type = e1000_i354;
                break;
        default:
index a8945ed..e8d6410 100644 (file)
@@ -129,14 +129,14 @@ u32  e1000_translate_register_82542(u32 reg);
  * TBI_ACCEPT macro definition:
  *
  * This macro requires:
- *      adapter = a pointer to struct e1000_hw
+ *      a = a pointer to struct e1000_hw
  *      status = the 8 bit status field of the Rx descriptor with EOP set
- *      error = the 8 bit error field of the Rx descriptor with EOP set
+ *      errors = the 8 bit error field of the Rx descriptor with EOP set
  *      length = the sum of all the length fields of the Rx descriptors that
  *               make up the current frame
  *      last_byte = the last byte of the frame DMAed by the hardware
- *      max_frame_length = the maximum frame length we want to accept.
- *      min_frame_length = the minimum frame length we want to accept.
+ *      min_frame_size = the minimum frame length we want to accept.
+ *      max_frame_size = the maximum frame length we want to accept.
  *
  * This macro is a conditional that should be used in the interrupt
  * handler's Rx processing routine when RxErrors have been detected.
@@ -162,10 +162,10 @@ u32  e1000_translate_register_82542(u32 reg);
         (((errors) & E1000_RXD_ERR_FRAME_ERR_MASK) == E1000_RXD_ERR_CE) && \
         ((last_byte) == CARRIER_EXTENSION) && \
         (((status) & E1000_RXD_STAT_VP) ? \
-         (((length) > (min_frame_size - VLAN_TAG_SIZE)) && \
-         ((length) <= (max_frame_size + 1))) : \
-         (((length) > min_frame_size) && \
-         ((length) <= (max_frame_size + VLAN_TAG_SIZE + 1)))))
+         (((length) > ((min_frame_size) - VLAN_TAG_SIZE)) && \
+         ((length) <= ((max_frame_size) + 1))) : \
+         (((length) > (min_frame_size)) && \
+         ((length) <= ((max_frame_size) + VLAN_TAG_SIZE + 1)))))
 
 #define E1000_MAX(a, b) ((a) > (b) ? (a) : (b))
 #define E1000_DIVIDE_ROUND_UP(a, b)    (((a) + (b) - 1) / (b)) /* ceil(a/b) */
index 5d31c27..e433dab 100644 (file)
 #define E1000_CTRL_EXT_IPS     0x00004000 /* Invert Power State */
 /* 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 */
 #define E1000_RCTL_RDMTS_HALF  0x00000000 /* Rx desc min thresh size */
 #define E1000_RCTL_RDMTS_QUAT  0x00000100 /* Rx desc min thresh size */
 #define E1000_RCTL_RDMTS_EIGTH 0x00000200 /* Rx desc min thresh size */
+#define E1000_RCTL_RDMTS_HEX   0x00010000
 #define E1000_RCTL_MO_SHIFT    12 /* multicast offset shift */
 #define E1000_RCTL_MO_0                0x00000000 /* multicast offset 11:0 */
 #define E1000_RCTL_MO_1                0x00001000 /* multicast offset 12:1 */
 
 #define E1000_CONNSW_ENRGSRC           0x4
 #define E1000_CONNSW_PHYSD             0x400
+#define E1000_CONNSW_PHY_PDN           0x800
 #define E1000_CONNSW_SERDESD           0x200
+#define E1000_CONNSW_AUTOSENSE_CONF    0x2
+#define E1000_CONNSW_AUTOSENSE_EN      0x1
 #define E1000_PCS_CFG_PCS_EN           8
 #define E1000_PCS_LCTL_FLV_LINK_UP     1
 #define E1000_PCS_LCTL_FSV_10          0
 #define E1000_STATUS_MTXCKOK           0x00000400 /* MTX clock running OK */
 #define E1000_STATUS_PCI66             0x00000800 /* In 66Mhz slot */
 #define E1000_STATUS_BUS64             0x00001000 /* In 64 bit slot */
+#define E1000_STATUS_2P5_SKU           0x00001000 /* Val of 2.5GBE SKU strap */
+#define E1000_STATUS_2P5_SKU_OVER      0x00002000 /* Val of 2.5GBE SKU Over */
 #define E1000_STATUS_PCIX_MODE         0x00002000 /* PCI-X mode */
 #define E1000_STATUS_PCIX_SPEED                0x0000C000 /* PCI-X bus speed */
 #define E1000_STATUS_BMC_SKU_0         0x00100000 /* BMC USB redirect disbld */
 #define SPEED_10       10
 #define SPEED_100      100
 #define SPEED_1000     1000
+#define SPEED_2500     2500
 #define HALF_DUPLEX    1
 #define FULL_DUPLEX    2
 
 #define E1000_ICR_ACK          0x00020000 /* Receive Ack frame */
 #define E1000_ICR_MNG          0x00040000 /* Manageability event */
 #define E1000_ICR_DOCK         0x00080000 /* Dock/Undock */
+#define E1000_ICR_ECCER                0x00400000 /* Uncorrectable ECC Error */
 #define E1000_ICR_TS           0x00080000 /* Time Sync Interrupt */
 #define E1000_ICR_DRSTA                0x40000000 /* Device Reset Asserted */
 #define E1000_ICR_ECCER                0x00400000 /* Uncorrectable ECC Error */
 #define E1000_IMS_ACK          E1000_ICR_ACK     /* Receive Ack frame */
 #define E1000_IMS_MNG          E1000_ICR_MNG     /* Manageability event */
 #define E1000_IMS_DOCK         E1000_ICR_DOCK    /* Dock/Undock */
+#define E1000_IMS_ECCER                E1000_ICR_ECCER   /* Uncorrectable ECC Error */
 #define E1000_IMS_TS           E1000_ICR_TS      /* Time Sync Interrupt */
 #define E1000_IMS_DRSTA                E1000_ICR_DRSTA   /* Device Reset Asserted */
 /* Q0 Rx desc FIFO parity error */
 #define E1000_EITR_ITR_INT_MASK        0x0000FFFF
 /* E1000_EITR_CNT_IGNR is only for 82576 and newer */
 #define E1000_EITR_CNT_IGNR    0x80000000 /* Don't reset counters on write */
+#define E1000_EITR_INTERVAL 0x00007FFC
 
 /* Transmit Descriptor Control */
 #define E1000_TXDCTL_PTHRESH   0x0000003F /* TXDCTL Prefetch Threshold */
 #define E1000_MDICNFG_COM_MDIO         0x40000000 /* MDI shared w/ lan 0 */
 #define E1000_MDICNFG_PHY_MASK         0x03E00000
 #define E1000_MDICNFG_PHY_SHIFT                21
-#define E1000_MEDIA_PORT_COPPER                1
-#define E1000_MEDIA_PORT_OTHER         2
-#define E1000_M88E1112_AUTO_A          0x010 /* Auto Copper/SGMII Mode */
-#define E1000_M88E1112_AUTO_B          0x011 /* Auto Copper/1000 Base X Mode */
-#define E1000_M88E1112_STATUS_LINK     0x0004 /* Interface Link Bit */
-#define E1000_M88E1112_MAC_CTRL_1      0x10 /* MAC Specific Control 1 */
-#define E1000_M88E1112_PAGE_ADDR       0x16
-#define E1000_M88E1112_STATUS          0x01
+
+#define E1000_MEDIA_PORT_COPPER                        1
+#define E1000_MEDIA_PORT_OTHER                 2
+#define E1000_M88E1112_AUTO_COPPER_SGMII       0x2
+#define E1000_M88E1112_AUTO_COPPER_BASEX       0x3
+#define E1000_M88E1112_STATUS_LINK             0x0004 /* Interface Link Bit */
+#define E1000_M88E1112_MAC_CTRL_1              0x10
+#define E1000_M88E1112_MAC_CTRL_1_MODE_MASK    0x0380 /* Mode Select */
+#define E1000_M88E1112_MAC_CTRL_1_MODE_SHIFT   7
+#define E1000_M88E1112_PAGE_ADDR               0x16
+#define E1000_M88E1112_STATUS                  0x01
 
 #define E1000_THSTAT_LOW_EVENT         0x20000000 /* Low thermal threshold */
 #define E1000_THSTAT_MID_EVENT         0x00200000 /* Mid thermal threshold */
 #define E1000_EEER_RX_LPI_STATUS       0x40000000 /* Rx in LPI state */
 #define E1000_EEER_TX_LPI_STATUS       0x80000000 /* Tx in LPI state */
 #define E1000_EEE_LP_ADV_ADDR_I350     0x040F     /* EEE LP Advertisement */
-#define E1000_M88E1545_PAGE_ADDR       0x16       /* Page Offset Register */
-#define E1000_M88E1545_EEE_CTRL_1      0x0
-#define E1000_M88E1545_EEE_CTRL_1_MS   0x0001     /* EEE Master/Slave */
+#define E1000_M88E1543_PAGE_ADDR       0x16       /* Page Offset Register */
+#define E1000_M88E1543_EEE_CTRL_1      0x0
+#define E1000_M88E1543_EEE_CTRL_1_MS   0x0001     /* EEE Master/Slave */
 #define E1000_EEE_ADV_DEV_I354         7
 #define E1000_EEE_ADV_ADDR_I354                60
 #define E1000_EEE_ADV_100_SUPPORTED    (1 << 1)   /* 100BaseTx EEE Supported */
 #define E1000_PCS_STATUS_TX_LPI_IND    0x0200     /* Tx in LPI state */
 #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 */
 #define IGP01E1000_I_PHY_ID    0x02A80380
 #define M88E1011_I_REV_4       0x04
 #define M88E1111_I_PHY_ID      0x01410CC0
-#define M88E1545_E_PHY_ID      0x01410EA0
+#define M88E1543_E_PHY_ID      0x01410EA0
+#define M88E1512_E_PHY_ID      0x01410DD0
 #define M88E1112_E_PHY_ID      0x01410C90
 #define I347AT4_E_PHY_ID       0x01410DC0
 #define M88E1340M_E_PHY_ID     0x01410DF0
 #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 */
+
 
 /* Proxy Filter Control */
 #define E1000_PROXYFC_D0               0x00000001 /* Enable offload in D0 */
 /* Lan ID bit field offset in status register */
 #define E1000_STATUS_LAN_ID_OFFSET     2
 #define E1000_VFTA_ENTRIES             128
+#ifndef E1000_UNUSEDARG
 #define E1000_UNUSEDARG
+#endif /* E1000_UNUSEDARG */
+#ifndef ERROR_REPORT
 #define ERROR_REPORT(fmt)      do { } while (0)
+#endif /* ERROR_REPORT */
 #endif /* _E1000_DEFINES_H_ */
index 62f5d3a..b27ca91 100644 (file)
@@ -180,6 +180,7 @@ struct e1000_hw;
 #define E1000_DEV_ID_I211_COPPER               0x1539
 #define E1000_DEV_ID_I354_BACKPLANE_1GBPS      0x1F40
 #define E1000_DEV_ID_I354_SGMII                        0x1F41
+#define E1000_DEV_ID_I354_BACKPLANE_2_5GBPS    0x1F45
 #define E1000_DEV_ID_DH89XXCC_SGMII            0x0438
 #define E1000_DEV_ID_DH89XXCC_SERDES           0x043A
 #define E1000_DEV_ID_DH89XXCC_BACKPLANE                0x043C
@@ -794,7 +795,7 @@ struct e1000_mac_info {
        u16 uta_reg_count;
 
        /* Maximum size of the MTA register table in all supported adapters */
-       #define MAX_MTA_REG 128
+#define MAX_MTA_REG 128
        u32 mta_shadow[MAX_MTA_REG];
        u16 rar_entry_count;
 
index 44d73fd..d55b6a4 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
 
-  Copyright (c) 2001-2011, Intel Corporation 
+  Copyright (c) 2001-2013, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -635,7 +635,7 @@ s32 e1000_validate_nvm_checksum_i210(struct e1000_hw *hw)
  **/
 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;
 
@@ -714,7 +714,7 @@ bool e1000_get_flash_presence_i210(struct e1000_hw *hw)
  **/
 s32 e1000_update_flash_i210(struct e1000_hw *hw)
 {
-       s32 ret_val = E1000_SUCCESS;
+       s32 ret_val;
        u32 flup;
 
        DEBUGFUNC("e1000_update_flash_i210");
@@ -770,7 +770,7 @@ s32 e1000_pool_flash_update_done_i210(struct e1000_hw *hw)
  **/
 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");
@@ -855,7 +855,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");
 
@@ -914,3 +914,90 @@ s32 e1000_write_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr, u16 data)
 
        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;
+}
index ae4c8c9..fab7284 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
 
-  Copyright (c) 2001-2011, Intel Corporation 
+  Copyright (c) 2001-2013, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -51,6 +51,7 @@ s32 e1000_read_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr,
                         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
@@ -88,11 +89,23 @@ enum E1000_INVM_STRUCTURE_TYPE {
                                         (ID_LED_OFF1_OFF2))
 #define ID_LED_DEFAULT_I210_SERDES     ((ID_LED_DEF1_DEF2 << 8) | \
                                         (ID_LED_DEF1_DEF2 <<  4) | \
-                                        (ID_LED_DEF1_DEF2))
+                                        (ID_LED_OFF1_ON2))
 
 /* NVM offset defaults for I211 devices */
 #define NVM_INIT_CTRL_2_DEFAULT_I211   0X7243
 #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
index 43984d2..7be02ef 100644 (file)
@@ -952,6 +952,7 @@ s32 e1000_set_default_fc_generic(struct e1000_hw *hw)
 {
        s32 ret_val;
        u16 nvm_data;
+       u16 nvm_offset = 0;
 
        DEBUGFUNC("e1000_set_default_fc_generic");
 
@@ -963,7 +964,18 @@ s32 e1000_set_default_fc_generic(struct e1000_hw *hw)
         * control setting, then the variable hw->fc will
         * be initialized based on a value in the EEPROM.
         */
-       ret_val = hw->nvm.ops.read(hw, NVM_INIT_CONTROL2_REG, 1, &nvm_data);
+       if (hw->mac.type == e1000_i350) {
+               nvm_offset = NVM_82580_LAN_FUNC_OFFSET(hw->bus.func);
+               ret_val = hw->nvm.ops.read(hw,
+                                          NVM_INIT_CONTROL2_REG +
+                                          nvm_offset,
+                                          1, &nvm_data);
+       } else {
+               ret_val = hw->nvm.ops.read(hw,
+                                          NVM_INIT_CONTROL2_REG,
+                                          1, &nvm_data);
+       }
+
 
        if (ret_val) {
                DEBUGOUT("NVM Read Error\n");
@@ -2090,7 +2102,8 @@ s32 e1000_disable_pcie_master_generic(struct e1000_hw *hw)
 
        while (timeout) {
                if (!(E1000_READ_REG(hw, E1000_STATUS) &
-                     E1000_STATUS_GIO_MASTER_ENABLE))
+                     E1000_STATUS_GIO_MASTER_ENABLE) ||
+                               E1000_REMOVED(hw->hw_addr))
                        break;
                usec_delay(100);
                timeout--;
index 99ffd66..a52086d 100644 (file)
@@ -36,6 +36,9 @@
 #define _E1000_MAC_H_
 
 void e1000_init_mac_ops_generic(struct e1000_hw *hw);
+#ifndef E1000_REMOVED
+#define E1000_REMOVED(a) (0)
+#endif /* E1000_REMOVED */
 void e1000_null_mac_generic(struct e1000_hw *hw);
 s32  e1000_null_ops_generic(struct e1000_hw *hw);
 s32  e1000_null_link_info(struct e1000_hw *hw, u16 *s, u16 *d);
index f84df49..7a1d44c 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
 
-  Copyright (c) 2001-2011, Intel Corporation 
+  Copyright (c) 2001-2013, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
index 5c506ee..efd2847 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
 
-  Copyright (c) 2001-2011, Intel Corporation 
+  Copyright (c) 2001-2013, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
index ba4b97d..ab7164d 100644 (file)
@@ -779,6 +779,12 @@ s32 e1000_read_pba_string_generic(struct e1000_hw *hw, u8 *pba_num,
 
        DEBUGFUNC("e1000_read_pba_string_generic");
 
+       if ((hw->mac.type >= e1000_i210) &&
+           !e1000_get_flash_presence_i210(hw)) {
+               DEBUGOUT("Flashless no PBA string\n");
+               return -E1000_ERR_NVM_PBA_SECTION;
+       }
+
        if (pba_num == NULL) {
                DEBUGOUT("PBA string buffer was null\n");
                return -E1000_ERR_INVALID_ARGUMENT;
@@ -1282,7 +1288,6 @@ void e1000_get_fw_version(struct e1000_hw *hw, struct e1000_fw_version *fw_vers)
        /* basic eeprom version numbers, bits used vary by part and by tool
         * used to create the nvm images */
        /* Check which data format we have */
-       hw->nvm.ops.read(hw, NVM_ETRACK_HIWORD, 1, &etrack_test);
        switch (hw->mac.type) {
        case e1000_i211:
                e1000_read_invm_version(hw, fw_vers);
@@ -1290,6 +1295,7 @@ void e1000_get_fw_version(struct e1000_hw *hw, struct e1000_fw_version *fw_vers)
        case e1000_82575:
        case e1000_82576:
        case e1000_82580:
+               hw->nvm.ops.read(hw, NVM_ETRACK_HIWORD, 1, &etrack_test);
                /* Use this format, unless EETRACK ID exists,
                 * then use alternate format
                 */
@@ -1304,7 +1310,13 @@ void e1000_get_fw_version(struct e1000_hw *hw, struct e1000_fw_version *fw_vers)
                }
                break;
        case e1000_i210:
+               if (!(e1000_get_flash_presence_i210(hw))) {
+                       e1000_read_invm_version(hw, fw_vers);
+                       return;
+               }
+               /* fall through */
        case e1000_i350:
+               hw->nvm.ops.read(hw, NVM_ETRACK_HIWORD, 1, &etrack_test);
                /* find combo image version */
                hw->nvm.ops.read(hw, NVM_COMB_VER_PTR, 1, &comb_offset);
                if ((comb_offset != 0x0) &&
@@ -1332,6 +1344,7 @@ void e1000_get_fw_version(struct e1000_hw *hw, struct e1000_fw_version *fw_vers)
                }
                break;
        default:
+               hw->nvm.ops.read(hw, NVM_ETRACK_HIWORD, 1, &etrack_test);
                return;
        }
        hw->nvm.ops.read(hw, NVM_VERSION, 1, &fw_version);
@@ -1360,8 +1373,12 @@ etrack_id:
                hw->nvm.ops.read(hw, (NVM_ETRACK_WORD + 1), 1, &eeprom_verh);
                fw_vers->etrack_id = (eeprom_verh << NVM_ETRACK_SHIFT)
                        | eeprom_verl;
+       } else if ((etrack_test & NVM_ETRACK_VALID) == 0) {
+               hw->nvm.ops.read(hw, NVM_ETRACK_WORD, 1, &eeprom_verh);
+               hw->nvm.ops.read(hw, (NVM_ETRACK_WORD + 1), 1, &eeprom_verl);
+               fw_vers->etrack_id = (eeprom_verh << NVM_ETRACK_SHIFT) |
+                                    eeprom_verl;
        }
-       return;
 }
 
 
index 5aa1b5a..6856d79 100644 (file)
@@ -1251,12 +1251,6 @@ s32 e1000_copper_link_setup_m88(struct e1000_hw *hw)
                        return ret_val;
        }
 
-       if (phy->type == e1000_phy_i210) {
-               ret_val = e1000_set_master_slave_mode(hw);
-               if (ret_val)
-                       return ret_val;
-       }
-
        return E1000_SUCCESS;
 }
 
@@ -1320,6 +1314,20 @@ s32 e1000_copper_link_setup_m88_gen2(struct e1000_hw *hw)
                phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
 
        /* Enable downshift and setting it to X6 */
+       if (phy->id == M88E1543_E_PHY_ID) {
+               phy_data &= ~I347AT4_PSCR_DOWNSHIFT_ENABLE;
+               ret_val =
+                   phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
+               if (ret_val)
+                       return ret_val;
+
+               ret_val = phy->ops.commit(hw);
+               if (ret_val) {
+                       DEBUGOUT("Error committing the PHY changes\n");
+                       return ret_val;
+               }
+       }
+
        phy_data &= ~I347AT4_PSCR_DOWNSHIFT_MASK;
        phy_data |= I347AT4_PSCR_DOWNSHIFT_6X;
        phy_data |= I347AT4_PSCR_DOWNSHIFT_ENABLE;
@@ -1853,7 +1861,8 @@ s32 e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw)
                        case I347AT4_E_PHY_ID:
                        case M88E1340M_E_PHY_ID:
                        case M88E1112_E_PHY_ID:
-                       case M88E1545_E_PHY_ID:
+                       case M88E1543_E_PHY_ID:
+                       case M88E1512_E_PHY_ID:
                        case I210_I_PHY_ID:
                                reset_dsp = FALSE;
                                break;
@@ -1896,7 +1905,8 @@ s32 e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw)
                return E1000_SUCCESS;
        if (hw->phy.id == I210_I_PHY_ID)
                return E1000_SUCCESS;
-       if (hw->phy.id == M88E1545_E_PHY_ID)
+       if ((hw->phy.id == M88E1543_E_PHY_ID) ||
+           (hw->phy.id == M88E1512_E_PHY_ID))
                return E1000_SUCCESS;
        ret_val = phy->ops.read_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data);
        if (ret_val)
@@ -2450,7 +2460,8 @@ s32 e1000_get_cable_length_m88_gen2(struct e1000_hw *hw)
                phy->max_cable_length = phy_data / (is_cm ? 100 : 1);
                phy->cable_length = phy_data / (is_cm ? 100 : 1);
                break;
-       case M88E1545_E_PHY_ID:
+       case M88E1543_E_PHY_ID:
+       case M88E1512_E_PHY_ID:
        case M88E1340M_E_PHY_ID:
        case I347AT4_E_PHY_ID:
                /* Remember the original page select and set it to 7 */
@@ -2984,7 +2995,8 @@ enum e1000_phy_type e1000_get_phy_type_from_id(u32 phy_id)
        case M88E1000_E_PHY_ID:
        case M88E1111_I_PHY_ID:
        case M88E1011_I_PHY_ID:
-       case M88E1545_E_PHY_ID:
+       case M88E1543_E_PHY_ID:
+       case M88E1512_E_PHY_ID:
        case I347AT4_E_PHY_ID:
        case M88E1112_E_PHY_ID:
        case M88E1340M_E_PHY_ID:
@@ -3480,16 +3492,10 @@ static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset,
 void e1000_power_up_phy_copper(struct e1000_hw *hw)
 {
        u16 mii_reg = 0;
-       u16 power_reg = 0;
 
        /* The PHY will retain its settings across a power down/up cycle */
        hw->phy.ops.read_reg(hw, PHY_CONTROL, &mii_reg);
        mii_reg &= ~MII_CR_POWER_DOWN;
-       if (hw->phy.type == e1000_phy_i210) {
-               hw->phy.ops.read_reg(hw, GS40G_COPPER_SPEC, &power_reg);
-               power_reg &= ~GS40G_CS_POWER_DOWN;
-               hw->phy.ops.write_reg(hw, GS40G_COPPER_SPEC, power_reg);
-       }
        hw->phy.ops.write_reg(hw, PHY_CONTROL, mii_reg);
 }
 
@@ -3504,17 +3510,10 @@ void e1000_power_up_phy_copper(struct e1000_hw *hw)
 void e1000_power_down_phy_copper(struct e1000_hw *hw)
 {
        u16 mii_reg = 0;
-       u16 power_reg = 0;
 
        /* The PHY will retain its settings across a power down/up cycle */
        hw->phy.ops.read_reg(hw, PHY_CONTROL, &mii_reg);
        mii_reg |= MII_CR_POWER_DOWN;
-       /* i210 Phy requires an additional bit for power up/down */
-       if (hw->phy.type == e1000_phy_i210) {
-               hw->phy.ops.read_reg(hw, GS40G_COPPER_SPEC, &power_reg);
-               power_reg |= GS40G_CS_POWER_DOWN;
-               hw->phy.ops.write_reg(hw, GS40G_COPPER_SPEC, power_reg);
-       }
        hw->phy.ops.write_reg(hw, PHY_CONTROL, mii_reg);
        msec_delay(1);
 }
@@ -4112,7 +4111,7 @@ s32 e1000_read_phy_reg_mphy(struct e1000_hw *hw, u32 address, u32 *data)
 {
        u32 mphy_ctrl = 0;
        bool locked = FALSE;
-       bool ready = FALSE;
+       bool ready;
 
        DEBUGFUNC("e1000_read_phy_reg_mphy");
 
@@ -4136,7 +4135,11 @@ s32 e1000_read_phy_reg_mphy(struct e1000_hw *hw, u32 address, u32 *data)
        ready = e1000_is_mphy_ready(hw);
        if (!ready)
                return -E1000_ERR_PHY;
-       mphy_ctrl |= (address & E1000_MPHY_ADDRESS_MASK);
+
+       /* We mask address, because we want to use only current lane */
+       mphy_ctrl = (mphy_ctrl & ~E1000_MPHY_ADDRESS_MASK &
+               ~E1000_MPHY_ADDRESS_FNC_OVERRIDE) |
+               (address & E1000_MPHY_ADDRESS_MASK);
        E1000_WRITE_REG(hw, E1000_MPHY_ADDR_CTRL, mphy_ctrl);
 
        /* Read data from the address */
@@ -4162,14 +4165,16 @@ s32 e1000_read_phy_reg_mphy(struct e1000_hw *hw, u32 address, u32 *data)
  *  @hw: pointer to the HW structure
  *  @address: address to write to
  *  @data: data to write to register at offset
+ *  @line_override: used when we want to use different line than default one
  *
  *  Writes data to mPHY control register.
  **/
-s32 e1000_write_phy_reg_mphy(struct e1000_hw *hw, u32 address, u32 data)
+s32 e1000_write_phy_reg_mphy(struct e1000_hw *hw, u32 address, u32 data,
+                            bool line_override)
 {
        u32 mphy_ctrl = 0;
        bool locked = FALSE;
-       bool ready = FALSE;
+       bool ready;
 
        DEBUGFUNC("e1000_write_phy_reg_mphy");
 
@@ -4193,7 +4198,14 @@ s32 e1000_write_phy_reg_mphy(struct e1000_hw *hw, u32 address, u32 data)
        ready = e1000_is_mphy_ready(hw);
        if (!ready)
                return -E1000_ERR_PHY;
-       mphy_ctrl |= (address & E1000_MPHY_ADDRESS_MASK);
+
+       /* We mask address, because we want to use only current lane */
+       if (line_override)
+               mphy_ctrl |= E1000_MPHY_ADDRESS_FNC_OVERRIDE;
+       else
+               mphy_ctrl &= ~E1000_MPHY_ADDRESS_FNC_OVERRIDE;
+       mphy_ctrl = (mphy_ctrl & ~E1000_MPHY_ADDRESS_MASK) |
+               (address & E1000_MPHY_ADDRESS_MASK);
        E1000_WRITE_REG(hw, E1000_MPHY_ADDR_CTRL, mphy_ctrl);
 
        /* Read data from the address */
index f60a4f0..d54f227 100644 (file)
@@ -117,7 +117,8 @@ s32  e1000_get_cable_length_82577(struct e1000_hw *hw);
 s32  e1000_write_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 data);
 s32  e1000_read_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 *data);
 s32 e1000_read_phy_reg_mphy(struct e1000_hw *hw, u32 address, u32 *data);
-s32 e1000_write_phy_reg_mphy(struct e1000_hw *hw, u32 address, u32 data);
+s32 e1000_write_phy_reg_mphy(struct e1000_hw *hw, u32 address, u32 data,
+                            bool line_override);
 bool e1000_is_mphy_ready(struct e1000_hw *hw);
 
 #define E1000_MAX_PHY_ADDR             8
@@ -223,10 +224,11 @@ bool e1000_is_mphy_ready(struct e1000_hw *hw);
 
 #define E1000_82580_PM_GO_LINKD                0x0020 /* Go Link Disconnect */
 
-#define E1000_MPHY_DIS_ACCESS  0x80000000 /* disable_access bit */
-#define E1000_MPHY_ENA_ACCESS  0x40000000 /* enable_access bit */
-#define E1000_MPHY_BUSY                0x00010000 /* busy bit */
-#define E1000_MPHY_ADDRESS_MASK        0x0000FFFF /* address bit mask */
+#define E1000_MPHY_DIS_ACCESS          0x80000000 /* disable_access bit */
+#define E1000_MPHY_ENA_ACCESS          0x40000000 /* enable_access bit */
+#define E1000_MPHY_BUSY                        0x00010000 /* busy bit */
+#define E1000_MPHY_ADDRESS_FNC_OVERRIDE        0x20000000 /* fnc_override bit */
+#define E1000_MPHY_ADDRESS_MASK                0x0000FFFF /* address mask */
 
 #define IGP01E1000_PHY_PCS_INIT_REG    0x00B4
 #define IGP01E1000_PHY_POLARITY_MASK   0x0078
@@ -275,6 +277,17 @@ bool e1000_is_mphy_ready(struct e1000_hw *hw);
 #define E1000_KMRNCTRLSTA_K1_CONFIG    0x7
 #define E1000_KMRNCTRLSTA_K1_ENABLE    0x0002 /* enable K1 */
 #define E1000_KMRNCTRLSTA_HD_CTRL      0x10   /* Kumeran HD Control */
+#if !defined(EXTERNAL_RELEASE) || defined(ULP_IN_D0_SUPPORT)
+#define E1000_KMRNCTRLSTA_K0S_CTRL     0x1E    /* Kumeran K0s Control */
+#define E1000_KMRNCTRLSTA_K0S_CTRL_ENTRY_LTNCY_SHIFT   0
+#define E1000_KMRNCTRLSTA_K0S_CTRL_MIN_TIME_SHIFT      4
+#define E1000_KMRNCTRLSTA_K0S_CTRL_ENTRY_LTNCY_MASK    \
+       (3 << E1000_KMRNCTRLSTA_K0S_CTRL_ENTRY_LTNCY_SHIFT)
+#define E1000_KMRNCTRLSTA_K0S_CTRL_MIN_TIME_MASK \
+       (7 << E1000_KMRNCTRLSTA_K0S_CTRL_MIN_TIME_SHIFT)
+#define E1000_KMRNCTRLSTA_OP_MODES     0x1F   /* Kumeran Modes of Operation */
+#define E1000_KMRNCTRLSTA_OP_MODES_LSC2CSC     0x0002 /* change LSC to CSC */
+#endif /* !EXTERNAL_RELEASE || ULP_IN_D0_SUPPORT */
 
 #define IFE_PHY_EXTENDED_STATUS_CONTROL        0x10
 #define IFE_PHY_SPECIAL_CONTROL                0x11 /* 100BaseTx PHY Special Ctrl */
index 964aa18..d688f4e 100644 (file)
 #define E1000_EEMNGCTL 0x01010  /* MNG EEprom Control */
 #define E1000_EEARBC   0x01024  /* EEPROM Auto Read Bus Control */
 #define E1000_FLASHT   0x01028  /* FLASH Timer Register */
+#define E1000_EEARBC_I210      0x12024 /* EEPROM Auto Read Bus Control */
 #define E1000_EEWR     0x0102C  /* EEPROM Write Register - RW */
 #define E1000_FLSWCTL  0x01030  /* FLASH control register */
 #define E1000_FLSWDATA 0x01034  /* FLASH data register */
 /* Queues fetch arbitration priority control register */
 #define E1000_I210_TQAVARBCTRL                 0x3574
 /* Queues priority masks where _n and _p can be 0-3. */
-#define E1000_TQAVARBCTRL_QUEUE_PRI(_n, _p)    ((_p) << (2 * _n))
+#define E1000_TQAVARBCTRL_QUEUE_PRI(_n, _p)    ((_p) << (2 * (_n)))
 /* QAV Tx mode control registers where _n can be 0 or 1. */
 #define E1000_I210_TQAVCC(_n)                  (0x3004 + 0x40 * (_n))
 
 #define E1000_PQGPTC(_n)               (0x010014 + (0x100 * (_n)))
 
 /* Queues packet buffer size masks where _n can be 0-3 and _s 0-63 [kB] */
-#define E1000_I210_TXPBS_SIZE(_n, _s)  ((_s) << (6 * _n))
+#define E1000_I210_TXPBS_SIZE(_n, _s)  ((_s) << (6 * (_n)))
 
 #define E1000_MMDAC                    13 /* MMD Access Control */
 #define E1000_MMDAAD                   14 /* MMD Access Address/Data */
index 1edad6a..7646f8b 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
 
-  Copyright (c) 2001-2011, Intel Corporation 
+  Copyright (c) 2001-2013, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -49,7 +49,7 @@ static s32 e1000_get_link_up_info_vf(struct e1000_hw *hw, u16 *speed,
 static s32 e1000_init_hw_vf(struct e1000_hw *hw);
 static s32 e1000_reset_hw_vf(struct e1000_hw *hw);
 static void e1000_update_mc_addr_list_vf(struct e1000_hw *hw, u8 *, u32);
-static int e1000_rar_set_vf(struct e1000_hw *, u8 *, u32);
+static int  e1000_rar_set_vf(struct e1000_hw *, u8 *, u32);
 static s32 e1000_read_mac_addr_vf(struct e1000_hw *);
 
 /**
@@ -321,7 +321,7 @@ static s32 e1000_init_hw_vf(struct e1000_hw *hw)
  *  @index receive address array register
  **/
 static int e1000_rar_set_vf(struct e1000_hw *hw, u8 *addr,
-                           u32 E1000_UNUSEDARG index)
+                            u32 E1000_UNUSEDARG index)
 {
        struct e1000_mbx_info *mbx = &hw->mbx;
        u32 msgbuf[3];
index 6385092..0865fa7 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
 
-  Copyright (c) 2001-2011, Intel Corporation 
+  Copyright (c) 2001-2013, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -208,7 +208,7 @@ struct e1000_mac_operations {
        s32  (*init_hw)(struct e1000_hw *);
        s32  (*setup_link)(struct e1000_hw *);
        void (*write_vfta)(struct e1000_hw *, u32, u32);
-       void (*rar_set)(struct e1000_hw *, u8*, u32);
+       int  (*rar_set)(struct e1000_hw *, u8*, u32);
        s32  (*read_mac_addr)(struct e1000_hw *);
 };
 
index 5847e7e..d3a25fd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001-2011, Intel Corporation 
+ * Copyright (c) 2001-2013, Intel Corporation 
  * All rights reserved.
  * 
  * Redistribution and use in source and binary forms, with or without 
@@ -130,6 +130,7 @@ static struct igb_device {
        IGB_DEVICE(I210_SGMII),
        IGB_DEVICE(I211_COPPER),
        IGB_DEVICE(I354_BACKPLANE_1GBPS),
+       IGB_DEVICE(I354_BACKPLANE_2_5GBPS),
        IGB_DEVICE(I354_SGMII),
 
        /* required last entry */
@@ -165,12 +166,13 @@ static int        igb_sysctl_npoll_txoff(SYSCTL_HANDLER_ARGS);
 #endif
 
 static void    igb_vf_init_stats(struct igb_softc *);
-static void    igb_reset(struct igb_softc *);
+static void    igb_reset(struct igb_softc *, boolean_t);
 static void    igb_update_stats_counters(struct igb_softc *);
 static void    igb_update_vf_stats_counters(struct igb_softc *);
 static void    igb_update_link_status(struct igb_softc *);
 static void    igb_init_tx_unit(struct igb_softc *);
 static void    igb_init_rx_unit(struct igb_softc *);
+static void    igb_init_dmac(struct igb_softc *, uint32_t);
 
 static void    igb_set_vlan(struct igb_softc *);
 static void    igb_set_multi(struct igb_softc *);
@@ -398,6 +400,9 @@ igb_attach(device_t dev)
            device_get_unit(dev));
        sc->dev = sc->osdep.dev = dev;
 
+       /* Enable bus mastering */
+       pci_enable_busmaster(dev);
+
        /*
         * Determine hardware and mac type
         */
@@ -473,9 +478,6 @@ igb_attach(device_t dev)
            igb_flowctrl);
        sc->ifm_flowctrl = ifmedia_str2ethfc(flowctrl);
 
-       /* Enable bus mastering */
-       pci_enable_busmaster(dev);
-
        /*
         * Allocate IO memory
         */
@@ -598,9 +600,9 @@ igb_attach(device_t dev)
 #endif
                if (sc->hw.phy.media_type == e1000_media_type_copper) {
                         if (sc->hw.mac.type == e1000_i354)
-                               e1000_set_eee_i354(&sc->hw);
+                               e1000_set_eee_i354(&sc->hw, TRUE, TRUE);
                        else
-                               e1000_set_eee_i350(&sc->hw);
+                               e1000_set_eee_i350(&sc->hw, TRUE, TRUE);
                }
        }
 
@@ -646,7 +648,7 @@ igb_attach(device_t dev)
        igb_add_sysctl(sc);
 
        /* Now get a good starting state */
-       igb_reset(sc);
+       igb_reset(sc, FALSE);
 
        /* Initialize statistics */
        igb_update_stats_counters(sc);
@@ -939,7 +941,7 @@ igb_init(void *xsc)
        /* Put the address into the Receive Address Array */
        e1000_rar_set(&sc->hw, sc->hw.mac.addr, 0);
 
-       igb_reset(sc);
+       igb_reset(sc, FALSE);
        igb_update_link_status(sc);
 
        E1000_WRITE_REG(&sc->hw, E1000_VET, ETHERTYPE_VLAN);
@@ -1028,9 +1030,9 @@ igb_init(void *xsc)
        /* Set Energy Efficient Ethernet */
        if (sc->hw.phy.media_type == e1000_media_type_copper) {
                if (sc->hw.mac.type == e1000_i354)
-                       e1000_set_eee_i354(&sc->hw);
+                       e1000_set_eee_i354(&sc->hw, TRUE, TRUE);
                else
-                       e1000_set_eee_i350(&sc->hw);
+                       e1000_set_eee_i350(&sc->hw, TRUE, TRUE);
        }
 }
 
@@ -1084,6 +1086,10 @@ igb_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
                else
                        ifmr->ifm_active |= IFM_1000_T;
                break;
+
+       case 2500:
+               ifmr->ifm_active |= IFM_2500_SX;
+               break;
        }
 
        if (sc->link_duplex == FULL_DUPLEX)
@@ -1349,6 +1355,14 @@ igb_update_link_status(struct igb_softc *sc)
                     hw->mac.type == e1000_i211) &&
                    hw->phy.id == I210_I_PHY_ID)
                        msec_delay(IGB_I210_LINK_DELAY);
+               /*
+                * Reset if the media type changed.
+                * Support AutoMediaDetect for Marvell M88 PHY in i354.
+                */
+               if (hw->dev_spec._82575.media_changed) {
+                       hw->dev_spec._82575.media_changed = FALSE;
+                       igb_reset(sc, TRUE);
+               }
                /* This can sleep */
                ifp->if_link_state = LINK_STATE_UP;
                if_link_state_change(ifp);
@@ -1399,7 +1413,7 @@ igb_stop(struct igb_softc *sc)
 }
 
 static void
-igb_reset(struct igb_softc *sc)
+igb_reset(struct igb_softc *sc, boolean_t media_reset)
 {
        struct ifnet *ifp = &sc->arpcom.ac_if;
        struct e1000_hw *hw = &sc->hw;
@@ -1497,73 +1511,18 @@ igb_reset(struct igb_softc *sc)
        e1000_reset_hw(hw);
        E1000_WRITE_REG(hw, E1000_WUC, 0);
 
+       /* Reset for AutoMediaDetect */
+       if (media_reset) {
+               e1000_setup_init_funcs(hw, TRUE);
+               e1000_get_bus_info(hw);
+       }
+
        if (e1000_init_hw(hw) < 0)
                if_printf(ifp, "Hardware Initialization Failed\n");
 
        /* Setup DMA Coalescing */
-       if (hw->mac.type > e1000_82580 && hw->mac.type != e1000_i211) {
-               uint32_t dmac;
-               uint32_t reg;
+       igb_init_dmac(sc, pba);
 
-               if (sc->dma_coalesce == 0) {
-                       /*
-                        * Disabled
-                        */
-                       reg = E1000_READ_REG(hw, E1000_DMACR);
-                       reg &= ~E1000_DMACR_DMAC_EN;
-                       E1000_WRITE_REG(hw, E1000_DMACR, reg);
-                       goto reset_out;
-               }
-
-               /* Set starting thresholds */
-               E1000_WRITE_REG(hw, E1000_DMCTXTH, 0);
-               E1000_WRITE_REG(hw, E1000_DMCRTRH, 0);
-
-               hwm = 64 * pba - sc->max_frame_size / 16;
-               if (hwm < 64 * (pba - 6))
-                       hwm = 64 * (pba - 6);
-               reg = E1000_READ_REG(hw, E1000_FCRTC);
-               reg &= ~E1000_FCRTC_RTH_COAL_MASK;
-               reg |= ((hwm << E1000_FCRTC_RTH_COAL_SHIFT)
-                   & E1000_FCRTC_RTH_COAL_MASK);
-               E1000_WRITE_REG(hw, E1000_FCRTC, reg);
-
-               dmac = pba - sc->max_frame_size / 512;
-               if (dmac < pba - 10)
-                       dmac = pba - 10;
-               reg = E1000_READ_REG(hw, E1000_DMACR);
-               reg &= ~E1000_DMACR_DMACTHR_MASK;
-               reg |= ((dmac << E1000_DMACR_DMACTHR_SHIFT)
-                   & E1000_DMACR_DMACTHR_MASK);
-               /* Transition to L0x or L1 if available.. */
-               reg |= (E1000_DMACR_DMAC_EN | E1000_DMACR_DMAC_LX_MASK);
-               /* timer = value in sc->dma_coalesce in 32usec intervals */
-               reg |= (sc->dma_coalesce >> 5);
-               E1000_WRITE_REG(hw, E1000_DMACR, reg);
-
-               /* Set the interval before transition */
-               reg = E1000_READ_REG(hw, E1000_DMCTLX);
-               reg |= 0x80000004;
-               E1000_WRITE_REG(hw, E1000_DMCTLX, reg);
-
-               /* Free space in tx packet buffer to wake from DMA coal */
-               E1000_WRITE_REG(hw, E1000_DMCTXTH,
-                   (20480 - (2 * sc->max_frame_size)) >> 6);
-
-               /* Make low power state decision controlled by DMA coal */
-               reg = E1000_READ_REG(hw, E1000_PCIEMISC);
-               reg &= ~E1000_PCIEMISC_LX_DECISION;
-               E1000_WRITE_REG(hw, E1000_PCIEMISC, reg);
-               if_printf(ifp, "DMA Coalescing enabled\n");
-       } else if (hw->mac.type == e1000_82580) {
-               uint32_t reg = E1000_READ_REG(hw, E1000_PCIEMISC);
-
-               E1000_WRITE_REG(hw, E1000_DMACR, 0);
-               E1000_WRITE_REG(hw, E1000_PCIEMISC,
-                   reg & ~E1000_PCIEMISC_LX_DECISION);
-       }
-
-reset_out:
        E1000_WRITE_REG(&sc->hw, E1000_VET, ETHERTYPE_VLAN);
        e1000_get_phy_info(hw);
        e1000_check_for_link(hw);
@@ -4901,3 +4860,108 @@ igb_set_timer_cpuid(struct igb_softc *sc, boolean_t polling)
        else
                sc->timer_cpuid = rman_get_cpuid(sc->intr_data[0].intr_res);
 }
+
+static void
+igb_init_dmac(struct igb_softc *sc, uint32_t pba)
+{
+       struct e1000_hw *hw = &sc->hw;
+       uint32_t reg;
+
+       if (hw->mac.type == e1000_i211)
+               return;
+
+       if (hw->mac.type > e1000_82580) {
+               uint32_t dmac;
+               uint16_t hwm;
+
+               if (sc->dma_coalesce == 0) { /* Disabling it */
+                       reg = ~E1000_DMACR_DMAC_EN;
+                       E1000_WRITE_REG(hw, E1000_DMACR, reg);
+                       return;
+               } else {
+                       if_printf(&sc->arpcom.ac_if,
+                           "DMA Coalescing enabled\n");
+               }
+
+               /* Set starting threshold */
+               E1000_WRITE_REG(hw, E1000_DMCTXTH, 0);
+
+               hwm = 64 * pba - sc->max_frame_size / 16;
+               if (hwm < 64 * (pba - 6))
+                       hwm = 64 * (pba - 6);
+               reg = E1000_READ_REG(hw, E1000_FCRTC);
+               reg &= ~E1000_FCRTC_RTH_COAL_MASK;
+               reg |= ((hwm << E1000_FCRTC_RTH_COAL_SHIFT)
+                   & E1000_FCRTC_RTH_COAL_MASK);
+               E1000_WRITE_REG(hw, E1000_FCRTC, reg);
+
+               dmac = pba - sc->max_frame_size / 512;
+               if (dmac < pba - 10)
+                       dmac = pba - 10;
+               reg = E1000_READ_REG(hw, E1000_DMACR);
+               reg &= ~E1000_DMACR_DMACTHR_MASK;
+               reg |= ((dmac << E1000_DMACR_DMACTHR_SHIFT)
+                   & E1000_DMACR_DMACTHR_MASK);
+
+               /* transition to L0x or L1 if available..*/
+               reg |= (E1000_DMACR_DMAC_EN | E1000_DMACR_DMAC_LX_MASK);
+
+               /*
+                * Check if status is 2.5Gb backplane connection
+                * before configuration of watchdog timer, which
+                * is in msec values in 12.8usec intervals watchdog
+                * timer = msec values in 32usec intervals for non
+                * 2.5Gb connection.
+                */
+               if (hw->mac.type == e1000_i354) {
+                       int status = E1000_READ_REG(hw, E1000_STATUS);
+
+                       if ((status & E1000_STATUS_2P5_SKU) &&
+                           !(status & E1000_STATUS_2P5_SKU_OVER))
+                               reg |= ((sc->dma_coalesce * 5) >> 6);
+                       else
+                               reg |= (sc->dma_coalesce >> 5);
+               } else {
+                       reg |= (sc->dma_coalesce >> 5);
+               }
+
+               E1000_WRITE_REG(hw, E1000_DMACR, reg);
+
+               E1000_WRITE_REG(hw, E1000_DMCRTRH, 0);
+
+               /* Set the interval before transition */
+               reg = E1000_READ_REG(hw, E1000_DMCTLX);
+               if (hw->mac.type == e1000_i350)
+                       reg |= IGB_DMCTLX_DCFLUSH_DIS;
+               /*
+                * In 2.5Gb connection, TTLX unit is 0.4 usec, which
+                * is 0x4*2 = 0xA.  But delay is still 4 usec.
+                */
+               if (hw->mac.type == e1000_i354) {
+                       int status = E1000_READ_REG(hw, E1000_STATUS);
+
+                       if ((status & E1000_STATUS_2P5_SKU) &&
+                           !(status & E1000_STATUS_2P5_SKU_OVER))
+                               reg |= 0xA;
+                       else
+                               reg |= 0x4;
+               } else {
+                       reg |= 0x4;
+               }
+               E1000_WRITE_REG(hw, E1000_DMCTLX, reg);
+
+               /* Free space in tx packet buffer to wake from DMA coal */
+               E1000_WRITE_REG(hw, E1000_DMCTXTH,
+                   (IGB_TXPBSIZE - (2 * sc->max_frame_size)) >> 6);
+
+               /* Make low power state decision controlled by DMA coal */
+               reg = E1000_READ_REG(hw, E1000_PCIEMISC);
+               reg &= ~E1000_PCIEMISC_LX_DECISION;
+               E1000_WRITE_REG(hw, E1000_PCIEMISC, reg);
+       } else if (hw->mac.type == e1000_82580) {
+               reg = E1000_READ_REG(hw, E1000_PCIEMISC);
+               E1000_WRITE_REG(hw, E1000_PCIEMISC,
+                   reg & ~E1000_PCIEMISC_LX_DECISION);
+               E1000_WRITE_REG(hw, E1000_DMACR, 0);
+       }
+}
index 6bf7abc..8afb6f0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001-2011, Intel Corporation 
+ * Copyright (c) 2001-2013, Intel Corporation 
  * All rights reserved.
  * 
  * Redistribution and use in source and binary forms, with or without 
 #define IGB_SMARTSPEED_MAX             15
 #define IGB_MAX_LOOP                   10
 
-#define IGB_RX_PTHRESH                 (hw->mac.type <= e1000_82576 ? 16 : 8)
+#define IGB_RX_PTHRESH                 ((hw->mac.type == e1000_i354) ? 12 : \
+                                         ((hw->mac.type <= e1000_82576) ? 16 : 8))
 #define IGB_RX_HTHRESH                 8
-#define IGB_RX_WTHRESH                 1
+#define IGB_RX_WTHRESH                 ((hw->mac.type == e1000_82576 && \
+                                         sc->msix_mem_res) ? 1 : 4)
 
-#define IGB_TX_PTHRESH                 8
+#define IGB_TX_PTHRESH                 ((hw->mac.type == e1000_i354) ? 20 : 8)
 #define IGB_TX_HTHRESH                 1
 #define IGB_TX_WTHRESH                 16
 
 #define IGB_TSO_SIZE                   (IP_MAXPACKET + \
                                         sizeof(struct ether_vlan_header))
 #define IGB_HDR_BUF                    128
+#define IGB_TXPBSIZE                   20408
 #define IGB_PKTTYPE_MASK               0x0000FFF0
 
 #define IGB_CSUM_FEATURES              (CSUM_IP | CSUM_TCP | CSUM_UDP)
 #define IGB_EITR_INTVL_MASK            0x7ffc
 #define IGB_EITR_INTVL_SHIFT           2
 
+/* Disable DMA Coalesce Flush */
+#define IGB_DMCTLX_DCFLUSH_DIS         0x80000000
+
 struct igb_softc;
 
 /*