ixgbe/base: move phy sfp detection in a function
[dpdk.git] / lib / librte_pmd_ixgbe / ixgbe / ixgbe_82599.c
index 26ff26c..5b5f36e 100644 (file)
@@ -1,6 +1,6 @@
 /*******************************************************************************
 
-Copyright (c) 2001-2012, Intel Corporation
+Copyright (c) 2001-2014, Intel Corporation
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -36,7 +36,7 @@ POSSIBILITY OF SUCH DAMAGE.
 #include "ixgbe_api.h"
 #include "ixgbe_common.h"
 #include "ixgbe_phy.h"
-#ident "$Id: ixgbe_82599.c,v 1.301 2012/11/08 11:33:27 jtkirshe Exp $"
+#ident "$Id: ixgbe_82599.c,v 1.334 2013/12/04 22:34:00 jtkirshe Exp $"
 
 #define IXGBE_82599_MAX_TX_QUEUES 128
 #define IXGBE_82599_MAX_RX_QUEUES 128
@@ -47,7 +47,6 @@ POSSIBILITY OF SUCH DAMAGE.
 
 STATIC s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw,
                                         ixgbe_link_speed speed,
-                                        bool autoneg,
                                         bool autoneg_wait_to_complete);
 STATIC s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw);
 STATIC s32 ixgbe_read_eeprom_82599(struct ixgbe_hw *hw,
@@ -61,8 +60,12 @@ void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw)
 
        DEBUGFUNC("ixgbe_init_mac_link_ops_82599");
 
-       /* enable the laser control functions for SFP+ fiber */
-       if (mac->ops.get_media_type(hw) == ixgbe_media_type_fiber) {
+       /*
+        * enable the laser control functions for SFP+ fiber
+        * and MNG not enabled
+        */
+       if ((mac->ops.get_media_type(hw) == ixgbe_media_type_fiber) &&
+           !ixgbe_mng_enabled(hw)) {
                mac->ops.disable_tx_laser =
                                       &ixgbe_disable_tx_laser_multispeed_fiber;
                mac->ops.enable_tx_laser =
@@ -124,7 +127,7 @@ s32 ixgbe_init_phy_ops_82599(struct ixgbe_hw *hw)
                                  &ixgbe_get_copper_link_capabilities_generic;
        }
 
-       /* Set necessary function pointers based on phy type */
+       /* Set necessary function pointers based on PHY type */
        switch (hw->phy.type) {
        case ixgbe_phy_tn:
                phy->ops.setup_link = &ixgbe_setup_phy_link_tnx;
@@ -143,7 +146,6 @@ s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw)
 {
        s32 ret_val = IXGBE_SUCCESS;
        u16 list_offset, data_offset, data_value;
-       bool got_lock = false;
 
        DEBUGFUNC("ixgbe_setup_sfp_modules_82599");
 
@@ -165,44 +167,26 @@ s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw)
                        goto setup_sfp_out;
                }
 
-               hw->eeprom.ops.read(hw, ++data_offset, &data_value);
+               if (hw->eeprom.ops.read(hw, ++data_offset, &data_value))
+                       goto setup_sfp_err;
                while (data_value != 0xffff) {
                        IXGBE_WRITE_REG(hw, IXGBE_CORECTL, data_value);
                        IXGBE_WRITE_FLUSH(hw);
-                       hw->eeprom.ops.read(hw, ++data_offset, &data_value);
+                       if (hw->eeprom.ops.read(hw, ++data_offset, &data_value))
+                               goto setup_sfp_err;
                }
 
                /* Release the semaphore */
                hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM);
-               /* Delay obtaining semaphore again to allow FW access */
-               msec_delay(hw->eeprom.semaphore_delay);
-
-               /* Need SW/FW semaphore around AUTOC writes if LESM on,
-                * likewise reset_pipeline requires lock as it also writes
-                * AUTOC.
+               /* Delay obtaining semaphore again to allow FW access
+                * prot_autoc_write uses the semaphore too.
                 */
-               if (ixgbe_verify_lesm_fw_enabled_82599(hw)) {
-                       ret_val = hw->mac.ops.acquire_swfw_sync(hw,
-                                                       IXGBE_GSSR_MAC_CSR_SM);
-                       if (ret_val != IXGBE_SUCCESS) {
-                               ret_val = IXGBE_ERR_SWFW_SYNC;
-                               goto setup_sfp_out;
-                       }
-
-                       got_lock = true;
-               }
+               msec_delay(hw->eeprom.semaphore_delay);
 
                /* Restart DSP and set SFI mode */
-               IXGBE_WRITE_REG(hw, IXGBE_AUTOC, (IXGBE_READ_REG(hw,
-                               IXGBE_AUTOC) | IXGBE_AUTOC_LMS_10G_SERIAL));
-
-               ret_val = ixgbe_reset_pipeline_82599(hw);
-
-               if (got_lock) {
-                       hw->mac.ops.release_swfw_sync(hw,
-                                                     IXGBE_GSSR_MAC_CSR_SM);
-                       got_lock = false;
-               }
+               ret_val = hw->mac.ops.prot_autoc_write(hw,
+                       hw->mac.orig_autoc | IXGBE_AUTOC_LMS_10G_SERIAL,
+                       false);
 
                if (ret_val) {
                        DEBUGOUT("sfp module setup not complete\n");
@@ -214,6 +198,88 @@ s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw)
 
 setup_sfp_out:
        return ret_val;
+
+setup_sfp_err:
+       /* Release the semaphore */
+       hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM);
+       /* Delay obtaining semaphore again to allow FW access */
+       msec_delay(hw->eeprom.semaphore_delay);
+       ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE,
+                     "eeprom read at offset %d failed", data_offset);
+       return IXGBE_ERR_PHY;
+}
+
+/**
+ *  prot_autoc_read_82599 - Hides MAC differences needed for AUTOC read
+ *  @hw: pointer to hardware structure
+ *  @locked: Return the if we locked for this read.
+ *  @reg_val: Value we read from AUTOC
+ *
+ *  For this part (82599) we need to wrap read-modify-writes with a possible
+ *  FW/SW lock.  It is assumed this lock will be freed with the next
+ *  prot_autoc_write_82599().
+ */
+s32 prot_autoc_read_82599(struct ixgbe_hw *hw, bool *locked, u32 *reg_val)
+{
+       s32 ret_val;
+
+       *locked = false;
+        /* If LESM is on then we need to hold the SW/FW semaphore. */
+       if (ixgbe_verify_lesm_fw_enabled_82599(hw)) {
+               ret_val = hw->mac.ops.acquire_swfw_sync(hw,
+                                       IXGBE_GSSR_MAC_CSR_SM);
+               if (ret_val != IXGBE_SUCCESS)
+                       return IXGBE_ERR_SWFW_SYNC;
+
+               *locked = true;
+       }
+
+       *reg_val = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+       return IXGBE_SUCCESS;
+}
+
+/**
+ * prot_autoc_write_82599 - Hides MAC differences needed for AUTOC write
+ * @hw: pointer to hardware structure
+ * @reg_val: value to write to AUTOC
+ * @locked: bool to indicate whether the SW/FW lock was already taken by
+ *           previous proc_autoc_read_82599.
+ *
+ * This part (82599) may need to hold the SW/FW lock around all writes to
+ * AUTOC. Likewise after a write we need to do a pipeline reset.
+ */
+s32 prot_autoc_write_82599(struct ixgbe_hw *hw, u32 autoc, bool locked)
+{
+       s32 ret_val = IXGBE_SUCCESS;
+
+       /* Blocked by MNG FW so bail */
+       if (ixgbe_check_reset_blocked(hw))
+               goto out;
+
+       /* We only need to get the lock if:
+        *  - We didn't do it already (in the read part of a read-modify-write)
+        *  - LESM is enabled.
+        */
+       if (!locked && ixgbe_verify_lesm_fw_enabled_82599(hw)) {
+               ret_val = hw->mac.ops.acquire_swfw_sync(hw,
+                                       IXGBE_GSSR_MAC_CSR_SM);
+               if (ret_val != IXGBE_SUCCESS)
+                       return IXGBE_ERR_SWFW_SYNC;
+
+               locked = true;
+       }
+
+       IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc);
+       ret_val = ixgbe_reset_pipeline_82599(hw);
+
+out:
+       /* Free the SW/FW semaphore as we either grabbed it here or
+        * already had it when this function was called.
+        */
+       if (locked)
+               hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM);
+
+       return ret_val;
 }
 
 /**
@@ -233,7 +299,7 @@ s32 ixgbe_init_ops_82599(struct ixgbe_hw *hw)
 
        DEBUGFUNC("ixgbe_init_ops_82599");
 
-       ret_val = ixgbe_init_phy_ops_generic(hw);
+       ixgbe_init_phy_ops_generic(hw);
        ret_val = ixgbe_init_ops_generic(hw);
 
        /* PHY */
@@ -257,6 +323,8 @@ s32 ixgbe_init_ops_82599(struct ixgbe_hw *hw)
        mac->ops.get_device_caps = &ixgbe_get_device_caps_generic;
        mac->ops.get_wwn_prefix = &ixgbe_get_wwn_prefix_generic;
        mac->ops.get_fcoe_boot_status = &ixgbe_get_fcoe_boot_status_generic;
+       mac->ops.prot_autoc_read = &prot_autoc_read_82599;
+       mac->ops.prot_autoc_write = &prot_autoc_write_82599;
 
        /* RAR, Multicast, VLAN */
        mac->ops.set_vmdq = &ixgbe_set_vmdq_generic;
@@ -299,6 +367,8 @@ s32 ixgbe_init_ops_82599(struct ixgbe_hw *hw)
        mac->ops.set_fw_drv_ver = &ixgbe_set_fw_drv_ver_generic;
 
 
+       mac->ops.get_rtrup2tc = &ixgbe_dcb_get_rtrup2tc_generic;
+
        return ret_val;
 }
 
@@ -306,13 +376,13 @@ s32 ixgbe_init_ops_82599(struct ixgbe_hw *hw)
  *  ixgbe_get_link_capabilities_82599 - Determines link capabilities
  *  @hw: pointer to hardware structure
  *  @speed: pointer to link speed
- *  @negotiation: true when autoneg or autotry is enabled
+ *  @autoneg: true when autoneg or autotry is enabled
  *
  *  Determines the link capabilities by reading the AUTOC register.
  **/
 s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw,
                                      ixgbe_link_speed *speed,
-                                     bool *negotiation)
+                                     bool *autoneg)
 {
        s32 status = IXGBE_SUCCESS;
        u32 autoc = 0;
@@ -323,10 +393,14 @@ s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw,
        /* Check if 1G SFP module. */
        if (hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0 ||
            hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1 ||
+#ifdef SUPPORT_1000BASE_LX
+           hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core0 ||
+           hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core1 ||
+#endif
            hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 ||
            hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1) {
                *speed = IXGBE_LINK_SPEED_1GB_FULL;
-               *negotiation = true;
+               *autoneg = true;
                goto out;
        }
 
@@ -343,22 +417,22 @@ s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw,
        switch (autoc & IXGBE_AUTOC_LMS_MASK) {
        case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
                *speed = IXGBE_LINK_SPEED_1GB_FULL;
-               *negotiation = false;
+               *autoneg = false;
                break;
 
        case IXGBE_AUTOC_LMS_10G_LINK_NO_AN:
                *speed = IXGBE_LINK_SPEED_10GB_FULL;
-               *negotiation = false;
+               *autoneg = false;
                break;
 
        case IXGBE_AUTOC_LMS_1G_AN:
                *speed = IXGBE_LINK_SPEED_1GB_FULL;
-               *negotiation = true;
+               *autoneg = true;
                break;
 
        case IXGBE_AUTOC_LMS_10G_SERIAL:
                *speed = IXGBE_LINK_SPEED_10GB_FULL;
-               *negotiation = false;
+               *autoneg = false;
                break;
 
        case IXGBE_AUTOC_LMS_KX4_KX_KR:
@@ -370,7 +444,7 @@ s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw,
                        *speed |= IXGBE_LINK_SPEED_10GB_FULL;
                if (autoc & IXGBE_AUTOC_KX_SUPP)
                        *speed |= IXGBE_LINK_SPEED_1GB_FULL;
-               *negotiation = true;
+               *autoneg = true;
                break;
 
        case IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII:
@@ -381,12 +455,12 @@ s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw,
                        *speed |= IXGBE_LINK_SPEED_10GB_FULL;
                if (autoc & IXGBE_AUTOC_KX_SUPP)
                        *speed |= IXGBE_LINK_SPEED_1GB_FULL;
-               *negotiation = true;
+               *autoneg = true;
                break;
 
        case IXGBE_AUTOC_LMS_SGMII_1G_100M:
                *speed = IXGBE_LINK_SPEED_1GB_FULL | IXGBE_LINK_SPEED_100_FULL;
-               *negotiation = false;
+               *autoneg = false;
                break;
 
        default:
@@ -398,7 +472,8 @@ s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw,
        if (hw->phy.multispeed_fiber) {
                *speed |= IXGBE_LINK_SPEED_10GB_FULL |
                          IXGBE_LINK_SPEED_1GB_FULL;
-               *negotiation = true;
+
+               *autoneg = true;
        }
 
 out:
@@ -443,9 +518,6 @@ enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw)
        case IXGBE_DEV_ID_82599_SFP_SF2:
        case IXGBE_DEV_ID_82599_SFP_SF_QP:
        case IXGBE_DEV_ID_82599EN_SFP:
-#ifdef RTE_NIC_BYPASS 
-       case IXGBE_DEV_ID_82599_BYPASS:
-#endif
                media_type = ixgbe_media_type_fiber;
                break;
        case IXGBE_DEV_ID_82599_CX4:
@@ -462,6 +534,33 @@ out:
        return media_type;
 }
 
+/**
+ *  ixgbe_stop_mac_link_on_d3_82599 - Disables link on D3
+ *  @hw: pointer to hardware structure
+ *
+ *  Disables link during D3 power down sequence.
+ *
+ **/
+void ixgbe_stop_mac_link_on_d3_82599(struct ixgbe_hw *hw)
+{
+       u32 autoc2_reg, fwsm;
+       u16 ee_ctrl_2 = 0;
+
+       DEBUGFUNC("ixgbe_stop_mac_link_on_d3_82599");
+       ixgbe_read_eeprom(hw, IXGBE_EEPROM_CTRL_2, &ee_ctrl_2);
+
+       /* Check to see if MNG FW could be enabled */
+       fwsm = IXGBE_READ_REG(hw, IXGBE_FWSM);
+
+       if (((fwsm & IXGBE_FWSM_MODE_MASK) != IXGBE_FWSM_FW_MODE_PT) &&
+           !hw->wol_enabled &&
+           ee_ctrl_2 & IXGBE_EEPROM_CCD_BIT) {
+               autoc2_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC2);
+               autoc2_reg |= IXGBE_AUTOC2_LINK_DISABLE_ON_D3_MASK;
+               IXGBE_WRITE_REG(hw, IXGBE_AUTOC2, autoc2_reg);
+       }
+}
+
 /**
  *  ixgbe_start_mac_link_82599 - Setup MAC link settings
  *  @hw: pointer to hardware structure
@@ -542,7 +641,11 @@ void ixgbe_disable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw)
 {
        u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP);
 
-       /* Disable tx laser; allow 100us to go dark per spec */
+       /* Blocked by MNG FW so bail */
+       if (ixgbe_check_reset_blocked(hw))
+               return;
+
+       /* Disable Tx laser; allow 100us to go dark per spec */
        esdp_reg |= IXGBE_ESDP_SDP3;
        IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
        IXGBE_WRITE_FLUSH(hw);
@@ -561,7 +664,7 @@ void ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw)
 {
        u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP);
 
-       /* Enable tx laser; allow 100ms to light up */
+       /* Enable Tx laser; allow 100ms to light up */
        esdp_reg &= ~IXGBE_ESDP_SDP3;
        IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
        IXGBE_WRITE_FLUSH(hw);
@@ -575,7 +678,7 @@ void ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw)
  *  When the driver changes the link speeds that it can support,
  *  it sets autotry_restart to true to indicate that we need to
  *  initiate a new autotry session with the link partner.  To do
- *  so, we set the speed then disable and re-enable the tx laser, to
+ *  so, we set the speed then disable and re-enable the Tx laser, to
  *  alert the link partner that it also needs to restart autotry on its
  *  end.  This is consistent with true clause 37 autoneg, which also
  *  involves a loss of signal.
@@ -584,6 +687,10 @@ void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw)
 {
        DEBUGFUNC("ixgbe_flap_tx_laser_multispeed_fiber");
 
+       /* Blocked by MNG FW so bail */
+       if (ixgbe_check_reset_blocked(hw))
+               return;
+
        if (hw->mac.autotry_restart) {
                ixgbe_disable_tx_laser_multispeed_fiber(hw);
                ixgbe_enable_tx_laser_multispeed_fiber(hw);
@@ -591,17 +698,17 @@ void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw)
        }
 }
 
+
 /**
  *  ixgbe_setup_mac_link_multispeed_fiber - Set MAC link speed
  *  @hw: pointer to hardware structure
  *  @speed: new link speed
- *  @autoneg: true if autonegotiation enabled
  *  @autoneg_wait_to_complete: true when waiting for completion is needed
  *
  *  Set the link speed in the AUTOC register and restarts link.
  **/
 s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
-                                    ixgbe_link_speed speed, bool autoneg,
+                                    ixgbe_link_speed speed,
                                     bool autoneg_wait_to_complete)
 {
        s32 status = IXGBE_SUCCESS;
@@ -610,13 +717,12 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
        u32 speedcnt = 0;
        u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP);
        u32 i = 0;
-       bool link_up = false;
-       bool negotiation;
+       bool autoneg, link_up = false;
 
        DEBUGFUNC("ixgbe_setup_mac_link_multispeed_fiber");
 
        /* Mask off requested but non-supported speeds */
-       status = ixgbe_get_link_capabilities(hw, &link_speed, &negotiation);
+       status = ixgbe_get_link_capabilities(hw, &link_speed, &autoneg);
        if (status != IXGBE_SUCCESS)
                return status;
 
@@ -639,16 +745,22 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
                        goto out;
 
                /* Set the module link speed */
-               esdp_reg |= (IXGBE_ESDP_SDP5_DIR | IXGBE_ESDP_SDP5);
-               IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
-               IXGBE_WRITE_FLUSH(hw);
+               switch (hw->phy.media_type) {
+               case ixgbe_media_type_fiber:
+                       esdp_reg |= (IXGBE_ESDP_SDP5_DIR | IXGBE_ESDP_SDP5);
+                       IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
+                       IXGBE_WRITE_FLUSH(hw);
+                       break;
+               default:
+                       DEBUGOUT("Unexpected media type.\n");
+                       break;
+               }
 
                /* Allow module to change analog characteristics (1G->10G) */
                msec_delay(40);
 
                status = ixgbe_setup_mac_link_82599(hw,
                                                    IXGBE_LINK_SPEED_10GB_FULL,
-                                                   autoneg,
                                                    autoneg_wait_to_complete);
                if (status != IXGBE_SUCCESS)
                        return status;
@@ -690,22 +802,28 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
                        goto out;
 
                /* Set the module link speed */
-               esdp_reg &= ~IXGBE_ESDP_SDP5;
-               esdp_reg |= IXGBE_ESDP_SDP5_DIR;
-               IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
-               IXGBE_WRITE_FLUSH(hw);
+               switch (hw->phy.media_type) {
+               case ixgbe_media_type_fiber:
+                       esdp_reg &= ~IXGBE_ESDP_SDP5;
+                       esdp_reg |= IXGBE_ESDP_SDP5_DIR;
+                       IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
+                       IXGBE_WRITE_FLUSH(hw);
+                       break;
+               default:
+                       DEBUGOUT("Unexpected media type.\n");
+                       break;
+               }
 
                /* Allow module to change analog characteristics (10G->1G) */
                msec_delay(40);
 
                status = ixgbe_setup_mac_link_82599(hw,
                                                    IXGBE_LINK_SPEED_1GB_FULL,
-                                                   autoneg,
                                                    autoneg_wait_to_complete);
                if (status != IXGBE_SUCCESS)
                        return status;
 
-               /* Flap the tx laser if it has not already been done */
+               /* Flap the Tx laser if it has not already been done */
                ixgbe_flap_tx_laser(hw);
 
                /* Wait for the link partner to also set speed */
@@ -727,7 +845,7 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
         */
        if (speedcnt > 1)
                status = ixgbe_setup_mac_link_multispeed_fiber(hw,
-                       highest_link_speed, autoneg, autoneg_wait_to_complete);
+                       highest_link_speed, autoneg_wait_to_complete);
 
 out:
        /* Set autoneg_advertised value based on input link speed */
@@ -746,13 +864,12 @@ out:
  *  ixgbe_setup_mac_link_smartspeed - Set MAC link speed using SmartSpeed
  *  @hw: pointer to hardware structure
  *  @speed: new link speed
- *  @autoneg: true if autonegotiation enabled
  *  @autoneg_wait_to_complete: true when waiting for completion is needed
  *
  *  Implements the Intel SmartSpeed algorithm.
  **/
 s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw,
-                                   ixgbe_link_speed speed, bool autoneg,
+                                   ixgbe_link_speed speed,
                                    bool autoneg_wait_to_complete)
 {
        s32 status = IXGBE_SUCCESS;
@@ -785,7 +902,7 @@ s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw,
        /* First, try to get link with full advertisement */
        hw->phy.smart_speed_active = false;
        for (j = 0; j < IXGBE_SMARTSPEED_MAX_RETRIES; j++) {
-               status = ixgbe_setup_mac_link_82599(hw, speed, autoneg,
+               status = ixgbe_setup_mac_link_82599(hw, speed,
                                                    autoneg_wait_to_complete);
                if (status != IXGBE_SUCCESS)
                        goto out;
@@ -820,7 +937,7 @@ s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw,
 
        /* Turn SmartSpeed on to disable KR support */
        hw->phy.smart_speed_active = true;
-       status = ixgbe_setup_mac_link_82599(hw, speed, autoneg,
+       status = ixgbe_setup_mac_link_82599(hw, speed,
                                            autoneg_wait_to_complete);
        if (status != IXGBE_SUCCESS)
                goto out;
@@ -845,7 +962,7 @@ s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw,
 
        /* We didn't get link.  Turn SmartSpeed back off. */
        hw->phy.smart_speed_active = false;
-       status = ixgbe_setup_mac_link_82599(hw, speed, autoneg,
+       status = ixgbe_setup_mac_link_82599(hw, speed,
                                            autoneg_wait_to_complete);
 
 out:
@@ -859,27 +976,25 @@ out:
  *  ixgbe_setup_mac_link_82599 - Set MAC link speed
  *  @hw: pointer to hardware structure
  *  @speed: new link speed
- *  @autoneg: true if autonegotiation enabled
  *  @autoneg_wait_to_complete: true when waiting for completion is needed
  *
  *  Set the link speed in the AUTOC register and restarts link.
  **/
 s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw,
-                              ixgbe_link_speed speed, bool autoneg,
+                              ixgbe_link_speed speed,
                               bool autoneg_wait_to_complete)
 {
+       bool autoneg = false;
        s32 status = IXGBE_SUCCESS;
-       u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+       u32 pma_pmd_1g, link_mode;
+       u32 current_autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC); /* holds the value of AUTOC register at this current point in time */
+       u32 orig_autoc = 0; /* holds the cached value of AUTOC register */
+       u32 autoc = current_autoc; /* Temporary variable used for comparison purposes */
        u32 autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2);
-       u32 start_autoc = autoc;
-       u32 orig_autoc = 0;
-       u32 link_mode = autoc & IXGBE_AUTOC_LMS_MASK;
-       u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK;
        u32 pma_pmd_10g_serial = autoc2 & IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_MASK;
        u32 links_reg;
        u32 i;
        ixgbe_link_speed link_capabilities = IXGBE_LINK_SPEED_UNKNOWN;
-       bool got_lock = false;
 
        DEBUGFUNC("ixgbe_setup_mac_link_82599");
 
@@ -901,6 +1016,9 @@ s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw,
        else
                orig_autoc = autoc;
 
+       link_mode = autoc & IXGBE_AUTOC_LMS_MASK;
+       pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK;
+
        if (link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR ||
            link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN ||
            link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII) {
@@ -937,31 +1055,11 @@ s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw,
                }
        }
 
-       if (autoc != start_autoc) {
-               /* Need SW/FW semaphore around AUTOC writes if LESM is on,
-                * likewise reset_pipeline requires us to hold this lock as
-                * it also writes to AUTOC.
-                */
-               if (ixgbe_verify_lesm_fw_enabled_82599(hw)) {
-                       status = hw->mac.ops.acquire_swfw_sync(hw,
-                                                       IXGBE_GSSR_MAC_CSR_SM);
-                       if (status != IXGBE_SUCCESS) {
-                               status = IXGBE_ERR_SWFW_SYNC;
-                               goto out;
-                       }
-
-                       got_lock = true;
-               }
-
+       if (autoc != current_autoc) {
                /* Restart link */
-               IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc);
-               ixgbe_reset_pipeline_82599(hw);
-
-               if (got_lock) {
-                       hw->mac.ops.release_swfw_sync(hw,
-                                                     IXGBE_GSSR_MAC_CSR_SM);
-                       got_lock = false;
-               }
+               status = hw->mac.ops.prot_autoc_write(hw, autoc, false);
+               if (status != IXGBE_SUCCESS)
+                       goto out;
 
                /* Only poll for autoneg to complete if specified to do so */
                if (autoneg_wait_to_complete) {
@@ -996,14 +1094,12 @@ out:
  *  ixgbe_setup_copper_link_82599 - Set the PHY autoneg advertised field
  *  @hw: pointer to hardware structure
  *  @speed: new link speed
- *  @autoneg: true if autonegotiation enabled
  *  @autoneg_wait_to_complete: true if waiting is needed to complete
  *
  *  Restarts link on PHY and MAC based on settings passed in.
  **/
 STATIC s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw,
                                         ixgbe_link_speed speed,
-                                        bool autoneg,
                                         bool autoneg_wait_to_complete)
 {
        s32 status;
@@ -1011,7 +1107,7 @@ STATIC s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw,
        DEBUGFUNC("ixgbe_setup_copper_link_82599");
 
        /* Setup the PHY according to input speed */
-       status = hw->phy.ops.setup_link_speed(hw, speed, autoneg,
+       status = hw->phy.ops.setup_link_speed(hw, speed,
                                              autoneg_wait_to_complete);
        /* Set up MAC */
        ixgbe_start_mac_link_82599(hw, autoneg_wait_to_complete);
@@ -1031,7 +1127,9 @@ s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw)
 {
        ixgbe_link_speed link_speed;
        s32 status;
-       u32 ctrl, i, autoc, autoc2;
+       u32 ctrl = 0;
+       u32 i, autoc, autoc2;
+       u32 curr_lms;
        bool link_up = false;
 
        DEBUGFUNC("ixgbe_reset_hw_82599");
@@ -1065,6 +1163,9 @@ s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw)
        if (hw->phy.reset_disable == false && hw->phy.ops.reset != NULL)
                hw->phy.ops.reset(hw);
 
+       /* remember AUTOC from before we reset */
+       curr_lms = IXGBE_READ_REG(hw, IXGBE_AUTOC) & IXGBE_AUTOC_LMS_MASK;
+
 mac_reset_top:
        /*
         * Issue global reset to the MAC.  Needs to be SW reset if link is up.
@@ -1128,29 +1229,25 @@ mac_reset_top:
                hw->mac.orig_autoc2 = autoc2;
                hw->mac.orig_link_settings_stored = true;
        } else {
-               if (autoc != hw->mac.orig_autoc) {
-                       /* Need SW/FW semaphore around AUTOC writes if LESM is
-                        * on, likewise reset_pipeline requires us to hold
-                        * this lock as it also writes to AUTOC.
-                        */
-                       bool got_lock = false;
-                       if (ixgbe_verify_lesm_fw_enabled_82599(hw)) {
-                               status = hw->mac.ops.acquire_swfw_sync(hw,
-                                                       IXGBE_GSSR_MAC_CSR_SM);
-                               if (status != IXGBE_SUCCESS) {
-                                       status = IXGBE_ERR_SWFW_SYNC;
-                                       goto reset_hw_out;
-                               }
-
-                               got_lock = true;
-                       }
 
-                       IXGBE_WRITE_REG(hw, IXGBE_AUTOC, hw->mac.orig_autoc);
-                       ixgbe_reset_pipeline_82599(hw);
+               /* If MNG FW is running on a multi-speed device that
+                * doesn't autoneg with out driver support we need to
+                * leave LMS in the state it was before we MAC reset.
+                * Likewise if we support WoL we don't want change the
+                * LMS state.
+                */
+               if ((hw->phy.multispeed_fiber && ixgbe_mng_enabled(hw)) ||
+                   hw->wol_enabled)
+                       hw->mac.orig_autoc =
+                               (hw->mac.orig_autoc & ~IXGBE_AUTOC_LMS_MASK) |
+                               curr_lms;
 
-                       if (got_lock)
-                               hw->mac.ops.release_swfw_sync(hw,
-                                                     IXGBE_GSSR_MAC_CSR_SM);
+               if (autoc != hw->mac.orig_autoc) {
+                       status = hw->mac.ops.prot_autoc_write(hw,
+                                                       hw->mac.orig_autoc,
+                                                       false);
+                       if (status != IXGBE_SUCCESS)
+                               goto reset_hw_out;
                }
 
                if ((autoc2 & IXGBE_AUTOC2_UPPER_MASK) !=
@@ -1196,12 +1293,31 @@ reset_hw_out:
        return status;
 }
 
+/**
+ * ixgbe_fdir_check_cmd_complete - poll to check whether FDIRCMD is complete
+ * @hw: pointer to hardware structure
+ */
+STATIC s32 ixgbe_fdir_check_cmd_complete(struct ixgbe_hw *hw)
+{
+       int i;
+
+       for (i = 0; i < IXGBE_FDIRCMD_CMD_POLL; i++) {
+               if (!(IXGBE_READ_REG(hw, IXGBE_FDIRCMD) &
+                     IXGBE_FDIRCMD_CMD_MASK))
+                       return IXGBE_SUCCESS;
+               usec_delay(10);
+       }
+
+       return IXGBE_ERR_FDIR_CMD_INCOMPLETE;
+}
+
 /**
  *  ixgbe_reinit_fdir_tables_82599 - Reinitialize Flow Director tables.
  *  @hw: pointer to hardware structure
  **/
 s32 ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw)
 {
+       s32 err;
        int i;
        u32 fdirctrl = IXGBE_READ_REG(hw, IXGBE_FDIRCTRL);
        fdirctrl &= ~IXGBE_FDIRCTRL_INIT_DONE;
@@ -1212,16 +1328,10 @@ s32 ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw)
         * Before starting reinitialization process,
         * FDIRCMD.CMD must be zero.
         */
-       for (i = 0; i < IXGBE_FDIRCMD_CMD_POLL; i++) {
-               if (!(IXGBE_READ_REG(hw, IXGBE_FDIRCMD) &
-                     IXGBE_FDIRCMD_CMD_MASK))
-                       break;
-               usec_delay(10);
-       }
-       if (i >= IXGBE_FDIRCMD_CMD_POLL) {
-               DEBUGOUT("Flow Director previous command isn't complete, "
-                        "aborting table re-initialization.\n");
-               return IXGBE_ERR_FDIR_REINIT_FAILED;
+       err = ixgbe_fdir_check_cmd_complete(hw);
+       if (err) {
+               DEBUGOUT("Flow Director previous command did not complete, aborting table re-initialization.\n");
+               return err;
        }
 
        IXGBE_WRITE_REG(hw, IXGBE_FDIRFREE, 0);
@@ -1345,8 +1455,10 @@ s32 ixgbe_init_fdir_signature_82599(struct ixgbe_hw *hw, u32 fdirctrl)
  *  @hw: pointer to hardware structure
  *  @fdirctrl: value to write to flow director control register, initially
  *          contains just the value of the Rx packet buffer allocation
+ *  @cloud_mode: true - cloud mode, false - other mode
  **/
-s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 fdirctrl)
+s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 fdirctrl,
+                       bool cloud_mode)
 {
        DEBUGFUNC("ixgbe_init_fdir_perfect_82599");
 
@@ -1395,14 +1507,14 @@ do { \
                bucket_hash ^= hi_hash_dword >> n; \
        else if (IXGBE_ATR_SIGNATURE_HASH_KEY & (0x01 << (n + 16))) \
                sig_hash ^= hi_hash_dword << (16 - n); \
-} while (0);
+} while (0)
 
 /**
  *  ixgbe_atr_compute_sig_hash_82599 - Compute the signature hash
  *  @stream: input bitstream to compute the hash on
  *
  *  This function is almost identical to the function above but contains
- *  several optomizations such as unwinding all of the loops, letting the
+ *  several optimizations such as unwinding all of the loops, letting the
  *  compiler work out all of the conditional ifs since the keys are static
  *  defines, and computing two keys at once since the hashed dword stream
  *  will be the same for both keys.
@@ -1431,7 +1543,7 @@ u32 ixgbe_atr_compute_sig_hash_82599(union ixgbe_atr_hash_dword input,
        /*
         * apply flow ID/VM pool/VLAN ID bits to lo hash dword, we had to
         * delay this because bit 0 of the stream should not be processed
-        * so we do not add the vlan until after bit 0 was processed
+        * so we do not add the VLAN until after bit 0 was processed
         */
        lo_hash_dword ^= flow_vm_vlan ^ (flow_vm_vlan << 16);
 
@@ -1475,8 +1587,9 @@ s32 ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw,
                                          union ixgbe_atr_hash_dword common,
                                          u8 queue)
 {
-       u64  fdirhashcmd;
-       u32  fdircmd;
+       u64 fdirhashcmd;
+       u32 fdircmd;
+       s32 err;
 
        DEBUGFUNC("ixgbe_fdir_add_signature_filter_82599");
 
@@ -1512,6 +1625,12 @@ s32 ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw,
        fdirhashcmd |= ixgbe_atr_compute_sig_hash_82599(input, common);
        IXGBE_WRITE_REG64(hw, IXGBE_FDIRHASH, fdirhashcmd);
 
+       err = ixgbe_fdir_check_cmd_complete(hw);
+       if (err) {
+               DEBUGOUT("Flow Director command did not complete!\n");
+               return err;
+       }
+
        DEBUGOUT2("Tx Queue=%x hash=%x\n", queue, (u32)fdirhashcmd);
 
        return IXGBE_SUCCESS;
@@ -1524,14 +1643,14 @@ do { \
                bucket_hash ^= lo_hash_dword >> n; \
        if (IXGBE_ATR_BUCKET_HASH_KEY & (0x01 << (n + 16))) \
                bucket_hash ^= hi_hash_dword >> n; \
-} while (0);
+} while (0)
 
 /**
  *  ixgbe_atr_compute_perfect_hash_82599 - Compute the perfect filter hash
  *  @atr_input: input bitstream to compute the hash on
  *  @input_mask: mask for the input bitstream
  *
- *  This function serves two main purposes.  First it applys the input_mask
+ *  This function serves two main purposes.  First it applies the input_mask
  *  to the atr_input resulting in a cleaned up atr_input data stream.
  *  Secondly it computes the hash and stores it in the bkt_hash field at
  *  the end of the input byte stream.  This way it will be available for
@@ -1543,34 +1662,20 @@ void ixgbe_atr_compute_perfect_hash_82599(union ixgbe_atr_input *input,
 
        u32 hi_hash_dword, lo_hash_dword, flow_vm_vlan;
        u32 bucket_hash = 0;
+       u32 hi_dword = 0;
+       u32 i = 0;
 
        /* Apply masks to input data */
-       input->dword_stream[0]  &= input_mask->dword_stream[0];
-       input->dword_stream[1]  &= input_mask->dword_stream[1];
-       input->dword_stream[2]  &= input_mask->dword_stream[2];
-       input->dword_stream[3]  &= input_mask->dword_stream[3];
-       input->dword_stream[4]  &= input_mask->dword_stream[4];
-       input->dword_stream[5]  &= input_mask->dword_stream[5];
-       input->dword_stream[6]  &= input_mask->dword_stream[6];
-       input->dword_stream[7]  &= input_mask->dword_stream[7];
-       input->dword_stream[8]  &= input_mask->dword_stream[8];
-       input->dword_stream[9]  &= input_mask->dword_stream[9];
-       input->dword_stream[10] &= input_mask->dword_stream[10];
+       for (i = 0; i < 14; i++)
+               input->dword_stream[i]  &= input_mask->dword_stream[i];
 
        /* record the flow_vm_vlan bits as they are a key part to the hash */
        flow_vm_vlan = IXGBE_NTOHL(input->dword_stream[0]);
 
        /* generate common hash dword */
-       hi_hash_dword = IXGBE_NTOHL(input->dword_stream[1] ^
-                                   input->dword_stream[2] ^
-                                   input->dword_stream[3] ^
-                                   input->dword_stream[4] ^
-                                   input->dword_stream[5] ^
-                                   input->dword_stream[6] ^
-                                   input->dword_stream[7] ^
-                                   input->dword_stream[8] ^
-                                   input->dword_stream[9] ^
-                                   input->dword_stream[10]);
+       for (i = 1; i <= 13; i++)
+               hi_dword ^= input->dword_stream[i];
+       hi_hash_dword = IXGBE_NTOHL(hi_dword);
 
        /* low dword is word swapped version of common */
        lo_hash_dword = (hi_hash_dword >> 16) | (hi_hash_dword << 16);
@@ -1584,26 +1689,13 @@ void ixgbe_atr_compute_perfect_hash_82599(union ixgbe_atr_input *input,
        /*
         * apply flow ID/VM pool/VLAN ID bits to lo hash dword, we had to
         * delay this because bit 0 of the stream should not be processed
-        * so we do not add the vlan until after bit 0 was processed
+        * so we do not add the VLAN until after bit 0 was processed
         */
        lo_hash_dword ^= flow_vm_vlan ^ (flow_vm_vlan << 16);
 
        /* Process remaining 30 bit of the key */
-       IXGBE_COMPUTE_BKT_HASH_ITERATION(1);
-       IXGBE_COMPUTE_BKT_HASH_ITERATION(2);
-       IXGBE_COMPUTE_BKT_HASH_ITERATION(3);
-       IXGBE_COMPUTE_BKT_HASH_ITERATION(4);
-       IXGBE_COMPUTE_BKT_HASH_ITERATION(5);
-       IXGBE_COMPUTE_BKT_HASH_ITERATION(6);
-       IXGBE_COMPUTE_BKT_HASH_ITERATION(7);
-       IXGBE_COMPUTE_BKT_HASH_ITERATION(8);
-       IXGBE_COMPUTE_BKT_HASH_ITERATION(9);
-       IXGBE_COMPUTE_BKT_HASH_ITERATION(10);
-       IXGBE_COMPUTE_BKT_HASH_ITERATION(11);
-       IXGBE_COMPUTE_BKT_HASH_ITERATION(12);
-       IXGBE_COMPUTE_BKT_HASH_ITERATION(13);
-       IXGBE_COMPUTE_BKT_HASH_ITERATION(14);
-       IXGBE_COMPUTE_BKT_HASH_ITERATION(15);
+       for (i = 1; i <= 15; i++)
+               IXGBE_COMPUTE_BKT_HASH_ITERATION(i);
 
        /*
         * Limit hash to 13 bits since max bucket count is 8K.
@@ -1613,7 +1705,7 @@ void ixgbe_atr_compute_perfect_hash_82599(union ixgbe_atr_input *input,
 }
 
 /**
- *  ixgbe_get_fdirtcpm_82599 - generate a tcp port from atr_input_masks
+ *  ixgbe_get_fdirtcpm_82599 - generate a TCP port from atr_input_masks
  *  @input_mask: mask to be bit swapped
  *
  *  The source and destination port masks for flow director are bit swapped
@@ -1650,7 +1742,7 @@ STATIC u32 ixgbe_get_fdirtcpm_82599(union ixgbe_atr_input *input_mask)
        IXGBE_NTOHS(((u16)(_value) >> 8) | ((u16)(_value) << 8))
 
 s32 ixgbe_fdir_set_input_mask_82599(struct ixgbe_hw *hw,
-                                   union ixgbe_atr_input *input_mask)
+                                   union ixgbe_atr_input *input_mask, bool cloud_mode)
 {
        /* mask IPv6 since it is currently not supported */
        u32 fdirm = IXGBE_FDIRM_DIPv6;
@@ -1738,7 +1830,7 @@ s32 ixgbe_fdir_set_input_mask_82599(struct ixgbe_hw *hw,
        IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM, ~fdirtcpm);
        IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM, ~fdirtcpm);
 
-       /* store source and destination IP masks (big-enian) */
+       /* store source and destination IP masks (big-endian) */
        IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRSIP4M,
                             ~input_mask->formatted.src_ip[0]);
        IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRDIP4M,
@@ -1749,7 +1841,7 @@ s32 ixgbe_fdir_set_input_mask_82599(struct ixgbe_hw *hw,
 
 s32 ixgbe_fdir_write_perfect_filter_82599(struct ixgbe_hw *hw,
                                          union ixgbe_atr_input *input,
-                                         u16 soft_id, u8 queue)
+                                         u16 soft_id, u8 queue, bool cloud_mode)
 {
        u32 fdirport, fdirvlan, fdirhash, fdircmd;
 
@@ -1775,7 +1867,7 @@ s32 ixgbe_fdir_write_perfect_filter_82599(struct ixgbe_hw *hw,
        fdirport |= IXGBE_NTOHS(input->formatted.src_port);
        IXGBE_WRITE_REG(hw, IXGBE_FDIRPORT, fdirport);
 
-       /* record vlan (little-endian) and flex_bytes(big-endian) */
+       /* record VLAN (little-endian) and flex_bytes(big-endian) */
        fdirvlan = IXGBE_STORE_AS_BE16(input->formatted.flex_bytes);
        fdirvlan <<= IXGBE_FDIRVLAN_FLEX_SHIFT;
        fdirvlan |= IXGBE_NTOHS(input->formatted.vlan_id);
@@ -1798,6 +1890,8 @@ s32 ixgbe_fdir_write_perfect_filter_82599(struct ixgbe_hw *hw,
                  IXGBE_FDIRCMD_LAST | IXGBE_FDIRCMD_QUEUE_EN;
        if (queue == IXGBE_FDIR_DROP_QUEUE)
                fdircmd |= IXGBE_FDIRCMD_DROP;
+       if (input->formatted.flow_type & IXGBE_ATR_L4TYPE_TUNNEL_MASK)
+               fdircmd |= IXGBE_FDIRCMD_TUNNEL_FILTER;
        fdircmd |= input->formatted.flow_type << IXGBE_FDIRCMD_FLOW_TYPE_SHIFT;
        fdircmd |= (u32)queue << IXGBE_FDIRCMD_RX_QUEUE_SHIFT;
        fdircmd |= (u32)input->formatted.vm_pool << IXGBE_FDIRCMD_VT_POOL_SHIFT;
@@ -1813,8 +1907,7 @@ s32 ixgbe_fdir_erase_perfect_filter_82599(struct ixgbe_hw *hw,
 {
        u32 fdirhash;
        u32 fdircmd = 0;
-       u32 retry_count;
-       s32 err = IXGBE_SUCCESS;
+       s32 err;
 
        /* configure FDIRHASH register */
        fdirhash = input->formatted.bkt_hash;
@@ -1827,18 +1920,12 @@ s32 ixgbe_fdir_erase_perfect_filter_82599(struct ixgbe_hw *hw,
        /* Query if filter is present */
        IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD, IXGBE_FDIRCMD_CMD_QUERY_REM_FILT);
 
-       for (retry_count = 10; retry_count; retry_count--) {
-               /* allow 10us for query to process */
-               usec_delay(10);
-               /* verify query completed successfully */
-               fdircmd = IXGBE_READ_REG(hw, IXGBE_FDIRCMD);
-               if (!(fdircmd & IXGBE_FDIRCMD_CMD_MASK))
-                       break;
+       err = ixgbe_fdir_check_cmd_complete(hw);
+       if (err) {
+               DEBUGOUT("Flow Director command did not complete!\n");
+               return err;
        }
 
-       if (!retry_count)
-               err = IXGBE_ERR_FDIR_REINIT_FAILED;
-
        /* if filter exists in hardware then remove it */
        if (fdircmd & IXGBE_FDIRCMD_FILTER_VALID) {
                IXGBE_WRITE_REG(hw, IXGBE_FDIRHASH, fdirhash);
@@ -1847,7 +1934,7 @@ s32 ixgbe_fdir_erase_perfect_filter_82599(struct ixgbe_hw *hw,
                                IXGBE_FDIRCMD_CMD_REMOVE_FLOW);
        }
 
-       return err;
+       return IXGBE_SUCCESS;
 }
 
 /**
@@ -1864,7 +1951,7 @@ s32 ixgbe_fdir_erase_perfect_filter_82599(struct ixgbe_hw *hw,
 s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw,
                                        union ixgbe_atr_input *input,
                                        union ixgbe_atr_input *input_mask,
-                                       u16 soft_id, u8 queue)
+                                       u16 soft_id, u8 queue, bool cloud_mode)
 {
        s32 err = IXGBE_ERR_CONFIG;
 
@@ -1876,6 +1963,7 @@ s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw,
         */
        switch (input->formatted.flow_type) {
        case IXGBE_ATR_FLOW_TYPE_IPV4:
+       case IXGBE_ATR_FLOW_TYPE_TUNNELED_IPV4:
                input_mask->formatted.flow_type = IXGBE_ATR_L4TYPE_IPV6_MASK;
                if (input->formatted.dst_port || input->formatted.src_port) {
                        DEBUGOUT(" Error on src/dst port\n");
@@ -1883,12 +1971,15 @@ s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw,
                }
                break;
        case IXGBE_ATR_FLOW_TYPE_SCTPV4:
+       case IXGBE_ATR_FLOW_TYPE_TUNNELED_SCTPV4:
                if (input->formatted.dst_port || input->formatted.src_port) {
                        DEBUGOUT(" Error on src/dst port\n");
                        return IXGBE_ERR_CONFIG;
                }
        case IXGBE_ATR_FLOW_TYPE_TCPV4:
+       case IXGBE_ATR_FLOW_TYPE_TUNNELED_TCPV4:
        case IXGBE_ATR_FLOW_TYPE_UDPV4:
+       case IXGBE_ATR_FLOW_TYPE_TUNNELED_UDPV4:
                input_mask->formatted.flow_type = IXGBE_ATR_L4TYPE_IPV6_MASK |
                                                  IXGBE_ATR_L4TYPE_MASK;
                break;
@@ -1898,7 +1989,7 @@ s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw,
        }
 
        /* program input mask into the HW */
-       err = ixgbe_fdir_set_input_mask_82599(hw, input_mask);
+       err = ixgbe_fdir_set_input_mask_82599(hw, input_mask, cloud_mode);
        if (err)
                return err;
 
@@ -1907,7 +1998,7 @@ s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw,
 
        /* program filters to filter memory */
        return ixgbe_fdir_write_perfect_filter_82599(hw, input,
-                                                    soft_id, queue);
+                                                    soft_id, queue, cloud_mode);
 }
 
 /**
@@ -2006,7 +2097,7 @@ s32 ixgbe_identify_phy_82599(struct ixgbe_hw *hw)
        if (status != IXGBE_SUCCESS) {
                /* 82599 10GBASE-T requires an external PHY */
                if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_copper)
-                       goto out;
+                       return status;
                else
                        status = ixgbe_identify_module_generic(hw);
        }
@@ -2014,14 +2105,13 @@ s32 ixgbe_identify_phy_82599(struct ixgbe_hw *hw)
        /* Set PHY type none if no PHY detected */
        if (hw->phy.type == ixgbe_phy_unknown) {
                hw->phy.type = ixgbe_phy_none;
-               status = IXGBE_SUCCESS;
+               return IXGBE_SUCCESS;
        }
 
        /* Return error if SFP module has been detected but is not supported */
        if (hw->phy.type == ixgbe_phy_sfp_unsupported)
-               status = IXGBE_ERR_SFP_NOT_SUPPORTED;
+               return IXGBE_ERR_SFP_NOT_SUPPORTED;
 
-out:
        return status;
 }
 
@@ -2040,8 +2130,6 @@ u32 ixgbe_get_supported_physical_layer_82599(struct ixgbe_hw *hw)
        u32 pma_pmd_10g_parallel = autoc & IXGBE_AUTOC_10G_PMA_PMD_MASK;
        u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK;
        u16 ext_ability = 0;
-       u8 comp_codes_10g = 0;
-       u8 comp_codes_1g = 0;
 
        DEBUGFUNC("ixgbe_get_support_physical_layer_82599");
 
@@ -2109,40 +2197,7 @@ sfp_check:
        /* SFP check must be done last since DA modules are sometimes used to
         * test KR mode -  we need to id KR mode correctly before SFP module.
         * Call identify_sfp because the pluggable module may have changed */
-       hw->phy.ops.identify_sfp(hw);
-       if (hw->phy.sfp_type == ixgbe_sfp_type_not_present)
-               goto out;
-
-       switch (hw->phy.type) {
-       case ixgbe_phy_sfp_passive_tyco:
-       case ixgbe_phy_sfp_passive_unknown:
-               physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU;
-               break;
-       case ixgbe_phy_sfp_ftl_active:
-       case ixgbe_phy_sfp_active_unknown:
-               physical_layer = IXGBE_PHYSICAL_LAYER_SFP_ACTIVE_DA;
-               break;
-       case ixgbe_phy_sfp_avago:
-       case ixgbe_phy_sfp_ftl:
-       case ixgbe_phy_sfp_intel:
-       case ixgbe_phy_sfp_unknown:
-               hw->phy.ops.read_i2c_eeprom(hw,
-                     IXGBE_SFF_1GBE_COMP_CODES, &comp_codes_1g);
-               hw->phy.ops.read_i2c_eeprom(hw,
-                     IXGBE_SFF_10GBE_COMP_CODES, &comp_codes_10g);
-               if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)
-                       physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR;
-               else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)
-                       physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
-               else if (comp_codes_1g & IXGBE_SFF_1GBASET_CAPABLE)
-                       physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_T;
-               else if (comp_codes_1g & IXGBE_SFF_1GBASESX_CAPABLE)
-                       physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_SX;
-               break;
-       default:
-               break;
-       }
-
+       physical_layer = ixgbe_get_supported_phy_sfp_layer_generic(hw);
 out:
        return physical_layer;
 }
@@ -2168,7 +2223,10 @@ s32 ixgbe_enable_rx_dma_82599(struct ixgbe_hw *hw, u32 regval)
 
        hw->mac.ops.disable_sec_rx_path(hw);
 
-       IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, regval);
+       if (regval & IXGBE_RXCTRL_RXEN)
+               ixgbe_enable_rx(hw);
+       else
+               ixgbe_disable_rx(hw);
 
        hw->mac.ops.enable_sec_rx_path(hw);
 
@@ -2176,7 +2234,7 @@ s32 ixgbe_enable_rx_dma_82599(struct ixgbe_hw *hw, u32 regval)
 }
 
 /**
- *  ixgbe_verify_fw_version_82599 - verify fw version for 82599
+ *  ixgbe_verify_fw_version_82599 - verify FW version for 82599
  *  @hw: pointer to hardware structure
  *
  *  Verifies that installed the firmware version is 0.6 or higher
@@ -2270,7 +2328,7 @@ bool ixgbe_verify_lesm_fw_enabled_82599(struct ixgbe_hw *hw)
            (fw_lesm_param_offset == 0) || (fw_lesm_param_offset == 0xFFFF))
                goto out;
 
-       /* get the lesm state word */
+       /* get the LESM state word */
        status = hw->eeprom.ops.read(hw, (fw_lesm_param_offset +
                                     IXGBE_FW_LESM_STATE_1),
                                     &fw_lesm_state);
@@ -2355,12 +2413,13 @@ STATIC s32 ixgbe_read_eeprom_82599(struct ixgbe_hw *hw,
  *  @hw: pointer to hardware structure
  *
  * Reset pipeline by asserting Restart_AN together with LMS change to ensure
- * full pipeline reset
+ * full pipeline reset.  This function assumes the SW/FW lock is held.
  **/
 s32 ixgbe_reset_pipeline_82599(struct ixgbe_hw *hw)
 {
-       s32 i, autoc_reg, autoc2_reg, ret_val;
-       s32 anlp1_reg = 0;
+       s32 ret_val;
+       u32 anlp1_reg = 0;
+       u32 i, autoc_reg, autoc2_reg;
 
        /* Enable link if disabled in NVM */
        autoc2_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC2);
@@ -2373,7 +2432,8 @@ s32 ixgbe_reset_pipeline_82599(struct ixgbe_hw *hw)
        autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
        autoc_reg |= IXGBE_AUTOC_AN_RESTART;
        /* Write AUTOC register with toggled LMS[2] bit and Restart_AN */
-       IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg ^ IXGBE_AUTOC_LMS_1G_AN);
+       IXGBE_WRITE_REG(hw, IXGBE_AUTOC,
+                       autoc_reg ^ (0x4 << IXGBE_AUTOC_LMS_SHIFT));
        /* Wait for AN to leave state 0 */
        for (i = 0; i < 10; i++) {
                msec_delay(4);