ixgbe: Update setup PHY link to unset all speeds
authorDon Skidmore <donald.c.skidmore@intel.com>
Sat, 22 Oct 2016 01:10:54 +0000 (21:10 -0400)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Sat, 5 Nov 2016 00:04:58 +0000 (17:04 -0700)
This patch updates ixgbe_setup_phy_link_generic to set/unset
auto-negotiation for all speeds. This ensures that unsupported
speeds are unset. This is necessary since the PHY NVM may
advertise unsupported speeds.

Signed-off-by: Don Skidmore <donald.c.skidmore@intel.com>
Tested-by: Krishneil Singh <krishneil.k.singh@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c

index 021ab9b89c71e30cd8262118e051ab9aaf672ec4..648739a3904af1cab261ca754ed1028efbbb1c0a 100644 (file)
@@ -705,53 +705,52 @@ s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw)
 
        ixgbe_get_copper_link_capabilities_generic(hw, &speed, &autoneg);
 
-       if (speed & IXGBE_LINK_SPEED_10GB_FULL) {
-               /* Set or unset auto-negotiation 10G advertisement */
-               hw->phy.ops.read_reg(hw, MDIO_AN_10GBT_CTRL,
-                                    MDIO_MMD_AN,
-                                    &autoneg_reg);
+       /* Set or unset auto-negotiation 10G advertisement */
+       hw->phy.ops.read_reg(hw, MDIO_AN_10GBT_CTRL, MDIO_MMD_AN, &autoneg_reg);
 
-               autoneg_reg &= ~MDIO_AN_10GBT_CTRL_ADV10G;
-               if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL)
-                       autoneg_reg |= MDIO_AN_10GBT_CTRL_ADV10G;
+       autoneg_reg &= ~MDIO_AN_10GBT_CTRL_ADV10G;
+       if ((hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL) &&
+           (speed & IXGBE_LINK_SPEED_10GB_FULL))
+               autoneg_reg |= MDIO_AN_10GBT_CTRL_ADV10G;
 
-               hw->phy.ops.write_reg(hw, MDIO_AN_10GBT_CTRL,
-                                     MDIO_MMD_AN,
-                                     autoneg_reg);
-       }
+       hw->phy.ops.write_reg(hw, MDIO_AN_10GBT_CTRL, MDIO_MMD_AN, autoneg_reg);
 
-       if (speed & IXGBE_LINK_SPEED_1GB_FULL) {
-               /* Set or unset auto-negotiation 1G advertisement */
-               hw->phy.ops.read_reg(hw,
-                                    IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG,
-                                    MDIO_MMD_AN,
-                                    &autoneg_reg);
-
-               autoneg_reg &= ~IXGBE_MII_1GBASE_T_ADVERTISE;
-               if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL)
-                       autoneg_reg |= IXGBE_MII_1GBASE_T_ADVERTISE;
+       hw->phy.ops.read_reg(hw, IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG,
+                            MDIO_MMD_AN, &autoneg_reg);
 
-               hw->phy.ops.write_reg(hw,
-                                     IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG,
-                                     MDIO_MMD_AN,
-                                     autoneg_reg);
+       if (hw->mac.type == ixgbe_mac_X550) {
+               /* Set or unset auto-negotiation 5G advertisement */
+               autoneg_reg &= ~IXGBE_MII_5GBASE_T_ADVERTISE;
+               if ((hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_5GB_FULL) &&
+                   (speed & IXGBE_LINK_SPEED_5GB_FULL))
+                       autoneg_reg |= IXGBE_MII_5GBASE_T_ADVERTISE;
+
+               /* Set or unset auto-negotiation 2.5G advertisement */
+               autoneg_reg &= ~IXGBE_MII_2_5GBASE_T_ADVERTISE;
+               if ((hw->phy.autoneg_advertised &
+                    IXGBE_LINK_SPEED_2_5GB_FULL) &&
+                   (speed & IXGBE_LINK_SPEED_2_5GB_FULL))
+                       autoneg_reg |= IXGBE_MII_2_5GBASE_T_ADVERTISE;
        }
 
-       if (speed & IXGBE_LINK_SPEED_100_FULL) {
-               /* Set or unset auto-negotiation 100M advertisement */
-               hw->phy.ops.read_reg(hw, MDIO_AN_ADVERTISE,
-                                    MDIO_MMD_AN,
-                                    &autoneg_reg);
+       /* Set or unset auto-negotiation 1G advertisement */
+       autoneg_reg &= ~IXGBE_MII_1GBASE_T_ADVERTISE;
+       if ((hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL) &&
+           (speed & IXGBE_LINK_SPEED_1GB_FULL))
+               autoneg_reg |= IXGBE_MII_1GBASE_T_ADVERTISE;
 
-               autoneg_reg &= ~(ADVERTISE_100FULL |
-                                ADVERTISE_100HALF);
-               if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_100_FULL)
-                       autoneg_reg |= ADVERTISE_100FULL;
+       hw->phy.ops.write_reg(hw, IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG,
+                             MDIO_MMD_AN, autoneg_reg);
 
-               hw->phy.ops.write_reg(hw, MDIO_AN_ADVERTISE,
-                                     MDIO_MMD_AN,
-                                     autoneg_reg);
-       }
+       /* Set or unset auto-negotiation 100M advertisement */
+       hw->phy.ops.read_reg(hw, MDIO_AN_ADVERTISE, MDIO_MMD_AN, &autoneg_reg);
+
+       autoneg_reg &= ~(ADVERTISE_100FULL | ADVERTISE_100HALF);
+       if ((hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_100_FULL) &&
+           (speed & IXGBE_LINK_SPEED_100_FULL))
+               autoneg_reg |= ADVERTISE_100FULL;
+
+       hw->phy.ops.write_reg(hw, MDIO_AN_ADVERTISE, MDIO_MMD_AN, autoneg_reg);
 
        /* Blocked by MNG FW so don't reset PHY */
        if (ixgbe_check_reset_blocked(hw))