ixgbe/base: add SFP+ dual-speed support
authorWenzhuo Lu <wenzhuo.lu@intel.com>
Fri, 5 Jun 2015 05:21:46 +0000 (13:21 +0800)
committerThomas Monjalon <thomas.monjalon@6wind.com>
Mon, 15 Jun 2015 20:44:53 +0000 (22:44 +0200)
This patch adds SFP+ dual-speed support.
82599 fiber link code was moved from ixgbe_82599.c to ixgbe_commom.c
for use by X550em, and the API was updated to support the common code
usage. SFP MAC link code is added to x550em.

Signed-off-by: Changchun Ouyang <changchun.ouyang@intel.com>
Signed-off-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
Acked-by: Helin Zhang <helin.zhang@intel.com>
drivers/net/ixgbe/base/ixgbe_82599.c
drivers/net/ixgbe/base/ixgbe_82599.h
drivers/net/ixgbe/base/ixgbe_api.c
drivers/net/ixgbe/base/ixgbe_api.h
drivers/net/ixgbe/base/ixgbe_common.c
drivers/net/ixgbe/base/ixgbe_common.h
drivers/net/ixgbe/base/ixgbe_phy.h
drivers/net/ixgbe/base/ixgbe_type.h
drivers/net/ixgbe/base/ixgbe_x550.c
drivers/net/ixgbe/base/ixgbe_x550.h

index 90de625..f0deb59 100644 (file)
@@ -84,6 +84,9 @@ void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw)
        if (hw->phy.multispeed_fiber) {
                /* Set up dual speed SFP+ support */
                mac->ops.setup_link = ixgbe_setup_mac_link_multispeed_fiber;
+               mac->ops.setup_mac_link = ixgbe_setup_mac_link_82599;
+               mac->ops.set_rate_select_speed =
+                                              ixgbe_set_hard_rate_select_speed;
        } else {
                if ((ixgbe_get_media_type(hw) == ixgbe_media_type_backplane) &&
                     (hw->phy.smart_speed == ixgbe_smart_speed_auto ||
@@ -729,172 +732,33 @@ void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw)
        }
 }
 
-
 /**
- *  ixgbe_setup_mac_link_multispeed_fiber - Set MAC link speed
+ *  ixgbe_set_hard_rate_select_speed - Set module link speed
  *  @hw: pointer to hardware structure
- *  @speed: new link speed
- *  @autoneg_wait_to_complete: true when waiting for completion is needed
+ *  @speed: link speed to set
  *
- *  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)
+ *  Set module link speed via RS0/RS1 rate select pins.
+ */
+void ixgbe_set_hard_rate_select_speed(struct ixgbe_hw *hw,
+                                       ixgbe_link_speed speed)
 {
-       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;
-
-       /*
-        * Try each speed one by one, highest priority first.  We do this in
-        * software because 10gb fiber doesn't support speed autonegotiation.
-        */
-       if (speed & IXGBE_LINK_SPEED_10GB_FULL) {
-               speedcnt++;
-               highest_link_speed = IXGBE_LINK_SPEED_10GB_FULL;
-
-               /* If we already have link at this speed, just jump out */
-               status = ixgbe_check_link(hw, &link_speed, &link_up, false);
-               if (status != IXGBE_SUCCESS)
-                       return status;
-
-               if ((link_speed == IXGBE_LINK_SPEED_10GB_FULL) && link_up)
-                       goto out;
-
-               /* Set the module link speed */
-               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;
-               case ixgbe_media_type_fiber_qsfp:
-                       /* QSFP module automatically detects MAC link speed */
-                       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_wait_to_complete);
-               if (status != IXGBE_SUCCESS)
-                       return status;
-
-               /* Flap the tx laser if it has not already been done */
-               ixgbe_flap_tx_laser(hw);
-
-               /*
-                * Wait for the controller to acquire link.  Per IEEE 802.3ap,
-                * Section 73.10.2, we may have to wait up to 500ms if KR is
-                * attempted.  82599 uses the same timing for 10g SFI.
-                */
-               for (i = 0; i < 5; i++) {
-                       /* Wait for the link partner to also set speed */
-                       msec_delay(100);
-
-                       /* If we have link, just jump out */
-                       status = ixgbe_check_link(hw, &link_speed,
-                                                 &link_up, false);
-                       if (status != IXGBE_SUCCESS)
-                               return status;
-
-                       if (link_up)
-                               goto out;
-               }
-       }
 
-       if (speed & IXGBE_LINK_SPEED_1GB_FULL) {
-               speedcnt++;
-               if (highest_link_speed == IXGBE_LINK_SPEED_UNKNOWN)
-                       highest_link_speed = IXGBE_LINK_SPEED_1GB_FULL;
-
-               /* If we already have link at this speed, just jump out */
-               status = ixgbe_check_link(hw, &link_speed, &link_up, false);
-               if (status != IXGBE_SUCCESS)
-                       return status;
-
-               if ((link_speed == IXGBE_LINK_SPEED_1GB_FULL) && link_up)
-                       goto out;
-
-               /* Set the module link speed */
-               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;
-               case ixgbe_media_type_fiber_qsfp:
-                       /* QSFP module automatically detects link speed */
-                       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_wait_to_complete);
-               if (status != IXGBE_SUCCESS)
-                       return status;
-
-               /* 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 */
-               msec_delay(100);
-
-               /* If we have link, just jump out */
-               status = ixgbe_check_link(hw, &link_speed, &link_up, false);
-               if (status != IXGBE_SUCCESS)
-                       return status;
-
-               if (link_up)
-                       goto out;
+       switch (speed) {
+       case IXGBE_LINK_SPEED_10GB_FULL:
+               esdp_reg |= (IXGBE_ESDP_SDP5_DIR | IXGBE_ESDP_SDP5);
+               break;
+       case IXGBE_LINK_SPEED_1GB_FULL:
+               esdp_reg &= ~IXGBE_ESDP_SDP5;
+               esdp_reg |= IXGBE_ESDP_SDP5_DIR;
+               break;
+       default:
+               DEBUGOUT("Invalid fixed module speed\n");
+               return;
        }
 
-       /*
-        * We didn't get link.  Configure back to the highest speed we tried,
-        * (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;
-
-       if (speed & IXGBE_LINK_SPEED_10GB_FULL)
-               hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10GB_FULL;
-
-       if (speed & IXGBE_LINK_SPEED_1GB_FULL)
-               hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_1GB_FULL;
-
-       return status;
+       IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
+       IXGBE_WRITE_FLUSH(hw);
 }
 
 /**
@@ -2601,7 +2465,6 @@ reset_pipeline_out:
        return ret_val;
 }
 
-
 /**
  *  ixgbe_read_i2c_byte_82599 - Reads 8 bit word over I2C
  *  @hw: pointer to hardware structure
@@ -2715,4 +2578,3 @@ release_i2c_access:
 
        return status;
 }
-
index adf109c..c034d3d 100644 (file)
@@ -40,9 +40,8 @@ enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw);
 void ixgbe_disable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw);
 void ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw);
 void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw);
-s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
-                                         ixgbe_link_speed speed,
-                                         bool autoneg_wait_to_complete);
+void ixgbe_set_hard_rate_select_speed(struct ixgbe_hw *hw,
+                                       ixgbe_link_speed speed);
 s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw,
                                    ixgbe_link_speed speed,
                                    bool autoneg_wait_to_complete);
index 1ba7b9a..8a14888 100644 (file)
@@ -659,6 +659,22 @@ s32 ixgbe_setup_link(struct ixgbe_hw *hw, ixgbe_link_speed speed,
                               IXGBE_NOT_IMPLEMENTED);
 }
 
+/**
+ *  ixgbe_setup_mac_link - Set link speed
+ *  @hw: pointer to hardware structure
+ *  @speed: new link speed
+ *
+ *  Configures link settings.  Restarts the link.
+ *  Performs autonegotiation if needed.
+ **/
+s32 ixgbe_setup_mac_link(struct ixgbe_hw *hw, ixgbe_link_speed speed,
+                        bool autoneg_wait_to_complete)
+{
+       return ixgbe_call_func(hw, hw->mac.ops.setup_mac_link, (hw, speed,
+                              autoneg_wait_to_complete),
+                              IXGBE_NOT_IMPLEMENTED);
+}
+
 /**
  *  ixgbe_get_link_capabilities - Returns link capabilities
  *  @hw: pointer to hardware structure
@@ -1543,3 +1559,16 @@ void ixgbe_enable_rx(struct ixgbe_hw *hw)
        if (hw->mac.ops.enable_rx)
                hw->mac.ops.enable_rx(hw);
 }
+
+/**
+ *  ixgbe_set_rate_select_speed - Set module link speed
+ *  @hw: pointer to hardware structure
+ *  @speed: link speed to set
+ *
+ *  Set module link speed via the rate select.
+ */
+void ixgbe_set_rate_select_speed(struct ixgbe_hw *hw, ixgbe_link_speed speed)
+{
+       if (hw->mac.ops.set_rate_select_speed)
+               hw->mac.ops.set_rate_select_speed(hw, speed);
+}
index 784d365..d822e52 100644 (file)
@@ -83,6 +83,8 @@ void ixgbe_enable_tx_laser(struct ixgbe_hw *hw);
 void ixgbe_flap_tx_laser(struct ixgbe_hw *hw);
 s32 ixgbe_setup_link(struct ixgbe_hw *hw, ixgbe_link_speed speed,
                     bool autoneg_wait_to_complete);
+s32 ixgbe_setup_mac_link(struct ixgbe_hw *hw, ixgbe_link_speed speed,
+                        bool autoneg_wait_to_complete);
 s32 ixgbe_check_link(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
                     bool *link_up, bool link_up_wait_to_complete);
 s32 ixgbe_get_link_capabilities(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
@@ -208,6 +210,7 @@ void ixgbe_disable_mdd(struct ixgbe_hw *hw);
 void ixgbe_enable_mdd(struct ixgbe_hw *hw);
 void ixgbe_mdd_event(struct ixgbe_hw *hw, u32 *vf_bitmap);
 void ixgbe_restore_mdd_vf(struct ixgbe_hw *hw, u32 vf);
+void ixgbe_set_rate_select_speed(struct ixgbe_hw *hw, ixgbe_link_speed speed);
 void ixgbe_disable_rx(struct ixgbe_hw *hw);
 void ixgbe_enable_rx(struct ixgbe_hw *hw);
 
index 11cc2f4..3758df1 100644 (file)
@@ -4908,3 +4908,231 @@ bool ixgbe_mng_enabled(struct ixgbe_hw *hw)
 
        return true;
 }
+
+/**
+ *  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 MAC and/or PHY register and restarts link.
+ **/
+s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
+                                         ixgbe_link_speed speed,
+                                         bool autoneg_wait_to_complete)
+{
+       ixgbe_link_speed link_speed = IXGBE_LINK_SPEED_UNKNOWN;
+       ixgbe_link_speed highest_link_speed = IXGBE_LINK_SPEED_UNKNOWN;
+       s32 status = IXGBE_SUCCESS;
+       u32 speedcnt = 0;
+       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;
+
+       /* Try each speed one by one, highest priority first.  We do this in
+        * software because 10Gb fiber doesn't support speed autonegotiation.
+        */
+       if (speed & IXGBE_LINK_SPEED_10GB_FULL) {
+               speedcnt++;
+               highest_link_speed = IXGBE_LINK_SPEED_10GB_FULL;
+
+               /* If we already have link at this speed, just jump out */
+               status = ixgbe_check_link(hw, &link_speed, &link_up, false);
+               if (status != IXGBE_SUCCESS)
+                       return status;
+
+               if ((link_speed == IXGBE_LINK_SPEED_10GB_FULL) && link_up)
+                       goto out;
+
+               /* Set the module link speed */
+               switch (hw->phy.media_type) {
+               case ixgbe_media_type_fiber:
+                       ixgbe_set_rate_select_speed(hw,
+                                                   IXGBE_LINK_SPEED_10GB_FULL);
+                       break;
+               case ixgbe_media_type_fiber_qsfp:
+                       /* QSFP module automatically detects MAC link speed */
+                       break;
+               default:
+                       DEBUGOUT("Unexpected media type.\n");
+                       break;
+               }
+
+               /* Allow module to change analog characteristics (1G->10G) */
+               msec_delay(40);
+
+               status = ixgbe_setup_mac_link(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 */
+               ixgbe_flap_tx_laser(hw);
+
+               /* Wait for the controller to acquire link.  Per IEEE 802.3ap,
+                * Section 73.10.2, we may have to wait up to 500ms if KR is
+                * attempted.  82599 uses the same timing for 10g SFI.
+                */
+               for (i = 0; i < 5; i++) {
+                       /* Wait for the link partner to also set speed */
+                       msec_delay(100);
+
+                       /* If we have link, just jump out */
+                       status = ixgbe_check_link(hw, &link_speed,
+                                                 &link_up, false);
+                       if (status != IXGBE_SUCCESS)
+                               return status;
+
+                       if (link_up)
+                               goto out;
+               }
+       }
+
+       if (speed & IXGBE_LINK_SPEED_1GB_FULL) {
+               speedcnt++;
+               if (highest_link_speed == IXGBE_LINK_SPEED_UNKNOWN)
+                       highest_link_speed = IXGBE_LINK_SPEED_1GB_FULL;
+
+               /* If we already have link at this speed, just jump out */
+               status = ixgbe_check_link(hw, &link_speed, &link_up, false);
+               if (status != IXGBE_SUCCESS)
+                       return status;
+
+               if ((link_speed == IXGBE_LINK_SPEED_1GB_FULL) && link_up)
+                       goto out;
+
+               /* Set the module link speed */
+               switch (hw->phy.media_type) {
+               case ixgbe_media_type_fiber:
+                       ixgbe_set_rate_select_speed(hw,
+                                                   IXGBE_LINK_SPEED_1GB_FULL);
+                       break;
+               case ixgbe_media_type_fiber_qsfp:
+                       /* QSFP module automatically detects link speed */
+                       break;
+               default:
+                       DEBUGOUT("Unexpected media type.\n");
+                       break;
+               }
+
+               /* Allow module to change analog characteristics (10G->1G) */
+               msec_delay(40);
+
+               status = ixgbe_setup_mac_link(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 */
+               ixgbe_flap_tx_laser(hw);
+
+               /* Wait for the link partner to also set speed */
+               msec_delay(100);
+
+               /* If we have link, just jump out */
+               status = ixgbe_check_link(hw, &link_speed, &link_up, false);
+               if (status != IXGBE_SUCCESS)
+                       return status;
+
+               if (link_up)
+                       goto out;
+       }
+
+       /* We didn't get link.  Configure back to the highest speed we tried,
+        * (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;
+
+       if (speed & IXGBE_LINK_SPEED_10GB_FULL)
+               hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10GB_FULL;
+
+       if (speed & IXGBE_LINK_SPEED_1GB_FULL)
+               hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_1GB_FULL;
+
+       return status;
+}
+
+/**
+ *  ixgbe_set_soft_rate_select_speed - Set module link speed
+ *  @hw: pointer to hardware structure
+ *  @speed: link speed to set
+ *
+ *  Set module link speed via the soft rate select.
+ */
+void ixgbe_set_soft_rate_select_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;
+}
index 25d5eb1..71507df 100644 (file)
@@ -179,4 +179,9 @@ s32 ixgbe_get_thermal_sensor_data_generic(struct ixgbe_hw *hw);
 s32 ixgbe_init_thermal_sensor_thresh_generic(struct ixgbe_hw *hw);
 void ixgbe_disable_rx_generic(struct ixgbe_hw *hw);
 void ixgbe_enable_rx_generic(struct ixgbe_hw *hw);
+s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
+                                         ixgbe_link_speed speed,
+                                         bool autoneg_wait_to_complete);
+void ixgbe_set_soft_rate_select_speed(struct ixgbe_hw *hw,
+                                     ixgbe_link_speed speed);
 #endif /* IXGBE_COMMON */
index ba5b308..ffab02e 100644 (file)
@@ -51,6 +51,8 @@ POSSIBILITY OF SUCH DAMAGE.
 #define IXGBE_SFF_CABLE_SPEC_COMP      0x3C
 #define IXGBE_SFF_SFF_8472_SWAP                0x5C
 #define IXGBE_SFF_SFF_8472_COMP                0x5E
+#define IXGBE_SFF_SFF_8472_OSCB                0x6E
+#define IXGBE_SFF_SFF_8472_ESCB                0x76
 #define IXGBE_SFF_IDENTIFIER_QSFP_PLUS 0xD
 #define IXGBE_SFF_QSFP_VENDOR_OUI_BYTE0        0xA5
 #define IXGBE_SFF_QSFP_VENDOR_OUI_BYTE1        0xA6
@@ -70,6 +72,9 @@ POSSIBILITY OF SUCH DAMAGE.
 #define IXGBE_SFF_1GBASET_CAPABLE      0x8
 #define IXGBE_SFF_10GBASESR_CAPABLE    0x10
 #define IXGBE_SFF_10GBASELR_CAPABLE    0x20
+#define IXGBE_SFF_SOFT_RS_SELECT_MASK  0x8
+#define IXGBE_SFF_SOFT_RS_SELECT_10G   0x8
+#define IXGBE_SFF_SOFT_RS_SELECT_1G    0x0
 #define IXGBE_SFF_ADDRESSING_MODE      0x4
 #define IXGBE_SFF_QSFP_DA_ACTIVE_CABLE 0x1
 #define IXGBE_SFF_QSFP_DA_PASSIVE_CABLE        0x8
index 4e38f53..d095ae8 100644 (file)
@@ -3541,9 +3541,11 @@ struct ixgbe_mac_operations {
        void (*enable_tx_laser)(struct ixgbe_hw *);
        void (*flap_tx_laser)(struct ixgbe_hw *);
        s32 (*setup_link)(struct ixgbe_hw *, ixgbe_link_speed, bool);
+       s32 (*setup_mac_link)(struct ixgbe_hw *, ixgbe_link_speed, bool);
        s32 (*check_link)(struct ixgbe_hw *, ixgbe_link_speed *, bool *, bool);
        s32 (*get_link_capabilities)(struct ixgbe_hw *, ixgbe_link_speed *,
                                     bool *);
+       void (*set_rate_select_speed)(struct ixgbe_hw *, ixgbe_link_speed);
 
        /* Packet Buffer manipulation */
        void (*setup_rxpba)(struct ixgbe_hw *, int, u32, int);
@@ -3583,16 +3585,16 @@ struct ixgbe_mac_operations {
        s32 (*set_fw_drv_ver)(struct ixgbe_hw *, u8, u8, u8, u8);
        s32 (*get_thermal_sensor_data)(struct ixgbe_hw *);
        s32 (*init_thermal_sensor_thresh)(struct ixgbe_hw *hw);
-       s32 (*dmac_config)(struct ixgbe_hw *hw);
-       s32 (*dmac_update_tcs)(struct ixgbe_hw *hw);
-       s32 (*dmac_config_tcs)(struct ixgbe_hw *hw);
        void (*get_rtrup2tc)(struct ixgbe_hw *hw, u8 *map);
-       s32 (*setup_eee)(struct ixgbe_hw *hw, bool enable_eee);
-       void (*set_ethertype_anti_spoofing)(struct ixgbe_hw *, bool, int);
-       void (*set_source_address_pruning)(struct ixgbe_hw *, bool,
-                                          unsigned int);
        void (*disable_rx)(struct ixgbe_hw *hw);
        void (*enable_rx)(struct ixgbe_hw *hw);
+       void (*set_source_address_pruning)(struct ixgbe_hw *, bool,
+                                          unsigned int);
+       void (*set_ethertype_anti_spoofing)(struct ixgbe_hw *, bool, int);
+       s32 (*dmac_update_tcs)(struct ixgbe_hw *hw);
+       s32 (*dmac_config_tcs)(struct ixgbe_hw *hw);
+       s32 (*dmac_config)(struct ixgbe_hw *hw);
+       s32 (*setup_eee)(struct ixgbe_hw *hw, bool enable_eee);
        s32 (*read_iosf_sb_reg)(struct ixgbe_hw *, u32, u32, u32 *);
        s32 (*write_iosf_sb_reg)(struct ixgbe_hw *, u32, u32, u32);
        void (*disable_mdd)(struct ixgbe_hw *hw);
index e6d0a9f..2698c54 100644 (file)
@@ -1046,10 +1046,14 @@ void ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw *hw)
        /* CS4227 does not support autoneg, so disable the laser control
         * functions for SFP+ fiber
         */
-        if (hw->device_id == IXGBE_DEV_ID_X550EM_X_SFP) {
+        if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber) {
                mac->ops.disable_tx_laser = NULL;
                mac->ops.enable_tx_laser = NULL;
                mac->ops.flap_tx_laser = NULL;
+               mac->ops.setup_link = ixgbe_setup_mac_link_multispeed_fiber;
+               mac->ops.setup_mac_link = ixgbe_setup_mac_link_sfp_x550em;
+               mac->ops.set_rate_select_speed =
+                                       ixgbe_set_soft_rate_select_speed;
         }
 }
 
@@ -1110,7 +1114,7 @@ s32 ixgbe_init_phy_ops_X550em(struct ixgbe_hw *hw)
 
        DEBUGFUNC("ixgbe_init_phy_ops_X550em");
 
-       if (hw->device_id == IXGBE_DEV_ID_X550EM_X_SFP) {
+       if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber) {
                phy->phy_semaphore_mask = IXGBE_GSSR_SHARED_I2C_SM;
                ixgbe_setup_mux_ctl(hw);
        }
@@ -1555,6 +1559,21 @@ STATIC s32 ixgbe_setup_ixfi_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed)
        return status;
 }
 
+/**
+ *  ixgbe_setup_mac_link_sfp_x550em - Configure the KR PHY for SFP.
+ *  @hw: pointer to hardware structure
+ *
+ *  Configures the integrated KR PHY for SFP support.
+ **/
+s32 ixgbe_setup_mac_link_sfp_x550em(struct ixgbe_hw *hw,
+                                   ixgbe_link_speed speed,
+                                   bool autoneg_wait_to_complete)
+{
+       UNREFERENCED_1PARAMETER(autoneg_wait_to_complete);
+
+       return ixgbe_setup_ixfi_x550em(hw, &speed);
+}
+
 /**
  * ixgbe_setup_internal_phy_x550em - Configure integrated KR PHY
  * @hw: point to hardware structure
index 16afad3..5589453 100644 (file)
@@ -87,5 +87,8 @@ s32 ixgbe_setup_internal_phy_x550em(struct ixgbe_hw *hw);
 s32 ixgbe_setup_phy_loopback_x550em(struct ixgbe_hw *hw);
 u32 ixgbe_get_supported_physical_layer_X550em(struct ixgbe_hw *hw);
 void ixgbe_disable_rx_x550(struct ixgbe_hw *hw);
+s32 ixgbe_setup_mac_link_sfp_x550em(struct ixgbe_hw *hw,
+                                   ixgbe_link_speed speed,
+                                   bool autoneg_wait_to_complete);
 #endif /* _IXGBE_X550_H_ */