e1000e: enable support for EEE on 82579
authorBruce Allan <bruce.w.allan@intel.com>
Wed, 16 Jun 2010 13:27:49 +0000 (13:27 +0000)
committerDavid S. Miller <davem@davemloft.net>
Sat, 19 Jun 2010 05:12:17 +0000 (22:12 -0700)
This patch enables IEEE802.3az (a.k.a. Energy Efficient Ethernet) on the
new 82579 LOMs.  An optional module parameter is provided to disable the
feature if desired.

Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Tested-by: Jeff Pieper <jeffrey.e.pieper@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/e1000e/e1000.h
drivers/net/e1000e/hw.h
drivers/net/e1000e/ich8lan.c
drivers/net/e1000e/param.c

index 0e59f15be11045c25b0873b34efc019d28ddac66..c233496b1f47897370e06592ba7a4b3463a32a5b 100644 (file)
@@ -423,6 +423,7 @@ struct e1000_info {
 #define FLAG2_IS_DISCARDING               (1 << 2)
 #define FLAG2_DISABLE_ASPM_L1             (1 << 3)
 #define FLAG2_HAS_PHY_STATS               (1 << 4)
+#define FLAG2_HAS_EEE                     (1 << 5)
 
 #define E1000_RX_DESC_PS(R, i)     \
        (&(((union e1000_rx_desc_packet_split *)((R).desc))[i]))
index 96116ce5e5cc8be6a0e7ed92a1c28b95393fd80d..eecb2eca507b1542ca63d3636ead57a035418367 100644 (file)
@@ -937,6 +937,7 @@ struct e1000_dev_spec_ich8lan {
        bool kmrn_lock_loss_workaround_enabled;
        struct e1000_shadow_ram shadow_ram[E1000_ICH8_SHADOW_RAM_WORDS];
        bool nvm_k1_enabled;
+       bool eee_disable;
 };
 
 struct e1000_hw {
index 8274499b7df62b21fe96602a4d36d95fea9d39df..5e55de002487a277a43759acbc81ceaea1c028fd 100644 (file)
 /* PHY Power Management Control */
 #define HV_PM_CTRL             PHY_REG(770, 17)
 
+/* PHY Low Power Idle Control */
+#define I82579_LPI_CTRL                        PHY_REG(772, 20)
+#define I82579_LPI_CTRL_ENABLE_MASK    0x6000
+
 /* Strapping Option Register - RO */
 #define E1000_STRAP                     0x0000C
 #define E1000_STRAP_SMBUS_ADDRESS_MASK  0x00FE0000
@@ -568,6 +572,35 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_adapter *adapter)
        return 0;
 }
 
+/**
+ *  e1000_set_eee_pchlan - Enable/disable EEE support
+ *  @hw: pointer to the HW structure
+ *
+ *  Enable/disable EEE based on setting in dev_spec structure.  The bits in
+ *  the LPI Control register will remain set only if/when link is up.
+ **/
+static s32 e1000_set_eee_pchlan(struct e1000_hw *hw)
+{
+       s32 ret_val = 0;
+       u16 phy_reg;
+
+       if (hw->phy.type != e1000_phy_82579)
+               goto out;
+
+       ret_val = e1e_rphy(hw, I82579_LPI_CTRL, &phy_reg);
+       if (ret_val)
+               goto out;
+
+       if (hw->dev_spec.ich8lan.eee_disable)
+               phy_reg &= ~I82579_LPI_CTRL_ENABLE_MASK;
+       else
+               phy_reg |= I82579_LPI_CTRL_ENABLE_MASK;
+
+       ret_val = e1e_wphy(hw, I82579_LPI_CTRL, phy_reg);
+out:
+       return ret_val;
+}
+
 /**
  *  e1000_check_for_copper_link_ich8lan - Check for link (Copper)
  *  @hw: pointer to the HW structure
@@ -625,6 +658,11 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
         */
        e1000e_check_downshift(hw);
 
+       /* Enable/Disable EEE after link up */
+       ret_val = e1000_set_eee_pchlan(hw);
+       if (ret_val)
+               goto out;
+
        /*
         * If we are forcing speed/duplex, then we simply return since
         * we have already determined whether we have link or not.
@@ -3820,7 +3858,8 @@ struct e1000_info e1000_pch2_info = {
                                  | FLAG_HAS_FLASH
                                  | FLAG_HAS_JUMBO_FRAMES
                                  | FLAG_APME_IN_WUC,
-       .flags2                 = FLAG2_HAS_PHY_STATS,
+       .flags2                 = FLAG2_HAS_PHY_STATS
+                                 | FLAG2_HAS_EEE,
        .pba                    = 18,
        .max_hw_frame_size      = DEFAULT_JUMBO,
        .get_variants           = e1000_get_variants_ich8lan,
index a150e48a117f2da94ff73727252263672e51bb8f..a74846097afdc8bcb52e9b20f569ae503a2da4ca 100644 (file)
@@ -161,6 +161,15 @@ E1000_PARAM(WriteProtectNVM, "Write-protect NVM [WARNING: disabling this can lea
 E1000_PARAM(CrcStripping, "Enable CRC Stripping, disable if your BMC needs " \
                           "the CRC");
 
+/*
+ * Enable/disable EEE (a.k.a. IEEE802.3az)
+ *
+ * Valid Range: 0, 1
+ *
+ * Default Value: 1
+ */
+E1000_PARAM(EEE, "Enable/disable on parts that support the feature");
+
 struct e1000_option {
        enum { enable_option, range_option, list_option } type;
        const char *name;
@@ -477,4 +486,23 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter)
                        }
                }
        }
+       { /* EEE for parts supporting the feature */
+               static const struct e1000_option opt = {
+                       .type = enable_option,
+                       .name = "EEE Support",
+                       .err  = "defaulting to Enabled",
+                       .def  = OPTION_ENABLED
+               };
+
+               if (adapter->flags2 & FLAG2_HAS_EEE) {
+                       /* Currently only supported on 82579 */
+                       if (num_EEE > bd) {
+                               unsigned int eee = EEE[bd];
+                               e1000_validate_option(&eee, &opt, adapter);
+                               hw->dev_spec.ich8lan.eee_disable = !eee;
+                       } else {
+                               hw->dev_spec.ich8lan.eee_disable = !opt.def;
+                       }
+               }
+       }
 }