diff --git a/sys/dev/ixgbe/if_ix.c b/sys/dev/ixgbe/if_ix.c --- a/sys/dev/ixgbe/if_ix.c +++ b/sys/dev/ixgbe/if_ix.c @@ -179,7 +179,7 @@ static void ixgbe_add_hw_stats(struct ixgbe_softc *); static int ixgbe_set_flowcntl(struct ixgbe_softc *, int); static int ixgbe_set_advertise(struct ixgbe_softc *, int); -static int ixgbe_get_advertise(struct ixgbe_softc *); +static int ixgbe_get_default_advertise(struct ixgbe_softc *); static void ixgbe_setup_vlan_hw_support(if_ctx_t); static void ixgbe_config_gpie(struct ixgbe_softc *); static void ixgbe_config_delay_values(struct ixgbe_softc *); @@ -1121,7 +1121,7 @@ /* Set an initial dmac value */ sc->dmac = 0; /* Set initial advertised speeds (if applicable) */ - sc->advertise = ixgbe_get_advertise(sc); + sc->advertise = ixgbe_get_default_advertise(sc); if (sc->feat_cap & IXGBE_FEATURE_SRIOV) ixgbe_define_iov_schemas(dev, &error); @@ -1286,6 +1286,11 @@ if (layer & IXGBE_PHYSICAL_LAYER_10BASE_T) ifmedia_add(sc->media, IFM_ETHER | IFM_10_T, 0, NULL); + if (hw->mac.type == ixgbe_mac_X550) { + ifmedia_add(sc->media, IFM_ETHER | IFM_2500_T, 0, NULL); + ifmedia_add(sc->media, IFM_ETHER | IFM_5000_T, 0, NULL); + } + if (layer & IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU || layer & IXGBE_PHYSICAL_LAYER_SFP_ACTIVE_DA) ifmedia_add(sc->media, IFM_ETHER | IFM_10G_TWINAX, 0, @@ -1407,6 +1412,36 @@ &negotiate); if (err) return; + + if (hw->mac.type == ixgbe_mac_X550 && + hw->phy.autoneg_advertised == 0) { + /* + * 2.5G and 5G autonegotiation speeds on X550 + * are disabled by default due to reported + * interoperability issues with some switches. + * + * The second condition checks if any operations + * involving setting autonegotiation speeds have + * been performed prior to this ixgbe_config_link() + * call. + * + * If hw->phy.autoneg_advertised does not + * equal 0, this means that the user might have + * set autonegotiation speeds via the sysctl + * before bringing the interface up. In this + * case, we should not disable 2.5G and 5G + * since that speeds might be selected by the + * user. + * + * Otherwise (i.e. if hw->phy.autoneg_advertised + * is set to 0), it is the first time we set + * autonegotiation preferences and the default + * set of speeds should exclude 2.5G and 5G. + */ + autoneg &= ~(IXGBE_LINK_SPEED_2_5GB_FULL | + IXGBE_LINK_SPEED_5GB_FULL); + } + if (hw->mac.ops.setup_link) err = hw->mac.ops.setup_link(hw, autoneg, sc->link_up); @@ -2230,6 +2265,15 @@ ifmr->ifm_active |= IFM_10_T | IFM_FDX; break; } + if (hw->mac.type == ixgbe_mac_X550) + switch (sc->link_speed) { + case IXGBE_LINK_SPEED_5GB_FULL: + ifmr->ifm_active |= IFM_5000_T | IFM_FDX; + break; + case IXGBE_LINK_SPEED_2_5GB_FULL: + ifmr->ifm_active |= IFM_2500_T | IFM_FDX; + break; + } if (layer & IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU || layer & IXGBE_PHYSICAL_LAYER_SFP_ACTIVE_DA) switch (sc->link_speed) { @@ -2406,6 +2450,12 @@ case IFM_10G_TWINAX: speed |= IXGBE_LINK_SPEED_10GB_FULL; break; + case IFM_5000_T: + speed |= IXGBE_LINK_SPEED_5GB_FULL; + break; + case IFM_2500_T: + speed |= IXGBE_LINK_SPEED_2_5GB_FULL; + break; case IFM_100_TX: speed |= IXGBE_LINK_SPEED_100_FULL; break; @@ -2419,10 +2469,12 @@ hw->mac.autotry_restart = true; hw->mac.ops.setup_link(hw, speed, true); sc->advertise = - ((speed & IXGBE_LINK_SPEED_10GB_FULL) ? 4 : 0) | - ((speed & IXGBE_LINK_SPEED_1GB_FULL) ? 2 : 0) | - ((speed & IXGBE_LINK_SPEED_100_FULL) ? 1 : 0) | - ((speed & IXGBE_LINK_SPEED_10_FULL) ? 8 : 0); + ((speed & IXGBE_LINK_SPEED_10GB_FULL) ? 0x4 : 0) | + ((speed & IXGBE_LINK_SPEED_5GB_FULL) ? 0x20 : 0) | + ((speed & IXGBE_LINK_SPEED_2_5GB_FULL) ? 0x10 : 0) | + ((speed & IXGBE_LINK_SPEED_1GB_FULL) ? 0x2 : 0) | + ((speed & IXGBE_LINK_SPEED_100_FULL) ? 0x1 : 0) | + ((speed & IXGBE_LINK_SPEED_10_FULL) ? 0x8 : 0); return (0); @@ -4093,10 +4145,13 @@ * ixgbe_set_advertise - Control advertised link speed * * Flags: - * 0x1 - advertise 100 Mb - * 0x2 - advertise 1G - * 0x4 - advertise 10G - * 0x8 - advertise 10 Mb (yes, Mb) + * 0x1 - advertise 100 Mb + * 0x2 - advertise 1G + * 0x4 - advertise 10G + * 0x8 - advertise 10 Mb (yes, Mb) + * 0x10 - advertise 2.5G (disabled by default) + * 0x20 - advertise 5G (disabled by default) + * ************************************************************************/ static int ixgbe_set_advertise(struct ixgbe_softc *sc, int advertise) @@ -4124,8 +4179,8 @@ return (EINVAL); } - if (advertise < 0x1 || advertise > 0xF) { - device_printf(dev, "Invalid advertised speed; valid modes are 0x1 through 0xF\n"); + if (advertise < 0x1 || advertise > 0x3F) { + device_printf(dev, "Invalid advertised speed; valid modes are 0x1 through 0x3F\n"); return (EINVAL); } @@ -4167,6 +4222,20 @@ } speed |= IXGBE_LINK_SPEED_10_FULL; } + if (advertise & 0x10) { + if (!(link_caps & IXGBE_LINK_SPEED_2_5GB_FULL)) { + device_printf(dev, "Interface does not support 2.5G advertised speed\n"); + return (EINVAL); + } + speed |= IXGBE_LINK_SPEED_2_5GB_FULL; + } + if (advertise & 0x20) { + if (!(link_caps & IXGBE_LINK_SPEED_5GB_FULL)) { + device_printf(dev, "Interface does not support 5G advertised speed\n"); + return (EINVAL); + } + speed |= IXGBE_LINK_SPEED_5GB_FULL; + } hw->mac.autotry_restart = true; hw->mac.ops.setup_link(hw, speed, true); @@ -4176,7 +4245,7 @@ } /* ixgbe_set_advertise */ /************************************************************************ - * ixgbe_get_advertise - Get current advertised speed settings + * ixgbe_get_default_advertise - Get default advertised speed settings * * Formatted for sysctl usage. * Flags: @@ -4184,9 +4253,11 @@ * 0x2 - advertise 1G * 0x4 - advertise 10G * 0x8 - advertise 10 Mb (yes, Mb) + * 0x10 - advertise 2.5G (disabled by default) + * 0x20 - advertise 5G (disabled by default) ************************************************************************/ static int -ixgbe_get_advertise(struct ixgbe_softc *sc) +ixgbe_get_default_advertise(struct ixgbe_softc *sc) { struct ixgbe_hw *hw = &sc->hw; int speed; @@ -4206,14 +4277,26 @@ if (err != IXGBE_SUCCESS) return (0); + if (hw->mac.type == ixgbe_mac_X550) { + /* + * 2.5G and 5G autonegotiation speeds on X550 + * are disabled by default due to reported + * interoperability issues with some switches. + */ + link_caps &= ~(IXGBE_LINK_SPEED_2_5GB_FULL | + IXGBE_LINK_SPEED_5GB_FULL); + } + speed = - ((link_caps & IXGBE_LINK_SPEED_10GB_FULL) ? 4 : 0) | - ((link_caps & IXGBE_LINK_SPEED_1GB_FULL) ? 2 : 0) | - ((link_caps & IXGBE_LINK_SPEED_100_FULL) ? 1 : 0) | - ((link_caps & IXGBE_LINK_SPEED_10_FULL) ? 8 : 0); + ((link_caps & IXGBE_LINK_SPEED_10GB_FULL) ? 0x4 : 0) | + ((link_caps & IXGBE_LINK_SPEED_5GB_FULL) ? 0x20 : 0) | + ((link_caps & IXGBE_LINK_SPEED_2_5GB_FULL) ? 0x10 : 0) | + ((link_caps & IXGBE_LINK_SPEED_1GB_FULL) ? 0x2 : 0) | + ((link_caps & IXGBE_LINK_SPEED_100_FULL) ? 0x1 : 0) | + ((link_caps & IXGBE_LINK_SPEED_10_FULL) ? 0x8 : 0); return speed; -} /* ixgbe_get_advertise */ +} /* ixgbe_get_default_advertise */ /************************************************************************ * ixgbe_sysctl_dmac - Manage DMA Coalescing diff --git a/sys/dev/ixgbe/ixgbe.h b/sys/dev/ixgbe/ixgbe.h --- a/sys/dev/ixgbe/ixgbe.h +++ b/sys/dev/ixgbe/ixgbe.h @@ -491,6 +491,8 @@ "\t0x2 - advertise 1G\n" \ "\t0x4 - advertise 10G\n" \ "\t0x8 - advertise 10M\n\n" \ + "\t0x10 - advertise 2.5G\n" \ + "\t0x20 - advertise 5G\n\n" \ "\t100M and 10M are only supported on certain adapters.\n" #define IXGBE_SYSCTL_DESC_SET_FC \