net/ixgbe/base: fix setting unsupported autoneg speeds
[dpdk.git] / drivers / net / ixgbe / base / ixgbe_phy.c
index 43c55d7..54e45b2 100644 (file)
@@ -528,11 +528,30 @@ s32 ixgbe_reset_phy_generic(struct ixgbe_hw *hw)
         */
        for (i = 0; i < 30; i++) {
                msec_delay(100);
-               hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL,
-                                    IXGBE_MDIO_PHY_XS_DEV_TYPE, &ctrl);
-               if (!(ctrl & IXGBE_MDIO_PHY_XS_RESET)) {
-                       usec_delay(2);
-                       break;
+               if (hw->phy.type == ixgbe_phy_x550em_ext_t) {
+                       status = hw->phy.ops.read_reg(hw,
+                                                 IXGBE_MDIO_TX_VENDOR_ALARMS_3,
+                                                 IXGBE_MDIO_PMA_PMD_DEV_TYPE,
+                                                 &ctrl);
+                       if (status != IXGBE_SUCCESS)
+                               return status;
+
+                       if (ctrl & IXGBE_MDIO_TX_VENDOR_ALARMS_3_RST_MASK) {
+                               usec_delay(2);
+                               break;
+                       }
+               } else {
+                       status = hw->phy.ops.read_reg(hw,
+                                                    IXGBE_MDIO_PHY_XS_CONTROL,
+                                                    IXGBE_MDIO_PHY_XS_DEV_TYPE,
+                                                    &ctrl);
+                       if (status != IXGBE_SUCCESS)
+                               return status;
+
+                       if (!(ctrl & IXGBE_MDIO_PHY_XS_RESET)) {
+                               usec_delay(2);
+                               break;
+                       }
                }
        }
 
@@ -768,91 +787,63 @@ 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, IXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG,
-                                    IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
-                                    &autoneg_reg);
+       /* Set or unset auto-negotiation 10G advertisement */
+       hw->phy.ops.read_reg(hw, IXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG,
+                            IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
+                            &autoneg_reg);
 
-               autoneg_reg &= ~IXGBE_MII_10GBASE_T_ADVERTISE;
-               if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL)
-                       autoneg_reg |= IXGBE_MII_10GBASE_T_ADVERTISE;
+       autoneg_reg &= ~IXGBE_MII_10GBASE_T_ADVERTISE;
+       if ((hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL) &&
+           (speed & IXGBE_LINK_SPEED_10GB_FULL))
+               autoneg_reg |= IXGBE_MII_10GBASE_T_ADVERTISE;
 
-               hw->phy.ops.write_reg(hw, IXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG,
-                                     IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
-                                     autoneg_reg);
-       }
+       hw->phy.ops.write_reg(hw, IXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG,
+                             IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
+                             autoneg_reg);
 
-       if (hw->mac.type == ixgbe_mac_X550) {
-               if (speed & IXGBE_LINK_SPEED_5GB_FULL) {
-                       /* Set or unset auto-negotiation 5G advertisement */
-                       hw->phy.ops.read_reg(hw,
-                               IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG,
-                               IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
-                               &autoneg_reg);
-
-                       autoneg_reg &= ~IXGBE_MII_5GBASE_T_ADVERTISE;
-                       if (hw->phy.autoneg_advertised &
-                            IXGBE_LINK_SPEED_5GB_FULL)
-                               autoneg_reg |= IXGBE_MII_5GBASE_T_ADVERTISE;
-
-                       hw->phy.ops.write_reg(hw,
-                               IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG,
-                               IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
-                               autoneg_reg);
-               }
+       hw->phy.ops.read_reg(hw, IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG,
+                            IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
+                            &autoneg_reg);
 
-               if (speed & IXGBE_LINK_SPEED_2_5GB_FULL) {
-                       /* Set or unset auto-negotiation 2.5G advertisement */
-                       hw->phy.ops.read_reg(hw,
-                               IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG,
-                               IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
-                               &autoneg_reg);
-
-                       autoneg_reg &= ~IXGBE_MII_2_5GBASE_T_ADVERTISE;
-                       if (hw->phy.autoneg_advertised &
-                           IXGBE_LINK_SPEED_2_5GB_FULL)
-                               autoneg_reg |= IXGBE_MII_2_5GBASE_T_ADVERTISE;
-
-                       hw->phy.ops.write_reg(hw,
-                               IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG,
-                               IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
-                               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,
-                                    IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
-                                    &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.write_reg(hw,
-                                     IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG,
-                                     IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
-                                     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, IXGBE_MII_AUTONEG_ADVERTISE_REG,
-                                    IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
-                                    &autoneg_reg);
-
-               autoneg_reg &= ~(IXGBE_MII_100BASE_T_ADVERTISE |
-                                IXGBE_MII_100BASE_T_ADVERTISE_HALF);
-               if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_100_FULL)
-                       autoneg_reg |= IXGBE_MII_100BASE_T_ADVERTISE;
-
-               hw->phy.ops.write_reg(hw, IXGBE_MII_AUTONEG_ADVERTISE_REG,
-                                     IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
-                                     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;
+
+       hw->phy.ops.write_reg(hw, IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG,
+                             IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
+                             autoneg_reg);
+
+       /* Set or unset auto-negotiation 100M advertisement */
+       hw->phy.ops.read_reg(hw, IXGBE_MII_AUTONEG_ADVERTISE_REG,
+                            IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
+                            &autoneg_reg);
+
+       autoneg_reg &= ~(IXGBE_MII_100BASE_T_ADVERTISE |
+                        IXGBE_MII_100BASE_T_ADVERTISE_HALF);
+       if ((hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_100_FULL) &&
+           (speed & IXGBE_LINK_SPEED_100_FULL))
+               autoneg_reg |= IXGBE_MII_100BASE_T_ADVERTISE;
+
+       hw->phy.ops.write_reg(hw, IXGBE_MII_AUTONEG_ADVERTISE_REG,
+                             IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
+                             autoneg_reg);
 
        /* Blocked by MNG FW so don't reset PHY */
        if (ixgbe_check_reset_blocked(hw))