Print this page
Import some changes from FreeBSD (details later, this is quick-n-dirty for now).
        
*** 1,8 ****
  /******************************************************************************
  
!   Copyright (c) 2001-2012, Intel Corporation 
    All rights reserved.
    
    Redistribution and use in source and binary forms, with or without 
    modification, are permitted provided that the following conditions are met:
    
--- 1,8 ----
  /******************************************************************************
  
!   Copyright (c) 2001-2013, Intel Corporation 
    All rights reserved.
    
    Redistribution and use in source and binary forms, with or without 
    modification, are permitted provided that the following conditions are met:
    
*** 38,63 ****
  #include "ixgbe_common.h"
  #include "ixgbe_phy.h"
  
  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,
                                     u16 offset, u16 *data);
  static s32 ixgbe_read_eeprom_buffer_82599(struct ixgbe_hw *hw, u16 offset,
                                            u16 words, u16 *data);
  
  void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw)
  {
          struct ixgbe_mac_info *mac = &hw->mac;
  
          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) {
                  mac->ops.disable_tx_laser =
                                         &ixgbe_disable_tx_laser_multispeed_fiber;
                  mac->ops.enable_tx_laser =
                                          &ixgbe_enable_tx_laser_multispeed_fiber;
                  mac->ops.flap_tx_laser = &ixgbe_flap_tx_laser_multispeed_fiber;
--- 38,85 ----
  #include "ixgbe_common.h"
  #include "ixgbe_phy.h"
  
  static s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw,
                                           ixgbe_link_speed speed,
                                           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,
                                     u16 offset, u16 *data);
  static s32 ixgbe_read_eeprom_buffer_82599(struct ixgbe_hw *hw, u16 offset,
                                            u16 words, u16 *data);
  
+ static bool ixgbe_mng_enabled(struct ixgbe_hw *hw)
+ {
+         u32 fwsm, manc, factps;
+ 
+         fwsm = IXGBE_READ_REG(hw, IXGBE_FWSM);
+         if ((fwsm & IXGBE_FWSM_MODE_MASK) != IXGBE_FWSM_FW_MODE_PT)
+                 return FALSE;
+ 
+         manc = IXGBE_READ_REG(hw, IXGBE_MANC);
+         if (!(manc & IXGBE_MANC_RCV_TCO_EN))
+                 return FALSE;
+ 
+         factps = IXGBE_READ_REG(hw, IXGBE_FACTPS);
+         if (factps & IXGBE_FACTPS_MNGCG)
+                 return FALSE;
+ 
+         return TRUE;
+ }
+ 
  void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw)
  {
          struct ixgbe_mac_info *mac = &hw->mac;
  
          DEBUGFUNC("ixgbe_init_mac_link_ops_82599");
  
!         /*
!          * 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 =
                                          &ixgbe_enable_tx_laser_multispeed_fiber;
                  mac->ops.flap_tx_laser = &ixgbe_flap_tx_laser_multispeed_fiber;
*** 133,145 ****
  }
  
  s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw)
  {
          s32 ret_val = IXGBE_SUCCESS;
-         u32 reg_anlp1 = 0;
-         u32 i = 0;
          u16 list_offset, data_offset, data_value;
  
          DEBUGFUNC("ixgbe_setup_sfp_modules_82599");
  
          if (hw->phy.sfp_type != ixgbe_sfp_type_unknown) {
                  ixgbe_init_mac_link_ops_82599(hw);
--- 155,166 ----
  }
  
  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");
  
          if (hw->phy.sfp_type != ixgbe_sfp_type_unknown) {
                  ixgbe_init_mac_link_ops_82599(hw);
*** 169,200 ****
                  /* 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);
  
!                 /* Now restart DSP by setting Restart_AN and clearing LMS */
!                 IXGBE_WRITE_REG(hw, IXGBE_AUTOC, ((IXGBE_READ_REG(hw,
!                                 IXGBE_AUTOC) & ~IXGBE_AUTOC_LMS_MASK) |
!                                 IXGBE_AUTOC_AN_RESTART));
  
!                 /* Wait for AN to leave state 0 */
!                 for (i = 0; i < 10; i++) {
!                         msec_delay(4);
!                         reg_anlp1 = IXGBE_READ_REG(hw, IXGBE_ANLP1);
!                         if (reg_anlp1 & IXGBE_ANLP1_AN_STATE_MASK)
!                                 break;
                  }
!                 if (!(reg_anlp1 & IXGBE_ANLP1_AN_STATE_MASK)) {
                          DEBUGOUT("sfp module setup not complete\n");
                          ret_val = IXGBE_ERR_SFP_SETUP_NOT_COMPLETE;
                          goto setup_sfp_out;
                  }
  
-                 /* Restart DSP by setting Restart_AN and return to SFI mode */
-                 IXGBE_WRITE_REG(hw, IXGBE_AUTOC, (IXGBE_READ_REG(hw,
-                                 IXGBE_AUTOC) | IXGBE_AUTOC_LMS_10G_SERIAL |
-                                 IXGBE_AUTOC_AN_RESTART));
          }
  
  setup_sfp_out:
          return ret_val;
  }
--- 190,232 ----
                  /* 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.
!                  */
!                 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;
                  }
! 
!                 /* Restart DSP and set SFI mode */
!                 IXGBE_WRITE_REG(hw, IXGBE_AUTOC, ((hw->mac.orig_autoc) |
!                                 IXGBE_AUTOC_LMS_10G_SERIAL));
!                 hw->mac.cached_autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
!                 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;
!                 }
! 
!                 if (ret_val) {
                          DEBUGOUT("sfp module setup not complete\n");
                          ret_val = IXGBE_ERR_SFP_SETUP_NOT_COMPLETE;
                          goto setup_sfp_out;
                  }
  
          }
  
  setup_sfp_out:
          return ret_val;
  }
*** 214,224 ****
          struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
          s32 ret_val;
  
          DEBUGFUNC("ixgbe_init_ops_82599");
  
!         ret_val = ixgbe_init_phy_ops_generic(hw);
          ret_val = ixgbe_init_ops_generic(hw);
  
          /* PHY */
          phy->ops.identify = &ixgbe_identify_phy_82599;
          phy->ops.init = &ixgbe_init_phy_ops_82599;
--- 246,256 ----
          struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
          s32 ret_val;
  
          DEBUGFUNC("ixgbe_init_ops_82599");
  
!         (void) ixgbe_init_phy_ops_generic(hw);
          ret_val = ixgbe_init_ops_generic(hw);
  
          /* PHY */
          phy->ops.identify = &ixgbe_identify_phy_82599;
          phy->ops.init = &ixgbe_init_phy_ops_82599;
*** 287,303 ****
  
  /**
   *  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
   *
   *  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)
  {
          s32 status = IXGBE_SUCCESS;
          u32 autoc = 0;
  
          DEBUGFUNC("ixgbe_get_link_capabilities_82599");
--- 319,335 ----
  
  /**
   *  ixgbe_get_link_capabilities_82599 - Determines link capabilities
   *  @hw: pointer to hardware structure
   *  @speed: pointer to link speed
!  *  @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 *autoneg)
  {
          s32 status = IXGBE_SUCCESS;
          u32 autoc = 0;
  
          DEBUGFUNC("ixgbe_get_link_capabilities_82599");
*** 307,317 ****
          if (hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0 ||
              hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1 ||
              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;
                  goto out;
          }
  
          /*
           * Determine link capabilities based on the stored value of AUTOC,
--- 339,349 ----
          if (hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0 ||
              hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1 ||
              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;
!                 *autoneg = TRUE;
                  goto out;
          }
  
          /*
           * Determine link capabilities based on the stored value of AUTOC,
*** 324,349 ****
                  autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
  
          switch (autoc & IXGBE_AUTOC_LMS_MASK) {
          case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
                  *speed = IXGBE_LINK_SPEED_1GB_FULL;
!                 *negotiation = FALSE;
                  break;
  
          case IXGBE_AUTOC_LMS_10G_LINK_NO_AN:
                  *speed = IXGBE_LINK_SPEED_10GB_FULL;
!                 *negotiation = FALSE;
                  break;
  
          case IXGBE_AUTOC_LMS_1G_AN:
                  *speed = IXGBE_LINK_SPEED_1GB_FULL;
!                 *negotiation = TRUE;
                  break;
  
          case IXGBE_AUTOC_LMS_10G_SERIAL:
                  *speed = IXGBE_LINK_SPEED_10GB_FULL;
!                 *negotiation = FALSE;
                  break;
  
          case IXGBE_AUTOC_LMS_KX4_KX_KR:
          case IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN:
                  *speed = IXGBE_LINK_SPEED_UNKNOWN;
--- 356,381 ----
                  autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
  
          switch (autoc & IXGBE_AUTOC_LMS_MASK) {
          case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
                  *speed = IXGBE_LINK_SPEED_1GB_FULL;
!                 *autoneg = FALSE;
                  break;
  
          case IXGBE_AUTOC_LMS_10G_LINK_NO_AN:
                  *speed = IXGBE_LINK_SPEED_10GB_FULL;
!                 *autoneg = FALSE;
                  break;
  
          case IXGBE_AUTOC_LMS_1G_AN:
                  *speed = IXGBE_LINK_SPEED_1GB_FULL;
!                 *autoneg = TRUE;
                  break;
  
          case IXGBE_AUTOC_LMS_10G_SERIAL:
                  *speed = IXGBE_LINK_SPEED_10GB_FULL;
!                 *autoneg = FALSE;
                  break;
  
          case IXGBE_AUTOC_LMS_KX4_KX_KR:
          case IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN:
                  *speed = IXGBE_LINK_SPEED_UNKNOWN;
*** 351,361 ****
                          *speed |= IXGBE_LINK_SPEED_10GB_FULL;
                  if (autoc & IXGBE_AUTOC_KX4_SUPP)
                          *speed |= IXGBE_LINK_SPEED_10GB_FULL;
                  if (autoc & IXGBE_AUTOC_KX_SUPP)
                          *speed |= IXGBE_LINK_SPEED_1GB_FULL;
!                 *negotiation = TRUE;
                  break;
  
          case IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII:
                  *speed = IXGBE_LINK_SPEED_100_FULL;
                  if (autoc & IXGBE_AUTOC_KR_SUPP)
--- 383,393 ----
                          *speed |= IXGBE_LINK_SPEED_10GB_FULL;
                  if (autoc & IXGBE_AUTOC_KX4_SUPP)
                          *speed |= IXGBE_LINK_SPEED_10GB_FULL;
                  if (autoc & IXGBE_AUTOC_KX_SUPP)
                          *speed |= IXGBE_LINK_SPEED_1GB_FULL;
!                 *autoneg = TRUE;
                  break;
  
          case IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII:
                  *speed = IXGBE_LINK_SPEED_100_FULL;
                  if (autoc & IXGBE_AUTOC_KR_SUPP)
*** 362,377 ****
                          *speed |= IXGBE_LINK_SPEED_10GB_FULL;
                  if (autoc & IXGBE_AUTOC_KX4_SUPP)
                          *speed |= IXGBE_LINK_SPEED_10GB_FULL;
                  if (autoc & IXGBE_AUTOC_KX_SUPP)
                          *speed |= IXGBE_LINK_SPEED_1GB_FULL;
!                 *negotiation = TRUE;
                  break;
  
          case IXGBE_AUTOC_LMS_SGMII_1G_100M:
                  *speed = IXGBE_LINK_SPEED_1GB_FULL | IXGBE_LINK_SPEED_100_FULL;
!                 *negotiation = FALSE;
                  break;
  
          default:
                  status = IXGBE_ERR_LINK_SETUP;
                  goto out;
--- 394,409 ----
                          *speed |= IXGBE_LINK_SPEED_10GB_FULL;
                  if (autoc & IXGBE_AUTOC_KX4_SUPP)
                          *speed |= IXGBE_LINK_SPEED_10GB_FULL;
                  if (autoc & IXGBE_AUTOC_KX_SUPP)
                          *speed |= IXGBE_LINK_SPEED_1GB_FULL;
!                 *autoneg = TRUE;
                  break;
  
          case IXGBE_AUTOC_LMS_SGMII_1G_100M:
                  *speed = IXGBE_LINK_SPEED_1GB_FULL | IXGBE_LINK_SPEED_100_FULL;
!                 *autoneg = FALSE;
                  break;
  
          default:
                  status = IXGBE_ERR_LINK_SETUP;
                  goto out;
*** 378,388 ****
          }
  
          if (hw->phy.multispeed_fiber) {
                  *speed |= IXGBE_LINK_SPEED_10GB_FULL |
                            IXGBE_LINK_SPEED_1GB_FULL;
!                 *negotiation = TRUE;
          }
  
  out:
          return status;
  }
--- 410,420 ----
          }
  
          if (hw->phy.multispeed_fiber) {
                  *speed |= IXGBE_LINK_SPEED_10GB_FULL |
                            IXGBE_LINK_SPEED_1GB_FULL;
!                 *autoneg = TRUE;
          }
  
  out:
          return status;
  }
*** 421,439 ****
--- 453,476 ----
                  break;
          case IXGBE_DEV_ID_82599_SFP:
          case IXGBE_DEV_ID_82599_SFP_FCOE:
          case IXGBE_DEV_ID_82599_SFP_EM:
          case IXGBE_DEV_ID_82599_SFP_SF2:
+         case IXGBE_DEV_ID_82599_SFP_SF_QP:
          case IXGBE_DEV_ID_82599EN_SFP:
                  media_type = ixgbe_media_type_fiber;
                  break;
          case IXGBE_DEV_ID_82599_CX4:
                  media_type = ixgbe_media_type_cx4;
                  break;
          case IXGBE_DEV_ID_82599_T3_LOM:
                  media_type = ixgbe_media_type_copper;
                  break;
+         case IXGBE_DEV_ID_82599_BYPASS:
+                 media_type = ixgbe_media_type_fiber_fixed;
+                 hw->phy.multispeed_fiber = TRUE;
+                 break;
          default:
                  media_type = ixgbe_media_type_unknown;
                  break;
          }
  out:
*** 453,473 ****
  {
          u32 autoc_reg;
          u32 links_reg;
          u32 i;
          s32 status = IXGBE_SUCCESS;
  
          DEBUGFUNC("ixgbe_start_mac_link_82599");
  
  
          /* Restart link */
!         autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
!         autoc_reg |= IXGBE_AUTOC_AN_RESTART;
!         IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
  
          /* Only poll for autoneg to complete if specified to do so */
          if (autoneg_wait_to_complete) {
                  if ((autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
                       IXGBE_AUTOC_LMS_KX4_KX_KR ||
                      (autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
                       IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN ||
                      (autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
--- 490,525 ----
  {
          u32 autoc_reg;
          u32 links_reg;
          u32 i;
          s32 status = IXGBE_SUCCESS;
+         bool got_lock = FALSE;
  
          DEBUGFUNC("ixgbe_start_mac_link_82599");
  
  
+         /*  reset_pipeline requires us to hold this lock as it 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)
+                         goto out;
+ 
+                 got_lock = TRUE;
+         }
+ 
          /* Restart link */
!         (void) ixgbe_reset_pipeline_82599(hw);
  
+         if (got_lock)
+                 hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM);
+ 
          /* Only poll for autoneg to complete if specified to do so */
          if (autoneg_wait_to_complete) {
+                 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
                  if ((autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
                       IXGBE_AUTOC_LMS_KX4_KX_KR ||
                      (autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
                       IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN ||
                      (autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
*** 487,496 ****
--- 539,549 ----
          }
  
          /* Add delay to filter out noises during initial link setup */
          msec_delay(50);
  
+ out:
          return status;
  }
  
  /**
   *  ixgbe_disable_tx_laser_multispeed_fiber - Disable Tx laser
*** 552,586 ****
                  hw->mac.autotry_restart = FALSE;
          }
  }
  
  /**
   *  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,
                                       bool autoneg_wait_to_complete)
  {
          s32 status = IXGBE_SUCCESS;
          ixgbe_link_speed link_speed = IXGBE_LINK_SPEED_UNKNOWN;
          ixgbe_link_speed highest_link_speed = IXGBE_LINK_SPEED_UNKNOWN;
          u32 speedcnt = 0;
          u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP);
          u32 i = 0;
!         bool link_up = FALSE;
!         bool negotiation;
  
          DEBUGFUNC("ixgbe_setup_mac_link_multispeed_fiber");
  
          /* Mask off requested but non-supported speeds */
!         status = ixgbe_get_link_capabilities(hw, &link_speed, &negotiation);
          if (status != IXGBE_SUCCESS)
                  return status;
  
          speed &= link_speed;
  
--- 605,706 ----
                  hw->mac.autotry_restart = FALSE;
          }
  }
  
  /**
+  *  ixgbe_set_fiber_fixed_speed - Set module link speed for fixed fiber
+  *  @hw: pointer to hardware structure
+  *  @speed: link speed to set
+  *
+  *  We set the module speed differently for fixed fiber.  For other
+  *  multi-speed devices we don't have an error value so here if we
+  *  detect an error we just log it and exit.
+  */
+ static void ixgbe_set_fiber_fixed_speed(struct ixgbe_hw *hw,
+                                         ixgbe_link_speed speed)
+ {
+         s32 status;
+         u8 rs, eeprom_data;
+ 
+         switch (speed) {
+         case IXGBE_LINK_SPEED_10GB_FULL:
+                 /* one bit mask same as setting on */
+                 rs = IXGBE_SFF_SOFT_RS_SELECT_10G;
+                 break;
+         case IXGBE_LINK_SPEED_1GB_FULL:
+                 rs = IXGBE_SFF_SOFT_RS_SELECT_1G;
+                 break;
+         default:
+                 DEBUGOUT("Invalid fixed module speed\n");
+                 return;
+         }
+ 
+         /* Set RS0 */
+         status = hw->phy.ops.read_i2c_byte(hw, IXGBE_SFF_SFF_8472_OSCB,
+                                            IXGBE_I2C_EEPROM_DEV_ADDR2,
+                                            &eeprom_data);
+         if (status) {
+                 DEBUGOUT("Failed to read Rx Rate Select RS0\n");
+                 goto out;
+         }
+ 
+         eeprom_data = (eeprom_data & ~IXGBE_SFF_SOFT_RS_SELECT_MASK) & rs;
+ 
+         status = hw->phy.ops.write_i2c_byte(hw, IXGBE_SFF_SFF_8472_OSCB,
+                                             IXGBE_I2C_EEPROM_DEV_ADDR2,
+                                             eeprom_data);
+         if (status) {
+                 DEBUGOUT("Failed to write Rx Rate Select RS0\n");
+                 goto out;
+         }
+ 
+         /* Set RS1 */
+         status = hw->phy.ops.read_i2c_byte(hw, IXGBE_SFF_SFF_8472_ESCB,
+                                            IXGBE_I2C_EEPROM_DEV_ADDR2,
+                                            &eeprom_data);
+         if (status) {
+                 DEBUGOUT("Failed to read Rx Rate Select RS1\n");
+                 goto out;
+         }
+ 
+         eeprom_data = (eeprom_data & ~IXGBE_SFF_SOFT_RS_SELECT_MASK) & rs;
+ 
+         status = hw->phy.ops.write_i2c_byte(hw, IXGBE_SFF_SFF_8472_ESCB,
+                                             IXGBE_I2C_EEPROM_DEV_ADDR2,
+                                             eeprom_data);
+         if (status) {
+                 DEBUGOUT("Failed to write Rx Rate Select RS1\n");
+                 goto out;
+         }
+ out:
+         return;
+ }
+ 
+ /**
   *  ixgbe_setup_mac_link_multispeed_fiber - Set MAC link speed
   *  @hw: pointer to hardware structure
   *  @speed: new link speed
   *  @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_wait_to_complete)
  {
          s32 status = IXGBE_SUCCESS;
          ixgbe_link_speed link_speed = IXGBE_LINK_SPEED_UNKNOWN;
          ixgbe_link_speed highest_link_speed = IXGBE_LINK_SPEED_UNKNOWN;
          u32 speedcnt = 0;
          u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP);
          u32 i = 0;
!         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, &autoneg);
          if (status != IXGBE_SUCCESS)
                  return status;
  
          speed &= link_speed;
  
*** 599,618 ****
  
                  if ((link_speed == IXGBE_LINK_SPEED_10GB_FULL) && link_up)
                          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);
  
                  /* 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;
  
                  /* Flap the tx laser if it has not already been done */
--- 719,742 ----
  
                  if ((link_speed == IXGBE_LINK_SPEED_10GB_FULL) && link_up)
                          goto out;
  
                  /* Set the module link speed */
+                 if (hw->phy.media_type == ixgbe_media_type_fiber_fixed) {
+                         ixgbe_set_fiber_fixed_speed(hw,
+                                                     IXGBE_LINK_SPEED_10GB_FULL);
+                 } else {
                          esdp_reg |= (IXGBE_ESDP_SDP5_DIR | IXGBE_ESDP_SDP5);
                          IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
                          IXGBE_WRITE_FLUSH(hw);
+                 }
  
                  /* Allow module to change analog characteristics (1G->10G) */
                  msec_delay(40);
  
                  status = ixgbe_setup_mac_link_82599(hw,
                                                      IXGBE_LINK_SPEED_10GB_FULL,
                                                      autoneg_wait_to_complete);
                  if (status != IXGBE_SUCCESS)
                          return status;
  
                  /* Flap the tx laser if it has not already been done */
*** 650,670 ****
  
                  if ((link_speed == IXGBE_LINK_SPEED_1GB_FULL) && link_up)
                          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);
  
                  /* 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 */
--- 774,798 ----
  
                  if ((link_speed == IXGBE_LINK_SPEED_1GB_FULL) && link_up)
                          goto out;
  
                  /* Set the module link speed */
+                 if (hw->phy.media_type == ixgbe_media_type_fiber_fixed) {
+                         ixgbe_set_fiber_fixed_speed(hw,
+                                                     IXGBE_LINK_SPEED_1GB_FULL);
+                 } else {
                          esdp_reg &= ~IXGBE_ESDP_SDP5;
                          esdp_reg |= IXGBE_ESDP_SDP5_DIR;
                          IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
                          IXGBE_WRITE_FLUSH(hw);
+                 }
  
                  /* Allow module to change analog characteristics (10G->1G) */
                  msec_delay(40);
  
                  status = ixgbe_setup_mac_link_82599(hw,
                                                      IXGBE_LINK_SPEED_1GB_FULL,
                                                      autoneg_wait_to_complete);
                  if (status != IXGBE_SUCCESS)
                          return status;
  
                  /* Flap the tx laser if it has not already been done */
*** 687,697 ****
           * (if there was more than one).  We call ourselves back with just the
           * single highest speed that the user requested.
           */
          if (speedcnt > 1)
                  status = ixgbe_setup_mac_link_multispeed_fiber(hw,
!                         highest_link_speed, autoneg, autoneg_wait_to_complete);
  
  out:
          /* Set autoneg_advertised value based on input link speed */
          hw->phy.autoneg_advertised = 0;
  
--- 815,825 ----
           * (if there was more than one).  We call ourselves back with just the
           * single highest speed that the user requested.
           */
          if (speedcnt > 1)
                  status = ixgbe_setup_mac_link_multispeed_fiber(hw,
!                         highest_link_speed, autoneg_wait_to_complete);
  
  out:
          /* Set autoneg_advertised value based on input link speed */
          hw->phy.autoneg_advertised = 0;
  
*** 706,722 ****
  
  /**
   *  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,
                                      bool autoneg_wait_to_complete)
  {
          s32 status = IXGBE_SUCCESS;
          ixgbe_link_speed link_speed = IXGBE_LINK_SPEED_UNKNOWN;
          s32 i, j;
--- 834,849 ----
  
  /**
   *  ixgbe_setup_mac_link_smartspeed - Set MAC link speed using SmartSpeed
   *  @hw: pointer to hardware structure
   *  @speed: new link speed
   *  @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_wait_to_complete)
  {
          s32 status = IXGBE_SUCCESS;
          ixgbe_link_speed link_speed = IXGBE_LINK_SPEED_UNKNOWN;
          s32 i, j;
*** 745,755 ****
           */
  
          /* 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,
                                                      autoneg_wait_to_complete);
                  if (status != IXGBE_SUCCESS)
                          goto out;
  
                  /*
--- 872,882 ----
           */
  
          /* 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_wait_to_complete);
                  if (status != IXGBE_SUCCESS)
                          goto out;
  
                  /*
*** 780,790 ****
              ((autoc_reg & IXGBE_AUTOC_KX4_KX_SUPP_MASK) == 0))
                  goto out;
  
          /* Turn SmartSpeed on to disable KR support */
          hw->phy.smart_speed_active = TRUE;
!         status = ixgbe_setup_mac_link_82599(hw, speed, autoneg,
                                              autoneg_wait_to_complete);
          if (status != IXGBE_SUCCESS)
                  goto out;
  
          /*
--- 907,917 ----
              ((autoc_reg & IXGBE_AUTOC_KX4_KX_SUPP_MASK) == 0))
                  goto out;
  
          /* Turn SmartSpeed on to disable KR support */
          hw->phy.smart_speed_active = TRUE;
!         status = ixgbe_setup_mac_link_82599(hw, speed,
                                              autoneg_wait_to_complete);
          if (status != IXGBE_SUCCESS)
                  goto out;
  
          /*
*** 805,815 ****
                          goto out;
          }
  
          /* We didn't get link.  Turn SmartSpeed back off. */
          hw->phy.smart_speed_active = FALSE;
!         status = ixgbe_setup_mac_link_82599(hw, speed, autoneg,
                                              autoneg_wait_to_complete);
  
  out:
          if (link_up && (link_speed == IXGBE_LINK_SPEED_1GB_FULL))
                  DEBUGOUT("Smartspeed has downgraded the link speed "
--- 932,942 ----
                          goto out;
          }
  
          /* We didn't get link.  Turn SmartSpeed back off. */
          hw->phy.smart_speed_active = FALSE;
!         status = ixgbe_setup_mac_link_82599(hw, speed,
                                              autoneg_wait_to_complete);
  
  out:
          if (link_up && (link_speed == IXGBE_LINK_SPEED_1GB_FULL))
                  DEBUGOUT("Smartspeed has downgraded the link speed "
*** 819,854 ****
  
  /**
   *  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,
                                 bool autoneg_wait_to_complete)
  {
          s32 status = IXGBE_SUCCESS;
!         u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
          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;
  
          DEBUGFUNC("ixgbe_setup_mac_link_82599");
  
          /* Check to see if speed passed in is supported. */
          status = ixgbe_get_link_capabilities(hw, &link_capabilities, &autoneg);
!         if (status != IXGBE_SUCCESS)
                  goto out;
  
          speed &= link_capabilities;
  
          if (speed == IXGBE_LINK_SPEED_UNKNOWN) {
--- 946,979 ----
  
  /**
   *  ixgbe_setup_mac_link_82599 - Set MAC link speed
   *  @hw: pointer to hardware structure
   *  @speed: new link speed
   *  @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_wait_to_complete)
  {
+         bool autoneg = FALSE;
          s32 status = IXGBE_SUCCESS;
!         u32 autoc, pma_pmd_1g, link_mode, start_autoc;
          u32 autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2);
          u32 orig_autoc = 0;
          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");
  
          /* Check to see if speed passed in is supported. */
          status = ixgbe_get_link_capabilities(hw, &link_capabilities, &autoneg);
!         if (status)
                  goto out;
  
          speed &= link_capabilities;
  
          if (speed == IXGBE_LINK_SPEED_UNKNOWN) {
*** 856,868 ****
                  goto out;
          }
  
          /* Use stored value (EEPROM defaults) of AUTOC to find KR/KX4 support*/
          if (hw->mac.orig_link_settings_stored)
!                 orig_autoc = hw->mac.orig_autoc;
          else
                  orig_autoc = autoc;
  
          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) {
                  /* Set KX4/KX/KR support according to speed requested */
--- 981,998 ----
                  goto out;
          }
  
          /* Use stored value (EEPROM defaults) of AUTOC to find KR/KX4 support*/
          if (hw->mac.orig_link_settings_stored)
!                 autoc = hw->mac.orig_autoc;
          else
+                 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+ 
          orig_autoc = autoc;
+         start_autoc = hw->mac.cached_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) {
                  /* Set KX4/KX/KR support according to speed requested */
*** 897,910 ****
                                  autoc |= IXGBE_AUTOC_LMS_1G_LINK_NO_AN;
                  }
          }
  
          if (autoc != start_autoc) {
                  /* Restart link */
-                 autoc |= IXGBE_AUTOC_AN_RESTART;
                  IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc);
  
                  /* Only poll for autoneg to complete if specified to do so */
                  if (autoneg_wait_to_complete) {
                          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) {
--- 1027,1062 ----
                                  autoc |= IXGBE_AUTOC_LMS_1G_LINK_NO_AN;
                  }
          }
  
          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;
+                 }
+ 
                  /* Restart link */
                  IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc);
+                 hw->mac.cached_autoc = autoc;
+                 (void) ixgbe_reset_pipeline_82599(hw);
  
+                 if (got_lock) {
+                         hw->mac.ops.release_swfw_sync(hw,
+                                                       IXGBE_GSSR_MAC_CSR_SM);
+                         got_lock = FALSE;
+                 }
+ 
                  /* Only poll for autoneg to complete if specified to do so */
                  if (autoneg_wait_to_complete) {
                          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) {
*** 934,965 ****
  
  /**
   *  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;
  
          DEBUGFUNC("ixgbe_setup_copper_link_82599");
  
          /* Setup the PHY according to input speed */
!         status = hw->phy.ops.setup_link_speed(hw, speed, autoneg,
                                                autoneg_wait_to_complete);
-         if (status == IXGBE_SUCCESS) {
                  /* Set up MAC */
!                 status =
!                     ixgbe_start_mac_link_82599(hw, autoneg_wait_to_complete);
!         }
  
          return status;
  }
  
  /**
--- 1086,1112 ----
  
  /**
   *  ixgbe_setup_copper_link_82599 - Set the PHY autoneg advertised field
   *  @hw: pointer to hardware structure
   *  @speed: new link speed
   *  @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_wait_to_complete)
  {
          s32 status;
  
          DEBUGFUNC("ixgbe_setup_copper_link_82599");
  
          /* Setup the PHY according to input speed */
!         status = hw->phy.ops.setup_link_speed(hw, speed,
                                                autoneg_wait_to_complete);
          /* Set up MAC */
!         (void) ixgbe_start_mac_link_82599(hw, autoneg_wait_to_complete);
  
          return status;
  }
  
  /**
*** 1056,1074 ****
           * stored off yet.  Otherwise restore the stored original
           * values since the reset operation sets back to defaults.
           */
          autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
          autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2);
          if (hw->mac.orig_link_settings_stored == FALSE) {
                  hw->mac.orig_autoc = autoc;
                  hw->mac.orig_autoc2 = autoc2;
                  hw->mac.orig_link_settings_stored = TRUE;
          } else {
!                 if (autoc != hw->mac.orig_autoc)
!                         IXGBE_WRITE_REG(hw, IXGBE_AUTOC, (hw->mac.orig_autoc |
!                                         IXGBE_AUTOC_AN_RESTART));
  
                  if ((autoc2 & IXGBE_AUTOC2_UPPER_MASK) !=
                      (hw->mac.orig_autoc2 & IXGBE_AUTOC2_UPPER_MASK)) {
                          autoc2 &= ~IXGBE_AUTOC2_UPPER_MASK;
                          autoc2 |= (hw->mac.orig_autoc2 &
                                     IXGBE_AUTOC2_UPPER_MASK);
--- 1203,1252 ----
           * stored off yet.  Otherwise restore the stored original
           * values since the reset operation sets back to defaults.
           */
          autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
          autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2);
+ 
+         /* Enable link if disabled in NVM */
+         if (autoc2 & IXGBE_AUTOC2_LINK_DISABLE_MASK) {
+                 autoc2 &= ~IXGBE_AUTOC2_LINK_DISABLE_MASK;
+                 IXGBE_WRITE_REG(hw, IXGBE_AUTOC2, autoc2);
+                 IXGBE_WRITE_FLUSH(hw);
+         }
+ 
          if (hw->mac.orig_link_settings_stored == FALSE) {
                  hw->mac.orig_autoc = autoc;
                  hw->mac.orig_autoc2 = autoc2;
+                 hw->mac.cached_autoc = autoc;
                  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);
+                         hw->mac.cached_autoc = hw->mac.orig_autoc;
+                         (void) ixgbe_reset_pipeline_82599(hw);
+ 
+                         if (got_lock)
+                                 hw->mac.ops.release_swfw_sync(hw,
+                                                       IXGBE_GSSR_MAC_CSR_SM);
+                 }
+ 
                  if ((autoc2 & IXGBE_AUTOC2_UPPER_MASK) !=
                      (hw->mac.orig_autoc2 & IXGBE_AUTOC2_UPPER_MASK)) {
                          autoc2 &= ~IXGBE_AUTOC2_UPPER_MASK;
                          autoc2 |= (hw->mac.orig_autoc2 &
                                     IXGBE_AUTOC2_UPPER_MASK);
*** 1168,1178 ****
          /* Poll init-done after we write FDIRCTRL register */
          for (i = 0; i < IXGBE_FDIR_INIT_DONE_POLL; i++) {
                  if (IXGBE_READ_REG(hw, IXGBE_FDIRCTRL) &
                                     IXGBE_FDIRCTRL_INIT_DONE)
                          break;
!                 usec_delay(10);
          }
          if (i >= IXGBE_FDIR_INIT_DONE_POLL) {
                  DEBUGOUT("Flow Director Signature poll time exceeded!\n");
                  return IXGBE_ERR_FDIR_REINIT_FAILED;
          }
--- 1346,1356 ----
          /* Poll init-done after we write FDIRCTRL register */
          for (i = 0; i < IXGBE_FDIR_INIT_DONE_POLL; i++) {
                  if (IXGBE_READ_REG(hw, IXGBE_FDIRCTRL) &
                                     IXGBE_FDIRCTRL_INIT_DONE)
                          break;
!                 msec_delay(1);
          }
          if (i >= IXGBE_FDIR_INIT_DONE_POLL) {
                  DEBUGOUT("Flow Director Signature poll time exceeded!\n");
                  return IXGBE_ERR_FDIR_REINIT_FAILED;
          }
*** 2103,2113 ****
   *  for SFI devices. All 82599 SFI devices should have version 0.6 or higher.
   *
   *  Returns IXGBE_ERR_EEPROM_VERSION if the FW is not present or
   *  if the FW version is not supported.
   **/
! static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw)
  {
          s32 status = IXGBE_ERR_EEPROM_VERSION;
          u16 fw_offset, fw_ptp_cfg_offset;
          u16 fw_version = 0;
  
--- 2281,2291 ----
   *  for SFI devices. All 82599 SFI devices should have version 0.6 or higher.
   *
   *  Returns IXGBE_ERR_EEPROM_VERSION if the FW is not present or
   *  if the FW version is not supported.
   **/
! s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw)
  {
          s32 status = IXGBE_ERR_EEPROM_VERSION;
          u16 fw_offset, fw_ptp_cfg_offset;
          u16 fw_version = 0;
  
*** 2252,2257 ****
--- 2430,2486 ----
                  ret_val = ixgbe_read_eeprom_bit_bang_generic(hw, offset, data);
  
          return ret_val;
  }
  
+ /**
+  * ixgbe_reset_pipeline_82599 - perform pipeline reset
+  *
+  *  @hw: pointer to hardware structure
+  *
+  * Reset pipeline by asserting Restart_AN together with LMS change to ensure
+  * full pipeline reset
+  **/
+ s32 ixgbe_reset_pipeline_82599(struct ixgbe_hw *hw)
+ {
+         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);
+         if (autoc2_reg & IXGBE_AUTOC2_LINK_DISABLE_MASK) {
+                 autoc2_reg &= ~IXGBE_AUTOC2_LINK_DISABLE_MASK;
+                 IXGBE_WRITE_REG(hw, IXGBE_AUTOC2, autoc2_reg);
+                 IXGBE_WRITE_FLUSH(hw);
+         }
+ 
+         autoc_reg = hw->mac.cached_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);
+         /* Wait for AN to leave state 0 */
+         for (i = 0; i < 10; i++) {
+                 msec_delay(4);
+                 anlp1_reg = IXGBE_READ_REG(hw, IXGBE_ANLP1);
+                 if (anlp1_reg & IXGBE_ANLP1_AN_STATE_MASK)
+                         break;
+         }
+ 
+         if (!(anlp1_reg & IXGBE_ANLP1_AN_STATE_MASK)) {
+                 DEBUGOUT("auto negotiation not completed\n");
+                 ret_val = IXGBE_ERR_RESET_FAILED;
+                 goto reset_pipeline_out;
+         }
+ 
+         ret_val = IXGBE_SUCCESS;
+ 
+ reset_pipeline_out:
+         /* Write AUTOC register with original LMS field and Restart_AN */
+         IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
+         IXGBE_WRITE_FLUSH(hw);
+ 
+         return ret_val;
+ }
+ 
+ 
+