Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net...
authorDavid S. Miller <davem@davemloft.net>
Wed, 28 May 2014 16:40:13 +0000 (12:40 -0400)
committerDavid S. Miller <davem@davemloft.net>
Wed, 28 May 2014 16:40:13 +0000 (12:40 -0400)
Jeff Kirsher says:

====================
Intel Wired LAN Driver Updates

This series contains updates to e1000, e1000e, ixgbe and i40evf.

Emil provides a fix for ixgbe so that non-fiber devices with MNG FW enabled
are able to link at 100Mbps.

Jacob provides several changes for ixgbe, most of which are PTP related.
Renames ixgbe_ptp_enable() to ixgbe_ptp_feature_enable() to better reflect
the functions purpose.  Extracts the hardware setup logic for the PTP
hardware bits from the ixgbe_ptp_set_ts_config() to enable future work for
the ixgbe_ptp_reset().  Maintain the hwstamp configuration through a reset
and extracts the creation of the PTP clock device from ptp_init() in order
to properly handle a suspend/resume cycle and only calls it if we don't
already have a ptp_clock pointer.

David provides a patch to expend the e1000e driver to turn on unicast
PROMISC when there is failure to write to a shared receive address register.
The fix update_phy_task() for 82579 is expanded to include newer PHYs as well
so that the dev_spec->eee_lp_ability has the correct value when going into
SX states.

Todd provides a e1000e fix an errata for 82574/82583 where it is possible
bad bits are read from SYSTIMH/L so check to see that the time is
incrementing at a reasonable rate and is a multiple of the time incremental
value.  Removes a redundant igb PHY power down register write.

Andi Kleen out of lines two write functions for e1000e to save 30k text size.

Tobias Klauser converts the e1000 and i40evf drivers to use the
is_broadcast_ether_addr() and is_multicast_ether_addr().
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
15 files changed:
drivers/net/ethernet/intel/e1000/e1000_hw.c
drivers/net/ethernet/intel/e1000e/80003es2lan.c
drivers/net/ethernet/intel/e1000e/82571.c
drivers/net/ethernet/intel/e1000e/e1000.h
drivers/net/ethernet/intel/e1000e/hw.h
drivers/net/ethernet/intel/e1000e/ich8lan.c
drivers/net/ethernet/intel/e1000e/mac.c
drivers/net/ethernet/intel/e1000e/mac.h
drivers/net/ethernet/intel/e1000e/netdev.c
drivers/net/ethernet/intel/i40evf/i40evf_main.c
drivers/net/ethernet/intel/igb/e1000_phy.c
drivers/net/ethernet/intel/igb/e1000_phy.h
drivers/net/ethernet/intel/ixgbe/ixgbe.h
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c

index c1d3fdb296a05e4f1cd86205bce12669e41ceb6b..e9b07ccc0ebaebc0b1b0993625485cae93b0b447 100644 (file)
@@ -4877,10 +4877,10 @@ void e1000_tbi_adjust_stats(struct e1000_hw *hw, struct e1000_hw_stats *stats,
         * since the test for a multicast frame will test positive on
         * a broadcast frame.
         */
-       if ((mac_addr[0] == (u8) 0xff) && (mac_addr[1] == (u8) 0xff))
+       if (is_broadcast_ether_addr(mac_addr))
                /* Broadcast packet */
                stats->bprc++;
-       else if (*mac_addr & 0x01)
+       else if (is_multicast_ether_addr(mac_addr))
                /* Multicast packet */
                stats->mprc++;
 
index a5f6b11d6992e63aa9af8da9f52540697455b2d1..08f22f348800ddd37aaf2d2d87eb4ce0e9c7f3b3 100644 (file)
@@ -1365,6 +1365,7 @@ static const struct e1000_mac_operations es2_mac_ops = {
        .setup_led              = e1000e_setup_led_generic,
        .config_collision_dist  = e1000e_config_collision_dist_generic,
        .rar_set                = e1000e_rar_set_generic,
+       .rar_get_count          = e1000e_rar_get_count_generic,
 };
 
 static const struct e1000_phy_operations es2_phy_ops = {
index e0aa7f1efb08ceb50d9049128dcbdb66f442b17d..218481e509f99f4e32deba736ae4117365c650e3 100644 (file)
@@ -1896,6 +1896,7 @@ static const struct e1000_mac_operations e82571_mac_ops = {
        .config_collision_dist  = e1000e_config_collision_dist_generic,
        .read_mac_addr          = e1000_read_mac_addr_82571,
        .rar_set                = e1000e_rar_set_generic,
+       .rar_get_count          = e1000e_rar_get_count_generic,
 };
 
 static const struct e1000_phy_operations e82_phy_ops_igp = {
index e27e60910949c95a5217cad20bfc722e35527cc5..7785240a0da1a1b409cfbc3d4b18ff63b5f2966a 100644 (file)
@@ -391,6 +391,8 @@ s32 e1000e_get_base_timinca(struct e1000_adapter *adapter, u32 *timinca);
  * 25MHz       46-bit  2^46 / 10^9 / 3600 = 19.55 hours
  */
 #define E1000_SYSTIM_OVERFLOW_PERIOD   (HZ * 60 * 60 * 4)
+#define E1000_MAX_82574_SYSTIM_REREADS 50
+#define E1000_82574_SYSTIM_EPSILON     (1ULL << 35ULL)
 
 /* hardware capability, feature, and workaround flags */
 #define FLAG_HAS_AMT                      (1 << 0)
@@ -573,35 +575,8 @@ static inline u32 __er32(struct e1000_hw *hw, unsigned long reg)
 
 #define er32(reg)      __er32(hw, E1000_##reg)
 
-/**
- * __ew32_prepare - prepare to write to MAC CSR register on certain parts
- * @hw: pointer to the HW structure
- *
- * When updating the MAC CSR registers, the Manageability Engine (ME) could
- * be accessing the registers at the same time.  Normally, this is handled in
- * h/w by an arbiter but on some parts there is a bug that acknowledges Host
- * accesses later than it should which could result in the register to have
- * an incorrect value.  Workaround this by checking the FWSM register which
- * has bit 24 set while ME is accessing MAC CSR registers, wait if it is set
- * and try again a number of times.
- **/
-static inline s32 __ew32_prepare(struct e1000_hw *hw)
-{
-       s32 i = E1000_ICH_FWSM_PCIM2PCI_COUNT;
-
-       while ((er32(FWSM) & E1000_ICH_FWSM_PCIM2PCI) && --i)
-               udelay(50);
-
-       return i;
-}
-
-static inline void __ew32(struct e1000_hw *hw, unsigned long reg, u32 val)
-{
-       if (hw->adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA)
-               __ew32_prepare(hw);
-
-       writel(val, hw->hw_addr + reg);
-}
+s32 __ew32_prepare(struct e1000_hw *hw);
+void __ew32(struct e1000_hw *hw, unsigned long reg, u32 val);
 
 #define ew32(reg, val) __ew32(hw, E1000_##reg, (val))
 
index 6b3de5f39a97862e2f5742b14a24530ba6ecc33f..72f5475c4b9093d075e608070c4415a4e0ad5afd 100644 (file)
@@ -469,8 +469,9 @@ struct e1000_mac_operations {
        s32  (*setup_led)(struct e1000_hw *);
        void (*write_vfta)(struct e1000_hw *, u32, u32);
        void (*config_collision_dist)(struct e1000_hw *);
-       void (*rar_set)(struct e1000_hw *, u8 *, u32);
+       int  (*rar_set)(struct e1000_hw *, u8 *, u32);
        s32  (*read_mac_addr)(struct e1000_hw *);
+       u32  (*rar_get_count)(struct e1000_hw *);
 };
 
 /* When to use various PHY register access functions:
index 5f55395616612d843b10a9b7f6ad0345f15344fb..8894ab8ed6bd82de2c0f720939d31a906096a12c 100644 (file)
@@ -139,8 +139,9 @@ static s32 e1000_k1_gig_workaround_hv(struct e1000_hw *hw, bool link);
 static s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw);
 static bool e1000_check_mng_mode_ich8lan(struct e1000_hw *hw);
 static bool e1000_check_mng_mode_pchlan(struct e1000_hw *hw);
-static void e1000_rar_set_pch2lan(struct e1000_hw *hw, u8 *addr, u32 index);
-static void e1000_rar_set_pch_lpt(struct e1000_hw *hw, u8 *addr, u32 index);
+static int e1000_rar_set_pch2lan(struct e1000_hw *hw, u8 *addr, u32 index);
+static int e1000_rar_set_pch_lpt(struct e1000_hw *hw, u8 *addr, u32 index);
+static u32 e1000_rar_get_count_pch_lpt(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_disable_ulp_lpt_lp(struct e1000_hw *hw, bool force);
@@ -704,6 +705,7 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw)
                mac->ops.rar_set = e1000_rar_set_pch_lpt;
                mac->ops.setup_physical_interface =
                    e1000_setup_copper_link_pch_lpt;
+               mac->ops.rar_get_count = e1000_rar_get_count_pch_lpt;
        }
 
        /* Enable PCS Lock-loss workaround for ICH8 */
@@ -1635,9 +1637,9 @@ static bool e1000_check_mng_mode_ich8lan(struct e1000_hw *hw)
        u32 fwsm;
 
        fwsm = er32(FWSM);
-       return ((fwsm & E1000_ICH_FWSM_FW_VALID) &&
+       return (fwsm & E1000_ICH_FWSM_FW_VALID) &&
                ((fwsm & E1000_FWSM_MODE_MASK) ==
-                (E1000_ICH_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT)));
+                (E1000_ICH_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT));
 }
 
 /**
@@ -1668,7 +1670,7 @@ static bool e1000_check_mng_mode_pchlan(struct e1000_hw *hw)
  *  contain the MAC address but RAR[1-6] are reserved for manageability (ME).
  *  Use SHRA[0-3] in place of those reserved for ME.
  **/
-static void e1000_rar_set_pch2lan(struct e1000_hw *hw, u8 *addr, u32 index)
+static int e1000_rar_set_pch2lan(struct e1000_hw *hw, u8 *addr, u32 index)
 {
        u32 rar_low, rar_high;
 
@@ -1690,7 +1692,7 @@ static void e1000_rar_set_pch2lan(struct e1000_hw *hw, u8 *addr, u32 index)
                e1e_flush();
                ew32(RAH(index), rar_high);
                e1e_flush();
-               return;
+               return 0;
        }
 
        /* RAR[1-6] are owned by manageability.  Skip those and program the
@@ -1713,7 +1715,7 @@ static void e1000_rar_set_pch2lan(struct e1000_hw *hw, u8 *addr, u32 index)
                /* verify the register updates */
                if ((er32(SHRAL(index - 1)) == rar_low) &&
                    (er32(SHRAH(index - 1)) == rar_high))
-                       return;
+                       return 0;
 
                e_dbg("SHRA[%d] might be locked by ME - FWSM=0x%8.8x\n",
                      (index - 1), er32(FWSM));
@@ -1721,6 +1723,43 @@ static void e1000_rar_set_pch2lan(struct e1000_hw *hw, u8 *addr, u32 index)
 
 out:
        e_dbg("Failed to write receive address at index %d\n", index);
+       return -E1000_ERR_CONFIG;
+}
+
+/**
+ *  e1000_rar_get_count_pch_lpt - Get the number of available SHRA
+ *  @hw: pointer to the HW structure
+ *
+ *  Get the number of available receive registers that the Host can
+ *  program. SHRA[0-10] are the shared receive address registers
+ *  that are shared between the Host and manageability engine (ME).
+ *  ME can reserve any number of addresses and the host needs to be
+ *  able to tell how many available registers it has access to.
+ **/
+static u32 e1000_rar_get_count_pch_lpt(struct e1000_hw *hw)
+{
+       u32 wlock_mac;
+       u32 num_entries;
+
+       wlock_mac = er32(FWSM) & E1000_FWSM_WLOCK_MAC_MASK;
+       wlock_mac >>= E1000_FWSM_WLOCK_MAC_SHIFT;
+
+       switch (wlock_mac) {
+       case 0:
+               /* All SHRA[0..10] and RAR[0] available */
+               num_entries = hw->mac.rar_entry_count;
+               break;
+       case 1:
+               /* Only RAR[0] available */
+               num_entries = 1;
+               break;
+       default:
+               /* SHRA[0..(wlock_mac - 1)] available + RAR[0] */
+               num_entries = wlock_mac + 1;
+               break;
+       }
+
+       return num_entries;
 }
 
 /**
@@ -1734,7 +1773,7 @@ out:
  *  contain the MAC address. SHRA[0-10] are the shared receive address
  *  registers that are shared between the Host and manageability engine (ME).
  **/
-static void e1000_rar_set_pch_lpt(struct e1000_hw *hw, u8 *addr, u32 index)
+static int e1000_rar_set_pch_lpt(struct e1000_hw *hw, u8 *addr, u32 index)
 {
        u32 rar_low, rar_high;
        u32 wlock_mac;
@@ -1756,7 +1795,7 @@ static void e1000_rar_set_pch_lpt(struct e1000_hw *hw, u8 *addr, u32 index)
                e1e_flush();
                ew32(RAH(index), rar_high);
                e1e_flush();
-               return;
+               return 0;
        }
 
        /* The manageability engine (ME) can lock certain SHRAR registers that
@@ -1788,12 +1827,13 @@ static void e1000_rar_set_pch_lpt(struct e1000_hw *hw, u8 *addr, u32 index)
                        /* verify the register updates */
                        if ((er32(SHRAL_PCH_LPT(index - 1)) == rar_low) &&
                            (er32(SHRAH_PCH_LPT(index - 1)) == rar_high))
-                               return;
+                               return 0;
                }
        }
 
 out:
        e_dbg("Failed to write receive address at index %d\n", index);
+       return -E1000_ERR_CONFIG;
 }
 
 /**
@@ -4977,6 +5017,7 @@ static const struct e1000_mac_operations ich8_mac_ops = {
        /* id_led_init dependent on mac type */
        .config_collision_dist  = e1000e_config_collision_dist_generic,
        .rar_set                = e1000e_rar_set_generic,
+       .rar_get_count          = e1000e_rar_get_count_generic,
 };
 
 static const struct e1000_phy_operations ich8_phy_ops = {
index baa0a466d1d05ca533999b9ffcac3846a476ab5f..8c386f3a15ebb6649e347f5316555827b151819b 100644 (file)
@@ -211,6 +211,11 @@ s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw)
        return 0;
 }
 
+u32 e1000e_rar_get_count_generic(struct e1000_hw *hw)
+{
+       return hw->mac.rar_entry_count;
+}
+
 /**
  *  e1000e_rar_set_generic - Set receive address register
  *  @hw: pointer to the HW structure
@@ -220,7 +225,7 @@ s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw)
  *  Sets the receive address array register at index to the address passed
  *  in by addr.
  **/
-void e1000e_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index)
+int e1000e_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index)
 {
        u32 rar_low, rar_high;
 
@@ -244,6 +249,8 @@ void e1000e_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index)
        e1e_flush();
        ew32(RAH(index), rar_high);
        e1e_flush();
+
+       return 0;
 }
 
 /**
index 4e81c2825b7a1ca60b9a870ce61737e29d4e7972..0513d90cdeeaa980b3fb226eaac6feebe481c4f3 100644 (file)
@@ -61,7 +61,8 @@ void e1000e_update_adaptive(struct e1000_hw *hw);
 void e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value);
 
 void e1000_set_lan_id_multi_port_pcie(struct e1000_hw *hw);
-void e1000e_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index);
+u32 e1000e_rar_get_count_generic(struct e1000_hw *hw);
+int e1000e_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index);
 void e1000e_config_collision_dist_generic(struct e1000_hw *hw);
 
 #endif
index e4207efd13f8651cf75b5ea9ba3a94a437f189a4..201cc93f36256d5776e882399d3afdf594b81192 100644 (file)
@@ -123,6 +123,36 @@ static const struct e1000_reg_info e1000_reg_info_tbl[] = {
        {0, NULL}
 };
 
+/**
+ * __ew32_prepare - prepare to write to MAC CSR register on certain parts
+ * @hw: pointer to the HW structure
+ *
+ * When updating the MAC CSR registers, the Manageability Engine (ME) could
+ * be accessing the registers at the same time.  Normally, this is handled in
+ * h/w by an arbiter but on some parts there is a bug that acknowledges Host
+ * accesses later than it should which could result in the register to have
+ * an incorrect value.  Workaround this by checking the FWSM register which
+ * has bit 24 set while ME is accessing MAC CSR registers, wait if it is set
+ * and try again a number of times.
+ **/
+s32 __ew32_prepare(struct e1000_hw *hw)
+{
+       s32 i = E1000_ICH_FWSM_PCIM2PCI_COUNT;
+
+       while ((er32(FWSM) & E1000_ICH_FWSM_PCIM2PCI) && --i)
+               udelay(50);
+
+       return i;
+}
+
+void __ew32(struct e1000_hw *hw, unsigned long reg, u32 val)
+{
+       if (hw->adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA)
+               __ew32_prepare(hw);
+
+       writel(val, hw->hw_addr + reg);
+}
+
 /**
  * e1000_regdump - register printout routine
  * @hw: pointer to the HW structure
@@ -3311,9 +3341,11 @@ static int e1000e_write_uc_addr_list(struct net_device *netdev)
 {
        struct e1000_adapter *adapter = netdev_priv(netdev);
        struct e1000_hw *hw = &adapter->hw;
-       unsigned int rar_entries = hw->mac.rar_entry_count;
+       unsigned int rar_entries;
        int count = 0;
 
+       rar_entries = hw->mac.ops.rar_get_count(hw);
+
        /* save a rar entry for our hardware address */
        rar_entries--;
 
@@ -3332,9 +3364,13 @@ static int e1000e_write_uc_addr_list(struct net_device *netdev)
                 * combining
                 */
                netdev_for_each_uc_addr(ha, netdev) {
+                       int rval;
+
                        if (!rar_entries)
                                break;
-                       hw->mac.ops.rar_set(hw, ha->addr, rar_entries--);
+                       rval = hw->mac.ops.rar_set(hw, ha->addr, rar_entries--);
+                       if (rval < 0)
+                               return -ENOMEM;
                        count++;
                }
        }
@@ -4093,12 +4129,37 @@ static cycle_t e1000e_cyclecounter_read(const struct cyclecounter *cc)
        struct e1000_adapter *adapter = container_of(cc, struct e1000_adapter,
                                                     cc);
        struct e1000_hw *hw = &adapter->hw;
-       cycle_t systim;
+       cycle_t systim, systim_next;
 
        /* latch SYSTIMH on read of SYSTIML */
        systim = (cycle_t)er32(SYSTIML);
        systim |= (cycle_t)er32(SYSTIMH) << 32;
 
+       if ((hw->mac.type == e1000_82574) || (hw->mac.type == e1000_82583)) {
+               u64 incvalue, time_delta, rem, temp;
+               int i;
+
+               /* errata for 82574/82583 possible bad bits read from SYSTIMH/L
+                * check to see that the time is incrementing at a reasonable
+                * rate and is a multiple of incvalue
+                */
+               incvalue = er32(TIMINCA) & E1000_TIMINCA_INCVALUE_MASK;
+               for (i = 0; i < E1000_MAX_82574_SYSTIM_REREADS; i++) {
+                       /* latch SYSTIMH on read of SYSTIML */
+                       systim_next = (cycle_t)er32(SYSTIML);
+                       systim_next |= (cycle_t)er32(SYSTIMH) << 32;
+
+                       time_delta = systim_next - systim;
+                       temp = time_delta;
+                       rem = do_div(temp, incvalue);
+
+                       systim = systim_next;
+
+                       if ((time_delta < E1000_82574_SYSTIM_EPSILON) &&
+                           (rem == 0))
+                               break;
+               }
+       }
        return systim;
 }
 
@@ -4499,7 +4560,7 @@ static void e1000e_update_phy_task(struct work_struct *work)
        e1000_get_phy_info(hw);
 
        /* Enable EEE on 82579 after link up */
-       if (hw->phy.type == e1000_phy_82579)
+       if (hw->phy.type >= e1000_phy_82579)
                e1000_set_eee_pchlan(hw);
 }
 
index 8dbaa779848595b103c16b19e4cfc2e8b4159475..23c9ff6698bcaf3e2d61ca0695fef11b39133ed8 100644 (file)
@@ -845,7 +845,7 @@ static void i40evf_set_rx_mode(struct net_device *netdev)
        list_for_each_entry_safe(f, ftmp, &adapter->mac_filter_list, list) {
                bool found = false;
 
-               if (f->macaddr[0] & 0x01) {
+               if (is_multicast_ether_addr(f->macaddr)) {
                        netdev_for_each_mc_addr(mca, netdev) {
                                if (ether_addr_equal(mca->addr, f->macaddr)) {
                                        found = true;
index 424f16c43759b1b787e44cb4d7c8194ec327c825..c1bb64d8366fa5e7741905ea9fc22d4b241054ce 100644 (file)
@@ -2204,16 +2204,10 @@ s32 igb_phy_init_script_igp3(struct e1000_hw *hw)
 void igb_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);
 }
 
@@ -2227,18 +2221,10 @@ void igb_power_up_phy_copper(struct e1000_hw *hw)
 void igb_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);
        usleep_range(1000, 2000);
 }
index fe921e29dda8f96a201b82d70152466c15a1da26..7af4ffab0285653c4c400992edcd163782f919ac 100644 (file)
@@ -151,7 +151,6 @@ s32  igb_check_polarity_m88(struct e1000_hw *hw);
 #define GS40G_MAC_LB                   0x4140
 #define GS40G_MAC_SPEED_1G             0X0006
 #define GS40G_COPPER_SPEC              0x0010
-#define GS40G_CS_POWER_DOWN            0x0002
 #define GS40G_LINE_LB                  0x4000
 
 /* SFP modules ID memory locations */
index 4c0203b01941d9729468caf08ac9c6a0cfb32fa7..ac9f2148cdc5ca6d20e81a43170a9550ff6ffce6 100644 (file)
@@ -957,6 +957,7 @@ static inline struct netdev_queue *txring_txq(const struct ixgbe_ring *ring)
 }
 
 void ixgbe_ptp_init(struct ixgbe_adapter *adapter);
+void ixgbe_ptp_suspend(struct ixgbe_adapter *adapter);
 void ixgbe_ptp_stop(struct ixgbe_adapter *adapter);
 void ixgbe_ptp_overflow_check(struct ixgbe_adapter *adapter);
 void ixgbe_ptp_rx_hang(struct ixgbe_adapter *adapter);
index 3d666020ea1529485764558cf03caf6c4460e483..ea11e2c8ee8cc5ce72792156013e1a0929b5b227 100644 (file)
@@ -5659,6 +5659,17 @@ err_setup_tx:
        return err;
 }
 
+static void ixgbe_close_suspend(struct ixgbe_adapter *adapter)
+{
+       ixgbe_ptp_suspend(adapter);
+
+       ixgbe_down(adapter);
+       ixgbe_free_irq(adapter);
+
+       ixgbe_free_all_tx_resources(adapter);
+       ixgbe_free_all_rx_resources(adapter);
+}
+
 /**
  * ixgbe_close - Disables a network interface
  * @netdev: network interface device structure
@@ -5676,14 +5687,10 @@ static int ixgbe_close(struct net_device *netdev)
 
        ixgbe_ptp_stop(adapter);
 
-       ixgbe_down(adapter);
-       ixgbe_free_irq(adapter);
+       ixgbe_close_suspend(adapter);
 
        ixgbe_fdir_filter_exit(adapter);
 
-       ixgbe_free_all_tx_resources(adapter);
-       ixgbe_free_all_rx_resources(adapter);
-
        ixgbe_release_hw_control(adapter);
 
        return 0;
@@ -5750,12 +5757,8 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake)
        netif_device_detach(netdev);
 
        rtnl_lock();
-       if (netif_running(netdev)) {
-               ixgbe_down(adapter);
-               ixgbe_free_irq(adapter);
-               ixgbe_free_all_tx_resources(adapter);
-               ixgbe_free_all_rx_resources(adapter);
-       }
+       if (netif_running(netdev))
+               ixgbe_close_suspend(adapter);
        rtnl_unlock();
 
        ixgbe_clear_interrupt_scheme(adapter);
@@ -8449,8 +8452,8 @@ skip_sriov:
 
        ixgbe_dbg_adapter_init(adapter);
 
-       /* Need link setup for MNG FW, else wait for IXGBE_UP */
-       if (ixgbe_mng_enabled(hw) && hw->mac.ops.setup_link)
+       /* setup link for SFP devices with MNG FW, else wait for IXGBE_UP */
+       if (ixgbe_mng_enabled(hw) && ixgbe_is_sfp(hw) && hw->mac.ops.setup_link)
                hw->mac.ops.setup_link(hw,
                        IXGBE_LINK_SPEED_10GB_FULL | IXGBE_LINK_SPEED_1GB_FULL,
                        true);
index 8902ae68345770ce5f28ba2ab91ee73bab3c7ff3..b3266b7536d50a70d210d88b0769ce042a0f26c7 100644 (file)
@@ -334,7 +334,7 @@ static int ixgbe_ptp_settime(struct ptp_clock_info *ptp,
 }
 
 /**
- * ixgbe_ptp_enable
+ * ixgbe_ptp_feature_enable
  * @ptp: the ptp clock structure
  * @rq: the requested feature to change
  * @on: whether to enable or disable the feature
@@ -342,8 +342,8 @@ static int ixgbe_ptp_settime(struct ptp_clock_info *ptp,
  * enable (or disable) ancillary features of the phc subsystem.
  * our driver only supports the PPS feature on the X540
  */
-static int ixgbe_ptp_enable(struct ptp_clock_info *ptp,
-                           struct ptp_clock_request *rq, int on)
+static int ixgbe_ptp_feature_enable(struct ptp_clock_info *ptp,
+                                   struct ptp_clock_request *rq, int on)
 {
        struct ixgbe_adapter *adapter =
                container_of(ptp, struct ixgbe_adapter, ptp_caps);
@@ -570,9 +570,9 @@ int ixgbe_ptp_get_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr)
 }
 
 /**
- * ixgbe_ptp_set_ts_config - control hardware time stamping
- * @adapter: pointer to adapter struct
- * @ifreq: ioctl data
+ * ixgbe_ptp_set_timestamp_mode - setup the hardware for the requested mode
+ * @adapter: the private ixgbe adapter structure
+ * @config: the hwtstamp configuration requested
  *
  * Outgoing time stamping can be enabled and disabled. Play nice and
  * disable it when requested, although it shouldn't cause any overhead
@@ -590,25 +590,25 @@ int ixgbe_ptp_get_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr)
  * packets, regardless of the type specified in the register, only use V2
  * Event mode. This more accurately tells the user what the hardware is going
  * to do anyways.
+ *
+ * Note: this may modify the hwtstamp configuration towards a more general
+ * mode, if required to support the specifically requested mode.
  */
-int ixgbe_ptp_set_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr)
+static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter,
+                                struct hwtstamp_config *config)
 {
        struct ixgbe_hw *hw = &adapter->hw;
-       struct hwtstamp_config config;
        u32 tsync_tx_ctl = IXGBE_TSYNCTXCTL_ENABLED;
        u32 tsync_rx_ctl = IXGBE_TSYNCRXCTL_ENABLED;
        u32 tsync_rx_mtrl = PTP_EV_PORT << 16;
        bool is_l2 = false;
        u32 regval;
 
-       if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
-               return -EFAULT;
-
        /* reserved for future extensions */
-       if (config.flags)
+       if (config->flags)
                return -EINVAL;
 
-       switch (config.tx_type) {
+       switch (config->tx_type) {
        case HWTSTAMP_TX_OFF:
                tsync_tx_ctl = 0;
        case HWTSTAMP_TX_ON:
@@ -617,7 +617,7 @@ int ixgbe_ptp_set_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr)
                return -ERANGE;
        }
 
-       switch (config.rx_filter) {
+       switch (config->rx_filter) {
        case HWTSTAMP_FILTER_NONE:
                tsync_rx_ctl = 0;
                tsync_rx_mtrl = 0;
@@ -641,7 +641,7 @@ int ixgbe_ptp_set_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr)
        case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
                tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_EVENT_V2;
                is_l2 = true;
-               config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
+               config->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
                break;
        case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
        case HWTSTAMP_FILTER_ALL:
@@ -652,7 +652,7 @@ int ixgbe_ptp_set_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr)
                 * Delay_Req messages and hardware does not support
                 * timestamping all packets => return error
                 */
-               config.rx_filter = HWTSTAMP_FILTER_NONE;
+               config->rx_filter = HWTSTAMP_FILTER_NONE;
                return -ERANGE;
        }
 
@@ -671,7 +671,6 @@ int ixgbe_ptp_set_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr)
        else
                IXGBE_WRITE_REG(hw, IXGBE_ETQF(IXGBE_ETQF_FILTER_1588), 0);
 
-
        /* enable/disable TX */
        regval = IXGBE_READ_REG(hw, IXGBE_TSYNCTXCTL);
        regval &= ~IXGBE_TSYNCTXCTL_ENABLED;
@@ -693,6 +692,29 @@ int ixgbe_ptp_set_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr)
        regval = IXGBE_READ_REG(hw, IXGBE_TXSTMPH);
        regval = IXGBE_READ_REG(hw, IXGBE_RXSTMPH);
 
+       return 0;
+}
+
+/**
+ * ixgbe_ptp_set_ts_config - user entry point for timestamp mode
+ * @adapter: pointer to adapter struct
+ * @ifreq: ioctl data
+ *
+ * Set hardware to requested mode. If unsupported, return an error with no
+ * changes. Otherwise, store the mode for future reference.
+ */
+int ixgbe_ptp_set_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr)
+{
+       struct hwtstamp_config config;
+       int err;
+
+       if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
+               return -EFAULT;
+
+       err = ixgbe_ptp_set_timestamp_mode(adapter, &config);
+       if (err)
+               return err;
+
        /* save these settings for future reference */
        memcpy(&adapter->tstamp_config, &config,
               sizeof(adapter->tstamp_config));
@@ -790,9 +812,13 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter)
  * ixgbe_ptp_reset
  * @adapter: the ixgbe private board structure
  *
- * When the MAC resets, all timesync features are reset. This function should be
- * called to re-enable the PTP clock structure. It will re-init the timecounter
- * structure based on the kernel time as well as setup the cycle counter data.
+ * When the MAC resets, all the hardware bits for timesync are reset. This
+ * function is used to re-enable the device for PTP based on current settings.
+ * We do lose the current clock time, so just reset the cyclecounter to the
+ * system real clock time.
+ *
+ * This function will maintain hwtstamp_config settings, and resets the SDP
+ * output if it was enabled.
  */
 void ixgbe_ptp_reset(struct ixgbe_adapter *adapter)
 {
@@ -804,8 +830,8 @@ void ixgbe_ptp_reset(struct ixgbe_adapter *adapter)
        IXGBE_WRITE_REG(hw, IXGBE_SYSTIMH, 0x00000000);
        IXGBE_WRITE_FLUSH(hw);
 
-       /* Reset the saved tstamp_config */
-       memset(&adapter->tstamp_config, 0, sizeof(adapter->tstamp_config));
+       /* reset the hardware timestamping mode */
+       ixgbe_ptp_set_timestamp_mode(adapter, &adapter->tstamp_config);
 
        ixgbe_ptp_start_cyclecounter(adapter);
 
@@ -825,16 +851,23 @@ void ixgbe_ptp_reset(struct ixgbe_adapter *adapter)
 }
 
 /**
- * ixgbe_ptp_init
+ * ixgbe_ptp_create_clock
  * @adapter: the ixgbe private adapter structure
  *
- * This function performs the required steps for enabling ptp
- * support. If ptp support has already been loaded it simply calls the
- * cyclecounter init routine and exits.
+ * This function performs setup of the user entry point function table and
+ * initializes the PTP clock device, which is used to access the clock-like
+ * features of the PTP core. It will be called by ixgbe_ptp_init, only if
+ * there isn't already a clock device (such as after a suspend/resume cycle,
+ * where the clock device wasn't destroyed).
  */
-void ixgbe_ptp_init(struct ixgbe_adapter *adapter)
+static int ixgbe_ptp_create_clock(struct ixgbe_adapter *adapter)
 {
        struct net_device *netdev = adapter->netdev;
+       long err;
+
+       /* do nothing if we already have a clock device */
+       if (!IS_ERR_OR_NULL(adapter->ptp_clock))
+               return 0;
 
        switch (adapter->hw.mac.type) {
        case ixgbe_mac_X540:
@@ -851,7 +884,7 @@ void ixgbe_ptp_init(struct ixgbe_adapter *adapter)
                adapter->ptp_caps.adjtime = ixgbe_ptp_adjtime;
                adapter->ptp_caps.gettime = ixgbe_ptp_gettime;
                adapter->ptp_caps.settime = ixgbe_ptp_settime;
-               adapter->ptp_caps.enable = ixgbe_ptp_enable;
+               adapter->ptp_caps.enable = ixgbe_ptp_feature_enable;
                break;
        case ixgbe_mac_82599EB:
                snprintf(adapter->ptp_caps.name,
@@ -867,24 +900,57 @@ void ixgbe_ptp_init(struct ixgbe_adapter *adapter)
                adapter->ptp_caps.adjtime = ixgbe_ptp_adjtime;
                adapter->ptp_caps.gettime = ixgbe_ptp_gettime;
                adapter->ptp_caps.settime = ixgbe_ptp_settime;
-               adapter->ptp_caps.enable = ixgbe_ptp_enable;
+               adapter->ptp_caps.enable = ixgbe_ptp_feature_enable;
                break;
        default:
                adapter->ptp_clock = NULL;
-               return;
+               return -EOPNOTSUPP;
        }
 
-       spin_lock_init(&adapter->tmreg_lock);
-       INIT_WORK(&adapter->ptp_tx_work, ixgbe_ptp_tx_hwtstamp_work);
-
        adapter->ptp_clock = ptp_clock_register(&adapter->ptp_caps,
                                                &adapter->pdev->dev);
        if (IS_ERR(adapter->ptp_clock)) {
+               err = PTR_ERR(adapter->ptp_clock);
                adapter->ptp_clock = NULL;
                e_dev_err("ptp_clock_register failed\n");
+               return err;
        } else
                e_dev_info("registered PHC device on %s\n", netdev->name);
 
+       /* set default timestamp mode to disabled here. We do this in
+        * create_clock instead of init, because we don't want to override the
+        * previous settings during a resume cycle.
+        */
+       adapter->tstamp_config.rx_filter = HWTSTAMP_FILTER_NONE;
+       adapter->tstamp_config.tx_type = HWTSTAMP_TX_OFF;
+
+       return 0;
+}
+
+/**
+ * ixgbe_ptp_init
+ * @adapter: the ixgbe private adapter structure
+ *
+ * This function performs the required steps for enabling PTP
+ * support. If PTP support has already been loaded it simply calls the
+ * cyclecounter init routine and exits.
+ */
+void ixgbe_ptp_init(struct ixgbe_adapter *adapter)
+{
+       /* initialize the spin lock first since we can't control when a user
+        * will call the entry functions once we have initialized the clock
+        * device
+        */
+       spin_lock_init(&adapter->tmreg_lock);
+
+       /* obtain a PTP device, or re-use an existing device */
+       if (ixgbe_ptp_create_clock(adapter))
+               return;
+
+       /* we have a clock so we can initialize work now */
+       INIT_WORK(&adapter->ptp_tx_work, ixgbe_ptp_tx_hwtstamp_work);
+
+       /* reset the PTP related hardware bits */
        ixgbe_ptp_reset(adapter);
 
        /* enter the IXGBE_PTP_RUNNING state */
@@ -894,28 +960,45 @@ void ixgbe_ptp_init(struct ixgbe_adapter *adapter)
 }
 
 /**
- * ixgbe_ptp_stop - disable ptp device and stop the overflow check
- * @adapter: pointer to adapter struct
+ * ixgbe_ptp_suspend - stop PTP work items
+ * @ adapter: pointer to adapter struct
  *
- * this function stops the ptp support, and cancels the delayed work.
+ * this function suspends PTP activity, and prevents more PTP work from being
+ * generated, but does not destroy the PTP clock device.
  */
-void ixgbe_ptp_stop(struct ixgbe_adapter *adapter)
+void ixgbe_ptp_suspend(struct ixgbe_adapter *adapter)
 {
        /* Leave the IXGBE_PTP_RUNNING state. */
        if (!test_and_clear_bit(__IXGBE_PTP_RUNNING, &adapter->state))
                return;
 
-       /* stop the PPS signal */
-       adapter->flags2 &= ~IXGBE_FLAG2_PTP_PPS_ENABLED;
-       ixgbe_ptp_setup_sdp(adapter);
+       /* since this might be called in suspend, we don't clear the state,
+        * but simply reset the auxiliary PPS signal control register
+        */
+       IXGBE_WRITE_REG(&adapter->hw, IXGBE_TSAUXC, 0x0);
 
+       /* ensure that we cancel any pending PTP Tx work item in progress */
        cancel_work_sync(&adapter->ptp_tx_work);
        if (adapter->ptp_tx_skb) {
                dev_kfree_skb_any(adapter->ptp_tx_skb);
                adapter->ptp_tx_skb = NULL;
                clear_bit_unlock(__IXGBE_PTP_TX_IN_PROGRESS, &adapter->state);
        }
+}
+
+/**
+ * ixgbe_ptp_stop - close the PTP device
+ * @adapter: pointer to adapter struct
+ *
+ * completely destroy the PTP device, should only be called when the device is
+ * being fully closed.
+ */
+void ixgbe_ptp_stop(struct ixgbe_adapter *adapter)
+{
+       /* first, suspend PTP activity */
+       ixgbe_ptp_suspend(adapter);
 
+       /* disable the PTP clock device */
        if (adapter->ptp_clock) {
                ptp_clock_unregister(adapter->ptp_clock);
                adapter->ptp_clock = NULL;